4

この問題の最初の裏話。私の現在のプロジェクトでは、FPGA を使用して最適化されたマンデルブロ計算機を作成しようとしています。この時点で、私は nios プロセッサと FPGA の間にブリッジを確立しようとしました (残念ながら、これまでのところ運がありません)。

Avalon バスを使用して nios と FPGA (VHDL を実行) の間の通信を理解しようとしています。私は現在 15 週間以上 VHDL を使用しており、過去 5 週間は nios 2 プロセッサを使用しています。今私が達成したいことは次のとおりです: 質問の達成 64 ビット値の 2 倍の送信をテストできるセットアップを作成したいのですが、VHDL でこの値を記憶し、Nios 2 プロセッサに戻るように読み取りを試みます。 (C コード)。

もちろん、私は自分でこれを理解しようとする前に、この質問をここに上げませんでした. これが今までやってきた仕事です。

nios では、2 つの 64 ビット値を FPGA に書き込み、それらを取得して赤と緑の LED に出力を表示するメインの簡単なセットアップを作成しました。ところで、これをアルテラ DE2 ボードで実行します。Cコードは次のようになります

int main (void)
{
    //Reset the green and red leds to off
    IOWR(REDLEDS_BASE, 0, 0x0);
    IOWR(GREENLEDS_BASE, 0, 0x0);

    //Write the 64 bit x coordinate
    IOWR(MANDELBROT_CORE_BASE, 0x0, 0xAAAAAAAA);
    IOWR(MANDELBROT_CORE_BASE, 0x4, 0xAAAAAAAA);

    //Write the 64 bit y coordinate
    IOWR(MANDELBROT_CORE_BASE, 0x8, 0xEEEEEEEE);
    IOWR(MANDELBROT_CORE_BASE, 0x12, 0xEEEEEEEE);

    //Read the 64 bit x coordinate
    double x = IORD(MANDELBROT_CORE_BASE, 0);

    //Read the 64 bit y coordinate
    double y = IORD(MANDELBROT_CORE_BASE, 8);

    //Write the values to the leds
    IOWR(REDLEDS_BASE, 0, x);
    IOWR(GREENLEDS_BASE, 0, y);

    while(bRunning == true)
    {
    }

    return 1;
}

IQRD は 32 ビット値しか取得できないため、このコードが正しくない可能性があることは承知しています。しかし、64 ビット アドレスを一度に読み取るための解決策を見つけることができません。この質問から、これを行う方法に関するほとんどのテクニックを入手しました。なので、これが正しいかどうかはわかりません。

次に、VHDL で記述された FPGA 側があります。このコンポーネントは、QSYS で nios の Avalon バスに接続されている 64 ビット コンポーネントです。着信および発信リクエストを処理する必要があるコンポーネントは、avalon_mandelbrot コンポーネントです (以下を参照)。

entity avalon_mandelbrot is
    port (
        avs_s0_read        : in  std_logic                     := '0'; -- s0.read
        avs_s0_readdata    : out std_logic_vector(63 downto 0);        -- readdata
        avs_s0_write       : in  std_logic                     := '0'; -- write
        avs_s0_writedata   : in  std_logic_vector(63 downto 0) := (others => '0'); -- writedata
        avs_s0_waitrequest : out std_logic;                                        -- waitrequest
        avs_s0_address     : in  std_logic_vector(7 downto 0)  := (others => '0'); -- address
        avs_s0_byteenable  : in  std_logic_vector(7 downto 0) ;                    -- byte enable
        clk                : in  std_logic                     := '0';             -- clock
        reset              : in  std_logic                     := '0';             -- reset
    );
end entity avalon_mandelbrot;

architecture rtl of avalon_mandelbrot is
   begin
       process(clk)
           variable data_in : std_logic_vector(63 downto 0):= (others => '0');
           variable data_temp_x : std_logic_vector(63 downto 0):= (others => '0');
           variable data_temp_y : std_logic_vector(63 downto 0):= (others => '0');
       begin

           if rising_edge(clk) then

               if avs_s0_write = '1' then
                   if avs_s0_byteenable(0) = '1' then
                       data_in(7 downto 0) := avs_s0_writedata(7 downto 0);
                   end if;

                   if avs_s0_byteenable(1) = '1' then
                       data_in(15 downto 8) := avs_s0_writedata(15 downto 8);
                   end if;

                   if avs_s0_byteenable(2) = '1' then
                       data_in(23 downto 16) := avs_s0_writedata(23 downto 16);
                   end if;

                   if avs_s0_byteenable(3) = '1' then
                       data_in(31 downto 24) := avs_s0_writedata(31 downto 24);
                   end if;

                   if avs_s0_byteenable(4) = '1' then
                       data_in(39 downto 32) := avs_s0_writedata(39 downto 32);
                   end if;

                   if avs_s0_byteenable(5) = '1' then
                       data_in(47 downto 40) := avs_s0_writedata(47 downto 40);
                   end if;

                   if avs_s0_byteenable(6) = '1' then
                       data_in(55 downto 48) := avs_s0_writedata(55 downto 48);
                   end if;

                   if avs_s0_byteenable(7) = '1' then
                       data_in(63 downto 56) := avs_s0_writedata(63 downto 56);
                   end if;
               end if;

        
               --Master wants to write to slave
               if avs_s0_write = '1' then
                   case avs_s0_address is
                       when "00000000" => -- ADDR 0
                           data_temp_x(31 downto 0) := data_in(31 downto 0);
                       when "00000100" => -- ADDR 4
                           data_temp_x(63 downto 32) := data_in(63 downto 32);
                       when "00001000" => -- ADDR 8
                           data_temp_y(31 downto 0) := data_in(31 downto 0);
                       when "00001100" => -- ADDR 12
                           data_temp_y(63 downto 32) := data_in(63 downto 32);
                   end case;
               end if;
        
               --Master wants to read from slave
               if avs_s0_read = '1' then
                   case avs_s0_address is
                       when "00000000" =>
                           avs_s0_readdata <= data_temp_x;
                       when "00001000" =>
                           avs_s0_readdata <= data_temp_y;
                       when others =>
                           avs_s0_readdata <= (others => '0');
                   end case;
               end if;
           end if;
       end process;
end architecture rtl;

このセットアップが機能するはずだと私には論理的に思えますが、全体をテストしようとすると、本来のように機能しないようです。明らかに、私はここで何か間違ったことをしています。おそらく、もう少し経験のある人がそれを見ることができます。うまくいけば、誰かがすぐにこれを手伝ってくれるでしょう。

4

2 に答える 2

4

私は特に NIOS との通信をあまり扱ったことがありませんが、Altera の Avalon バス インターフェイスを扱ったことはあります。

まだ読んでいない場合は、参考資料を読んでください。www.altera.com/literature/manual/mnl_avalon_spec.pdf

特に、典型的な転送の例を示すセクション 3.5.1。

この例では、この特定の Avalon インターフェイスに固定の待機状態時間を使用することを指定していません。それが NIOS で構成可能かどうかはわかりませんが、通常、固定待機状態は Avalon バスのデフォルト動作ではありません。avs_s0_waitrequest読み取り/書き込みが完了したときに、信号を使用してマスター (NIOS) に通知する必要があることを意味します。このポートは、デザインでは接続されていません。

あなたの場合、書き込み操作中に接続avs_s0_waitrequestするのと同じくらい簡単で、読み取りレイテンシーが1であるため、読み取り中に接続するだけです。avs_s0_writeavs_s0_read

于 2015-01-02T16:46:45.873 に答える
0

Nios コードでは、addr 12 (16 進数で 0xC) とは異なる 0x12 に書き込みます。

IOWR(MANDELBROT_CORE_BASE, 0x12, 0xEEEEEEEE);

あなたが必要だった

IOWR(MANDELBROT_CORE_BASE, 0xC, 0xEEEEEEEE);

于 2017-12-14T09:27:04.907 に答える