跳转到主要内容
--## 电子创新网图库均出自电子创新网,版权归属电子创新网,欢迎其他网站、自媒体使用,使用时请注明“图片来自电子创新网图库”,不过本图库图片仅限于网络文章使用,不得用于其他用途,否则我们保留追诉侵权的权利。 ##--

本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
judy 提交于

本文转载自: FPGA入门到精通(微信号:weilaikejisaidao)

本文主要介绍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属性强制规定使用的资料类型。

(*rom_style = "block" *)表示用Block RAM实现

(*rom_style = "reg" *)表示用寄存器实现

(*rom_style = "distributed" *)表示用分布式 RAM实现

(*rom_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

2、伪双端口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

3、真双端口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

4、初始化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,以及一些常见的设计方法和示例代码。在任何情况下,都要格外注意存储器的读写一致性和正确性,确保系统的稳定性和正确性。

精彩推荐

2026英伟达GTC大会专题

CES 2026(国际消费类电子产品展览会)专题

第四届南渡江智慧医疗与康复产业高峰论坛

第十五届松山湖中国IC创新高峰论坛

第四届滴水湖中国RISC-V产业论坛

Recent comments

  • 1873774516_516738
  • 2460440665_516737
  • 1457585548_516736
  • 780289498_516735
  • 2283262460_516734