本文主要介紹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文章
562瀏覽量
85681 -
RAM
+關注
關注
8文章
1367瀏覽量
114546 -
Verilog
+關注
關注
28文章
1345瀏覽量
109996 -
代碼
+關注
關注
30文章
4753瀏覽量
68369 -
Vivado
+關注
關注
19文章
808瀏覽量
66349
發布評論請先 登錄
相關推薦
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
?9652次閱讀
ROM、RAM、DRAM、SRAM和FLASH的區別
常見存儲器概念辨析:RAM、SRAM、SDRAM、ROM、EPROM、EEPROM、Flash存儲器可以分為很多種類,其中根據掉電數據是否丟失可以分為RAM(隨機存取存儲器)和ROM(
發表于 12-04 14:23
?2868次閱讀
ram和rom的區別之處
存儲器是數字系統中用以存儲大量信息的設備或部件,是計算機和數字設備中的重要組成部分。存儲器可分為隨機存取存儲器(ram)和只讀存儲器(rom)兩大類。要說它倆有什么區別,下面就由英尚微電子為大家解惑
發表于 05-10 10:28
?3192次閱讀
采用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
評論