Imported Upstream version 3.0
[debian/gnuradio] / usrp / fpga / toplevel / mrfm / biquad_2stage.v
1 `include "mrfm.vh"
2
3 module biquad_2stage (input clock, input reset, input strobe_in,
4                       input serial_strobe, input [6:0] serial_addr, input [31:0] serial_data,
5                       input wire [15:0] sample_in, output reg [15:0] sample_out, output wire [63:0] debugbus);
6
7    wire [3:0]          coeff_addr, coeff_wr_addr;
8    wire [3:0]          data_addr, data_wr_addr;
9    reg [3:0]           cur_offset, data_addr_int, data_wr_addr_int;
10    
11    wire [15:0]         coeff, coeff_wr_data, data, data_wr_data;
12    wire                coeff_wr;
13    reg                 data_wr;
14    
15    wire [30:0]         product;
16    wire [33:0]         accum;
17    wire [15:0]         scaled_accum;             
18    
19    wire [7:0]          shift;
20    reg [3:0]           phase;
21    wire                enable_mult, enable_acc, latch_out, select_input;
22    reg                 done, clear_acc;
23    
24    setting_reg #(`FR_MRFM_IIR_COEFF) sr_coeff(.clock(clock),.reset(reset),
25                                               .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
26                                               .out({coeff_wr_addr,coeff_wr_data}),.changed(coeff_wr));
27    
28    setting_reg #(`FR_MRFM_IIR_SHIFT) sr_shift(.clock(clock),.reset(reset),
29                                               .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
30                                               .out(shift),.changed());
31    
32    ram16 coeff_ram(.clock(clock),.write(coeff_wr),.wr_addr(coeff_wr_addr),.wr_data(coeff_wr_data),
33                    .rd_addr(coeff_addr),.rd_data(coeff));
34    
35    ram16 data_ram(.clock(clock),.write(data_wr),.wr_addr(data_wr_addr),.wr_data(data_wr_data),
36                   .rd_addr(data_addr),.rd_data(data));
37    
38    mult mult (.clock(clock),.x(data),.y(coeff),.product(product),.enable_in(enable_mult),.enable_out() );
39    
40    acc acc (.clock(clock),.reset(reset),.clear(clear_acc),.enable_in(enable_acc),.enable_out(),
41             .addend(product),.sum(accum) );
42    
43    shifter shifter (.in(accum),.out(scaled_accum),.shift(shift));
44    
45    assign              data_wr_data = select_input ? sample_in : scaled_accum;
46    assign              enable_mult = 1'b1;
47    
48    always @(posedge clock)
49      if(reset)
50        cur_offset <= #1 4'd0;
51      else if(latch_out)
52        cur_offset <= #1 cur_offset + 4'd1;
53    
54    assign              data_addr = data_addr_int + cur_offset;           
55    assign              data_wr_addr = data_wr_addr_int + cur_offset;             
56    
57    always @(posedge clock)
58      if(reset)
59        done <= #1 1'b0;
60      else if(latch_out)
61        done <= #1 1'b1;
62      else if(strobe_in)
63        done <= #1 1'b0;
64    
65    always @(posedge clock)
66      if(reset)
67        phase <= #1 4'd0;
68      else if(strobe_in)
69        phase <= #1 4'd0;
70      else if(!done)
71        phase <= #1 phase + 4'd1;
72    
73    assign              coeff_addr = phase;
74    
75    always @(phase)
76      case(phase)
77        4'd01 : data_addr_int = 4'd00; 4'd02 : data_addr_int = 4'd01; 4'd03 : data_addr_int = 4'd02;
78        4'd04 : data_addr_int = 4'd03; 4'd05 : data_addr_int = 4'd04;
79        
80        4'd07 : data_addr_int = 4'd03; 4'd08 : data_addr_int = 4'd04; 4'd09 : data_addr_int = 4'd05;
81        4'd10 : data_addr_int = 4'd06; 4'd11 : data_addr_int = 4'd07;
82        default : data_addr_int = 4'd00;
83      endcase // case(phase)
84    
85    always @(phase)
86      case(phase)
87        4'd0 : data_wr_addr_int = 4'd2;
88        4'd8 : data_wr_addr_int = 4'd5;
89        4'd14 : data_wr_addr_int = 4'd8;
90        default : data_wr_addr_int = 4'd0;
91      endcase // case(phase)
92
93    always @(phase)
94      case(phase)
95        4'd0, 4'd8, 4'd14 : data_wr = 1'b1;
96        default : data_wr = 1'b0;
97      endcase // case(phase)
98
99    assign              select_input = (phase == 4'd0);
100    
101    always @(phase)
102      case(phase)
103        4'd0, 4'd1, 4'd2, 4'd3, 4'd9, 4'd15 : clear_acc = 1'd1;
104        default : clear_acc = 1'b0;
105      endcase // case(phase)
106    
107    assign              enable_acc = ~clear_acc;
108    assign              latch_out = (phase == 4'd14);
109    
110    always @(posedge clock)
111      if(reset)
112        sample_out <= #1 16'd0;
113      else if(latch_out)
114        sample_out <= #1 scaled_accum;
115
116    ////////////////////////////////////////////////////////
117    //  Debug
118
119    wire [3:0]          debugmux;
120    
121    setting_reg #(`FR_MRFM_DEBUG) sr_debugmux(.clock(clock),.reset(reset),
122                                              .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
123                                              .out(debugmux),.changed());
124
125    assign              debugbus[15:0] = debugmux[0] ? {coeff_addr,data_addr,data_wr_addr,cur_offset} : {phase,data_addr_int,data_wr_addr_int,cur_offset};
126    assign              debugbus[31:16] = debugmux[1] ? scaled_accum : {clock, strobe_in, data_wr, enable_mult, enable_acc, clear_acc, latch_out,select_input,done, data_addr_int};
127    assign              debugbus[47:32] = debugmux[2] ? sample_out : coeff;
128    assign              debugbus[63:48] = debugmux[3] ? sample_in : data;
129       
130 endmodule // biquad_2stage
131