赞
踩
简单双口RAM有两个端口Port A和port B,其中Port A用于写数据,Port B用于读数据,读写接口可以独立时钟工作。这一点和真双口RAM是有区别的,真双口RAM的A B两个Port都可以进行读写操作。
RAM是FPGA中重要的数据结构,可用于数据的缓存和跨时钟域信号处理。本文就xilink 的简单双口RAM 进行读写测试。
本文对简单双口RAM做如下仿真:先对Port A进行连续写操作128次,每次数据和地址加1,结束后开始从Port B口读对应128个地址的数据,读写时钟独立,对比读写数据是否一致。
仿真结果如下:
数据写入仿真
数据读出仿真,数据在地址变化后延迟一个时钟输出。
ram ip的设置如下
注意不要勾选 Primitives Output Regster,不然Port B数据会延迟两个周期。
简单双口RAM的接口定义如下
直接上代码 dual_ram_top.v
- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Create Date: 2024/03/22 20:18:12
- // Design Name:
- // Module Name: dual_ram_top
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //
-
-
- module dual_ram_top(
- input clka,
- input clkb,
- input rst_n,
- output [7:0] doutb
- );
-
- reg [7:0]dina;
- reg [12:0] addra;
-
- reg ena;
- reg wea;
- reg [3:0] wr_state;
- always@(posedge clka or negedge rst_n) begin
- if(!rst_n) begin
- wr_state <= 4'd0;
-
- ena <= 1'b0;
- wea <= 1'b0;
- dina <= 8'd0;
- addra <= 13'd0;
- end
- else begin
- case(wr_state)
- 4'd0:begin
- wr_state <= 4'd1;
-
- wea <= 1'b1; // 写使能
- end
-
- 4'd1:begin
- wr_state <= 4'd2;
-
- addra <= 13'd0;
- dina <= 8'd0;
- ena <= 1'b1;
-
- end
-
- 4'd2:begin
- if(addra == 13'd127) begin
- wr_state <= 4'd3;
-
- ena <= 1'b0;
- addra <= 13'd0;
- dina <= 8'd0;
- end
- else begin
- wr_state <= wr_state;
-
- addra <= addra + 13'd1;
- dina <= dina + 8'd1;
- ena <= 1'b1;
- end
- end
-
- 4'd3:begin // write end
- wr_state <= 4'd4;
-
- wea <= 1'b0; // 读使能
- end
-
- 4'd4:begin
- wr_state <= wr_state;
- end
- endcase
- end
- end
-
- wire rd_start;
- assign rd_start =(wr_state==4'd4)?1:0;
-
- reg [12:0] addrb;
- reg enb;
-
- reg [3:0] rd_state;
- always@(posedge clkb or negedge rst_n) begin
- if(!rst_n) begin
- rd_state <= 4'd0;
-
- enb <= 1'b0;
- addrb <= 13'd0;
- end
- else begin
- case(rd_state)
- 4'd0:begin
- if(rd_start) begin
- rd_state <= 4'd1;
-
- enb <= 1'd1;
- addrb <= 13'd0;
- end
- else begin
- rd_state <= rd_state;
-
- enb <= 1'd0;
- addrb <= 13'd0;
- end
- end
-
- 4'd1:begin
- if(addrb == 13'd127) begin
- rd_state <= 4'd2;
-
- enb <= 1'd0;
- addrb <= 13'd0;
- end
- else begin
- rd_state <= rd_state;
-
- enb <= 1'd1;
- addrb <= addrb +13'd1;
- end
- end
-
- 4'd2:begin
- rd_state <= rd_state;
-
- enb <= 1'd0;
- addrb <= 13'd0;
- end
- endcase
- end
- end
-
- blk_mem_gen_0 blk_mem_gen_uut0 (
- .clka(clka), // input wire clka
- .ena(ena), // input wire ena
- .wea(wea), // input wire [0 : 0] wea
- .addra(addra), // input wire [12 : 0] addra
- .dina(dina), // input wire [7 : 0] dina
- .clkb(clkb), // input wire clkb
- .enb(enb), // input wire enb
- .addrb(addrb), // input wire [12 : 0] addrb
- .doutb(doutb) // output wire [7 : 0] doutb
- );
- endmodule
仿真测试代码ram_wr_top.v
- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Create Date: 2024/03/22 22:27:59
- // Design Name:
- // Module Name: ram_wr_top
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //
-
-
- module ram_wr_top(
- );
- reg clka;
- reg clkb;
- reg rst_n;
- wire [7:0]doutb;
-
- localparam clk_prioda = 50;
- localparam clk_priodb = 20;
-
- initial begin
- clka =1'b0;
- clkb = 1'b0;
- rst_n = 1'b0;
- #(100)
- rst_n = ~rst_n;
- end
-
- always#(clk_prioda/2) clka = ~clka;
- always#(clk_priodb/2) clkb = ~clkb;
-
- dual_ram_top dual_ram_top_uut0(
- .clka(clka),
- .clkb(clkb),
- .rst_n(rst_n),
- .doutb(doutb)
- );
- endmodule
通过连续读写对比 验证了IP读写的一致性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。