2

私はこのPCモジュールを非常にシンプルに持っています(コードは最後にあります)。最初に何らかの入力信号port_intを生成し、プロセスの最後にpc_out <= port_int. 私の目標は、入力信号に応じて、PC をインクリメントまたは加算または減算することです。

シミュレーションでは、内部port_int信号は正常に機能しますが、pc_out機能しません。なぜこうなった?シミュレーションを見てください: シム

遅れているport_int間に、それがどのように変化するかを見てください。pc_outシミュレーションの後半でpc_outはさらに悪化し、単に遅れるだけでなく、不規則に変化します。

私は何を間違っていますか?変更する別の方法はありpc_outますか?Bcoz、信号を変更することはできません。それは非常に悪い習慣outだと言われています..inout

コードは次のとおりです。

entity PC is
    Port ( clk : in STD_LOGIC; 
       enable : in STD_LOGIC; 
       reset : in STD_LOGIC;
       pc_out : out  STD_LOGIC_VECTOR (3 downto 0);
       data : in  STD_LOGIC_VECTOR (3 downto 0);    -- jump value
       zero : in  STD_LOGIC;    -- jump condition
       jmp_en : in  STD_LOGIC;      -- jump enable
       jmp_dir : in STD_LOGIC;  -- jump direction
       ctrl_en : out STD_LOGIC);   -- output signal
end PC;

architecture Behavioral of PC is

type state_type is (s0, s1, s2, s3);
signal reg_state, next_state : state_type;

signal port_int : std_logic_vector(3 downto 0);

begin

state_transition: process(clk, reset)
begin
    if (reset = '1') then
        reg_state <= s0;
    elsif(rising_edge(clk)) then
        reg_state <= next_state;
    end if;
end process;

next_state_logic: process(reg_state, enable)
begin
    case reg_state is
        when s0 =>
            if(enable = '1') then
                next_state <= s2;
            else
                next_state <= s1;
            end if;

        when s1 =>
            if(enable = '1') then
                next_state <= s2;
            else
                next_state <= s1;
            end if;

        when s2 =>
            next_state <= s3;

        when s3 =>
            if(enable = '1') then
                next_state <= s2;
            else
                next_state <= s1;
            end if;
    end case;
end process;

output_logic: process(reg_state, zero, jmp_en, jmp_dir, data)
begin
    case reg_state is
        when s0 =>
            pc_out <= "0000";
            port_int <= "0000";
            ctrl_en <= '0';

        when s1 =>
            ctrl_en <= '0';

        when s2 =>
            if(zero = '1' and jmp_en = '1' and jmp_dir = '1')then
                port_int <= port_int + data;    -- jump forward
            elsif(zero = '1' and jmp_en = '1' and jmp_dir = '0')then
                port_int <= port_int - data;    -- jump backward
            else    -- nije ispunjen uslov skoka
                port_int <= port_int + '1'; -- increment PC
            end if;
            pc_out <= port_int;

        when s3 =>
            ctrl_en <= '1';
    end case;
end process;

end Behavioral;

編集:

モジュールをプロセッサ全体にインポートすると、これが発生 sim3 します。同じpc_out信号が奇妙に動作し、すべての入力が同じです。pc_out信号を 1 か所だけ使用して、メモリを選択します。正常に動作しないのはなぜですか?何が原因でしょうか?

4

2 に答える 2

2

出力値を計算する2 番目のプロセス ( output_logic: process ) には、いくつかの問題があります。

まず、組み合わせ回路 (したがって、メモリレス)を実装することを思い出してください。そのため、 port_int <= port_int + dataのような方程式は、 port_intの値がどこかに格納されている場合にのみ計算できます。ところで、コードを修正した後、内部信号port_intを削除して、 pc_outを直接使用できます。

第二に、このプロセスは組み合わせ回路であるため、その完全な真理値表を指定する必要があります。それ以外の場合、ラッチが推論されます。たとえば、状態s1ではctrl_enの値のみが指定されていることに注意してください。すべての状態ですべての出力値 (同じリスト) を指定するか、同等に、caseステートメントの前に出力値のリストを作成して、値が明示的に宣言されていない場合にコンパイラがそれらをデフォルト値として使用するようにする必要があります。

于 2013-12-23T12:18:15.503 に答える
2

あなたが正しくやろうとしていることを理解していれば、processブロックの外側に単一のステートメントが必要です:

pc_out <= port_int;

何かを割り当てる他のすべてのステートメントをpc_out設計から取り除きます。<=次のシミュレーション デルタまで実際にシグナル ドライバを更新するのを待っているオペレータにつまずいていると思います。

于 2013-12-18T01:32:01.627 に答える