2012-10-16 20 views
0

它又是我! 首先我想說幾天前我學會了VHDL,在這方面我是一個新手,所以我傾向於犯下愚蠢的錯誤。任何建議都會很棒。 我寫了一個模塊的VHDL代碼,可以用作內存控制器。我的VHDL代碼的輸出變得復位依賴

這裏是我的代碼:

library IEEE; 
use IEEE.std_logic_1164.all; 
use IEEE.std_logic_arith.all; 
use IEEE.std_logic_unsigned.all; 
use ieee.numeric_std.all; 
entity memory_controller is 
port(clk: in std_logic; 
    reset: in std_logic; 
    bus_id: in std_logic_vector(7 downto 0); 
    read_write, burst: in std_logic; 
    ready: in std_logic; 
    oe, we: out std_logic; 
    addr_1, addr_2: out std_logic_vector(7 downto 0) 
    ); 
end memory_controller; 
architecture behavioral of memory_controller is 
    type statetype is (idle, decision, wr, rd1, rd2, rd3, rd4); 
    signal present_state, next_state : statetype; 
    signal addr_int : integer range 0 to (2**addr_1'length)-1; 
    begin 
    Synch_reset: process(clk) 
    begin 
     if (rising_edge(clk)) then 
      if (reset ='0') then 
       present_state <= next_state; 
      else 
       present_state <= idle; 
      end if; 
     end if; 
    end process; 
    decision_logic: process(present_state, read_write, ready, burst) 
    begin 
     case present_state is 
      when idle => 
       oe <= '0'; we <= '0'; addr_int <= 0; 
       addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length)); 
       addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length)); 
       if(bus_id = "11110011") then 
        next_state <= decision; 
       else 
        next_state <= idle; 
       end if; 
      when decision => 
       if (read_write = '1') then 
        next_state <= rd1; 
       else 
        next_state <= wr; 
       end if; 
      when wr => 
       we <= '1'; 
       if (ready = '1') then 
        next_state <= idle; 
       else 
        next_state <= wr; 
       end if; 
      when rd1 => 
       oe <= '1'; 
       if(ready = '0') then 
        next_state <= rd1; 
       else 
        if(burst = '0') then 
         next_state <= idle; 
        else 
         next_state <= rd2; 
         addr_int <= addr_int + 1; 
       addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length)); 
       addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length)); 
        end if; 
       end if; 
      when rd2 => 
       oe <= '1'; 
       if(ready = '1') then 
        next_state <= rd3; 
        addr_int <= addr_int + 1; 
       addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length)); 
       addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length)); 
       else 
        next_state <= rd2; 
       end if; 
      when rd3 => 
       oe <= '1'; 
       if(ready = '1') then 
        next_state <= rd4; 
        addr_int <= addr_int + 1; 
       addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length)); 
       addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length)); 
       else 
        next_state <= rd3; 
       end if; 
      when rd4 => 
       oe <= '1'; 
       if(ready = '1') then 
        next_state <= idle; 
       else 
        next_state <= rd4; 
       end if; 
     end case; 
    end process; 
end behavioral; 

這裏是我的測試平臺:

Library IEEE; 
USE IEEE.std_logic_1164.all; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 
entity memory_controller_tb is 
end memory_controller_tb; 
architecture test of memory_controller_tb is 
component memory_controller 
port(clk: in std_logic; 
    reset: in std_logic; 
    bus_id: in std_logic_vector(7 downto 0); 
    read_write, burst: in std_logic; 
    ready: in std_logic; 
    oe, we: out std_logic; 
    addr_1, addr_2: out std_logic_vector(7 downto 0) 
    ); 
end component; 
signal clk: std_logic; 
signal reset: std_logic; 
signal read_write, burst, oe, we: std_logic; 
signal addr_1, addr_2: std_logic_vector(7 downto 0); 
signal ready: std_logic; 
signal bus_id: std_logic_vector(7 downto 0); 
signal StopClock : boolean := FALSE; 
begin 
UUT :memory_controller 
port map(clk => clk, 
      reset => reset, 
      bus_id => bus_id, 
      read_write => read_write, 
      burst => burst, 
      ready => ready, 
      oe => oe, 
      we => we, 
      addr_1 => addr_1, 
      addr_2 => addr_2); 
clk_process: process 
begin 
while not StopClock loop 
clk <= '0'; 
wait for 5 ns; 
clk <= '1'; 
wait for 5 ns; 
end loop; 
end process clk_process; 
stim: process is 
begin 
reset <= '1', '0' after 50 ns; 
bus_id <= "11110011"; 
wait for 5 ns; 
read_write <= '0'; 
wait for 5 ns; 
ready <= '1'; 
bus_id <= "11110011"; 
wait for 5 ns; 
read_write <= '1'; 
assert (ready <='1' and burst <= '1') 
report "Illegal state" 
severity error; 
assert (ready <= '1' and burst <='0') 
report "Illegal state" 
severity error; 
wait for 5 ns; 
ready <= '0'; 
wait for 5 ns; 
burst <= '0'; 
wait for 5 ns; 
ready <= '1'; 
wait for 5 ns; 
burst <= '1'; 
wait for 5 ns; 
ready <= '0'; 
wait for 5 ns; 
ready <= '1'; 
wait for 5 ns; 
ready <= '1'; 
end process; 
end test; 

configuration CFG_memory_controller of memory_controller_tb is 
    for test 
     for UUT : memory_controller 
     end for; 
    end for; 
end; 

當突發斷言它應該throught READ1讀取2。讀和read4上的準備斷言(如突發時= 1它應該繼續讀取2,讀取3,如果就緒爲1,則讀取4),並且如果在兩者之間的任何時候重置爲0,則不得進入空閒狀態。但它對我有用。如何更改程序以使其不依賴重置?

而且,地址不會被重置爲0時,它被重置爲重新回到空閒狀態。當我嘗試更改代碼時,它說我試圖從多個地方聲明地址。

而且我覺得我的測試臺的寫作技巧吸吮,還有什麼樣的規則或指引,或你有隻爲它開發的本能?

謝謝!

+0

1.破除 「等5納秒;」,做出 「等到rising_edge(CLK);」。這樣你將確保你沒有得到任何增量循環問題。 2.你的控制器代碼有點狡猾:我確定你想讓addr_int(至少)成爲一個註冊表,否則你的計數器會做一些有趣的事情。然後回來;-) – BennyBarns

+0

我認爲你正在編寫軟件,而不是硬件了。請仔細閱讀您的書:在組合邏輯中,某些信號被分配爲「a <= a + 1」或「a <= 1」,然後是「b = a + 2」。那麼,你覺得它成了什麼?請通過您的軟件思考。如果沒有,沒有人可以定義你的錯誤。 P/S:HDL是硬件**描述**語言。你沒有編程,你正在描述。 HDL代碼必須導致架構。 – Khanh

回答

0

你有一個組合循環:你看,在你的組合過程中,這會導致各種問題寫信號addr_int。要麼創建一個信號next_addr_int並在時鐘進程中分配該信號,要麼將所有內容放在一個時鐘進程中。

與代碼的其他問題:

  • std_logic_arithstd_logic_unsigned已被棄用。改爲使用ieee.numeric_std
  • 轉換這樣使你的代碼很難理解:的addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));使用unsigned代替std_logic_vector代替。
  • 在你復位條款,人們就會認爲你既然檢查reset = '0'復位爲低電平有效。相反,請檢查reset = '1'並反轉ifelse部分。我猜這些工具不會介意你的編碼風格,但它會混淆人類。