2013-10-23 2 views
0

이 실습의 요점은 ModelSim의 모듈 코드를 시뮬레이트하여 타이머가 테스트 벤치 (변경 불가능)를 사용하여 작동 함을 보여주는 것입니다. 시뮬레이션 할 때 시계 파형 만 변경되고 모든 16 진수 디스플레이는 항상 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;  

시험대 :

스턱 카운터
--***************************************************************************** 
--*************************** 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

한가지 이유는, 리셋 신호 _n 전형적 리셋 낮은 경우 활성임을 나타낸다 reset_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'이 아닙니다.

측면 의견 상기 부분처럼 비동기 재설정 조건으로 복잡한 식을 사용하여 저장되지 않고 :

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

이유는 약간 를 왜곡 할 수있다 sec 카운터 상이한 비트의 업데이트 인

55 : 0b110111 (침전 후의 최종 값)

하드웨어에 의한 내부 타이밍 때문에 업데이트 sec 동안과 같이 표시 될 516,

63 0b111111 (비트 3 비트 2 전에 1로 얻었다 중간 값 : 0있어 '0')

56 : 0b111000 (최종 값 정착 후) 그래서

sec > 59 부 내부 타이밍에 따라 에 따라 표현식이 참일 수 있습니다. 하드웨어에 구현 된 경우 (부분) 비동기 재설정이 발생할 수 있으며 시뮬레이션에서 이 표시되지 않으므로 이러한 문제를 파악하기 어렵습니다. .

관련 문제