带D触发器的2位向上4位计数器-VHDL

时间:2018-11-19 21:35:33

标签: vhdl counter bit

您好,我一直在尝试为该原理图编写VHDL代码。 当使能发送信号时,计数器应开始计数。禁用启用后,计数将停止。如果启用发送了另一个信号,则计数器将从上次停止的值开始计数。

enter image description here

起初,我创建了D触发器代码。

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 :(得分:1)

在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

好锁!