本文主要介绍ROM和RAM实现的verilog代码版本,可以借鉴参考下。
一、ROM设计方法
Read-only memory(ROM)使用ROM_STYLE属性选择使用寄存器或块RAM资源来实现ROM,示例代码如下:
//使用块RAM资源实现ROM
module rams_sp_rom_1 (
input clk,
input rd_en,
input [5:0] rd_addr,
output [19:0] dout
);
(*rom_style = "block" *) reg [19:0] data;
always @(posedge clk) begin
if (rd_en)
case(rd_addr)
6'd0: data <= 20'h0200A;
6'd1: data <= 20'h00300;
6'd2: data <= 20'h08101;
......
6'd32: data <= 20'h00301;
default: data <= 20'h00102;
endcase
end
assign dout = data;
endmodule
二、RAM设计方式
RAM设计方式有很多,可以用BRAM、LUT、分布式RAM、URAM实现,可以使用RAM_STYLE属性强制规定使用的资料类型。
- (*ram_style = "block" *)表示用Block RAM实现
- (*ram_style = "reg" *)表示用寄存器实现
- (*ram_style = "distributed" *)表示用分布式 RAM实现
- (*ram_style = "uram" *)表示用uram实现
1、单端口RAM
单端口RAM支持3种不同的读写同步模式,解决同时读写同一地址的情况,每一个读、写端口都可以配置为:
- Write-First模式:新内容载入时可以马上被读取;
- Read-First模式:新内容载入时,先读取旧的内容;
- No-Change模式:新内容载入时,不读取该地址的内容(即维持之前的值不变);
// 数据输出可复位的单端块RAM,Read_first
module rams_sp_rf_rst (
input clk,
input en,
input we,
input rst,
input [9:0]addr,
input [15:0]di,
output reg [15:0]dout
);
reg [15:0] ram [1023:0];
always @(posedge clk)
if (en) begin //块RAM使能
if (we) ram[addr] <= di; //写使能
if (rst) dout <= 0; //输出复位
else dout <= ram[addr];
end
endmodule
// 写优先模式的单端块RAM,Wrist_first
module rams_sp_wf (
input clk,
input en,
input we,
input [9:0] addr,
input [15:0] di,
output reg [15:0] dout
);
reg [15:0] ram [1023:0];
always @(posedge clk)
if (en) begin
if (we) begin
RAM[addr] <= di;
dout <= di;
end
else dout <= RAM[addr];
end
endmodule
// No-Change模式的单端块RAM
module rams_sp_wf (
input clk,
input en,
input we,
input [9:0] addr,
input [15:0] di,
output reg [15:0] dout
);
reg [15:0] ram [1023:0];
always @(posedge clk)
if (en) begin
if (we) RAM[addr] <= di;
else dout <= RAM[addr];
end
endmodule
3、伪双端口RAM
// 单时钟控制,伪双端块RAM
module simple_dual_one_clock (
input clk,
input ena,
input enb,
input wea,
input [9:0] addra,
input [15:0] dia,
input [9:0] addrb,
output reg [15:0] dob
);
reg [15:0] ram [1023:0];
always @(posedge clk) //写
if (ena)
if (wea) ram[addra] <= dia;
always @(posedge clk)
if (enb) dob <= ram[addrb]; //读
endmodule
// 双时钟控制,伪双端块RAM
module simple_dual_two_clocks (
input clk,
input ena,
input enb,
input wea,
input [9:0] addra,
input [15:0] dia,
input [9:0] addrb,
output reg [15:0] dob
);
reg [15:0] ram [1023:0];
always @(posedge clka) //写
if (ena)
if (wea) ram[addra] <= dia;
always @(posedge clkb)
if (enb) dob <= ram[addrb]; //读
endmodule
4、真双端口RAM
// 带有两个写端口的双端块RAM
module rams_tdp_rf_rf (
input clka,
input clkb,
input ena,
input enb,
input wea,
input web,
input [9:0] addra,
input [9:0] addrb,
input [15:0] dia,
input [15:0] dib,
output reg [15:0] doa,
output reg [15:0] dob
);
reg [15:0] ram [1023:0];
always @(posedge clka) //端口1
if (ena) begin
if (wea) ram[addra] <= dia;
doa <= ram[addra];
end
always @(posedge clkb) //端口2
if (enb) begin
if (web) ram[addrb] <= dib;
dob <= ram[addrb];
end
endmodule
// 带有可选输出寄存器的块RAM
module rams_pipeline (
input clk1,
input clk2,
input we,
input en1,
input en2,
input [9:0] addr1,
input [9:0] addr2,
input [15:0] di,
output reg [15:0] res1,
output reg [15:0] res2
);
reg [15:0] RAM [1023:0];
reg [15:0] do1;
reg [15:0] do2;
always @(posedge clk1) begin //端口1可读可写
if (we == 1'b1) RAM[addr1] <= di;
do1 <= RAM[addr1];
end
always @(posedge clk2) //端口2只用于读
do2 <= RAM[addr2];
always @(posedge clk1)
if (en1 == 1'b1) res1 <= do1;
always @(posedge clk2)
if (en2 == 1'b1) res2 <= do2;
endmodule
5、初始化RAM内容
初始化RAM可以在HDL源代码中进行,也可以利用外部数据文件设置。
//Verilog初始化为一个值
reg [DATA_WIDTH-1:0] ram [DEPTH-1:0];
integer i;
initial for (i=0; i < DEPTH; i=i+1) ram[i] = 0;
//读取二进制形式存储文件
reg [31:0] ram [0:3];
initial begin
$readmemb("ram.data", ram, 0, 3);
end
//读取16进制形式存储文件
reg [31:0] ram [0:3];
initial begin
$readmemh("ram.data", ram, 0, 3);
end
三、总结
本文介绍了如何使用Verilog HDL实现ROM和RAM,以及一些常见的设计方法和示例代码。对于不同类型的存储器,我们介绍了不同的实现方式,包括分布式RAM、单端口RAM和伪双端口RAM等。在任何情况下,都要格外注意存储器的读写一致性和正确性,确保系统的稳定性和正确性。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
ROM
+关注
关注
4文章
575浏览量
85954 -
RAM
+关注
关注
8文章
1369浏览量
114958 -
Verilog
+关注
关注
28文章
1351浏览量
110336 -
代码
+关注
关注
30文章
4823浏览量
68982 -
Vivado
+关注
关注
19文章
815浏览量
66854
发布评论请先 登录
相关推荐
Vivado的多种RAM编写方式
过多介绍。下面给出几个各种实现方式的Verilog示例代码。分布式RAM下面给出一个异步读模式的双口分布式RAM的示例:module ram
发表于 09-29 09:40
Vivado中进行HDL代码设计
源代码中初始化RAM组件更容易;支持package;自定义类型;枚举类型;没有reg和wire之间的混淆。Verilog语言的优势有:与C语言类似的语法;代码结构更紧凑;支持块注释(老
发表于 09-29 10:08
Vivado Synthesis中如何为Verilog代码中的“include file”设置路径?
在Verilog代码开发时,我们可以把经常会用到的公共变量和参数,单独放在一个cfg.v文件中,然后在别的文件中include这个文件,这样便于代码的组织管理,可以使得代码结构更加清晰
发表于 11-10 14:49
•9812次阅读
ROM、RAM、DRAM、SRAM和FLASH的区别
常见存储器概念辨析:RAM、SRAM、SDRAM、ROM、EPROM、EEPROM、Flash存储器可以分为很多种类,其中根据掉电数据是否丢失可以分为RAM(随机存取存储器)和ROM(
发表于 12-04 14:23
•3173次阅读
ram和rom的区别之处
存储器是数字系统中用以存储大量信息的设备或部件,是计算机和数字设备中的重要组成部分。存储器可分为随机存取存储器(ram)和只读存储器(rom)两大类。要说它俩有什么区别,下面就由英尚微电子为大家解惑
发表于 05-10 10:28
•3330次阅读
采用IEEE745格式的浮点+ROM RAM的方式成功实现FFT的设计
采用IEEE745格式的浮点+ROM RAM的方式成功实现FFT的设计(嵌入式开发要学什么知乎)-采用IEEE745格式的浮点+ROM RAM
发表于 07-30 16:21
•9次下载
浅谈单片机rom和ram与代码的关系,以及为什么要加上拉电阻
ROM,RAM以及code,dataram掉电丢失rom掉电不丢失因为单片机RAM很有限,所以将不变的保存到ROM中CODE关键字的作用就是
发表于 11-25 18:36
•8次下载
一个单片机软件需要多少ROM和RAM
:Total ROM size: 即所需实际ROM最小值,包括代码code, 只读数据RO Data,还需包括初始化的读写数据,因为断电后这部分数据需存储于ROM中,上电后装载到
发表于 12-20 19:14
•0次下载
Vivado使用技巧-支持的Verilog语法
)和连线(wire)息息相关。Verilog便具有将ASM图表和电路框图用计算机语言表达的能力,本文将讲述Vivado综合支持的Verilog硬件描述语言; Verilog提供了行为化
什么是RAM和ROM
RAM(Random Access Memory,随机存取存储器)和ROM(Read-Only Memory,只读存储器)是计算机存储系统中的两种重要组成部分,它们在计算机的性能和功能上扮演着不同的角色。下面将分别详细解释RAM
评论