1`include "mrfm.vh" 2 3module mrfm_iir (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); 6 7 wire [5:0] coeff_addr, coeff_wr_addr; 8 wire [4:0] data_addr, data_wr_addr; 9 reg [4: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 [5: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 ram64 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 ram32 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 5'd0; 51 else if(latch_out) 52 cur_offset <= #1 cur_offset + 5'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 6'd0; 68 else if(strobe_in) 69 phase <= #1 6'd0; 70 else if(!done) 71 phase <= #1 phase + 6'd1; 72 73 always @(phase) 74 case(phase) 75 6'd0 : data_addr_int = 5'd0; 76 default : data_addr_int = 5'd0; 77 endcase // case(phase) 78 79 assign coeff_addr = phase; 80 81 always @(phase) 82 case(phase) 83 6'd01 : data_addr_int = 5'd00; 6'd02 : data_addr_int = 5'd01; 6'd03 : data_addr_int = 5'd02; 84 6'd04 : data_addr_int = 5'd03; 6'd05 : data_addr_int = 5'd04; 85 86 6'd07 : data_addr_int = 5'd03; 6'd08 : data_addr_int = 5'd04; 6'd09 : data_addr_int = 5'd05; 87 6'd10 : data_addr_int = 5'd06; 6'd11 : data_addr_int = 5'd07; 88 89 6'd13 : data_addr_int = 5'd06; 6'd14 : data_addr_int = 5'd07; 6'd15 : data_addr_int = 5'd08; 90 6'd16 : data_addr_int = 5'd09; 6'd17 : data_addr_int = 5'd10; 91 92 6'd19 : data_addr_int = 5'd09; 6'd20 : data_addr_int = 5'd10; 6'd21 : data_addr_int = 5'd11; 93 6'd22 : data_addr_int = 5'd12; 6'd23 : data_addr_int = 5'd13; 94 95 6'd25 : data_addr_int = 5'd12; 6'd26 : data_addr_int = 5'd13; 6'd27 : data_addr_int = 5'd14; 96 6'd28 : data_addr_int = 5'd15; 6'd29 : data_addr_int = 5'd16; 97 98 6'd31 : data_addr_int = 5'd15; 6'd32 : data_addr_int = 5'd16; 6'd33 : data_addr_int = 5'd17; 99 6'd34 : data_addr_int = 5'd18; 6'd35 : data_addr_int = 5'd19; 100 101 default : data_addr_int = 5'd00; 102 endcase // case(phase) 103 104 always @(phase) 105 case(phase) 106 6'd0 : data_wr_addr_int = 5'd2; 107 6'd8 : data_wr_addr_int = 5'd5; 108 6'd14 : data_wr_addr_int = 5'd8; 109 6'd20 : data_wr_addr_int = 5'd11; 110 6'd26 : data_wr_addr_int = 5'd14; 111 6'd32 : data_wr_addr_int = 5'd17; 112 6'd38 : data_wr_addr_int = 5'd20; 113 default : data_wr_addr_int = 5'd0; 114 endcase // case(phase) 115 116 always @(phase) 117 case(phase) 118 6'd0, 6'd8, 6'd14, 6'd20, 6'd26, 6'd32, 6'd38: data_wr = 1'b1; 119 default : data_wr = 1'b0; 120 endcase // case(phase) 121 122 always @(phase) 123 case(phase) 124 6'd0, 6'd1, 6'd2, 6'd3, 6'd9, 6'd15, 6'd21, 6'd27, 6'd33 : clear_acc = 1'd1; 125 default : clear_acc = 1'b0; 126 endcase // case(phase) 127 128 assign enable_acc = ~clear_acc; 129 assign latch_out = (phase == 6'd38); 130 131 always @(posedge clock) 132 if(reset) 133 sample_out <= #1 16'd0; 134 else if(latch_out) 135 sample_out <= #1 scaled_accum; 136 137endmodule // mrfm_iir 138