2014-04-10 99 views
0

不工作,我討厭問另一個問題就在這裏,但顯然我與模擬真沒用:(VHDL狀態轉換 - 適用於主板,但在模擬器

基本上,我有一個紅綠燈控制器,它由許多不同的狀態和幾個定時器組成,它們運行不同的時間長度,當系統進入一個狀態時,它激活一個定時器,並且有一條if語句來監視定時器的輸出和當計時器輸出值爲1時,將系統指向下一個狀態。

這一切都可以在主板上正常工作,但是當我模擬它時,計數會打勾爲'1',但是t他未選擇下一個狀態。由此可以看出,在這裏:

Simplified simulation

我試圖歸結代碼到下面的要領,但如果你需要更多的內容(和感覺更加大方,比我應得的),那麼全代碼是here

初始化:

entity trafficlightcontroller is 
    port 
    (
    clk  : in std_logic; 
    reset  : in std_logic; 
    ambulance : in std_logic; 
    smr   : in std_logic; 
    sml   : in std_logic; 
    ssr   : in std_logic; 
    rlmr   : out std_logic; 
    almr   : out std_logic; 
    glmr   : out std_logic; 
    rlsr   : out std_logic; 
    alsr   : out std_logic; 
    glsr   : out std_logic 
); 
end entity; 

architecture rtl of trafficlightcontroller is 

    -- Build an enumerated type for the state machine 
    -- r=red;a=amber;g=green;c=car waiting;m=main road;s=side road 
    type state_type is (rmgs, rmas, rmrs, amrs, gmrs, gmrcs, ramrs, rmacs, rmrcs, ramrcs, rmras, rmrs2); 

    -- Signals to hold the states 
    signal present_state, next_state : state_type; 
     signal divclk, reset2, reset2b, reset3, reset3b, reset10, reset20, reset20b, count2, count2b, count3, count3b, count10, count20, count20b: std_logic; 

     component timer is 
      generic (
       trigger_cnt: natural := 20 
      ); 
      port (
       clk:  in  std_logic; 
       reset:  in  std_logic; 
       count:  buffer std_logic 
      ); 
     end component timer; 

     component clockdivider 
      port(clkin : in std_logic; 
     dividedclk : out std_logic 
      ); 
     end component clockdivider; 
     begin 

     timer2 : timer generic map (trigger_cnt => 2) port map(divclk,reset2,count2); 
     timer2b : timer generic map (trigger_cnt => 2) port map(divclk,reset2b,count2b); 
     timer3 : timer generic map (trigger_cnt => 3) port map(divclk,reset3,count3); 
     timer3b : timer generic map (trigger_cnt => 3) port map(divclk,reset3b,count3b); 
     timer10 : timer generic map (trigger_cnt => 10) port map(divclk,reset10,count10); 
     timer20 : timer generic map (trigger_cnt => 20) port map(divclk,reset20,count20); 
     timer20b : timer generic map (trigger_cnt => 20) port map(divclk,reset20b,count20b); 
     divider : clockdivider port map(clk, divclk); 

狀態(包括在仿真中所示的狀態)的開始:

case present_state is 

     --Red light main; green side road 
    when rmgs=> 
     reset2 <= '0'; 
     reset2b <= '0'; 
     reset3 <= '0'; 
     reset3b <= '0'; 
     reset20 <= '0'; 
     reset20b <= '0'; 
     rlmr <= '1'; 
     almr <= '0'; 
     glmr <= '0'; 
     rlsr <= '0'; 
     alsr <= '0'; 
     glsr <= '1'; 
     reset10 <= '1'; 
     --if count is complete then move to next state 
     if (count10='1') THEN 
      next_state <= rmas; 
     --otherwise, return to current state 
     else 
      next_state <= rmgs; 
     end if; 

時鐘過程:

--Every clock tick, the next state is selected as the present state. 
    state_clocked: process(clk) 
    begin 
    if (rising_edge(clk)) THEN 
     present_state <= next_state; 
    end if; 
end process state_clocked; 

我輸入到線模擬器初始化時鐘:

force clk 0 0ns, 1 10 ns -repeat 20ns 

回答

1

您的next_state進程在靈敏度列表中缺少大量信號。這可能會解決它。 VHDL-2008允許您使用關鍵字「all」而不是信號名稱。如果你的綜合工具支持這個,可能值得使用。

其餘的都是建議:

隨着兩個處理的statemachine,復位邏輯是最經常在state_clocked過程捕獲的。因此,看起來更像是這樣的:

state_clocked: process(clk) 
begin 
    if (rising_edge(clk)) THEN 
    if Reset = '0' then 
     present_state <= rmrs; 
    else 
     present_state <= next_state; 
    end if ; 
    end if; 
end process state_clocked; 

您可以縮短你的代碼,如果顯著您使用默認分配到「關」的值賦給next_state過程的所有信號輸出:

next_state_proc : process (present_state, ssr, ambulance, Count10, Count3, ...) 
begin 
    -- default assignments 
    reset2 <= '0'; 
    reset2b <= '0'; 
    reset3 <= '0'; 
    reset3b <='0'; 
    reset10 <= '0'; 
    reset20 <= '0'; 
    reset20b <= '0'; 
    rlmr <= '1'; 
    almr <= '0'; 
    glmr <= '0'; 
    rlsr <= '1'; 
    alsr <= '0'; 
    glsr <= '0'; 
    next_state <= present_state ; -- optional 

    -- Statemachine code starts here 
    -- Only do assignments that are different from the default. 

    if ssr = '0' then 
    -- Do you change the values from the defaults here? 
    -- with the defaults, it is not necessary to do any assignments here, however, 
    -- without the defaults these outputs would have latches on them. 
    case present_state is 
     when gmrs => next_state <= gmrcs; 
     when rmas => next_state <= rmacs; 
     ... 
    end case ; 

    elsif ambulance = '0' then 
    -- Do you change the values from the defaults here? 
    -- with the defaults, it is not necessary to do any assignments here, however, 
    -- without the defaults these outputs would have latches on them. 
    case present_state is 
     when gmrs | ramrs | ramrcs => next_state <= amrs; 
     -- when rmas => ??? 
     when rmgs | rmras => next_state <= rmas; 
     ... 
    end case ; 

    else 
    -- main statemachine 
    case present_state is 
     when rmgs=> 
     -- Only drive outputs that are different from the defaults here. 
     rlsr <= '0'; 
     glsr <= '1'; 
     reset10 <= '1'; 
     --if count is complete then move to next state 
     if (count10='1') THEN 
       next_state <= rmas; 
     --otherwise, return to current state 
     else 
       next_state <= rmgs; 
     end if; 
     when rmas=> 
     . . . 
    end case ; 
+0

不應該present_state作爲在present_state寄存器中重置的目標嗎? (你顯示next_state,它在兩個不同的進程中創建兩個驅動程序。) – user1155120

+0

@DavidKoontz。謝謝。我已經更新了代碼。如果您願意,歡迎您自行編輯。 –

1

對於模擬,並不嚴格需要對present_state寄存器進行重置,但應該在那裏進行綜合。

state_clocked: 
    process(reset,clk) 
    begin 
     if reset = '0' then 
      present_state <= rmrs; 
     elsif rising_edge(clk) THEN 
      present_state <= next_state; 
     end if; 
    end process; 

(吉姆打敗了我)。

process (present_state, reset, ssr, ambulance, count2, count2b, 
      count3, count3b, count10, count20, count20b) 

添加工藝敏感性元件(以及使用復位):

tb_rfc with cross traffic

(I更增添了幾分到它的許多設計的似乎是工作到良好的程度。)

並考慮使用測試臺,它將允許通過在救護車,smr,sml和ssr上生成輸入來進行自動化測試。

library ieee; 
use ieee.std_logic_1164.all; 

entity tb_tfc is 
end entity; 

architecture foo of tb_tfc is 
    signal clk:  std_logic := '0'; 
    signal reset:  std_logic; 
    signal ambulance: std_logic := '1'; 
    signal smr:  std_logic := '1'; 
    signal sml:  std_logic := '1'; 
    signal ssr:  std_logic := '1'; 
    signal rlmr:  std_logic; 
    signal almr:  std_logic; 
    signal glmr:  std_logic; 
    signal rlsr:  std_logic; 
    signal alsr:  std_logic; 
    signal glsr:  std_logic; 
begin 

DUT: 
    entity work.trafficlightcontroller 
    port map ( 
      clk, 
      reset, 
      ambulance, 
      smr, 
      sml, 
      ssr, 
      rlmr, -- out 
      almr, -- out 
      glmr, -- out 
      rlsr, -- out 
      alsr, -- out 
      glsr -- out 
    ); 

CLOCK: 
    process 

    begin 
     wait for 10 ns; 
     clk <= not clk; 
     if Now > 1280 ns then 
      wait; 
     end if; 
    end process; 

STIMULUS: 
    process 
    begin 
     reset <= '0'; -- 
     wait for 20 ns; 
     reset <= '1'; 
     wait for 1020 ns; 
     ssr <= '0'; 
     wait; 
    end process; 
end architecture; 
相關問題