1

我已经使用 D 触发器模拟了 4 位环形计数器。

D 触发器位于单独的文件中,包含在我的工作区中。D 触发器正常工作(提供正确的输出波形)。

这是环形计数器的代码:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ring4counter is
    port (
        clk: std_logic;
        output: out std_logic_vector(3 downto 0));
end ring4counter;

architecture ring4counter_arch of ring4counter is
    component dff
    port (
        clk: std_logic;
        d: in std_logic;
        q: out std_logic;
        qbar: out std_logic);
    end component;

    signal temp:std_logic_vector(3 downto 0):=(others=>'0');
begin
    r1: dff port map(clk, temp(3), temp(0));
    r2: dff port map(clk, temp(0), temp(1));
    r3: dff port map(clk, temp(1), temp(2));
    r4: dff port map(clk, temp(2), temp(3));
    output <= temp;
end ring4counter_arch;

这是环形计数器的测试台代码:

library ieee;
use ieee.std_logic_1164.all;

entity ring4_tb is end ring4_tb ;

architecture arch of ring4_tb is
    component tbc is
    port (
        clk: std_logic;
        output: out std_logic_vector(3 downto 0));
    end component ;

    component dff
    port (
        clk: std_logic;
        d: in std_logic;
        q: out std_logic;
        qbar: out std_logic);
    end component;

    constant period : time := 50 ns ;

    signal clk      : std_logic := '0' ;    
    signal done     : boolean := false ;
    signal output   : std_logic_vector(3 downto 0) ;

    shared variable cycle : natural := 0 ;

    signal temp:std_logic_vector(3 downto 0):=(others=>'0');

begin
-- this is the unit under test
    u1: tbc
    port map(
        clk    => clk,
        output => output) ;

    clkprocess: process(done, clk)
    begin
    if (not done) then
        if (clk = '1') then
        cycle := cycle + 1 ;
        end if ;
        clk <= not clk after period / 2 ;
    end if ;
    end process ;

    r1: dff port map(clk, temp(3), temp(0));
    r2: dff port map(clk, temp(0), temp(1));
    r3: dff port map(clk, temp(1), temp(2));
    r4: dff port map(clk, temp(2), temp(3));
    output <= temp;

    testbench: process
    begin
    wait until (clk = '0') ;
    temp <= "1000";
    wait for period*4 ;

    done <= true ;      -- force the clock process to shutdown
    wait ;          -- this waits forever
    end process ;
end arch ;

但是“输出”的波形对于所有位都是“U”。我哪里错了?

4

3 回答 3

2

在测试台过程中,当您尝试将 temp 初始化为“1000”时,触发器仍在驱动 temp 信号,因此您实际上正在进行一场总线斗争。

于 2011-10-28T17:17:49.947 回答
0

使用temp您的环形计数器中的初始化来设置信号。

请注意,这可能无法正确合成,具体取决于您的架构和合成工具。

最通用的方法是向除 on 之外的所有 DFF 添加一个复位信号,并在该 DFF 上放置一个预设信号。然后您在开始时断言重置,这会将 DFF 设置为一个好的值。

这是您的代码的一个更简单的版本,它可以做到这一点并避免使用显式 DFF。您还可以更改宽度,temp代码将为您完成所有其余工作:

process (clk)
begin
   if reset = '1' then
      temp <= (0=>'1', others => '0'); -- set one bit high, the others low.
   elsif rising_edge(clk) then
      -- take the high bit and move it to the low bit. 
      -- Move the other bits left 1 place
      temp <= temp(temp'high-1 downto 0) & temp(temp'high);
   end if;
end process;

(注意:代码只是输入到消息中,可能有语法错别字!)


顺便说一句,shared variable除非它们是protected类型,否则 s 是个坏主意。他们可以有竞争条件。

于 2011-10-30T15:24:32.097 回答
-1

要做的一件事是为 D 触发器添加一个使能信号。当您想重置电路时,使启用信号变低,然后将温度更改为“1000”。

r1: dff port map(clk, temp(3), temp(0), enable);

process(clk,reset)
begin
if(rising_edge(clk)) then
 if( reset='1') then
  enable='0';
  temp <= "1000";
 else
  enable <= '1';
 end if;
end if;
end process;
于 2011-10-29T13:38:34.563 回答