0

入力 w で 4 つの 1 または 0 のシーケンスを検出するワンホット エンコーディングを使用して、有限ステート マシンを作成するように依頼されました。case ステートメントを使用してコードを既に作成しましたが、9 つのフリップフロップへの入力として論理式を提供する必要もあります。z で正しい出力が得られず、その理由がよくわかりません。

これまでのところ、D フリップフロップ用に次のコードを書きました。

library ieee;
use ieee.std_logic_1164.all;

entity dflipflop is
    port (D, clk, reset: in std_logic;
        Q: out std_logic);
end dflipflop;

architecture behavior of dflipflop is
begin
process(clk)
begin
    if reset <= '0' then 
        Q <= '0';
    elsif rising_edge(clk) then
        Q <= D;
    end if;
end process;
end behavior;

次に、これをコードの残りの部分として使用します。ここに問題があると思います。

library ieee;
use ieee.std_logic_1164.all;

entity part1 is 
port (clk, w, reset : in std_logic;
        z: out std_logic);
end part1;

architecture behavior of part1 is
    component dflipflop 
    port (D, clk, reset: in std_logic; 
            Q: out std_logic);
    end component;

    signal A, B, C, D, E, F, G, H, I: std_logic;
    signal Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9: std_logic;

   dff1: dflipflop port map (clk=>clk, reset=>reset, D=>Y1, Q=>A);
   dff2: dflipflop port map (clk=>clk, reset=>reset, D=>Y2, Q=>B);
   dff3: dflipflop port map (clk=>clk, reset=>reset, D=>Y3, Q=>C);
   dff4: dflipflop port map (clk=>clk, reset=>reset, D=>Y4, Q=>D);
   dff5: dflipflop port map (clk=>clk, reset=>reset, D=>Y5, Q=>E);
   dff6: dflipflop port map (clk=>clk, reset=>reset, D=>Y6, Q=>F);
   dff7: dflipflop port map (clk=>clk, reset=>reset, D=>Y7, Q=>G);
   dff8: dflipflop port map (clk=>clk, reset=>reset, D=>Y8, Q=>H);
   dff9: dflipflop port map (clk=>clk, reset=>reset, D=>Y9, Q=>I);

begin
process(clk);
begin
if rising_edge(clk) then
    Y1 <= (((not w) and C) or ((not w) and G) or ((not w) and H) or ((not w) and I) or (w and B) or (w and D) or (w and E) or (w and F));
    Y2 <= ((not w) and A);
    Y3 <= (w and A);
    Y4 <= ((not w) and B);
    Y5 <= ((not w) and D);
    Y6 <= (((not w) and E) or ((not w) and F));
    Y7 <= (w and C);
    Y8 <= (w and G);
    Y9 <= ((w and H) or (w and I));
end if;
end process;
z <= (Y6 OR Y9);

end behavior;

私が間違っている可能性があることについて、誰かがヒントや洞察を提供できますか?

4

3 に答える 3

1

最初のコメント(ソースコードを見て):

  • 非同期リセットを使用する理由はわかりませんが、dflipflop の説明は問題ないようですデザインで実際に FF を非同期にリセットする必要がある場合を除き、同期リセット フリップフロップに変更することを検討してください。

  • クロック プロセス内に組み合わせ論理文を配置しました。ここで、フリップフロップを構造的にインスタンス化する場合は、フリップフロップによって既にクロックが供給されているため、これらすべての文を 1 つに含めないでください。

  • 信号名はより賢明に使用する必要があります。そうしないと、特に複雑なデザインの場合、コードの読み取りとデバッグが非常に困難になります。また、それぞれアクティブ ハイまたはアクティブ ロー リセットが必要な場合は、読みやすくするために の代わりにreset= '1'またはを使用してください。reset='0'reset <='0'

どうすればいいですか:

次の図と合計 9 つの状態を持つビット検出器の単純な有限状態マシン (FSM) の構造記述を探していると思います。ワンホット エンコーディングとは、状態ごとに 1 つのフリップフロップを割り当てる必要があることを意味します。

まず、9 つの std_logic 信号を宣言します。各信号は、1 つのホット エンコードされた FSM の 1 つの状態を表します。これらは、9 つ​​の FF の出力信号になります。

 signal init : std_logic;  -- Initial/reset state            
 signal zeros_1 : std_logic;  -- 1 zero  detected
 signal zeros_2 : std_logic;  -- 2 zeros detected
 signal zeros_3 : std_logic;  -- 3 zeros detected
 signal zeros_4 : std_logic;  -- 4 zeros detected
 signal ones_1  : std_logic;  -- 1 one   detected
 signal ones_2  : std_logic;  -- 1 one   detected
 signal ones_3  : std_logic;  -- 1 one   detected
 signal ones_4  : std_logic;  -- 1 one   detected

追加の 9 つの std_logic 信号を宣言して、対応する状態のフリップフロップの次の値を保持します。これらは、9 つ​​の FF の入力信号になります。

 signal go_to_init   : std_logic;
 signal go_to_zeros_1 : std_logic;  
 signal go_to_zeros_2 : std_logic;  
 signal go_to_zeros_3 : std_logic;  
 signal go_to_zeros_4 : std_logic;  
 signal go_to_ones_1  : std_logic;  
 signal go_to_ones_2  : std_logic;  
 signal go_to_ones_3  : std_logic;  
 signal go_to_ones_4  : std_logic;  

9 つのフリップフロップを対応する信号にマップします。

ステート マシンを RESET 信号で初期化する場合は、RESET で HIGH になる D フリップフロップが必要になることに注意してください。dflipflopの説明を使用して、新しいdflipflop_RHを実装するために変更if reset='1' then Q <='0'し て使用できます。if reset='1' then Q <='1'

init_ff   : dflipflop_RH port map (clk=>clk, reset=>reset,D=> go_to_init, Q=> init);
zeros_1_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_1, Q=> zeros_1 );
zeros_2_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_2, Q=> zeros_2 );
zeros_3_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_3, Q=> zeros_3 );
zeros_4_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_4, Q=> zeros_4 );
ones_1_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_1, Q=> ones_1 );
ones_2_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_2, Q=> ones_2 );
ones_3_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_3, Q=> ones_3 );
ones_4_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_4, Q=> ones_4 );

最後に、組み合わせロジックを追加して、現在の状態と入力信号 'w' から次の状態を計算します。これは非常に単純な FSM であるため、FSM のグラフィカル表現を VHDL コードに変換するだけです。

 go_to_init <= '0';  -- never go to init (only when reset='1') 

 go_to_zeros_1 <= (init or ones_1 or ones_2 or ones_3 or ones_4  ) and (not w);
 go_to_zeros_2 <= zeros_1 and (not w);
 go_to_zeros_3 <= zeros_2 and (not w);
 go_to_zeros_4 <= (zeros_3 or zeros_4) and (not w);

 go_to_ones_1 <= (init or zeros_1 or zeros_2 or zeros_3 or zeros_4) and w;
 go_to_ones_2 <= ones_1 and w;
 go_to_ones_3 <= ones_2 and w;
 go_to_ones_4 <= (ones_3 or ones_4) and w;

 z <= ones_4 or zeros_4;
于 2013-03-03T05:49:10.087 に答える
0

私はそのような小さなタスクのためにはるかに読みやすいコードを書くでしょう:

library ieee;
use ieee.std_logic_1164.all;

entity part1 is 
port (
    clk     : in  std_logic;
    w       : in  std_logic;
    reset_n : in  std_logic; -- mark low active signals with suffix _n
    z       : out std_logic
);
end part1;

architecture rtl of part1 is
     signal sreg : std_logic_vector(3 downto 0);
begin
     process
     begin
         wait until rising_edge( clk);

         -- shift register
         sreg <= sreg(2 downto 0) & w;

         if sreg = "0000" or sreg = "1111" then
             z <= '1';
         else
             z <= '0';
         end if;

         -- do we really need a reset?
         if reset_n = '0' then
             sreg <= "0000";
         end if;
     end process;
end architecture rtl;
于 2013-03-04T16:29:35.563 に答える
0

リセット後、d フリップフロップのすべての出力は「0」になります。

if reset <= '0' then 
    Q <= '0';

つまり、A、B、C、D、E、F、G、H と私は「0」です。

Yn 信号を割り当てるブール論理により、Yn は常に「0」になります。

例えば

Y2 <= ((not w) and A); -- A is at '0' => Y2 will always be '0'.

出力「z」は常に「0」になります。

z <= (Y6 OR Y9); -- Y6 is always '0', Y9 is always '0' => Z will always be '0'.

ところで、コンポーネントの出力を登録するのは良い設計規則です。プロセスのz <= (Y6 OR Y9);中に配置します。

dflipflop の出力はリセット時に「1」でなければならないのでしょうか?

于 2013-02-27T08:26:47.530 に答える