1

要するに、私はある種のプロセッサを作ろうとしています (「ある種の」というのは理由がありますが、詳細には立ち入らないでください)。もの。

つまり、このコードでは:

programmProcess: process (clk,rst) is
    variable counter : natural;
begin
    if (rst = '1') then
        counter := 0;
    elsif (clk'event and clk = '1' and pm_nEn= '1') then
        RAM(counter) <= data; --This is where the issue is
        counter := counter + 1;
        if (counter = 1024) then
            counter := 0;
        end if;
    end if;
    data <= "ZZZZZZZZZZZZZZZZ";
end process programmProcess;

...そして、これはテストベンチプロセスです:

 stim_proc1: process 
 begin  
    rst <= '1';
    pm_nEn <= '1';
    wait for clk_period;

    rst <= '0' ;

    data <="0000111110111001";
    wait for clk_period;

    data <="0000111010111001";
    wait for clk_period;

    data <= "ZZZZZZZZZZZZZZZZ";
    pm_nEn <= '0';
    wait for 10*clk_period;
    wait;
end process;

... ここで、RAM は 16 ビットの 1024 個のベクトルの配列であり、データは 16 ビットの inout ベクトルであり、pm_nEn は基本的に RAM に値を入力できる単一ビットです。

アイデアは、RAM(カウンター) がデータ ベクターから値を取得するというもので、これはテストベンチで手動で値が供給されますが、これは起こりません。つまり、データが必要な値を持っているにもかかわらず、すべての RAM の値は「UUUUUUUUUUUUUUU」のままです。最初に評価され、カウンターが 0 の場合でも、RAM(0) は未定義です。

私は ISE スイートを使用しており、シミュレーションを試みた後、すべてのステップをトレースしただけで、RAM(カウンター) に値が割り当てられるステップが表示され、データ ベクトルには手動で追加された値があります。テストベンチを実行しますが、RAM はまだ値を取得しません。

質問は基本的に - なぜこれが起こるのですか? RAM に値が割り当てられないのはなぜですか?

また、完全な VHDL とテストベンチ (便利なように ISE で生成されたもの) を Google ドキュメント形式で示します。

VHDL

テストベンチ

4

3 に答える 3

2

メイン プロセス内で「zzzz」を Data に割り当てても害はありません (ただし、現在のコード フラグメントでは冗長です)。

合成で問題を引き起こす可能性があることの 1 つは、次のとおりです。

 elsif (clk'event and clk = '1' and pm_nEn= '1') then
    ... actions
 end if;

合成ツールがクロック処理されたプロセスに期待するパターンに一致させるには、

 elsif clk'event and clk = '1' then
    if pm_nEn= '1' then
       ... actions
    end if;
 end if;

ただし、シミュレーションでは 2 つのバージョンが同等であると予想されます。別のプロセスの RAM に別のドライバーはありませんね。

編集:明らかに、別のプロセスにRAMを設定する別のドライバーがあります。ソフトウェアの観点から見ると、一方のプロセスが の場合に駆動しen = '0'、他方のプロセスが の場合に駆動するため、これで問題ないと考えるかもしれませんen = '1'。ただし、ブール値のフリックでドライバーハードウェアを表示および非表示にすることはできません。RAM 信号には常に 2 つのドライバーがあります。明示的に使用していないものは、値を「UUUU」として保持しています。

最善の方法は、それらのいずれかを排除することです。いずれかのプロセスに RAM への書き込みを担当させます。このプロセスを使用します。他のプロセスを使用すると、デザインがよりクリーンで整然としたものになる場合があります。それもOKです。

簡単です。このプロセスを次の行に沿って再編成するだけです。

 elsif clk'event and clk = '1' then
    if pm_nEn= '1' then
       ... actions
    else    -- or elsif external_enable then 
       RAM(external_address) <= external_data;
    end if;
 end if;

ちなみに、 のような式を見ると、RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3))))))) <= std_logic_vector(signed(OP1) + signed(OP2)); 通常、最初に間違った型として宣言されているものがあるという手がかりになります。たとえば、OP1 と OP2 は署名されている可能性があり、R は整数の配列である必要があります。すべての醜さを取り除くことができない場合は、少なくともヘルパー関数 (おそらくパッケージ内) を使用してメイン プログラム フローに干渉するのを止めることができます。

function gen_reg_addr(IR : Register) return natural is ...

RAM(gen_reg_addr(IR)) <= ...
于 2013-02-16T23:41:38.877 に答える
0

問題は、あなたが書く場所がたくさんあることにあると思いますdata。複数のステートメントを同じ変数に書き込んでいて、それによってシミュレーターが値Z.

たとえば、プロセスの 1 つが次のようになります。

glavenProcess: process (clk,rst) is
begin
    data <= "ZZZZZZZZZZZZZZZZ";
    ...
end process;
于 2013-02-16T23:05:43.753 に答える
0

問題が見つかりました。RAM を Signal ではなく変数に変更してください。VHDL マニュアルを参照して、Signal と変数の違いを確認してください。

        library IEEE;
use IEEE.std_logic_1164.all;
use  ieee.numeric_std.all;

entity mp is
    port(
        clk, rst, pm_nEn : in std_logic;
        data : inout std_logic_vector(15 downto 0);
       adr : out std_logic_vector(15 downto 0);
       rd_nwr : out std_logic
    );
end entity mp;

architecture beh of mp is
    signal PC, IR, OP1, OP2 : std_logic_vector(15 downto 0);
    type csignals is array(7 downto 0) of std_logic_vector(15 downto 0);
    signal R: csignals;

    type memory_array is array(1024 downto 0) of std_logic_vector(15 downto 0);
      shared variable RAM: memory_array;
begin                    

    glavenProcess: process (clk,rst) is
    begin
         data <= "ZZZZZZZZZZZZZZZZ";
        if (rst = '1') then
            PC <= "0000000000000000";
             R(0) <= "0000000000000000";
            R(1) <= "0000000000000000";
            R(2) <= "0000000000000000";
            R(3) <= "0000000000000000";
            R(4) <= "0000000000000000";
            R(5) <= "0000000000000000";
            R(6) <= "0000000000000000";
            R(7) <= "0000000000000001";
        elsif (clk'event and clk = '1' and pm_nEn= '0') then
            IR <= RAM(to_integer(unsigned(PC)));
            if (IR(15) = '0') then
                if (IR(14) = '0') then
                        OP1 <= R(to_integer(unsigned(IR(11 downto 9))));
                else
                        OP1 <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(11 downto 9)))))));
                end if;

                  if (IR(13) = '0') then
                        OP2 <= R(to_integer(unsigned(IR(8 downto 6))));
                else
                         if (IR(0) = '0') then
                                     adr <= R(to_integer(unsigned(IR(8 downto 6))));
                                     OP2 <= data;
                                     rd_nwr <= '1' ;
                         else
                                     OP2 <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(8 downto 6)))))));
                         end if;
                end if;

                if (IR(2) = '1') then OP2 <= not OP2 ; end if;
                if (IR(1) = '1') then OP1 <= not OP1 ; end if;

                  if (IR(0) = '0') then
                         if (IR(12) = '0') then
                                 R(to_integer(unsigned(IR(5 downto 3)))) <= std_logic_vector(signed(OP1) + signed(OP2));
                         else
                                 RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3))))))) := std_logic_vector(signed(OP1) + signed(OP2));
                         end if;
                   else
                         if (IR(12) = '0') then
                                 adr <= R(to_integer(unsigned(IR(5 downto 3))));
                         else
                                 adr <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3)))))));
                         end if;
                         data <= std_logic_vector(signed(OP1) + signed(OP2));
                         rd_nwr <= '0' ;
                   end if;
                PC <= std_logic_vector(unsigned(PC) + 1);
             else
                 if (IR(8 downto 7) = "00") then
                         if (R(to_integer(unsigned(IR(11 downto 9)))) = R(to_integer(unsigned(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "01") then
                         if (R(to_integer(signed(IR(11 downto 9)))) > R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "10") then
                         if (R(to_integer(signed(IR(11 downto 9)))) < R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "11") then
                     if ( not R(to_integer(signed(IR(11 downto 9)))) = R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 end if;
             end if;
         end if;
    end process glavenProcess;

    programmProcess: process (clk,rst) is
        variable counter : natural;
    begin
        if (rst = '1') then
            counter := 0;
        else 
            if (clk'event and clk = '1' and pm_nEn= '1')  then
            RAM(counter) := data;
            counter := counter + 1;                       
            if (counter = 1024) then counter := 0; end if;
        end if;



        end if;

    end process programmProcess;
end architecture beh;

テストベンチ:

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;

    -- Add your library and packages declaration here ...

entity mp_tb is
end mp_tb;

architecture TB_ARCHITECTURE of mp_tb is
    -- Component declaration of the tested unit
    component mp
    port(
        clk : in STD_LOGIC;
        rst : in STD_LOGIC;
        pm_nEn : in STD_LOGIC;
        data : inout STD_LOGIC_VECTOR(15 downto 0);
        adr : out STD_LOGIC_VECTOR(15 downto 0);
        rd_nwr : out STD_LOGIC );
    end component;

    -- Stimulus signals - signals mapped to the input and inout ports of tested entity
    signal clk : STD_LOGIC;
    signal rst : STD_LOGIC;
    signal pm_nEn : STD_LOGIC;
    signal data : STD_LOGIC_VECTOR(15 downto 0);
    -- Observed signals - signals mapped to the output ports of tested entity
    signal adr : STD_LOGIC_VECTOR(15 downto 0);
    signal rd_nwr : STD_LOGIC;

    -- Add your code here ...

begin

    -- Unit Under Test port map
    UUT : mp
        port map (
            clk => clk,
            rst => rst,
            pm_nEn => pm_nEn,
            data => data,
            adr => adr,
            rd_nwr => rd_nwr
        );   
        clock:process is
        begin           

           clk<='0';
           wait for 10 ns;
           clk<='1';
           wait for 10 ns;



        end process;
process is
begin
rst <= '1';
    pm_nEn <= '1';



    wait  for 25 ns;
    rst <= '0' ;
    data <="0000111110111001";

    wait  for 45 ns;

    data <="0000111010111001";

    wait  for 55 ns;
    data <= "ZZZZZZZZZZZZZZZZ";
    pm_nEn <= '0';

    wait;
end process;
end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_mp of mp_tb is
    for TB_ARCHITECTURE
        for UUT : mp
            use entity work.mp(beh);


        end for;
    end for;
end TESTBENCH_FOR_mp;
于 2013-02-16T23:23:11.793 に答える