2013-10-23 40 views
0

因此,本實驗的目的是模擬ModelSim中的模塊代碼,以顯示計時器使用測試工作臺(我無法改變)工作。當我模擬時,只有時鐘波形發生變化,並且我所有的十六進制顯示都始終爲0b1000000。有人可以幫我找到爲什麼計時器不運行?時間代碼編譯但不起作用VHDL ModelSim

CODE:

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

entity PRELAB7 is 
port (clk,load_n,reset_n : in std_logic; 
    sw : in std_logic_vector (15 downto 0); 
--for the set hr min sec 
    hex2 : out std_logic_vector(6 downto 0); 
    hex4 : out std_logic_vector(6 downto 0); 
    hex6 : out std_logic_vector(6 downto 0); 
    hex3 : out std_logic_vector(6 downto 0); 
    hex5 : out std_logic_vector(6 downto 0); 
    hex7 : out std_logic_vector(6 downto 0) 
    ); 
    end PRELAB7; 

    architecture Behavioral of PRELAB7 is 
    SIGNAL sec,min,hour   :std_logic_vector(6 DOWNTO 0); 
    SIGNAL int_count    :std_logic_vector(27 DOWNTO 0); 
    CONSTANT MAX_VAL    :std_logic_vector(27 DOWNTO 0):= x"2FAF080"; 
    SIGNAL timer_flag    :std_logic; 
    SIGNAL temp_sec,temp_min,temp_hour :std_logic_vector(6 DOWNTO 0) := "0000000"; 

    CONSTANT ZERO : STD_LOGIC_VECTOR(6 downto 0) :="1000000"; --0 
    CONSTANT ONE : STD_LOGIC_VECTOR(6 downto 0) :="1111001"; --1 
    CONSTANT TWO : STD_LOGIC_VECTOR(6 downto 0) :="0100100"; --2 
    CONSTANT THREE : STD_LOGIC_VECTOR(6 downto 0) :="0110000"; --3 
    CONSTANT FOUR : STD_LOGIC_VECTOR(6 downto 0) :="0011001"; --4 
    CONSTANT FIVE : STD_LOGIC_VECTOR(6 downto 0) :="0010010"; --5 
    CONSTANT SIX : STD_LOGIC_VECTOR(6 downto 0) :="0000010"; --6 
    CONSTANT SEVEN : STD_LOGIC_VECTOR(6 downto 0) :="1111000"; --7 
CONSTANT EIGHT : STD_LOGIC_VECTOR(6 downto 0) :="0000000"; --8 
CONSTANT NINE : STD_LOGIC_VECTOR(6 downto 0) :="0010000"; --9 

begin 
    timer:PROCESS(clk,reset_n) 
    BEGIN 
     if(reset_n = '0') then 
      int_count <=(others => '0'); 
     elsif(rising_edge(clk)) then  
      if(int_count = MAX_VAL) then 
       int_count <= (others => '0'); 
       timer_flag <= '1'; 
      else 
       int_count <= int_count + 1; 
       timer_flag <= '0'; 
      end if; 
     end if; 
    END PROCESS; 

    seconds:PROCESS(reset_n,sec,clk,load_n) 
    BEGIN 
     if (reset_n = '1' OR sec > 59 OR load_n = '1') then 
      sec <= "0000000"; 
     else 
      if(rising_edge(clk)) then 
    --   if timer_flag = '1' then 
       sec <= sec + 1; 
    --   end if; 
      else 
       sec <= sec; 
      end if; 
     end if; 
    END PROCESS; 

    minutes:PROCESS(reset_n,min,sec,clk,load_n,sw) 
    BEGIN 
     if (reset_n = '1' OR min > 59) then 
      min <= "0000000"; 
     Elsif load_n = '1' then 
      min(6 DOWNTO 4) <= sw(6 downto 4); 
      min(3 DOWNTO 0) <= sw(3 downto 0); 
     else 
      if(sec = 59) then 
       if rising_edge(clk) then 
    --    if timer_flag = '1' then 
        min <= min + 1; 
    --    end if; 
       end if; 
      else 
       min <= min; 
      end if; 
     end if; 
    END PROCESS; 

    hours:PROCESS(reset_n,hour,min,sec,clk,load_n,sw) 
    BEGIN 
     if (reset_n = '1' OR hour > 23) then 
      hour <= "0000000"; 
     elsif (load_n = '1') then 
      hour(6 DOWNTO 4) <= sw(13 downto 11); 
      hour(3 DOWNTO 0) <= sw(10 downto 7); 
     else 
      if ((min = 59) AND (sec = 59)) then 
       if (rising_edge(clk)) then 
    --    if timer_flag = '1' then 
        hour <= hour + 1; 
    --    end if; 
       end if; 
      else 
       hour <= hour; 
      end if; 
     end if; 
    END PROCESS; 



    tenhour_display:PROCESS(hour) 
    BEGIN 
     IF(hour < 10) THEN 
      hex7 <= ZERO; 
     ELSIF(hour < 20)THEN 
      hex7 <= ONE; 
     else 
      hex7 <= TWO; 
     END IF; 
    END PROCESS; 

    onehour_display:PROCESS(hour,temp_hour) 
    BEGIN 
     IF(hour < 10) THEN 
      temp_hour <= hour; 
     ELSIF (hour < 20) THEN 
      temp_hour <= hour - 10; 
     ELSE 
      temp_hour <= hour -20; 
     END IF; 

     IF temp_hour = 0 THEN 
      hex6 <= ZERO; 
     ELSIF temp_hour = 1 THEN 
      hex6 <= ONE; 
     ELSIF temp_hour = 2 THEN 
      hex6 <= TWO; 
     ELSE 
      hex6 <= THREE; 
     END IF; 
    END PROCESS; 

    tenmin_display:PROCESS(min) 
    BEGIN 
     IF(min < 10) THEN 
      hex5 <= ZERO; 
     ELSIF (min < 20) THEN 
      hex5 <= ONE; 
     ELSIF (min < 30) THEN 
      hex5 <= TWO; 
     ELSIF (min < 40) THEN 
      hex5 <= THREE; 
     ELSIF (min < 50) THEN 
      hex5 <= FOUR; 
     ELSE 
      hex5 <= FIVE; 
     END IF; 
    END PROCESS; 

    onemin_display:PROCESS(min,temp_min) 
    BEGIN 
     IF(min < 10) THEN 
      temp_min <= min; 
     ELSIF (min < 20) THEN 
      temp_min <= min - 10; 
     ELSIF (min < 30) THEN 
      temp_min <= min -20; 
     ELSIF (min < 40) THEN 
      temp_min <= min -30; 
     ELSIF (min < 50) THEN 
      temp_min <= min -40; 
     ELSE 
      temp_min <= min - 50; 
     END IF; 

     IF temp_min = 0 THEN 
      hex4 <= ZERO; 
     ELSIF temp_min = 1 THEN 
      hex4 <= ONE; 
     ELSIF temp_min = 2 THEN 
      hex4 <= TWO; 
     ELSIF temp_min = 3 THEN 
      hex4 <= THREE; 
     ELSIF temp_min = 4 THEN 
      hex4 <= FOUR; 
     ELSIF temp_min = 5 THEN 
      hex4 <= FIVE; 
     ELSIF temp_min = 6 THEN 
      hex4 <= SIX; 
     ELSIF temp_min = 7 THEN 
      hex4 <= SEVEN; 
     ELSIF temp_min = 8 THEN 
      hex4 <= EIGHT; 
     ELSE 
      hex4 <= NINE; 
     END IF; 
    END PROCESS; 

    tensec_display:PROCESS(sec) 
    BEGIN 
     IF(sec < 10) THEN 
      hex3 <= ZERO; 
     ELSIF (sec < 20) THEN 
      hex3 <= ONE; 
     ELSIF (sec < 30) THEN 
      hex3 <= TWO; 
     ELSIF (sec < 40) THEN 
      hex3 <= THREE; 
     ELSIF (sec < 50) THEN 
      hex3 <= FOUR; 
     ELSE 
      hex3 <= FIVE; 
     END IF; 
    END PROCESS; 

    sec_display:PROCESS(sec,temp_sec) 
    BEGIN 
     IF(sec < 10) THEN 
      temp_sec <= sec; 
     ELSIF (sec < 20) THEN 
      temp_sec <= sec - 10; 
     ELSIF (sec < 30) THEN 
      temp_sec <= sec -20; 
     ELSIF (sec < 40) THEN 
      temp_sec <= sec -30; 
     ELSIF (sec < 50) THEN 
      temp_sec <= sec -40; 
     ELSE 
      temp_sec <= sec - 50; 
     END IF;  

     IF temp_sec = 0 THEN 
      hex2 <= ZERO; 
     ELSIF temp_sec = 1 THEN 
      hex2 <= ONE; 
     ELSIF temp_sec = 2 THEN 
      hex2 <= TWO; 
     ELSIF temp_sec = 3 THEN 
      hex2 <= THREE; 
     ELSIF temp_sec = 4 THEN 
      hex2 <= FOUR; 
     ELSIF temp_sec = 5 THEN 
      hex2 <= FIVE; 
     ELSIF temp_sec = 6 THEN 
      hex2 <= SIX; 
     ELSIF temp_sec = 7 THEN 
      hex2 <= SEVEN; 
     ELSIF temp_sec = 8 THEN 
      hex2 <= EIGHT; 
     ELSE 
      hex2 <= NINE; 
     END IF; 
    END PROCESS; 

END behavioral;  

TEST BENCH:

用於卡住計數器
--***************************************************************************** 
--*************************** VHDL Source Code ****************************** 
--********* Copyright 2010, Rochester Institute of Technology *************** 
--***************************************************************************** 
-- 
-- DESIGNER NAME: Jeanne Christman 
-- 
--  LAB NAME: VHDL Timers and Counter 
-- 
--  FILE NAME: TOD_tb.vhd 
-- 
------------------------------------------------------------------------------- 
-- 
-- DESCRIPTION 
-- 
-- This test bench will provide input to test the implemention of the 
-- circuit on the DE2 board that acts as a time-of-day clock. It displays 
-- the hour (from 0 to 23) on the 7-segment displays HEX7-6, the minute 
-- (from 0 to 60) on HEX5-4 and the second (from 0 to 60) on HEX3-2. 
-- The contents of the value displayed on the 7-segment displays must be 
-- manually verfied. 
-- 
------------------------------------------------------------------------------- 
-- 
-- REVISION HISTORY 
-- 
-- _______________________________________________________________________ 
-- | DATE | USER | Ver | Description         | 
-- |==========+======+=====+================================================ 
-- |   |  |  | 
-- | 10/16/13 | JWC | 1.0 | Created 
-- |   |  |  | 
-- 
--***************************************************************************** 
--***************************************************************************** 


LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 

ENTITY TOD_tb IS 
END TOD_tb; 


ARCHITECTURE test OF TOD_tb IS 

    -- Component Declaration for the Unit Under Test (UUT) 
    -- if you use a package with the component defined then you do not need this 
    COMPONENT PRELAB7 
     PORT (
     clk  : IN std_logic; 
     reset_n : IN std_logic; 
     load_n : IN std_logic; 
     SW  : IN std_logic_vector(15 DOWNTO 0); 
     -- 
     hex2   : OUT std_logic_vector(6 DOWNTO 0); 
     hex3   : OUT std_logic_vector(6 DOWNTO 0); 
     hex4   : OUT std_logic_vector(6 DOWNTO 0); 
     hex5   : OUT std_logic_vector(6 DOWNTO 0); 
     hex6   : OUT std_logic_vector(6 DOWNTO 0); 
     hex7   : OUT std_logic_vector(6 DOWNTO 0) 
     ); 
    END COMPONENT; 

    -- define signals for component ports 
    SIGNAL clock_50  : std_logic      := '0'; 
    SIGNAL sys_reset_n : std_logic      := '0'; 
    SIGNAL load_enable_n : std_logic      := '0'; 
    SIGNAL bcd_load_time : std_logic_vector(15 DOWNTO 0) := x"0000"; 
    -- 
    -- Outputs 
    SIGNAL hex2   : std_logic_vector(6 DOWNTO 0); 
    SIGNAL hex3   : std_logic_vector(6 DOWNTO 0); 
    SIGNAL hex4   : std_logic_vector(6 DOWNTO 0); 
    SIGNAL hex5   : std_logic_vector(6 DOWNTO 0); 
    SIGNAL hex6   : std_logic_vector(6 DOWNTO 0); 
    SIGNAL hex7   : std_logic_vector(6 DOWNTO 0); 

    -- signals for test bench control 
    SIGNAL sim_done : boolean := false; 
    SIGNAL PERIOD_c : time := 20 ns; -- 50MHz 

BEGIN -- test 

    -- component instantiation 
    UUT : PRELAB7 
     PORT MAP (
     clk   => clock_50, 
     reset_n  => sys_reset_n, 
     load_n  => load_enable_n, 
     SW   => bcd_load_time, 
     -- 
     hex2   => hex2, 
     hex3   => hex3, 
     hex4   => hex4, 
     hex5   => hex5, 
     hex6   => hex6, 
     hex7   => hex7 
     ); 

    -- This creates an clock_50 that will shut off at the end of the Simulation 
    -- this makes a clock_50 that you can shut off when you are done. 
    clock_50 <= NOT clock_50 AFTER PERIOD_C/2 WHEN (NOT sim_done) ELSE '0'; 


    --------------------------------------------------------------------------- 
    -- NAME: Stimulus 
    -- 
    -- DESCRIPTION: 
    -- This process will apply stimulus to the UUT. 
    --------------------------------------------------------------------------- 
    stimulus : PROCESS 
    BEGIN 
     -- de-assert all inputs except the reset which is asserted 
     sys_reset_n <= '0'; 
     load_enable_n <= '1'; 
     bcd_load_time <= x"0000"; 
     WAIT FOR 5 ns; 

     -- now lets sync the stimulus to the clock_50 
     -- move stimulus 1ns after clock edge 
     WAIT UNTIL clock_50 = '1'; 
     WAIT FOR 1 ns; 

     -- de-assert reset and let run for 4 seconds 
     sys_reset_n <= '1'; 
     WAIT FOR 20*PERIOD_C; -- adjust this time to lengthen/shorten sim 

     -- load a new time 
     load_enable_n <= '0'; 
     bcd_load_time <= x"1958"; 
     WAIT FOR 5*PERIOD_C; 
     load_enable_n <= '1'; 
     WAIT FOR 3 sec; -- adjust this time to lengthen/shorten sim 


     -- shutting down simulation 
     sim_done <= true; 
     WAIT FOR PERIOD_c*1; 

     ----------------------------------------------------------------------- 
     -- This Last WAIT statement needs to be here to prevent the PROCESS 
     -- sequence from re starting. 
     ----------------------------------------------------------------------- 
     WAIT; 

    END PROCESS stimulus; 



END test; 

回答

1

一個原因是,在復位信號是reset_n,其中 的_n通常表明復位激活時低(0),這也是 在這個設計中的情況,可以在測試臺和波形中看到。

然而,PRELAB7模塊使用復位彷彿高電平有效,如圖 這和其他的部分代碼:

... 
seconds:PROCESS(reset_n,sec,clk,load_n) 
BEGIN 
    if (reset_n = '1' OR sec > 59 OR load_n = '1') then 
    sec <= "0000000"; 
    else 
    if(rising_edge(clk)) then 
     sec <= sec + 1; 
... 

所以至少在開始你應該使用reset_n = '0'檢查活動的 復位,而不是reset_n = '1'

A面註釋:不保存在上述部分使用複雜的表達式作爲條件 異步復位等:

if (reset_n = '1' OR sec > 59 OR load_n = '1') then 

原因是不同的位的更新在sec計數器可以稍微偏斜 在硬件由於內部定時,所以更新sec過程中可能顯示爲:

55:0b110111(沉降後的最終值)

63:0b111111(沉降後的最終值)

所以sec > 59部分0b111000:(中間體值的比特2之前,其中第3位得到了 '1':0得到爲 '0')

56的表達可能在意想不到的時間是真實的,並且取決於內部時序,如果以硬件實現,這可能導致(部分)異步復位 ,並且這樣的問題難以捕捉,因爲它們不會在模擬中顯示出來 。