verilog入门实例2——双端口RAM,单按键控制多样式流水灯
一. 双端口RAM
设计一个位宽8bit,地址深度为128,可以同时读写的双端口RAM
模块名字:ram_dual
功能说明:当外部给出写使能时,写地址和写数据有效,将数据存放在对应地址中。当外部给出读使能时,通过读地址读取数据。读写可同时进行。
输入端口:rst, clk_r, clk_w, addr_r[7:0], addr_w[7:0], data_w[7:0], rd_en, wr_en(_r表示读,_w表示写,_en使能)
输出端口:data_rd[7:0](为读取数据)
测试激励要求:向第一个地址写入数据0x01,第十个地址写入数据0x0a,第二十个地址写入数据0x20,第一百个地址写入数据0x64。然后依次读取这四个地址的数据。
使用define语句给以上地址起个名字,将命名单独放到define.v文件,激励中地址用别名替代。
首先了解RAM的具体概念,FPGA中的RAM有单端口,双端口和伪双端口之分。
单端口RAM(Single-Port RAM)
输入只有一组数据线和一组地址线,只有一个时钟,读写公用地址线。
输出只有一个端口。
所以但端口RAM的读写操作不能同时进行。当wea拉高时,会将数据写入对应的地址,同时douta输出的数据与此时写入的数据是一致的,因此在读的时候需要重新生成对应的读地址给addra,并且将wea变为低电平。
伪双端口RAM(Simple Dual-Port RAM)
输入有一组数据线,两组地址线,两个时钟。
提供了两个端口A和B,通过端口A进行写访问,通过端口B进行读访问。互相不影响。
双端口RAM(True Dual-Port RAM)
提供两个端口A和B,这两个端口都可以对存储进行写读访问。
从以上概念可知,题目要求是需要一个伪双端口RAM
src
module ram_dual(
input rst_n,
input clk_r,
input clk_w,
input [7:0]addr_r,
input [7:0]addr_w,
input [7:0]data_w,
input rd_en,
input wr_en,//_r表示读,_w表示写,_en使能
output reg[7:0]data_rd //为读取数据
);
reg [7:0] ram[127:0];
// Port read
always@(posedge clk_r or negedge rst_n)
begin
if(!rst_n)
data_rd <= 1'b0;
else if (rd_en)
data_rd <= ram[addr_r];
else
data_rd <= 8'b00000000;
end
// Port write
always@(posedge clk_w or negedge rst_n)
begin
if (!rst_n)
ram[addr_w] <= ram[addr_w];
else if (wr_en)
ram[addr_w] <= data_w;
else
ram[addr_w] <= ram[addr_w];
end
endmodule
tb
`timescale 1ns/1ps
`include "define.v"
module tb_ram_dual;<