使用结构设计制作一个减速计数器

时间:2016-03-20 17:00:54

标签: vhdl counter

我试图使用结构设计制作一个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;

Flip Flop的代码:

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;

我必须注意,加载和启用是同步的,而重置是异步的,我还会附加一张模拟图片。enter image description here

1 个答案:

答案 0 :(得分:1)

  

当我模拟它时,它从0开始,因为它应该导致复位,然后计数到1然后再次为0。我不知道为什么它会在1之后回到0。

我修改了昨天的测试平台以复制你的波形:

counter4bit_tb_duplicate.png

我不得不用&#39; 0&#39;修改重置。到&#39; 1&#39;和&#39; 1&#39;到&#39; 0&#39;一组三角形周期让反击显示为所有&#39; 0

首先要注意的是你的复位极性是错误的。

修复提供:

counter4bit_tb_wrong_sensitivity.png

我们可以看到计数没有正常增加而且仍然停滞不前。

在没有进入加载极性的情况下,停滞的值是由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

这就产生了:

counter4bit_tb_sensitivity_fixed.png

仍然没有显示增量,但确实有变化。

将负载值更改为&#39; 0&#39;在testbench中给出了我们在计数器上丢失的事务,但值仍然是错误的:

counter4bit_tb_load_low.png

告诉我们您的选择方程式错误或您的多路复用器输入错误或两者的某种组合。

无论如何,MUX似乎是你应该集中注意力的地方。

因此,通过在MUX中输入您选择的更改,您在评论中告诉我们为您提供正确的升值:

-- sel(0) <= not load;
-- sel(1) <= y or z ;
sel(1) <= (not load);  -- per comments
sel(0) <= y or z; 

我们得到:

counter4bit_tb_selects_changed.png

显示向上计数正确但不计算向下计数。注意,在选择中已经改变了负载的极性,并且在上面的波形中匹配。

现在我们知道我们应该根据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上使用相同的值来切换bitout(特定cnt元素的相应D_FlipFlop的输入)。

我们非常确定z想成为:

z <= not updown and not i0 and not i1 and not i2 and en;

用于递减(不是更新)。

当我们做出改变时,计数并不起作用。我们需要MUX的未使用输入为updown的正确值,&#39; 1&#39; for up(as now))或&#39; 0&#39;为了下来。

我们可以用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);

这给了我们:

counter4bit_tb_working.png

请注意,此波形尚未测试加载或启用(false),但它会计数,然后成功退回。

D_FlipFlop上还有一些未使用的端口(加载,启用,更新)。