8

VHDL でレジスタ ファイルを書き込もうとしています。このファイルには、16 個の 64 ビット レジスタが含まれています。各サイクルで、2 つのレジスタが読み取られ、1 つのレジスタが書き込まれます (書き込みが有効になっている場合)。1 つのサイクルで同じレジスタに対して読み書きを行う場合、書き込まれたばかりの値が出力に直接転送されるように、データ バイパス (転送) が必要です。

私のアイデアは、これを 1 サイクルで完了するために、クロックの立ち上がりエッジで書き込み、立ち下がりエッジで読み取ることでした。ただし、私のデザインは機能していません (立ち上がりエッジをチェックするifブロック内の立ち下がりエッジのチェックが期待どおりに機能するとは思わないため、期待していたわけではありません)。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity register_file is   
    port
    (
    outA          : out std_logic_vector(63 downto 0);
    outB          : out std_logic_vector(63 downto 0);
    input         : in  std_logic_vector(63 downto 0);
    writeEnable   : in std_logic;
    regASel       : in std_logic_vector(5 downto 0);
    regBSel       : in std_logic_vector(5 downto 0);
    writeRegSel   : in std_logic_vector(5 downto 0);
    clk           : in std_logic
    );
end register_file;

architecture behavioral of register_file is
type registerFile is array(0 to 15) of std_logic_vector(63 downto 0);
signal registers : registerFile;
begin

    regFile: process(clk)
    begin
        if rising_edge(clk) then 
            if(writeEnable = '1') then
                registers(to_integer(unsigned(writeRegSel))) <= input;
            end if;
            if falling_edge(clk) then
                outA <= registers(to_integer(unsigned(regASel)));
                outB <= registers(to_integer(unsigned(regBSel)));
            end if;
        end if;
        if falling_edge(clk) then
                outA <= registers(to_integer(unsigned(regASel)));
                outB <= registers(to_integer(unsigned(regBSel)));
        end if;
    end process;
end behavioral;

どんな助けでも大歓迎です。

4

2 に答える 2

9

送信された VHDL コードには、次の構造があります。

...
if rising_edge(clk) then
  ...
  if falling_edge(clk) then
  ...

rising_edgeと の両方をfalling_edge同時に真にすることはできないため、これはデッド コードのままになります。また、立ち上がりエッジと立ち下がりエッジの両方を使用するという考えは、設計と合成の問題を引き起こすことがよくあります。

最良のタイミング、および設計と合成の制約を容易にするために、立ち上がりエッジと立ち下がりエッジの両方を使用することが必須でない限り、立ち上がりエッジのみを使用することをお勧めします。

同じサイクルで読み出し A と B の書き込みデータをバイパスすると、レジスタ ファイルは次のようになります。

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

entity register_file is
  port(
    outA        : out std_logic_vector(63 downto 0);
    outB        : out std_logic_vector(63 downto 0);
    input       : in  std_logic_vector(63 downto 0);
    writeEnable : in  std_logic;
    regASel     : in  std_logic_vector(3 downto 0);
    regBSel     : in  std_logic_vector(3 downto 0);
    writeRegSel : in  std_logic_vector(3 downto 0);
    clk         : in  std_logic
    );
end register_file;


architecture behavioral of register_file is
  type registerFile is array(0 to 15) of std_logic_vector(63 downto 0);
  signal registers : registerFile;
begin
  regFile : process (clk) is
  begin
    if rising_edge(clk) then
      -- Read A and B before bypass
      outA <= registers(to_integer(unsigned(regASel)));
      outB <= registers(to_integer(unsigned(regBSel)));
      -- Write and bypass
      if writeEnable = '1' then
        registers(to_integer(unsigned(writeRegSel))) <= input;  -- Write
        if regASel = writeRegSel then  -- Bypass for read A
          outA <= input;
        end if;
        if regBSel = writeRegSel then  -- Bypass for read B
          outB <= input;
        end if;
      end if;
    end if;
  end process;
end behavioral;

*Sel の「アドレス」は、Daniel Kamil Kozar も指摘しているように、レジスタ ファイル内の 16 の必要なエントリと一致するように 4 ビットのみに縮小されていることに注意してください。

シミュレーションでは X 値のチェックはありませんが Is_X、必要に応じて関数で追加できます。

于 2013-11-13T12:14:02.360 に答える