DSP

乒乓buffer

2019-07-13 19:49发布

module ping_pong_buffer( input clk, input rst_n, //external write interface input[7:0] i_data, input i_data_valid, //ping ram buffer interface output ping_ram_buffer_wclk, output ping_ram_buffer_wea, output[9:0] ping_ram_buffer_w_addr, output[7:0] ping_ram_buffer_w_data, output ping_ram_buffer_rclk, output[8:0] ping_ram_buffer_r_addr, input[15:0] ping_ram_buffer_r_data, //pong ram buffer interface output pong_ram_buffer_wclk, output pong_ram_buffer_wea, output[9:0] pong_ram_buffer_w_addr, output[7:0] pong_ram_buffer_w_data, output pong_ram_buffer_rclk, output[8:0] pong_ram_buffer_r_addr, input[15:0] pong_ram_buffer_r_data, //internal read interface input r_clk, output o_data_valid,//256x16 output[15:0] o_data ); reg i_data_valid_delay_1,i_data_valid_delay_2; reg wr_buffer_sel; reg ping_buffer_wea,pong_buffer_wea; reg[9:0] ping_buffer_wr_addr,pong_buffer_wr_addr; reg wr_finish; reg wr_finish_sync1,wr_finish_sync2,wr_finish_sync3; reg[8:0] buffer_rd_addr; reg buffer_rd_ena,buffer_rd_ena_delay; reg buffer_rd_sel; //-------------------------------write operation--------------------------------// always@(posedge clk)begin if(rst_n == 1'b0)begin i_data_valid_delay_1 <= 1'b0; i_data_valid_delay_2 <= 1'b0; end else begin i_data_valid_delay_1 <= i_data_valid; i_data_valid_delay_2 <= i_data_valid_delay_1; end end always@(posedge clk)begin if(rst_n == 1'b0) wr_buffer_sel <= 1'b0; else if(i_data_valid == 1'b0 && i_data_valid_delay_1 == 1'b1) wr_buffer_sel <= ~wr_buffer_sel; end always@* begin ping_buffer_wea <= ~wr_buffer_sel & i_data_valid; pong_buffer_wea <= wr_buffer_sel & i_data_valid; end assign ping_ram_buffer_wea = ping_buffer_wea; assign pong_ram_buffer_wea = pong_buffer_wea; assign ping_ram_buffer_wclk = clk; assign pong_ram_buffer_wclk = clk; assign ping_ram_buffer_w_data = i_data; assign pong_ram_buffer_w_data = i_data; always@(posedge clk)begin if(rst_n == 1'b0) ping_buffer_wr_addr <= 10'b0; else if(ping_buffer_wea == 1'b1) ping_buffer_wr_addr <= ping_buffer_wr_addr+1; else ping_buffer_wr_addr <= 10'b0; end always@(posedge clk)begin if(rst_n == 1'b0) pong_buffer_wr_addr <= 10'b0; else if(pong_buffer_wea == 1'b1) pong_buffer_wr_addr <= pong_buffer_wr_addr+1; else pong_buffer_wr_addr <= 10'b0; end assign ping_ram_buffer_w_addr = ping_buffer_wr_addr; assign pong_ram_buffer_w_addr = pong_buffer_wr_addr; always@(posedge clk)begin if(rst_n == 1'b0) wr_finish <= 1'b0; else if(i_data_valid == 1'b0 && i_data_valid_delay_2 == 1'b1) wr_finish <= 1'b1; else wr_finish <= 1'b0; end //-----------------------------read operation--------------------------------// assign ping_ram_buffer_rclk = r_clk; assign pong_ram_buffer_rclk = r_clk; always@(r_clk)begin if(rst_n == 1'b0)begin wr_finish_sync1 <= 1'b0; wr_finish_sync2 <= 1'b0; wr_finish_sync3 <= 1'b0; end else begin wr_finish_sync1 <= wr_finish; wr_finish_sync2 <= wr_finish_sync1; wr_finish_sync3 <= wr_finish_sync2; end end always@(r_clk)begin if(rst_n == 1'b0) buffer_rd_ena <= 1'b0; else if(wr_finish_sync2 == 1 && wr_finish_sync3 == 0) buffer_rd_ena <= 1'b1; else if(buffer_rd_addr == 9'd511) buffer_rd_ena <= 1'b0; end always@(r_clk)begin if(rst_n == 1'b0) buffer_rd_ena_delay <= 1'b0; else buffer_rd_ena_delay <= buffer_rd_ena; end always@(r_clk)begin if(rst_n == 1'b0) buffer_rd_addr <= 9'b0; else if(buffer_rd_ena) buffer_rd_addr <= buffer_rd_addr + 1; else buffer_rd_addr <= 9'b0; end always@(r_clk)begin if(rst_n == 1'b0) buffer_rd_sel <= 1'b0; else if(buffer_rd_ena == 1'b0 && buffer_rd_ena_delay == 1'b1) buffer_rd_sel <= ~buffer_rd_sel; end assign ping_ram_buffer_r_addr = (buffer_rd_sel == 1'b0)?buffer_rd_addr:9'b0; assign pong_ram_buffer_r_addr = (buffer_rd_sel == 1'b1)?buffer_rd_addr:9'b0; assign o_data = (buffer_rd_sel == 1'b0)?ping_ram_buffer_r_data:pong_ram_buffer_r_data; assign o_data_valid = buffer_rd_ena_delay; endmodule testbench的编写: `timescale 1ns/1ns `define clock_period 10 module tb_ping_pong_buffer; reg clk; reg rst_n; wire wclk,rclk; wire ping_ram_buffer_wea,pong_ram_buffer_wea; wire[9:0] ping_ram_buffer_w_addr,pong_ram_buffer_w_addr; wire[7:0] ping_ram_buffer_w_data,pong_ram_buffer_w_data; wire[8:0] ping_ram_buffer_r_addr,pong_ram_buffer_r_addr; wire [15:0] ping_ram_buffer_r_data,pong_ram_buffer_r_data; reg i_data_valid; reg [7:0] i_data; wire o_data_valid; wire[7:0] o_data; integer i; ping_pong_buffer inst1( .clk(clk), .rst_n(rst_n), //external write interface .i_data(i_data), .i_data_valid(i_data_valid), //ping ram buffer interface .ping_ram_buffer_wclk(wclk), .ping_ram_buffer_wea(ping_ram_buffer_wea), .ping_ram_buffer_w_addr(ping_ram_buffer_w_addr), .ping_ram_buffer_w_data(ping_ram_buffer_w_data), .ping_ram_buffer_rclk(rclk), .ping_ram_buffer_r_addr(ping_ram_buffer_r_addr), .ping_ram_buffer_r_data(ping_ram_buffer_r_data), //pong ram buffer interface .pong_ram_buffer_wclk(wclk), .pong_ram_buffer_wea(pong_ram_buffer_wea), .pong_ram_buffer_w_addr(pong_ram_buffer_w_addr), .pong_ram_buffer_w_data(pong_ram_buffer_w_data), .pong_ram_buffer_rclk(rclk), .pong_ram_buffer_r_addr(pong_ram_buffer_r_addr), .pong_ram_buffer_r_data(pong_ram_buffer_r_data), //internal read interface .r_clk(clk), .o_data_valid(o_data_valid),//256x16 .o_data(o_data) ); initial clk = 1; always #(`clock_period/2) clk = ~clk; initial begin rst_n = 1'b0; #(`clock_period*100+1); rst_n = 1'b1; i_data_valid = 1'b0; i_data = 8'b0; #(`clock_period*20); for (i=0;i<=1023;i=i+1)begin i_data_valid = 1; i_data = i; #`clock_period; end i_data_valid = 1'b0; #(`clock_period*20); for (i=0;i<=1023;i=i+1)begin i_data_valid = 1; i_data = i; #`clock_period; end i_data_valid = 1'b0; #(`clock_period*600); $stop; end endmodule