带 D 触发器的 2 位递增 4 位计数器 - VHDL
2 bit up 4 bit counter with D flip flops - VHDL
您好,我一直在尝试为此原理图编写 VHDL 代码。
当启用发送信号时,计数器应开始计数。当启用被停用时,计数停止。如果启用发送另一个信号,则计数器从上次停止的值开始计数。
起初我创建了 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
的实现有点困惑。
在 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;
When module instantiations are same parameters, we can use a beautiful statement called FOR GENERATE
. you can use bellow style:
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;
Good-lock!
您好,我一直在尝试为此原理图编写 VHDL 代码。 当启用发送信号时,计数器应开始计数。当启用被停用时,计数停止。如果启用发送另一个信号,则计数器从上次停止的值开始计数。
起初我创建了 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
的实现有点困惑。
在 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;
When module instantiations are same parameters, we can use a beautiful statement called
FOR GENERATE
. you can use bellow style:
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;
Good-lock!