2012-03-27 209 views
0

好了VHDL的另一個問題。以下是我的代碼。假設我希望我的輸入存儲在內存中。並可以說我想添加其中兩個。 (不要強調它,稍後它將被替換)。這是我的代碼:vhdl ram模塊和寄存器的使用

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
USE ieee.numeric_std.ALL; 

use work.my_package.all; 

entity landmark_1 is 
    generic 
     (data_length :integer := 8; 
     address_length:integer:=3); 
     port (clk:in std_logic; 
     vin:in std_logic; 
     rst:in std_logic; 
     flag: in std_logic; 
     din: in signed(data_length -1 downto 0); 
     done: out std_logic 
     ); 
end landmark_1; 

architecture TB_ARCHITECTURE of landmark_1 is 


component ram IS 
    generic 
    (
     ADDRESS_WIDTH : integer := 4; 
     DATA_WIDTH : integer := 8 
    ); 
    port 
    (
     clock   : IN std_logic; 
     data   : IN signed(DATA_WIDTH - 1 DOWNTO 0); 
     write_address   : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0); 
     read_address   : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0); 
     we   : IN std_logic; 
     q   : OUT signed(DATA_WIDTH - 1 DOWNTO 0) 
    ); 
end component; 

signal inp1,inp2: matrix1_t(0 to address_length); 
signal out_temp: signed(data_length-1 downto 0); 
signal k:unsigned(address_length-1 downto 0); 

signal i: integer range 0 to 100:=0; 
begin 

read1:ram generic map(ADDRESS_WIDTH=>address_length, DATA_WIDTH=>data_length) port map (clk,din,k,k,vin,out_temp); 
inp1(i)<=out_temp; 

process (clk) 
    begin 
    if (clk'event and clk='1') then 
    if (flag='1') then out_temp<=inp1(0)+inp1(1); 
    end if; 
    end if; 
end process ; 

end TB_ARCHITECTURE; 

下面是我的問題:

  1. 爲什麼要使用RAM,而不是隻是做inp(i)<=din;。我認爲這將有助於合成器理解這是一個內存,但還有什麼?此外,我需要inp1寄存器。如果我打算使用它們,爲什麼要使用ram作爲中間件?
  2. 如果inp1是不必要的,我將如何在我的過程中獲取這兩個元素?我的意思是我需要像ram(address1)+ram(address2)這樣的東西,對吧?

下面是我的ram_code:

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 
USE ieee.numeric_std.ALL; 

ENTITY ram IS 
    GENERIC 
    (
     ADDRESS_WIDTH : integer := 4; 
     DATA_WIDTH : integer := 8 
    ); 
    PORT 
    (
     clock   : IN std_logic; 
     data   : IN signed(DATA_WIDTH - 1 DOWNTO 0); 
     write_address   : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0); 
     read_address   : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0); 
     we   : IN std_logic; 
     q   : OUT signed(DATA_WIDTH - 1 DOWNTO 0) 
    ); 
END ram; 

ARCHITECTURE rtl OF ram IS 
    TYPE RAM IS ARRAY(0 TO 2 ** ADDRESS_WIDTH - 1) OF signed(DATA_WIDTH - 1 DOWNTO 0); 

    SIGNAL ram_block : RAM; 
BEGIN 
    PROCESS (clock) 
    BEGIN 
     IF (clock'event AND clock = '1') THEN 
      IF (we = '1') THEN 
       ram_block(to_integer(unsigned(write_address))) <= data; 
      END IF; 

      q <= ram_block(to_integer(unsigned(read_address))); 
     END IF; 
    END PROCESS; 
END rtl; 

3,可誰能告訴我爲什麼Q(輸出)以後估計一個時鐘?

編輯:總而言之,我被告知我應該使用內存,這是我的實現。問題是當我插入RAM模型時,通過更改我的inp1(i)<=din;獲得了什麼。那麼我該如何使用它? (在使用公羊之前,我剛剛寫下了例如np1(i)+inp2(i+1))。

編輯2:包裝類型。

library IEEE; 
use IEEE.std_logic_1164.all; 
use ieee.numeric_std.all; 

package my_package is 
    type matrix1_t is array(integer range<>) of signed(7 downto 0); 
    type big_matrix is array(integer range<>) of signed(23 downto 0); 
    type matrix2d is array (integer range<>) of big_matrix(0 to 3); 

end my_package; 
+0

請你可以編輯你的代碼,刪除被註釋掉的位,並正確縮進它。如果您希望我們幫助您,只要您儘可能簡單地閱讀您的問題,就會得到更好的答覆。 – 2012-03-28 09:45:45

+0

好吧,我編輯了我的答案並刪除了評論 – 2012-03-28 09:58:08

+0

我並不是說刪除評論 - 只是註釋掉的*代碼*的位! – 2012-03-28 10:25:52

回答

2

爲什麼要使用該ram,而不只是做inp(i)< = din;

在現實世界中設計使用的RAM來存儲大量的數據,因爲他們是小(物理,在芯片上)是翻轉的陣列無人問津。在合成過程中,RAM被替換爲供應商庫中的一個。這個RAM看起來很小,但我猜你已經被告知使用一個作爲練習。

此外,我需要inp1寄存器。如果我打算使用它們,爲什麼要使用ram作爲中間件?

我不太確定imp1是什麼,因爲我不知道matrix_t是什麼,但我猜測它是RAM的寄存器版本。在這種情況下,這是多餘的。

如果inp1是不必要的,我將如何在我的過程中獲取這兩個元素?我的意思是我需要像ram(address1)+ ram(address2)這樣的東西,對吧?

...這是真正的問題。你需要問自己'如果你不能在一個循環中讀更多的東西,你如何添加兩個數字?'

誰能告訴我爲什麼q(輸出)是估計一個鐘後?

因爲這就是RAM的工作原理。您在一個週期內應用地址,並且數據稍後會出現一些週期(通常是一個週期,但不總是)由於RAM尺寸較小,RAM是必需的。您需要了解使用它們的問題以及如何使用它們。

+0

偉大的職位,以幫助我理解。所以最後一個問題,我會檢查你的答案。假設我想從ram中獲取元素的時間不是在同一個週期,而是在一段時間後。我將不得不再次移植地圖,並從我的輸出中獲取我想要的元素(例如we ='0')?我的意思是,這不是一個簡單的方法 - 只需編寫ram_block(address)並獲取該元素,就像我通常在寄存器中執行的那樣,對嗎? Inp1只是一個複製ram元素的數組,因此是多餘的。 – 2012-03-28 17:22:34

+0

你的問題不清楚。我想你是問你是否可以在同一個週期內讀寫,答案將取決於RAM的設計。一些RAM具有獨立的讀寫端口以允許這樣做。其他人有一個合併端口。你有一個單獨的讀取地址和寫入地址,所以你可以獨立執行這兩個操作,但當它們都是同一個地址時要小心。 – 2012-03-29 09:35:02

1

我假設你試圖用信號inp1表示一個RAM。但是,表示RAM的信號在您的ram實體中爲ram_block

由於您連接信號k作爲讀寫地址,因此您使用的是實體。這有兩個問題。首先,k在您的設計中似乎沒有被驅動到任何地方。其次,你可能不希望這兩個地址是一樣的。

我假設你想寫一些值到RAM,同時讀取兩個值並添加它們。我建議你使用一個進程來設置一個寫地址和一個設置讀地址的進程。您還需要至少一個具有RAM輸出寬度的寄存器。從RAM中讀取的第一個值存儲在該寄存器中。然後,您將該寄存器中的值和RAM中讀取的第二個值相加,並將結果存儲在另一個寄存器中。

+0

好的。有人告訴我應該使用內存,這是我的實現。問題是我通過改變我的inp1(i)<= din;當我插入ram模型。那麼我該如何使用它? – 2012-03-27 23:14:22

+0

但要實施什麼?你能顯示'matrix_1t'類型的定義嗎? – simon 2012-03-28 07:29:54

+0

編輯。好吧,想象我以前的代碼是這樣的。 過程(CLK) INP(I)<= DIN ...變化我 結束處理 現在我取代,與衝頭的模型,因爲該合成給我警告上,它不能識別INP1陣列作爲衝頭模塊。 – 2012-03-28 08:16:56

2

您不會將i設置爲0以外的任何值,因此您只能指定inp1(0)

假設RAM有多個存儲值,並且您需要在每個時鐘週期讀取其中的兩個以進行添加,則需要2個RAM塊(或單個雙端口塊),然後將兩個地址到這些RAM塊中。下一個週期你想要的兩個值將出現在數據輸出中,你可以將它們相加。您觀察到的時鐘週期延遲屬於同步RAM(這是大多數FPGA對其「大容量存儲器」所具有的特性) - 有些可以創建更小的異步RAM,其中數據在讀取地址之後出現短暫延遲改變,完全異步的時鐘。

+0

實際計算與此差異不同。並且我從一個測試平臺更改它的值。只是爲了瞭解如何使寫入過程獨立於從RAM讀取(我的計算要求所有數據已被首先讀取)。 – 2012-03-28 10:58:59