什么是 RAM(隨機存取存儲器)?
RAM(隨機存取存儲器)是用于系統(tǒng)讀/寫和存儲數(shù)據(jù)的存儲設(shè)備。RAM 存在范圍從嵌入式系統(tǒng)、智能手機等小型系統(tǒng)到臺式機、筆記本電腦等大型系統(tǒng)。系統(tǒng)中使用的 RAM 對系統(tǒng)性能有重大影響。它負(fù)責(zé)執(zhí)行多項任務(wù)并存儲數(shù)據(jù)。RAM的版本越高,它的性能就越高。
現(xiàn)在我們對 RAM 是什么有了清晰的認(rèn)識,讓我們看看如何在 VHDL 中實現(xiàn) RAM。盡管業(yè)界使用了更高版本的 RAM。在本教程中,我們將實現(xiàn)一個簡單的 32X8 RAM。它是存儲設(shè)備的小規(guī)模版本。
內(nèi)存規(guī)格
通常,內(nèi)存用 M x N 表示,其中 M 是位置數(shù),N 是數(shù)據(jù)線。所以這里 32 x 8,“32”代表 32 個位置,或者一個有 32 個位置的數(shù)組,“8”代表 8 條數(shù)據(jù)線。簡單來說,一個 32 x 8 RAM 有 32 個位置,每 32 個位置可以存儲 8 位數(shù)據(jù)。因此,32 x 8 RAM 可以存儲的總位數(shù)為 256 位。現(xiàn)在,您可以想象用于筆記本電腦/臺式機的 8GB、16GB RAM 的存儲容量。
下面給出了一個示意圖,指示了 RAM 中的端口/線路。
RAM 具有數(shù)據(jù)線、地址線、寫入信號、時鐘信號和用于從 RAM 讀取內(nèi)容的數(shù)據(jù)輸出端口。地址線大小/位因 M x N 規(guī)格而異。讓我們了解如何計算地址線位 (A) 的大小。
地址線位數(shù)/大小 (A):2 A =M。因此,在我們的例子中,它是 2 A =32 (M=32),其中 A=5。
An → 地址線
M → 位置數(shù)
N → 數(shù)據(jù)線
W → 寫信號
由于 RAM 是時序電路,因此它具有時鐘信號。所有時序電路都有時鐘信號。此外,寫入信號負(fù)責(zé)將數(shù)據(jù)刻錄到 RAM 中。只有當(dāng)時鐘和寫信號都為“1”時,數(shù)據(jù)才會存儲在 RAM 中。
下面給出了與寫入和時鐘信號有關(guān)的事件。
RAM 的 VHDL 代碼:
?
圖書館 IEEE; 使用 IEEE.STD_LOGIC_1164.ALL; 使用 ieee.numeric_std.ALL; 實體 RAM_32X8 是 端口( 地址:in std_logic_vector(4 downto 0); data_in:in std_logic_vector(7 downto 0); write_in:in std_logic; 時鐘:in std_logic; data_out:out std_logic_vector(7 downto 0) ); 結(jié)束 RAM_32X8; 架構(gòu) RAM_32X8 的行為是 類型 ram_array 是 std_logic_vector 的數(shù)組(0 到 31 )(7 到 0); 信號 ram_data: ram_array :=( b"10000000",b"01001101",x"77",x"67", x"99",x"25",x"00",x"1A", x"00 ",x"00",x"00",x"00", x" x"00",x"00",b"00111100",x"00", x"00",x"00",x"00",x"00", x"00",x"00", x"00",x"1F" ); 開始 進(jìn)程(時鐘) 開始 如果(上升沿(時鐘))然后 如果(寫入='1')然后 ram_data(to_integer(無符號(地址)))<=數(shù)據(jù)輸入; 萬一; 萬一; 結(jié)束進(jìn)程; data_out <= ram_data(to_integer(unsigned(address))); 結(jié)束行為;
?
讓我們先一步一步來,以便我們可以跟蹤事情。首先,讓我們逐段編寫代碼,然后合并。
第一步是導(dǎo)入庫和實體聲明。就像“使用IEEE.std_logic_1164.all?”、“使用IEEE.numeric_std.ALL?”一樣,導(dǎo)入了我們將使用的數(shù)字庫。這個庫的使用將在下面的代碼中解釋。
該實體使用標(biāo)簽“?RAM_32X8?”聲明。接下來,聲明了所有輸入和輸出端口。位大小為五 (5) 的地址線 (A)、數(shù)據(jù)線 (即 N = 8)、寫入信號 (W)、時鐘信號和數(shù)據(jù)輸出是對應(yīng)的輸入和輸出端口,如前所述。
?
圖書館 IEEE; 使用 IEEE.STD_LOGIC_1164.ALL; 使用 ieee.numeric_std.ALL; 實體 RAM_32X8 是 港口( 地址:在 std_logic_vector(4 downto 0) 中; data_in: 在 std_logic_vector(7 downto 0); write_in:在std_logic中; 時鐘:在 std_logic 中; data_out: 輸出 std_logic_vector(7 downto 0) ); 結(jié)束 RAM_32X8;
?
一旦實體被聲明,我們就可以從架構(gòu)定義開始。該架構(gòu)被標(biāo)記為“RAM_32x8”。
?
RAM_32X8 的架構(gòu)行為是
?
ram_array 類型是 std_logic_vector(7 到 0)的數(shù)組(0 到 31):?現(xiàn)在,我們必須創(chuàng)建一個大小為 32 的數(shù)組。因此,我們將變量“?ram_array?”聲明為“類型 ram_array”,它是一個枚舉類型。枚舉類型什么都不是,只是列出變量的所有可能值。“is array (0 to 31)”表示“type ram_array”將是一個大小為(M)為32的數(shù)組,從0開始到31結(jié)束。這32個位置應(yīng)該能夠存儲一個8位向量為N= 8.?因此,我們將其聲明為“?std_logic_vector (7 down to 0)?”。所以通常 ram_arary 是一個有 32 個位置的數(shù)組,每個位置可以存儲 8 位。
?
類型 ram_array 是 std_logic_vector 的數(shù)組(0 到 31)(從 7 到 0);
?
現(xiàn)在,我們必須將其存儲為信號。因此,我們將“ram_data”聲明為信號并將其映射到數(shù)組“ram_array”。現(xiàn)在“ram_array”的內(nèi)容將被映射到信號“ram_data”。所以,我們必須初始化數(shù)組的內(nèi)容。所以,我已經(jīng)初始化了一些值。
注意:我們可以用二進(jìn)制或十六進(jìn)制表示/初始化。“b”代表二進(jìn)制,“x”代表十六進(jìn)制。然而,ModelSim 在模擬時默認(rèn)將表示轉(zhuǎn)換為二進(jìn)制。
?
信號 ram_data: ram_array :=( b"10000000",b"01001101",x"77",x"67", x"99",x"25",x"00",x"1A", x"00 ",x"00",x"00",x"00", x"00",x"00",x"00",x"00", x"00",x"0F",x"00 ",x"00", x"00",x"00",b"00111100",x"00", x"00",x"00",x"00",x"00", x"00 ",x"00",x"00",x"1F"
?
由于整個if條件過程都依賴于時鐘,我們通過“process(clock)”聲明
?
開始 進(jìn)程(時鐘) 開始
?
if (rising_edge(clock)) then:?ModelSim 有一個預(yù)定義的函數(shù)“rising_edge()”。“rising_edge”表示信號從低到高的轉(zhuǎn)換點。因此,只有在發(fā)生從低到高的轉(zhuǎn)換時,它才會傳遞到下一條語句。
?
如果(上升沿(時鐘))那么
?
if (write_in='1') then:這是一個簡單的 if 條件,只有當(dāng)信號“write_in”為 1 時,它才會傳遞到下一個。
?
if(write_in='1') 那么
?
ram_data v(to_integer(unsigned(address))) <= data_in:??“ram_data”信號本身是一個數(shù)組,因此我們必須設(shè)置必須存儲數(shù)據(jù)的數(shù)組的索引。該索引將只接受一個正整數(shù)。“to_integer()”將轉(zhuǎn)換為整數(shù)值。“無符號”用于將二進(jìn)制數(shù)轉(zhuǎn)換為無符號二進(jìn)制數(shù)。“IEEE.NUMERIC_STD all”包負(fù)責(zé)整數(shù)轉(zhuǎn)換。
注意:默認(rèn)情況下,Modelsim 會將給定的輸入作為二進(jìn)制。
如果您的地址是“11111”,ModelSim 有時會將“11111”解釋為負(fù)數(shù),因為 MSB(最高有效位)為“1”。因此,始終建議使用unsigned()。最后,當(dāng) ModelSim 處理這條語句時,它會是ram_data(index)。?只是我們已經(jīng)將給定的地址轉(zhuǎn)換為適當(dāng)?shù)?a target="_blank">索引格式。現(xiàn)在,“data_in”信號中的數(shù)據(jù)將被存儲到適當(dāng)?shù)摹皉am_data”索引中。
由于我們使用了 2 個 if,我們必須通過兩個“end if”來終止 if
?
萬一; 萬一; 結(jié)束進(jìn)程;
?
由于必須通過給定地址從 RAM 中讀取數(shù)據(jù),因此聲明了“data_out”信號以從特定索引讀取內(nèi)容。
?
data_out <= ram_data(to_integer(unsigned(address)));
?
只需復(fù)制粘貼上面的代碼,編譯和模擬代碼。仿真過程請參考“ModelSim中使用VHDL實現(xiàn)基本邏輯門”
沿波形移動光標(biāo)以讀取信號的內(nèi)容。這就是用 VHDL 編寫 RAM 的方式。
圖書館 IEEE;
使用 IEEE.STD_LOGIC_1164.ALL;
使用 ieee.numeric_std.ALL;
實體 RAM_32X8 是
端口(
地址:in std_logic_vector(4 downto 0);
data_in:in std_logic_vector(7 downto 0);
write_in:in std_logic;
時鐘:in std_logic;
data_out:out std_logic_vector(7 downto 0)
);
結(jié)束 RAM_32X8;
架構(gòu) RAM_32X8 的行為是
類型 ram_array 是 std_logic_vector 的數(shù)組(0 到 31 )(7 到 0);
信號 ram_data: ram_array :=(
b“10000000”,b“01001101”,x“77”,x“67”,
x“99”,x“25”,x“00”,x“1A”,
x“00 ”,x“00”,x“00”,x“00”,
x“00”,x“00”,b“00111100”,x“00”,
x“00”,x“00”,x“00”,x“00”,
x“00”,x“00”, x“00”,x“1F”
);
開始
進(jìn)程(時鐘)
開始
如果(上升沿(時鐘))然后
如果(寫入=‘1’)然后
ram_data(to_integer(無符號(地址)))《=數(shù)據(jù)輸入;
萬一;
萬一;
結(jié)束進(jìn)程;
data_out 《= ram_data(to_integer(unsigned(address)));
結(jié)束行為;
評論
查看更多