Имитация 5-разрядного счетчика Джонсона в VHDL выводит только нули

#vhdl #counter

#vhdl #счетчик

Вопрос:

Файл jk_flipflop.vhd :

 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity JK_FlipFlop is
    Port (J, K, clk: IN STD_LOGIC;
          Q, Qn: OUT STD_LOGIC);
end entity;

architecture behavioral of JK_FlipFlop is
    Signal current_state: STD_LOGIC := '0';
begin
    Process (J,K) Is
    begin
        If J='0' and K='1' Then
            current_state<='0';
        ElsIf J='1' and K='0' Then
            current_state<='1';
        ElsIf J='1' and K='1' Then
            current_state<=not(current_state);
        Else
            current_state<=current_state;
        End If;
    End process;
    Process (clk) Is
    begin
        If rising_edge(clk) Then
            Q<=current_state;
        Else
            Q<=not(current_state);
        End if;
    end process;
end architecture;
  

Файл johnson_counter.vhd :

 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity johnson_counter is
    port(clk: in STD_LOGIC;
         b0,b1,b2,b3,b4: out STD_LOGIC);
end entity;

architecture structural of johnson_counter is
    signal q0 : STD_LOGIC := '0';
     signal qn0 : STD_LOGIC := '1';
     signal q1 : STD_LOGIC := '0';
     signal qn1 : STD_LOGIC := '1';
     signal q2 : STD_LOGIC := '0';
     signal qn2 : STD_LOGIC := '1';
     signal q3 : STD_LOGIC :='0';
     signal qn3 : STD_LOGIC :='1';
     signal q4 : STD_LOGIC :='0';
     signal qn4 : STD_LOGIC :='1';
begin
    s0: ENTITY work.jk_flipflop Port map(qn4,q4,clk,q0,qn0);
    s1: ENTITY work.jk_flipflop Port map(q0,qn0,clk,q1,qn1);
    s2: ENTITY work.jk_flipflop Port map(q1,qn1,clk,q2,qn2);
    s3: ENTITY work.jk_flipflop Port map(q2,qn2,clk,q3,qn3);
    s4: ENTITY work.jk_flipflop Port map(q3,qn3,clk,q4,qn4);
    b0 <= q0;
    b1 <= q1;
    b2 <= q2;
    b3 <= q3;
    b4 <= q4;
end architecture;
  

Файл tester.vhd :

 Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tester is end entity;

architecture behavioral of tester is
    Signal flipflops : STD_LOGIC_VECTOR(4 downto 0) := "00000";
    Signal clk: STD_LOGIC := '0';
begin
    s1: entity work.johnson_counter port map(clk,
            flipflops(0),
            flipflops(1),
            flipflops(2),
            flipflops(3),
            flipflops(4)
            );
    process
        variable output: String(1 to 5);
        variable i: Integer;
        variable j: Integer;
    begin
        j:=0;
        while j<20 loop
            clk<=not(clk);
            if clk='1' then
                i:=1;
                while i<=5 loop
                    if flipflops(i-1)='1' then
                        output(i):='1';
                    else
                        output(i):='0';
                    end if;
                    i:=i 1;
                end loop;
                report output;
            end if;
            wait for 50 ns;
            j:=j 1;
        end loop;
        wait;
    end process;
end architecture;
  

Ожидаемый результат:

 00000
10000
11000
11100
11110
11111
01111
00111
00011
00001
  

Однако результат, который я получаю, является:

 tester.vhd:35:17:@50ns:(report note): 00000
tester.vhd:35:17:@150ns:(report note): 00000
tester.vhd:35:17:@250ns:(report note): 00000
tester.vhd:35:17:@350ns:(report note): 00000
tester.vhd:35:17:@450ns:(report note): 00000
tester.vhd:35:17:@550ns:(report note): 00000
tester.vhd:35:17:@650ns:(report note): 00000
tester.vhd:35:17:@750ns:(report note): 00000
tester.vhd:35:17:@850ns:(report note): 00000
tester.vhd:35:17:@950ns:(report note): 00000
  

Что я делаю не так?

Ответ №1:

Извините за это, это была глупая ошибка в JK-flipflop. Вот правильная реализация этого:

 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity JK_FlipFlop is
    Port (J, K, clk: IN STD_LOGIC;
          Q, Qn: OUT STD_LOGIC);
end entity;

architecture behavioral of JK_FlipFlop is
    Signal current_state: STD_LOGIC := '0';
begin
    Process (J,K) Is
    begin
        If J='0' and K='1' Then
            current_state<='0';
        ElsIf J='1' and K='0' Then
            current_state<='1';
        ElsIf J='1' and K='1' Then
            current_state<=not(current_state);
        Else
            current_state<=current_state;
        End If;
    End process;
    Process (clk) Is
    begin
        If rising_edge(clk) Then
            Q<=current_state;
            Qn<=not(current_state);
        End if;
    end process;
end architecture;