//------------------------------------------------ // MemoryFir.vhd // by Toshio Iwata at digitalfilter.com 2004/09/09 // no timescale needed module MemoryFirRch( counter8b, WRADDR, RDADDR, HnXn_20b, ADDOUT, ADDOUT_dly, ADDOUT_dly_clr, RST_N, MCLK, FSCLK, XIN, YOUT ); input RST_N; input MCLK; input FSCLK; input [15:0] XIN; output [15:0] YOUT; output [7:0] counter8b; output [7:0] WRADDR, RDADDR; output [19:0] HnXn_20b; output [21:0] ADDOUT; output [21:0] ADDOUT_dly; output ADDOUT_dly_clr; wire RST_N; wire MCLK; wire FSCLK; wire [15:0] XIN; reg [15:0] YOUT; wire signed [15:0] Xn; wire signed [15:0] Hn; wire signed [31:0] HnXn; reg signed [19:0] HnXn_20b; reg signed [15:0] XIN_sig; reg signed [21:0] ADDOUT_dly; wire signed [21:0] ADDOUT; reg [7:0] counter8b; reg [7:0] counter8b_fs; wire [7:0] rdaddr_sig; reg [7:0] ADDR; reg [7:0] RDADDR; reg [7:0] WRADDR; reg signed [15:0] MuxXn; reg signed [15:0] MuxHn; reg fsclk_dly1; wire ADDOUT_dly_clr; wire WR_N; // MemoryFir //----------------------------------------------------------------- assign WR_N = ~FSCLK; //----------------------------------------------------------------- always @(counter8b) begin ADDR <= counter8b; end //----------------------------------------------------------------- assign rdaddr_sig = counter8b + counter8b_fs + 1; //----------------------------------------------------------------- always @(rdaddr_sig) begin RDADDR <= rdaddr_sig; end //----------------------------------------------------------------- always @(counter8b_fs) begin WRADDR <= counter8b_fs; end //----------------------------------------------------------------- RomRch Rom_1( .CLK(MCLK), .ADDR(ADDR), .DATA(Hn)); //----------------------------------------------------------------- Ram Ram_1( .CLK(MCLK), .WR_N(WR_N), .WRADDR(WRADDR), .RDADDR(RDADDR), .WRDATA(XIN), .RDDATA(Xn)); //----------------------------------------------------------------- always @(negedge RST_N or posedge MCLK) begin if((RST_N == 1'b 0)) begin fsclk_dly1 <= 1'b 0; end else begin fsclk_dly1 <= FSCLK; end end //----------------------------------------------------------------- assign ADDOUT_dly_clr = fsclk_dly1; //----------------------------------------------------------------- always @(negedge RST_N or posedge MCLK) begin if((RST_N == 1'b 0)) begin counter8b <= {8{1'b0}}; end else begin if((FSCLK == 1'b 1)) begin counter8b <= {8{1'b0}}; end else begin counter8b <= counter8b + 1; // up counter end end end //----------------------------------------------------------------- always @(negedge RST_N or posedge MCLK) begin if((RST_N == 1'b 0)) begin counter8b_fs <= {8{1'b1}}; end else begin if((FSCLK == 1'b 1)) begin counter8b_fs <= counter8b_fs - 1; // down counter end end end //----------------------------------------------------------------- always @(Xn) begin MuxXn <= Xn; end //----------------------------------------------------------------- always @(Hn) begin MuxHn <= Hn; end //----------------------------------------------------------------- assign HnXn = MuxXn * MuxHn; //----------------------------------------------------------------- always @(XIN) begin XIN_sig <= XIN; end //-------------------------------------------------- always @(HnXn) begin HnXn_20b[19] <= HnXn[19 + 11]; HnXn_20b[18] <= HnXn[18 + 11]; HnXn_20b[17] <= HnXn[17 + 11]; HnXn_20b[16] <= HnXn[16 + 11]; HnXn_20b[15] <= HnXn[15 + 11]; HnXn_20b[14] <= HnXn[14 + 11]; HnXn_20b[13] <= HnXn[13 + 11]; HnXn_20b[12] <= HnXn[12 + 11]; HnXn_20b[11] <= HnXn[11 + 11]; HnXn_20b[10] <= HnXn[10 + 11]; HnXn_20b[9] <= HnXn[9 + 11]; HnXn_20b[8] <= HnXn[8 + 11]; HnXn_20b[7] <= HnXn[7 + 11]; HnXn_20b[6] <= HnXn[6 + 11]; HnXn_20b[5] <= HnXn[5 + 11]; HnXn_20b[4] <= HnXn[4 + 11]; HnXn_20b[3] <= HnXn[3 + 11]; HnXn_20b[2] <= HnXn[2 + 11]; HnXn_20b[1] <= HnXn[1 + 11]; HnXn_20b[0] <= HnXn[0 + 11]; end //-------------------------------------------------- assign ADDOUT = HnXn_20b + ADDOUT_dly; //-------------------------------------------------- always @(negedge RST_N or posedge MCLK) begin : P1 reg [21:0] tmpint; if((RST_N == 1'b 0)) begin ADDOUT_dly <= {22{1'b0}}; end else begin if((ADDOUT_dly_clr == 1'b 1)) begin ADDOUT_dly <= {22{1'b0}}; end else begin ADDOUT_dly <= ADDOUT; end end end //----------------------------------------------------------------- always @(negedge RST_N or posedge MCLK) begin if((RST_N == 1'b 0)) begin YOUT <= {16{1'b0}}; end else begin if((ADDOUT_dly_clr == 1'b 1)) begin if((ADDOUT_dly[21] == 1'b 0 && (ADDOUT_dly[20] == 1'b 1 || ADDOUT_dly[19] == 1'b 1))) begin // overflow YOUT <= 16'b 0111111111111111; end else if((ADDOUT_dly[21] == 1'b 1 && (ADDOUT_dly[20] == 1'b 0 || ADDOUT_dly[19] == 1'b 0))) begin // underflow YOUT <= 16'b 1000000000000000; end else begin YOUT[15] <= ADDOUT_dly[15 + 4]; YOUT[14] <= ADDOUT_dly[14 + 4]; YOUT[13] <= ADDOUT_dly[13 + 4]; YOUT[12] <= ADDOUT_dly[12 + 4]; YOUT[11] <= ADDOUT_dly[11 + 4]; YOUT[10] <= ADDOUT_dly[10 + 4]; YOUT[9] <= ADDOUT_dly[9 + 4]; YOUT[8] <= ADDOUT_dly[8 + 4]; YOUT[7] <= ADDOUT_dly[7 + 4]; YOUT[6] <= ADDOUT_dly[6 + 4]; YOUT[5] <= ADDOUT_dly[5 + 4]; YOUT[4] <= ADDOUT_dly[4 + 4]; YOUT[3] <= ADDOUT_dly[3 + 4]; YOUT[2] <= ADDOUT_dly[2 + 4]; YOUT[1] <= ADDOUT_dly[1 + 4]; YOUT[0] <= ADDOUT_dly[0 + 4]; end end end end endmodule