使用结构设计制作加减柜台
Make an up down counter using structural design
我尝试使用结构设计制作一个 4 位加减计数器。
我的代码如下:
entity counter4bit is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
counterOut : out STD_LOGIC_VECTOR (3 downto 0);
updown : in STD_LOGIC);
end counter4bit;
architecture Behavioral of counter4bit is
component D_FlipFlop
Port ( d : in STD_LOGIC;
reset : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
updown : in STD_LOGIC;
q : out STD_LOGIC);
end component;
component MUX
Port ( i0 : in STD_LOGIC;
i1 : in STD_LOGIC;
i2 : in STD_LOGIC;
i3 : in STD_LOGIC;
inload : in STD_LOGIC;
bitout : out STD_LOGIC;
load : in STD_LOGIC;
updown : in STD_LOGIC;
en : in STD_LOGIC);
end component;
signal w: std_logic_vector(3 downto 0);
signal cnt : std_logic_vector(3 downto 0);
begin
FF0 : D_FlipFlop
port map( d => w(0),
reset => reset,
clock =>clock,
load => load,
enable => enable,
updown => updown,
q => cnt(0) );
FF1 : D_FlipFlop
port map( d => w(1),
reset => reset,
Clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(1));
FF2 : D_FlipFlop
port map( d => w(2),
reset => reset,
clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(2));
FF3 : D_FlipFlop
port map( d => w(3),
reset => reset,
clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(3));
MUX0 : MUX
port map( i0 => '1',
i1 => '1',
i2 => '1',
i3 => cnt(0),
inload => '1',
bitout =>w(0) ,
load => load,
updown => updown,
en => enable);
MUX1 : MUX
port map( i0 => cnt(0),
i1 =>'1',
i2 => '1',
i3 => cnt(1),
inload => '1',
bitout =>w(1) ,
load => load,
updown => updown,
en => enable);
MUX2 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 => '1',
i3 => cnt(2),
inload => '0',
bitout =>w(2) ,
load => load,
updown => updown,
en => enable);
MUX3 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 =>cnt(2),
i3 => cnt(3),
inload => '0',
bitout =>w(3) ,
load => load,
updown => updown,
en => enable);
counterOut <= cnt ;
end Behavioral;
当我模拟它时,它从 0 开始,因为它应该导致重置,然后计数到 1,然后再次计数到 0。我不明白为什么它在 1 之后又回到 0。
这是我的 mux 代码:
entity MUX is
Port ( i0 : in STD_LOGIC;
i1 : in STD_LOGIC;
i2 : in STD_LOGIC;
i3 : in STD_LOGIC;
inload : in STD_LOGIC;
bitout : out STD_LOGIC;
load : in STD_LOGIC;
updown : in STD_LOGIC;
en : in STD_LOGIC);
end MUX;
architecture Behavioral of MUX is
signal sel : std_logic_vector(1 downto 0);
signal y, z, x: std_logic;
begin
y <= (updown and i0 and i1 and i2 and en);
z <= (not updown) and i0 and i1 and i2 and en;
sel(0) <= not load;
sel(1) <= y or z ;
process(sel, x)
begin
if sel = "00" then x<= i3;
elsif sel = "01" then x <= (not i3);
else x <= inload;
end if;
end process;
bitout <= x ;
end Behavioral;
触发器的代码:
entity D_FlipFlop is
Port ( d : in STD_LOGIC;
reset : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
updown : in STD_LOGIC;
q : out STD_LOGIC);
end D_FlipFlop;
architecture Behavioral of D_FlipFlop is
begin
process(clock, reset)
begin
if (reset = '0') then
q <= '0';
elsif (rising_edge(clock)) then
q <= d;
end if;
end process;
end Behavioral;
需要注意的是load和enable是同步的,reset是异步的,我也会附上一张我的仿真图。
When I simulate it it starts from 0 as it should cause of the reset , then counts to 1 and then again 0 . I can't see why it goes back to 0 after 1.
我修改了昨天的测试台以复制您的波形:
我不得不修改重置为“0”到“1”和“1”到“0”的一组增量循环,以使计数器显示为全“0”。
首先要注意的是你的复位极性错误。
修正给出:
我们可以看到计数没有正确增加并且仍然停止。
在不考虑负载极性的情况下,停滞值是由 MUX 中进程的敏感列表引起的:
process(sel, x)
begin
if sel = "00" then x<= i3;
elsif sel = "01" then x <= (not i3);
else x <= inload;
end if;
end process;
bitout <= x ;
end Behavioral;
应该有一个敏感度列表:
process (sel, i3, inload) -- was (sel, x) -- incorrect sensitivity list
这会产生:
仍然缺少增量显示,但确实有变化。
在测试台中将加载值更改为“0”会在反击时为我们提供丢失的事务,但值仍然是错误的:
这告诉我们您的 select 方程式错误或您的多路复用器输入错误或两者的某种组合。
无论如何,MUX 似乎是您应该关注的地方。
因此,通过在 MUX 中输入您的 select 更改,您在评论中告诉我们,您可以获得正确的计数:
-- sel(0) <= not load;
-- sel(1) <= y or z ;
sel(1) <= (not load); -- per comments
sel(0) <= y or z;
我们得到:
显示向上计数正确但向下计数不正确。请注意负载的极性在 select 秒内已更改,并与上面的波形匹配。
现在我们知道我们应该根据 updown 增加或减少 cnt,
y <= updown and i0 and i1 and i2 and en;
用于向上计数,剩下
z <= not updown and i0 and i1 and i2 and en;
不幸的是,它在 i0、i1 和 i2 上使用相同的值来切换位输出(特定 cnt 元素的相应 D_FlipFlop 的输入)。
我们相当确定 z 想成为:
z <= not updown and not i0 and not i1 and not i2 and en;
用于递减(不是递增)。
当我们进行更改时,计数不起作用。我们需要 MUX 的未使用输入是 updown 的正确值,“1”表示向上(如现在))或“0”表示向下。
我们可以在 counter4bit 中使用 updown 来做到这一点:
MUX0 : MUX
port map( i0 => updown, -- '1'
i1 => updown, -- '1',
i2 => updown, -- '1',
i3 => cnt(0),
inload => '1',
bitout =>w(0) ,
load => load,
updown => updown,
en => enable);
MUX1 : MUX
port map( i0 => cnt(0),
i1 => updown, -- '1',
i2 => updown, -- '1',
i3 => cnt(1),
inload => '1',
bitout =>w(1) ,
load => load,
updown => updown,
en => enable);
MUX2 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 => updown, -- '1',
i3 => cnt(2),
inload => '0',
bitout =>w(2) ,
load => load,
updown => updown,
en => enable);
这给了我们:
注意此波形尚未测试加载或启用 (false),但它会向上计数,然后成功返回。
D_FlipFlop(加载、启用、上行)上还有一些未使用的端口。
我尝试使用结构设计制作一个 4 位加减计数器。 我的代码如下:
entity counter4bit is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
counterOut : out STD_LOGIC_VECTOR (3 downto 0);
updown : in STD_LOGIC);
end counter4bit;
architecture Behavioral of counter4bit is
component D_FlipFlop
Port ( d : in STD_LOGIC;
reset : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
updown : in STD_LOGIC;
q : out STD_LOGIC);
end component;
component MUX
Port ( i0 : in STD_LOGIC;
i1 : in STD_LOGIC;
i2 : in STD_LOGIC;
i3 : in STD_LOGIC;
inload : in STD_LOGIC;
bitout : out STD_LOGIC;
load : in STD_LOGIC;
updown : in STD_LOGIC;
en : in STD_LOGIC);
end component;
signal w: std_logic_vector(3 downto 0);
signal cnt : std_logic_vector(3 downto 0);
begin
FF0 : D_FlipFlop
port map( d => w(0),
reset => reset,
clock =>clock,
load => load,
enable => enable,
updown => updown,
q => cnt(0) );
FF1 : D_FlipFlop
port map( d => w(1),
reset => reset,
Clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(1));
FF2 : D_FlipFlop
port map( d => w(2),
reset => reset,
clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(2));
FF3 : D_FlipFlop
port map( d => w(3),
reset => reset,
clock => clock,
load => load,
enable => enable,
updown => updown,
q => cnt(3));
MUX0 : MUX
port map( i0 => '1',
i1 => '1',
i2 => '1',
i3 => cnt(0),
inload => '1',
bitout =>w(0) ,
load => load,
updown => updown,
en => enable);
MUX1 : MUX
port map( i0 => cnt(0),
i1 =>'1',
i2 => '1',
i3 => cnt(1),
inload => '1',
bitout =>w(1) ,
load => load,
updown => updown,
en => enable);
MUX2 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 => '1',
i3 => cnt(2),
inload => '0',
bitout =>w(2) ,
load => load,
updown => updown,
en => enable);
MUX3 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 =>cnt(2),
i3 => cnt(3),
inload => '0',
bitout =>w(3) ,
load => load,
updown => updown,
en => enable);
counterOut <= cnt ;
end Behavioral;
当我模拟它时,它从 0 开始,因为它应该导致重置,然后计数到 1,然后再次计数到 0。我不明白为什么它在 1 之后又回到 0。
这是我的 mux 代码:
entity MUX is
Port ( i0 : in STD_LOGIC;
i1 : in STD_LOGIC;
i2 : in STD_LOGIC;
i3 : in STD_LOGIC;
inload : in STD_LOGIC;
bitout : out STD_LOGIC;
load : in STD_LOGIC;
updown : in STD_LOGIC;
en : in STD_LOGIC);
end MUX;
architecture Behavioral of MUX is
signal sel : std_logic_vector(1 downto 0);
signal y, z, x: std_logic;
begin
y <= (updown and i0 and i1 and i2 and en);
z <= (not updown) and i0 and i1 and i2 and en;
sel(0) <= not load;
sel(1) <= y or z ;
process(sel, x)
begin
if sel = "00" then x<= i3;
elsif sel = "01" then x <= (not i3);
else x <= inload;
end if;
end process;
bitout <= x ;
end Behavioral;
触发器的代码:
entity D_FlipFlop is
Port ( d : in STD_LOGIC;
reset : in STD_LOGIC;
clock : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
updown : in STD_LOGIC;
q : out STD_LOGIC);
end D_FlipFlop;
architecture Behavioral of D_FlipFlop is
begin
process(clock, reset)
begin
if (reset = '0') then
q <= '0';
elsif (rising_edge(clock)) then
q <= d;
end if;
end process;
end Behavioral;
需要注意的是load和enable是同步的,reset是异步的,我也会附上一张我的仿真图。
When I simulate it it starts from 0 as it should cause of the reset , then counts to 1 and then again 0 . I can't see why it goes back to 0 after 1.
我修改了昨天的测试台以复制您的波形:
我不得不修改重置为“0”到“1”和“1”到“0”的一组增量循环,以使计数器显示为全“0”。
首先要注意的是你的复位极性错误。
修正给出:
我们可以看到计数没有正确增加并且仍然停止。
在不考虑负载极性的情况下,停滞值是由 MUX 中进程的敏感列表引起的:
process(sel, x)
begin
if sel = "00" then x<= i3;
elsif sel = "01" then x <= (not i3);
else x <= inload;
end if;
end process;
bitout <= x ;
end Behavioral;
应该有一个敏感度列表:
process (sel, i3, inload) -- was (sel, x) -- incorrect sensitivity list
这会产生:
仍然缺少增量显示,但确实有变化。
在测试台中将加载值更改为“0”会在反击时为我们提供丢失的事务,但值仍然是错误的:
这告诉我们您的 select 方程式错误或您的多路复用器输入错误或两者的某种组合。
无论如何,MUX 似乎是您应该关注的地方。
因此,通过在 MUX 中输入您的 select 更改,您在评论中告诉我们,您可以获得正确的计数:
-- sel(0) <= not load;
-- sel(1) <= y or z ;
sel(1) <= (not load); -- per comments
sel(0) <= y or z;
我们得到:
显示向上计数正确但向下计数不正确。请注意负载的极性在 select 秒内已更改,并与上面的波形匹配。
现在我们知道我们应该根据 updown 增加或减少 cnt,
y <= updown and i0 and i1 and i2 and en;
用于向上计数,剩下
z <= not updown and i0 and i1 and i2 and en;
不幸的是,它在 i0、i1 和 i2 上使用相同的值来切换位输出(特定 cnt 元素的相应 D_FlipFlop 的输入)。
我们相当确定 z 想成为:
z <= not updown and not i0 and not i1 and not i2 and en;
用于递减(不是递增)。
当我们进行更改时,计数不起作用。我们需要 MUX 的未使用输入是 updown 的正确值,“1”表示向上(如现在))或“0”表示向下。
我们可以在 counter4bit 中使用 updown 来做到这一点:
MUX0 : MUX
port map( i0 => updown, -- '1'
i1 => updown, -- '1',
i2 => updown, -- '1',
i3 => cnt(0),
inload => '1',
bitout =>w(0) ,
load => load,
updown => updown,
en => enable);
MUX1 : MUX
port map( i0 => cnt(0),
i1 => updown, -- '1',
i2 => updown, -- '1',
i3 => cnt(1),
inload => '1',
bitout =>w(1) ,
load => load,
updown => updown,
en => enable);
MUX2 : MUX
port map( i0 => cnt(0),
i1 => cnt(1),
i2 => updown, -- '1',
i3 => cnt(2),
inload => '0',
bitout =>w(2) ,
load => load,
updown => updown,
en => enable);
这给了我们:
注意此波形尚未测试加载或启用 (false),但它会向上计数,然后成功返回。
D_FlipFlop(加载、启用、上行)上还有一些未使用的端口。