1. 程式人生 > >FPGA乒乓操作Verilog程式

FPGA乒乓操作Verilog程式

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--------------------------------//     

[email protected](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       
[email protected]
(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          [email protected]* 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;          
[email protected]
(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          [email protected](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;          [email protected](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;          [email protected](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          [email protected](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          [email protected](r_clk)begin         if(rst_n == 1'b0)             buffer_rd_ena_delay <= 1'b0;         else             buffer_rd_ena_delay <= buffer_rd_ena;     end          [email protected](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          [email protected](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