2016-08-22 61 views
-1

所有代碼行均以並行方式執行,因爲它是一臺機器。 我想創建這個內存從ram塊讀取某個寄存器到輸出,只有'後來'寫入輸入相同的寄存器。我的代碼是這樣的:讀取,然後在VHDL中寫入RAM VHDL

architecture Behavioral of RAM is 

type ram_t is array (0 to numOfRegs-1) of std_logic_vector (rLength-1 downto 0); 
signal ram_s: ram_t; 
signal loc : integer; 

begin 

process(clk) 
begin 
    if(rising_edge(clk)) then 
     if(we='1') then 
      dataout <= ram_s(loc); -- reads the 'old' data to the output 
      ram_s(loc) <= datain; -- writes the 'new' data to the RAM 
      loc <= conv_integer(addr); 
     end if; 
    end if; 
end process;     
end Behavioral; 

有呈現 here類似的情況。

所以我想問一下,我的代碼是否正常工作,或者需要進行調整,如延遲半個時鐘週期,如果是這樣,如何實現它。 感謝您的耐心和幫助,我對VHDL非常陌生。

我在下面添加一個測試臺模擬。可以看出數據輸出根本不起作用。

testbench i've simulated

+0

它做了你想要的模擬? –

+1

您只想在寫入啓用時讀取數據? –

回答

1

你的問題不存在一個Minimal, Verifiable and Complete example,缺乏複製您的結果的能力。

這樣做的後果之一是,如果未顯示代碼部分中存在一個或多個問題原因,則答案可能不明確。

Brian對我們無效時沒有讀取數據的評論非常尖銳,並且會對波形中黃色標記左邊的時鐘週期中的'U'負責。

還有一個問題是loc是一個信號。計劃更新信號,並且在當前模擬週期中計劃恢復的任何進程尚未恢復並暫停時,不會發生更新。

這意味着您的地址的整數版本被延遲,並且在下一個上升沿之前不會在過程中看到。

通過使一個變量作爲替代流水線datain和移動dataout分配在以下更改RAM過程中完成修復loc

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; -- standard package 

entity ram is 
    generic (
     ADDRLENGTH: natural := 8; 
     RLENGTH: natural := 16; 
     NUMOFREGS: natural := 256 
    ); 
    port (
     clk:  in std_logic; 
     we:   in std_logic; 
     addr:  in std_logic_vector (ADDRLENGTH - 1 downto 0); 
     datain:  in std_logic_vector (RLENGTH - 1 downto 0); 
     dataout: out std_logic_vector (RLENGTH - 1 downto 0) 
    ); 

end entity; 

architecture behavioral of ram is 

    type ram_t is array (0 to NUMOFREGS - 1) of 
      std_logic_vector (RLENGTH - 1 downto 0); 
    signal ram_s: ram_t; 

    -- signal loc: integer; -- USE VARIABLE in process instead 

begin 

    process(clk) 
    variable loc: integer; -- MAKE loc variable so it's immediately available 
    begin 
     if rising_edge(clk) then 
      loc := to_integer(unsigned(addr)); -- MOVED so READ works 
      if we = '1' then 
       -- dataout <= ram_s(loc); -- reads the 'old' data to the output 
       ram_s(loc) <= datain; -- writes the 'new' data to the ram 
       -- loc <= conv_integer(addr); 
      end if; 
      dataout <= ram_s(loc); -- MOVED reads the 'old' data to the output 
     end if; 
    end process;     
end architecture behavioral; 

還有在實體聲明填充的自由並使用Synopsys的std_logic_arith包將其從conv_integer轉換爲IEEE的numeric_std包中的to_integer。使用-2008兼容的工具鏈,您可以改爲使用IEEE的package numeric_std_unsigned,並將類型轉換爲無符號。

因爲還沒有提供的ram_test測試平臺測試臺被寫入複製您的波形顯示的圖像:

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

entity ram_tb is 
end entity; 

architecture foo of ram_tb is 
    constant ADDRLENGTH: natural := 8; 
    constant RLENGTH: natural := 16; 
    constant NUMOFREGS: natural := 256; 
    signal clk:  std_logic := '0'; 
    signal we:   std_logic := '1'; 
    signal addr:  std_logic_vector (ADDRLENGTH - 1 downto 0); 
    signal datain:  std_logic_vector (RLENGTH - 1 downto 0); 
    signal dataout: std_logic_vector (RLENGTH - 1 downto 0); 

begin 
DUT: 
    entity work.ram 
     generic map (
      ADDRLENGTH => ADDRLENGTH, 
      RLENGTH => RLENGTH, 
      NUMOFREGS => NUMOFREGS 
     ) 
     port map (
      clk => clk, 
      we => we, 
      addr => addr, 
      datain => datain, 
      dataout => dataout 
     ); 

CLOCK: 
    process 
    begin 
     if now = 500 ps then 
      wait for 200 ps; 
     else 
      wait for 100 ps; 
     end if; 
     clk <= not clk; 
     if now >= 1100 ps then 
      wait; 
     end if; 
    end process; 

STIMULI: 
    process 
    begin 
     for i in 0 to 2 loop 
      addr <= std_logic_vector(to_unsigned (i, ADDRLENGTH)); 
      case i is 
       when 0 => 
        datain <= x"00FF"; 
       when 1 => 
        datain <= x"FF00"; 
       when 2 => 
        datain <= x"FFFF"; 
      end case; 
      wait until falling_edge(clk); 
      if i = 1 then 
       we <= '0'; 
      end if; 
     end loop; 
     for i in 1 to 2 loop 
      addr <= std_logic_vector(to_unsigned (i, ADDRLENGTH)); 
      case i is 
       when 1 => 
        datain <= x"FF00"; 
       when 2 => 
        datain <= x"FFFF"; 
      end case; 
      wait until falling_edge(clk); 
     end loop;   
     wait; 
    end process; 

end architecture; 

而且由此產生:

ram_tb_match.png

當一個寫的地址是隨後閱讀顯示正確的數據。

使用的模擬器不會在波形轉儲中顯示非信號(聲明中的邊界必須是靜態的),並且在您提供的設計規範的部分中找不到rst

如前所述,不保證您的問題中未提供您的設計規範或測試平臺部分的其他問題。

顯示的測試臺並不全面。