2-битный 4-битный счетчик с D-триггерами - VHDL - PullRequest
0 голосов
/ 20 ноября 2018

Здравствуйте, я пытался написать код VHDL для этой схемы.Счетчик должен начать отсчет, когда активировать отправляет сигнал.Когда разрешение деактивировано, отсчет останавливается.Если enable отправляет другой сигнал, то счетчик начинает считать со значения, которое он остановил в прошлый раз.

enter image description here

Сначала я создал код D Flip Flop.

library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsgined.all;

entity dff is
  port(d,rst,clk: in std_logic;
        q: inout std_logic);
end  dff;

architecture rtl of dff is
  begin
    process (clk, rst)
begin
  if (rst='0') then
    q<='0';
  else
    if(clk='1' and clk' event) then
      if (d='0') then q<='0';
    else q<='1';
  end if;
end if;
  end if;
end process;

end rtl;

После этого я попытался реализовать основную схему, и это код, который я написал.

library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsgined.all;

entity updff is
  port (rst,clk:in std_logic;
        q: inout std_logic_vector(3 downto 0));
end updff;

architecture rtl of updff is
component dff is
  port(d,rst,clk: in std_logic;
        q: inout std_logic);
end component;

signal a,b,c,d,e,f : std_logic;

begin
  a<=not q(0);
  D1 :
   dff
   port map(
   a,rst,clk,q(0)
   );

  b<=(q(0) xor q(1));

  D2 :
   dff
   port map(
   b,rst,clk,q(1);
   );

  c<= q(0) and q(1) xor q(2);

  D3 :
   dff
    port map(
    c,rst,clk,q(2)
    );

    d <= q(0) and q(1);
    e <= d and q(2);
    f <= e xor q(3)

  D4 :
   dff
   port map(
   i,rst,clk,q(3)
   );
end rtl;

Поэтому я пишу, чтобы спросить ваше мнение, потому что я немного запутался с реализацией D1, D2, D3, D4.

1 Ответ

0 голосов
/ 20 ноября 2018

Существует множество способов описания счетчиков в VHDL.

Если вы хотите реализовать счетчик структурным способом, ваш реализованный метод является текущим способом, но будет лучше, если вы будете использовать векторы вместо простых сигналов. Это делает код очень четким и читабельным.

  • в вашем модуле ddf можно удалить одно из операторов IF
  • в счетчике вы не хотите использовать q в режиме ввода, так что лучший способ для использования, это определить внутренние сигналы и присвоить то q

Например, вы можете сильфонный стиль:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY dff IS
    PORT
    (
        clk     : IN  STD_LOGIC;
        rst : IN  STD_LOGIC;
        din : IN  STD_LOGIC;
      qout  : OUT STD_LOGIC
    );
END dff;

ARCHITECTURE behavioral OF dff IS

BEGIN

    PROCESS (clk, rst)
    BEGIN
        IF (rst = '0') THEN
            qout<='0';
        ELSIF(clk = '1' AND clk'EVENT) THEN
            qout <= din;
        END IF;
    END PROCESS;

END behavioral;

и для описания стиля счетчика ниже:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY upcount4 IS
    PORT
    (
        clk     : IN  STD_LOGIC;
        rst : IN  STD_LOGIC;
        en      : IN  STD_LOGIC;
      qout  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
    );
END upcount4;


ARCHITECTURE rt_level OF upcount4 IS

    COMPONENT dff IS
        PORT
        (
            clk     : IN  STD_LOGIC;
            rst : IN  STD_LOGIC;
            din : IN  STD_LOGIC;
            qout    : OUT STD_LOGIC
        );
    END COMPONENT;

    SIGNAL dffs_out : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL dffs_in : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL ands_out : STD_LOGIC_VECTOR(2 DOWNTO 0);

BEGIN

    ands_out(0) <= en AND dffs_out(0);
    ands_out(1) <= ands_out(0) AND dffs_out(1);
    ands_out(2) <= ands_out(1) AND dffs_out(2);

    dffs_in(0) <= en XOR dffs_out(0);
    dffs_in(1) <= ands_out(0) XOR dffs_out(1);
    dffs_in(2) <= ands_out(1) XOR dffs_out(2);
    dffs_in(3) <= ands_out(2) XOR dffs_out(3);

    qout <= dffs_out;

    dff_0:dff 
    PORT MAP
    (   
        clk  => clk,
        rst  => rst,
        din  => dffs_in(0),
        qout => dffs_out(0)     
    );
    dff_1:dff 
    PORT MAP
    (   
        clk => clk,
        rst => rst,
        din => dffs_in(1),
        qout=> dffs_out(1)      
    );

    dff_2:dff 
    PORT MAP
    (   
        clk => clk,
        rst => rst,
        din => dffs_in(2),
        qout=> dffs_out(2)
    );

    dff_3:dff 
    PORT MAP
    (   
        clk => clk,
        rst => rst,
        din => dffs_in(3),
        qout=> dffs_out(3)      
    );

END rt_level;

Когда экземпляры модулей имеют одинаковые параметры, мы можем использовать красивое выражение под названием FOR GENERATE. Вы можете использовать стиль ниже:

ARCHITECTURE rt_levelgen OF upcount4 IS

    COMPONENT dff IS
        PORT
        (
            clk     : IN  STD_LOGIC;
            rst : IN  STD_LOGIC;
            din : IN  STD_LOGIC;
            qout    : OUT STD_LOGIC
        );
    END COMPONENT;

    SIGNAL dffs_out : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL dffs_in : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL ands_out : STD_LOGIC_VECTOR(2 DOWNTO 0);

BEGIN

    ands_out(0) <= en AND dffs_out(0);
    ands_out(1) <= ands_out(0) AND dffs_out(1);
    ands_out(2) <= ands_out(1) AND dffs_out(2);

    dffs_in(0) <= en XOR dffs_out(0);
    dffs_in(1) <= ands_out(0) XOR dffs_out(1);
    dffs_in(2) <= ands_out(1) XOR dffs_out(2);
    dffs_in(3) <= ands_out(2) XOR dffs_out(3);

    qout <= dffs_out;

    generate_label:
    FOR index in 0 to 3 GENERATE
        dffs_0_3_label:dff 
        PORT MAP
        (   
            clk  => clk,
            rst  => rst,
            din  => dffs_in(index),
            qout => dffs_out(index)     
        );
    END GENERATE;
END rt_levelgen;

Если вы не хотите реализовывать счетчик со структурной моделью, вы можете описать его в поведенческой модели, и инструмент реализации (например, Vivado или ISE) преобразует его в реальное оборудование (например, зарегистрируетесь с сумматором). Ниже приведен код описания поведения в поведенческой модели:

ARCHITECTURE behavioral OF upcount4 IS

    SIGNAL counter : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN
    PROCESS(reset,clock)
    BEGIN
        IF(reset = '0') THEN
            counter <= (OTHERS => '0');
        ELSIF( RISING_EDGE(clock) )THEN
            IF(enable = '1') THEN
                counter <= counter + X"1"; 
            END IF;
        END IF;
    END PROCESS;
    qout <= counter;

END behavioral;

Модуль испытательного стенда и форма волны

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY counter_tb IS
END counter_tb;

ARCHITECTURE behavior OF counter_tb IS 

    COMPONENT upcount4
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic;
         en : IN  std_logic;
         qout : OUT  std_logic_vector(3 downto 0)
        );
    END COMPONENT;

   signal clk : std_logic := '0';
   signal rst : std_logic := '0';
   signal en : std_logic := '0';

   signal qout : std_logic_vector(3 downto 0);

BEGIN

   uut: upcount4 PORT MAP(
        clk => clk,
         rst => rst,
         en => en,
         qout => qout);

    clk <= NOT clk AFTER 5 NS;

    rst <= '0', 
             '1' AFTER 30 NS;

    en  <= '0', 
             '1' AFTER 40 NS, 
             '0' AFTER 70 NS, 
             '1' AFTER 90 NS;

END;

Simulation Waveform

Хороший замок!

...