0

私はこれに不慣れです... :)カウントCNTの値に基づいて、2つの利用可能な出力ポートTX_ADDRとTX_DATAのいずれかの間で出力を切り替えたい信号があります。アイデアは、シリアルで取得した最初の 32 ビット値をアドレス バスにパイプし、次にデータ バスにパイプし、次にアドレス、データの順にパイプすることです。そして、私は基本的にそのルーチンを無限に続けています。

次のようなものがある場合:

   process(sCNT)
   begin
   if(sCNT = false) then
       TX_ADDR <= sTXD;
       sCNT    <= true;
   else
       TX_DATA <= sTXD;
       sCNT    <= false;
   end if;
   end process;

...うまくいかないようです。基本的な考え方は、別のプロセスが 32 ビットのデータをシリアルに受信したら、sCNT ('s' はシグナルを示す) を切り替える必要があるというものです。次の 32 ビットは基本的にそれを再びトリガーし、出力は sCNT の状態に応じて TX_ADDR または TX_DATA に切り替えられます。

ありがとうございました!

ジョン

編集:これは完全に更新された「動作する」コードです。これほど多くのコードをコメントに貼り付けることができる場所がわからなかったので、ここで共有したいと思いました。

process(CLK, RST)
 begin
    if (RST = '1') then
      sRXD       <= x"00000000";
      sINDEX     <= 31;
      sTXD       <= x"00000000";
      sSCLK_old  <= '0';
      sSCLK_l    <= '0';
      sCS_old    <= '0';
      sCS_l      <= '0';
      DONE       <= '0';
      sMOSI_l    <= '0';

    elsif( rising_edge(CLK) ) then

      sSCLK_l       <= SCLK;
      sSCLK_old     <= sSCLK_l;
      sCS_l         <= CS;
      sCS_old       <= sCS_l;
      DONE          <= '0';
      sMOSI_l       <= MOSI;

      if(TX_EN = '1') then
          sTXD <= TX_DATA;
      end if;

      if (sCS_old = '1' and sCS_l = '0') then
          sINDEX <= 31;
      end if;

      if( sCS_l = '0' ) then
         if(sSCLK_old = '0' and sSCLK_l = '1') then
            sRXD <= sRXD(30 downto 0) & sMOSI_l;
            if(sINDEX = 0) then
               sINDEX <= 31;
            else
               sINDEX <= sINDEX-1;
            end if;
         elsif(sSCLK_old = '1' and sSCLK_l = '0') then
            if( sINDEX = 31 ) then
               DONE <= '1';
            end if;
            sTXD <= sTXD(30 downto 0) & '1';
         end if;
      end if;


     if(sCNT = false) then
         RX_ADDR <= sRXD;
         sCNT    <= true;
     else
         RX_DATA <= sRXD;
         sCNT    <= false;
     end if;
   end if;
   end process;

   MISO    <= sTXD(31);
end arch;
4

1 に答える 1

3

プロセスを駆動するためにクロックを使用する必要があります。

process(clk)
begin

    if rising_edge(clk) then

        if sCNT = false then
            TX_ADDR <= sTXD;
            sCNT <= true;
        else
            TX_DATA <= sTXD;
            sCNT <= false;
        end if;

    end if;

end process

ここclkは、シリアルに来るデータのクロックでなければなりません。あなたのやり方は、あなたのプロセスが無限ループに「似ている」のです。「sCNT」を変更すると、すぐに更新されると思いますか?? ただし、時計を使用すると、新しいデータ (に同期されている) でのみ更新されclkます。

于 2013-04-19T06:13:00.163 に答える