Imported Upstream version 3.0
[debian/gnuradio] / usrp / fpga / toplevel / mrfm / mrfm_compensator.v
1
2
3 module mrfm_compensator (input clock, input reset, input strobe_in,
4                          input serial_strobe, input [6:0] serial_addr, input [31:0] serial_data,
5                          input [15:0] i_in, input [15:0] q_in, output reg [15:0] i_out, output reg [15:0] q_out);
6
7    wire [15:0]                        a11,a12,a21,a22;
8    reg [15:0]                         i_in_reg, q_in_reg;
9    wire [30:0]                        product;
10    reg [3:0]                          phase;
11    wire [15:0]                        data,coeff;
12    wire [7:0]                         shift;
13    wire [33:0]                        accum;
14    wire [15:0]                        scaled_accum;
15    wire enable_acc;
16
17    setting_reg #(`FR_MRFM_COMP_A11) sr_a11(.clock(clock),.reset(reset),
18                                            .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
19                                            .out(a11),.changed());
20    setting_reg #(`FR_MRFM_COMP_A12) sr_a12(.clock(clock),.reset(reset),
21                                            .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
22                                            .out(a12),.changed());
23    setting_reg #(`FR_MRFM_COMP_A21) sr_a21(.clock(clock),.reset(reset),
24                                            .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
25                                            .out(a21),.changed());
26    setting_reg #(`FR_MRFM_COMP_A22) sr_a22(.clock(clock),.reset(reset),
27                                            .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
28                                            .out(a22),.changed());
29    setting_reg #(`FR_MRFM_COMP_SHIFT) sr_cshift(.clock(clock),.reset(reset),
30                                                 .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
31                                                 .out(shift),.changed());
32    
33    mult mult (.clock(clock),.x(data),.y(coeff),.product(product),.enable_in(1'b1),.enable_out() );
34    acc acc (.clock(clock),.reset(reset),.clear(clear_acc),.enable_in(enable_acc),.enable_out(),
35             .addend(product),.sum(accum) );   
36    shifter shifter (.in(accum),.out(scaled_accum),.shift(shift));
37    
38    always @(posedge clock)
39      if(reset)
40        begin
41           i_in_reg <= #1 16'd0;
42           q_in_reg <= #1 16'd0;
43        end
44      else if(strobe_in)
45        begin
46           i_in_reg <= #1 i_in;
47           q_in_reg <= #1 q_in;
48        end        
49
50    always @(posedge clock)
51      if(reset)
52        phase <= #1 4'd0;
53      else if(strobe_in)
54        phase <= #1 4'd1;
55      else if(strobe_in != 4'd8)
56        phase <= #1 phase + 4'd1;
57
58    assign data = ((phase == 4'd1)||(phase === 4'd4)) ? i_in_reg : 
59           ((phase == 4'd2)||(phase == 4'd5)) ? q_in_reg : 16'd0;
60
61    assign coeff = (phase == 4'd1) ? a11 : (phase == 4'd2) ? a12 : 
62           (phase == 4'd4) ? a21 : (phase == 4'd5) ? a22 : 16'd0;
63
64    assign clear_acc = (phase == 4'd0) || (phase == 4'd1) || (phase == 4'd4) || (phase==4'd8);
65    assign enable_acc = ~clear_acc;
66    
67    always @(posedge clock)
68      if(reset)
69        i_out <= #1 16'd0;
70      else if(phase == 4'd4)
71        i_out <= #1 scaled_accum;
72
73    always @(posedge clock)
74      if(reset)
75        q_out <= #1 16'd0;
76      else if(phase == 4'd7)
77        q_out <= #1 scaled_accum;
78    
79        
80 endmodule // mrfm_compensator