TA的每日心情 | 郁闷 2017-12-4 18:33 |
---|
签到天数: 94 天 连续签到: 1 天 [LV.6]常住居民II
|
写本帖的原因有两个,一是分享FPGA学习心得,二是验证寄存器二维数组(即HDL描述的RAM/ROM)可以在两个always过程块中被调用。
同步真双口RAM包含两个独立的访问端口,允许两个寄存器同时操作。功能如下:
- 当读操作和写操作在同一个端口发生时,要写入存储器的新数据被读取出来;
- 当读操作和写操作发生在不同的端口,但使用相同的地址时。存储器中的旧数据被读取出来,需要附件的旁路逻辑恢复数据;
- 通过两个端口想同一个地址写数据将导致无法预料的行为发生。。。。
在实现过程中,EDA软件会自行编译选择相应的分布式存储设备。在Quatus中被识别为M4K内部同步嵌入式存储模块,在ISE/Vivado中识别为Block RAM,Diamond中则识别为EBR(内嵌块RAM)。- module dual_port_ram_true
- #(
- parameter DATA_WIDTH = 8,
- ADDR_WIDTH = 10
- )
- (
- input wire clk,
- input wire we_a,we_b,
- input wire [ADDR_WIDTH-1:0] addr_a,addr_b,
- input wire [DATA_WIDTH-1:0] d_a,d_b,
- output wire [DATA_WIDTH-1:0] q_a,q_b
- );
- //signal declaration
- reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
- reg [DATA_WIDTH-1:0] data_a_reg,data_b_reg;
-
- //body
- //port a
- always@(posedge clk)begin
- if(we_a)begin
- ram[addr_a] <= d_a;
- data_a_reg <= d_a;
- end
- else
- data_a_reg <= ram[addr_a];
- end
-
- //port b
- always@(posedge clk)begin
- if(we_b)begin
- ram[addr_b] <= d_b;
- data_b_reg <= d_b;
- end
- else
- data_b_reg <= ram[addr_b];
- end
-
- //output
- assign q_a = data_a_reg;
- assign q_b = data_b_reg;
-
- endmodule
复制代码 代码解析:
由于代码中利用读数据寄存器,且在过程块中使用非阻塞赋值,因此在同一时刻,不同端口对同一地址分别进行读写操作时,读操作的结果是之前的旧数据。
可以用下面的数据交换来理解:- always@(posedge clk)begin
- a <= b;
- b <= a;
- end
复制代码 在同一个时钟上升沿,既要对a进行写入b的值,又要将a的值读出来写到b中。
|
|