2013-10-23 43 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的表达可能在意想不到的时间是真实的,并且取决于内部时序,如果以硬件实现,这可能导致(部分)异步复位 ,并且这样的问题难以捕捉,因为它们不会在模拟中显示出来 。