2011-10-28 1 views
1

D 플립 플롭을 사용하여 4 비트 링 카운터를 모델링했습니다.링 카운터의 정의되지 않은 출력 테스트 파형

D 플립 플롭은 별도의 파일에 있으며 내 작업 공간에 포함되어 있습니다. D 플립 플롭이 올바르게 작동합니다 (올바른 출력 파형 제공). 여기

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

entity ring4counter is 
    port (
     clk: std_logic; 
     output: out std_logic_vector(3 downto 0)); 
end ring4counter; 

architecture ring4counter_arch of ring4counter is 
    component dff 
    port (
     clk: std_logic; 
     d: in std_logic; 
     q: out std_logic; 
     qbar: out std_logic); 
    end component; 

    signal temp:std_logic_vector(3 downto 0):=(others=>'0'); 
begin 
    r1: dff port map(clk, temp(3), temp(0)); 
    r2: dff port map(clk, temp(0), temp(1)); 
    r3: dff port map(clk, temp(1), temp(2)); 
    r4: dff port map(clk, temp(2), temp(3)); 
    output <= temp; 
end ring4counter_arch; 

링 카운터 테스트 벤치 코드 :

library ieee; 
use ieee.std_logic_1164.all; 

entity ring4_tb is end ring4_tb ; 

architecture arch of ring4_tb is 
    component tbc is 
    port (
     clk: std_logic; 
     output: out std_logic_vector(3 downto 0)); 
    end component ; 

    component dff 
    port (
     clk: std_logic; 
     d: in std_logic; 
     q: out std_logic; 
     qbar: out std_logic); 
    end component; 

    constant period : time := 50 ns ; 

    signal clk  : std_logic := '0' ;  
    signal done  : boolean := false ; 
    signal output : std_logic_vector(3 downto 0) ; 

    shared variable cycle : natural := 0 ; 

    signal temp:std_logic_vector(3 downto 0):=(others=>'0'); 

begin 
-- this is the unit under test 
    u1: tbc 
    port map(
     clk => clk, 
     output => output) ; 

    clkprocess: process(done, clk) 
    begin 
    if (not done) then 
     if (clk = '1') then 
     cycle := cycle + 1 ; 
     end if ; 
     clk <= not clk after period/2 ; 
    end if ; 
    end process ; 

    r1: dff port map(clk, temp(3), temp(0)); 
    r2: dff port map(clk, temp(0), temp(1)); 
    r3: dff port map(clk, temp(1), temp(2)); 
    r4: dff port map(clk, temp(2), temp(3)); 
    output <= temp; 

    testbench: process 
    begin 
    wait until (clk = '0') ; 
    temp <= "1000"; 
    wait for period*4 ; 

    done <= true ;  -- force the clock process to shutdown 
    wait ;   -- this waits forever 
    end process ; 
end arch ; 

그러나 '출력'의 파형은 'U'는 모든 비트입니다

이 링 카운터의 부호이다. 어디서 잘못 가고 있습니까?

+0

나는 이것이 오래된 게시물 인 것을 알고 있지만, 문체를 사용하여 의견을 말하고 싶습니다. 실제 세계에서의 위치에 따라 게시물을 지정하면, 당신은 사냥 당하고 구타를 당할 것입니다. 절대하지 마. 간단한 구성 요소에 대해 한 줄에 'r1 : dff 포트 맵 (clk => clk, d => temp (3), q => temp (0));을 사용할 수 있습니다 (그러나 DFF 구성 요소가 필요함). –

+0

하하 나는 내가 두들겨 맞을 거라 생각하지 않아! 나는 링 카운터에 DFF가 필요 없다는 것을 알고있다. 그러나 당신이 배우고있을 때 (나는 배우는 중입니다), 명백한 길을 택하는 것이 이치에 맞습니다. –

답변

2

온도를 "1000"으로 초기화하려고 할 때 테스트 벤치 프로세스에서 플립 플롭은 여전히 ​​임시 신호를 발생 시키므로 효과적으로 버스 경기를 진행할 수 있습니다.

+0

네, 버스를 운전하는 데 여러 가지 일을 할 수는 없습니다. (일반적으로) –

+0

이 문제를 해결할 수있는 방법이 있습니다. 나는 VHDL을 많이 모른다. 나는 심지어 라인 temp <= "1000"을 생략했다. –

+0

D 플립 플롭을 초기화하는 방법을 변경해야합니다. 한 가지 방법은 D와 Q 입력을 분리하고 리셋 할 때 초기화 값을 명시 적으로로드하는 것입니다. 주석에 형식화 된 코드를 넣을 수는 없지만 r1 : dff 포트 맵 (clk, temp_in (3), temp (0)); temp_in <= "1000"reset = '1'이면 else temp; 당신을 올바른 방향으로 이끌어야합니다. –

-1

할 일은 D 플립 플롭에 인 에이블 신호를 추가하는 것입니다. 회로를 리셋하려면 인 에이블 신호를 낮추고 온도를 "1000"으로 변경하십시오.

r1: dff port map(clk, temp(3), temp(0), enable); 

process(clk,reset) 
begin 
if(rising_edge(clk)) then 
if(reset='1') then 
    enable='0'; 
    temp <= "1000"; 
else 
    enable <= '1'; 
end if; 
end if; 
end process; 
+1

나는 그것이 작동 할 것이라고 생각하지 않습니다. DFF는 리셋 중에도 여전히 신호를 보내고 있습니다. –

+0

@ 마틴 : 알았어. 그러나 Q <= D가 인 에이블 신호가 높은 경우에만 할당되도록 D 플립 플롭을 정의하면 어떨까요? 그렇지 않으면 할당이 완료되지 않습니다. 이 경우 작동합니까? – vipin

+0

할당이 발생하지 않습니다. 프로세스가 그 프로세스의 어딘가에 할당되어 있다는 사실은 "드라이버"를 생성하고 드라이버는 충돌합니다. VHDL에는 비활성 드라이버가 없습니다. 'std_logic'을 사용하면 Z 드라이버를 가질 수 있습니다. 그러면 Z 드라이버가 예상대로 작동하지만 여전히 드라이버입니다. –

0

신호를 설정하려면 링 카운터에서 temp의 초기화를 사용하십시오.

아키텍처 및 합성 도구에 따라 올바르게 합성되지 않을 수 있습니다.

가장 일반적인 목적은 켜기를 제외한 모든 DFF에 재설정 신호를 추가하고 그 신호에 사전 설정 신호를 넣는 것입니다. 그런 다음 DFF를 적절한 값으로 설정하는 시작시 재설정을 주장합니다.

여기에 명시적인 DFF를 사용할 필요가없는 간단한 코드가 있습니다. 또한 temp의 폭을 변경할 수 있으며, 코드는 당신을위한 모든 나머지를 할 것입니다 :

process (clk) 
begin 
    if reset = '1' then 
     temp <= (0=>'1', others => '0'); -- set one bit high, the others low. 
    elsif rising_edge(clk) then 
     -- take the high bit and move it to the low bit. 
     -- Move the other bits left 1 place 
     temp <= temp(temp'high-1 downto 0) & temp(temp'high); 
    end if; 
end process; 

(참고 :! 코드는 단지 메시지에 입력있을 수 있습니다 구문 오타가에)


BTW, shared variableprotected 유형이 아닌 한 나쁜 아이디어입니다. 그들은 경쟁 조건을 가질 수 있습니다.

관련 문제