双口 RAM 的结构,是可以解决跨时钟域的问题,在 a_clk 的时钟下, a 端口的数据不断写入,而 b_clk 的时钟下, b 端口不断把数据读出来,而且跟 a 端口写入的数据是相同的
IP核配置
module ram(clk_a,clk_b,rst_n); input clk_a,clk_b,rst_n; //wire [7:0]data_a; wire [7:0]data_outa,data_outb;//输出 wire wr_a,wr_b; wire [7:0]data_a,data_b;//a,b的写数据 wire [9:0]addr_a,addr_b; two_ram two_ram( .address_a(addr_a), .address_b(addr_b), .clock_a(clk_a), .clock_b(clk_b), .data_a(data_a), .data_b(8'd0), .wren_a(wr_a), .wren_b(wr_b), .q_a(data_outa), .q_b(data_outb) ); ram_crtl ram_crtl( .clk_a(clk_a), .clk_b(clk_b), .rst_n(rst_n), .data_a(data_a), .addr_a(addr_a), .wr_a(wr_a), .addr_b(addr_b), .wr_b(wr_b) ); endmodule //先写后读 module ram_crtl( clk_a, clk_b, rst_n, data_a,//写数据 addr_a, wr_a, addr_b, wr_b ); input clk_a,clk_b,rst_n; output reg wr_a,wr_b; output reg [7:0]data_a; output reg [9:0]addr_a,addr_b; //在 a_clk 的时钟下, a 端口的数据不断写入 always @(posedge clk_a or negedge rst_n) if(!rst_n)begin data_a <= 8'd0; addr_a <= 10'd0; wr_a <= 1'd0; end else begin if(addr_a < 1023)begin wr_a <= 1'd1; addr_a <= addr_a + 10'd1; data_a <= data_a + 8'd1; end else begin wr_a <= 1'd0; addr_a <= addr_a; data_a <= data_a; end end always @(posedge clk_b or negedge rst_n) if(!rst_n)begin wr_b <= 1'd0; addr_b <= 10'd0; end else addr_b <= addr_b + 1'd1; endmodule `timescale 1ns/1ns `define clock_period 20 module ram_tb; reg clk_a,clk_b,rst_n; //wire [7:0]data; initial clk_a =1; always #(`clock_period/2) clk_a = ~clk_a; initial clk_b =1; always #(`clock_period) clk_b = ~clk_b; initial begin #1; rst_n = 1'b0; #(`clock_period*5) rst_n = 1'b1; #(`clock_period + 1); #(`clock_period*200); $stop; end ram ram( .clk_a(clk_a), .clk_b(clk_b), .rst_n(rst_n) ); endmodule
由于顶层没有输出信号,fpga占用逻辑资源为0
仿真结果:
文章评论(0条评论)
登录后参与讨论