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