2016-02-27 65 views
0
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use ieee.std_logic_arith.all; 
entity RAM_controler is 
port(
     clk_50 : in std_logic; 
     clk_baud : in std_logic; 
     main_reset : in std_logic; 
     enable: in std_logic; --active high write enable 
     in_data : in std_logic_vector(7 downto 0); 
     W_order : out std_logic; 
     R_order : out std_logic; 
     Data_OUT : out std_logic_vector(7 downto 0); 
     Write_Address_OUT: out std_logic_vector(7 downto 0); 
     Read_Address_OUT: out std_logic_vector(7 downto 0)   
    ); 
end entity RAM_controler; 
architecture Behavioral of RAM_controler is 
type state is (reset,operation); 
signal state_reg,next_state_reg : state; 
signal write_address : std_logic_vector(W-1 downto 0):="00000000"; 
signal next_write_address : std_logic_vector(W-1 downto 0):="00000000";   
begin 
state_change : process(clk_50, main_reset) 
begin 
    if (main_reset = '1') then 
     state_reg <= reset;  
    elsif (rising_edge(clk_50)) then 
     state_reg <= operation; 
     read_counter <= next_read_counter; 
     write_address<= next_write_address; 
     read_address <= next_read_address; 
    end if;  
end process; 

writecounter : process(clk_baud, main_reset,enable) 
begin 
    if (main_reset='1') then 
     next_write_address <= "00000000"; 
     Data_OUT <= "ZZZZZZZZ"; 
     W_order <='0'; 
     Write_Address_OUT <="ZZZZZZZZ"; 
    elsif (rising_edge(clk_baud) and enable='1') then 
     W_order <='1'; 
     Data_OUT <= in_data;    
     Write_Address_OUT <= write_address; 
     if (write_address = "11111111") then 
      next_write_address <= "00000000"; 
     else 
      next_write_address <= write_address+1; 
     end if; 
    else 
     W_order <='0'; 
     Write_Address_OUT <= "ZZZZZZZZ"; 
     next_write_address <= write_address+1; 
    end if; 
end process;   
end Behavioral; 

上面的代碼描述了RAM控制器。VHDL - 時鐘邊緣外的編碼錯誤

使問題的部分是「elsif(rising_edge(clk_baud)和enable ='1')then」。

錯誤:不能老是爲「Write_Address_OUT」間寄存器在RAM_controler.vhd因爲它沒有保持時鐘邊沿

我不`噸知道爲什麼這一點是錯誤以外的價值。

有人向我提出建議嗎?

謝謝!

+0

最後一個'else'中的分配應該與時鐘的上升沿同步嗎?你正在使用哪個綜合工具? –

+1

您的代碼不是[最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve),對'W','read_address','next_read_address','read_counter'和'next_read_counter'的聲明'丟失。請注意,例如,您正在使用在rising_edge(clk_baud)上指定的'next_write_address'在rising_edge(clk_50)上分配'write_address'。還有其他一些設計問題,比如Bill Lynch指出,例如在任何'clk_baud,main_reset'和'enable'事件中你都會執行'Write_Address_OUT'的分配。 – user1155120

+0

我正在使用Quartus II。 其實下面的答案對我很有幫助。 但我不知道爲什麼最後的其他改變如下。 – Kim

回答

2

如果你的編碼順序邏輯,明智的做法是堅持一個模板。這裏就是這樣的一個模板,時序邏輯與異步重置,所有的綜合工具應該明白:

process(clock, async_reset) -- nothing else should go in the sensitivity list 
begin 
    -- never put anything here 
    if async_reset ='1' then -- or '0' for an active low reset 
     -- set/reset the flip-flops here 
     -- ie drive the signals to their initial values 
    elsif rising_edge(clock) then -- or falling_edge(clock) 
     -- put the synchronous stuff here 
     -- ie the stuff that happens on the rising or falling edge of the clock 
    end if; 
    -- never put anything here 
end process;   

所以使不應該在敏性列表,它不應該在同一個if語句作爲測試異步復位和時鐘測試。

爲什麼你收到此錯誤的原因:

Error : Can`t inter register for "Write_Address_OUT" at RAM_controler.vhd because it does not hold its value outside the clock edge

是因爲在你的代碼的最後三位分配:

  W_order <='0'; 
      Write_Address_OUT <= "ZZZZZZZZ"; 
      next_write_address <= write_address+1; 

可以在時鐘或的下降沿發生(因爲你也有在您的靈敏度列表中啓用),而不依賴於任何時鐘。邏輯合成器不能合成像那樣的邏輯。如果你堅持這個模板,你就不會遇到這種問題(這讓你更仔細地考慮你期望合成器合成的邏輯)。

所以,我會編碼的writecounter過程中更是這樣的:

writecounter : process(clk_baud, main_reset) 
begin 
    if (main_reset='1') then 
     next_write_address <= "00000000"; 
     Data_OUT <= "ZZZZZZZZ"; 
     W_order <='0'; 
     Write_Address_OUT <="ZZZZZZZZ"; 
    elsif rising_edge(clk_baud) then 
     if enable='1' then 
      W_order <='1'; 
      Data_OUT <= in_data;    
      Write_Address_OUT <= write_address; 
      if (write_address = "11111111") then 
       next_write_address <= "00000000"; 
      else 
       next_write_address <= write_address+1; 
      end if; 
     else 
      W_order <='0'; 
      Write_Address_OUT <= "ZZZZZZZZ"; 
      next_write_address <= write_address+1; 
     end if; 
    end if; 
end process;   

不過,我要強調的是我的代碼不完全一樣你的。我不知道你的設計意圖,所以我只能猜測你的意圖。如果你打算採取其他行爲,那麼你將不得不實施。無論您的設計意圖如何,我堅持使用模板的建議都很重要。

+0

代碼模板很有幫助。但是,爲了更好地理解,您還應該解釋爲什麼OP的代碼沒有描述寄存器。 –

+0

@馬丁扎貝爾你是對的。在閱讀了Kim在該問題下的評論之後,我在添加該解釋,因爲您在評論... –

+0

謝謝。有用的評論。 除了你指出的內容之外,還有什麼其他的原因使啓用不應該在敏感列表中? – Kim

0

最後else在你的代碼實際上應該是:

elsif (rising_edge(clk_baud) and enable='0') then