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て、信号を設定します。

アーキテクチャと合成ツールによっては、これが正しく合成されない場合があることに注意してください。

これを行う最も一般的な目的の方法は、オンを除くすべてのDFFにリセット信号を追加し、その1つにプリセット信号を配置することです。次に、開始時にリセットをアサートします。これにより、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でない限り、sは悪い考えです。protected彼らは競合状態を持つことができます。

于 2011-10-30T15:24:32.097 に答える
-1

すべきことの 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 に答える