VHDL - данные файла регистрации не всегда записываются - PullRequest
0 голосов
/ 11 декабря 2018

Мы строим процессор для нашего финального проекта.Нам сказали построить регистровый файл с двумя выходами чтения и одним входом записи.Мы должны использовать мультиплексоры для выбора читаемых регистров и декодер для выбора записываемого регистра.

Мы используем Vivado 2015.4 и плату Nexys4.Я синтезировал файл регистров как часть всего процессора, но не сам по себе.Я запустил симуляцию тестового стенда только для регистров.

Верхний уровень файла регистрации:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.RegPackage.all;

entity register_file1 is
    Port ( clk : in STD_LOGIC;
           reset : in STD_LOGIC;
           w_en : in STD_LOGIC;
           w_data : in STD_LOGIC_VECTOR (63 downto 0);
           r_data1 : out STD_LOGIC_VECTOR (63 downto 0);
           r_data2 : out STD_LOGIC_VECTOR (63 downto 0);
           w_reg : in STD_LOGIC_VECTOR (4 downto 0);
           r_reg1 : in STD_LOGIC_VECTOR (4 downto 0);
           r_reg2 : in STD_LOGIC_VECTOR (4 downto 0);
           r_data19 : out STD_LOGIC_VECTOR (63 downto 0); --Here down are just to track that the registers are being written to properly
           r_data20 : out STD_LOGIC_VECTOR (63 downto 0);
           r_data21 : out STD_LOGIC_VECTOR (63 downto 0);
           r_data24 : out STD_LOGIC_VECTOR (63 downto 0));
end register_file1;

architecture Behavioral of register_file1 is
    signal reg_sel : STD_LOGIC_VECTOR (31 downto 0);
    signal w_sel: STD_LOGIC_VECTOR(31 downto 0);
    signal reg_data0 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data1 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data2 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data3 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data4 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data5 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data6 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data7 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data8 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data9 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data10 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data11 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data12 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data13 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data14 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data15 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data16 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data17 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data18 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data19 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data20 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data21 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data22 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data23 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data24 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data25 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data26 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data27 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data28 : STD_LOGIC_VECTOR(63 downto 0);    
    signal reg_data29 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data30 : STD_LOGIC_VECTOR(63 downto 0);
    signal reg_data31 : STD_LOGIC_VECTOR(63 downto 0) := x"0000000000000000"; --zero register

 begin
    --These are signals for the test bench to track if they are being properly written to
    r_data19 <= reg_data19;
    r_data20 <= reg_data20;
    r_data21 <= reg_data21;
    r_data24 <= reg_data24;

    --mux for read data1
    r_data1 <= reg_data0 when (r_reg1 = "00000")
               else reg_data1 when (r_reg1 = "00001")
               else reg_data2 when (r_reg1 = "00010")
               else reg_data3 when (r_reg1 = "00011")
               else reg_data4 when (r_reg1 = "00100")
               else reg_data5 when (r_reg1 = "00101")
               else reg_data6 when (r_reg1 = "00110")
               else reg_data7 when (r_reg1 = "00111")
               else reg_data8 when (r_reg1 = "01000")
               else reg_data9 when (r_reg1 = "01001")
               else reg_data10 when (r_reg1 = "01010")
               else reg_data11 when (r_reg1 = "01011")
               else reg_data12 when (r_reg1 = "01100")
               else reg_data13 when (r_reg1 = "01101")
               else reg_data14 when (r_reg1 = "01110")
               else reg_data15 when (r_reg1 = "01111")
               else reg_data16 when (r_reg1 = "10000")
               else reg_data17 when (r_reg1 = "10001")
               else reg_data18 when (r_reg1 = "10010")
               else reg_data19 when (r_reg1 = "10011")
               else reg_data20 when (r_reg1 = "10100")
               else reg_data21 when (r_reg1 = "10101")
               else reg_data22 when (r_reg1 = "10110")
               else reg_data23 when (r_reg1 = "10111")
               else reg_data24 when (r_reg1 = "11000")
               else reg_data25 when (r_reg1 = "11001")
               else reg_data26 when (r_reg1 = "11010")
               else reg_data27 when (r_reg1 = "11011")
               else reg_data28 when (r_reg1 = "11100")
               else reg_data29 when (r_reg1 = "11101")
               else reg_data30 when (r_reg1 = "11110")
               else reg_data31 when (r_reg1 = "11111");

    --mux for read data 2
    r_data2 <= reg_data0 when (r_reg2 = "00000")
               else reg_data1 when (r_reg2 = "00001")
               else reg_data2 when (r_reg2 = "00010")
               else reg_data3 when (r_reg2 = "00011")
               else reg_data4 when (r_reg2 = "00100")
               else reg_data5 when (r_reg2 = "00101")
               else reg_data6 when (r_reg2 = "00110")
               else reg_data7 when (r_reg2 = "00111")
               else reg_data8 when (r_reg2 = "01000")
               else reg_data9 when (r_reg2 = "01001")
               else reg_data10 when (r_reg2 = "01010")
               else reg_data11 when (r_reg2 = "01011")
               else reg_data12 when (r_reg2 = "01100")
               else reg_data13 when (r_reg2 = "01101")
               else reg_data14 when (r_reg2 = "01110")
               else reg_data15 when (r_reg2 = "01111")
               else reg_data16 when (r_reg2 = "10000")
               else reg_data17 when (r_reg2 = "10001")
               else reg_data18 when (r_reg2 = "10010")
               else reg_data19 when (r_reg2 = "10011")
               else reg_data20 when (r_reg2 = "10100")
               else reg_data21 when (r_reg2 = "10101")
               else reg_data22 when (r_reg2 = "10110")
               else reg_data23 when (r_reg2 = "10111")
               else reg_data24 when (r_reg2 = "11000")
               else reg_data25 when (r_reg2 = "11001")
               else reg_data26 when (r_reg2 = "11010")
               else reg_data27 when (r_reg2 = "11011")
               else reg_data28 when (r_reg2 = "11100")
               else reg_data29 when (r_reg2 = "11101")
               else reg_data30 when (r_reg2 = "11110")
               else reg_data31 when (r_reg2 = "11111");


    decoder1 : decoder port map(reg_addr => w_reg, w => w_en, found => reg_sel);

    --write select signal. Takes the write enable (w_en) and the selected register from the decoder and uses that to determine which, if any, register is to be written to. Register 31 is never selected, because it is the zero register and cannot be written to.
    w_sel(0) <= (reg_sel(0) and w_en);
    w_sel(1) <= (reg_sel(1) and w_en);
    w_sel(2) <= (reg_sel(2) and w_en);
    w_sel(3) <= (reg_sel(3) and w_en);
    w_sel(4) <= (reg_sel(4) and w_en);
    w_sel(5) <= (reg_sel(5) and w_en);
    w_sel(6) <= (reg_sel(6) and w_en);
    w_sel(7) <= (reg_sel(7) and w_en);
    w_sel(8) <= (reg_sel(8) and w_en);
    w_sel(9) <= (reg_sel(9) and w_en);
    w_sel(10) <= (reg_sel(10) and w_en);
    w_sel(11) <= (reg_sel(11) and w_en);
    w_sel(12) <= (reg_sel(12) and w_en);
    w_sel(13) <= (reg_sel(13) and w_en);
    w_sel(14) <= (reg_sel(14) and w_en);
    w_sel(15) <= (reg_sel(15) and w_en);
    w_sel(16) <= (reg_sel(16) and w_en);
    w_sel(17) <= (reg_sel(17) and w_en);
    w_sel(18) <= (reg_sel(18) and w_en);
    w_sel(19) <= (reg_sel(19) and w_en);
    w_sel(20) <= (reg_sel(20) and w_en);
    w_sel(21) <= (reg_sel(21) and w_en);
    w_sel(22) <= (reg_sel(22) and w_en);
    w_sel(23) <= (reg_sel(23) and w_en);
    w_sel(24) <= (reg_sel(24) and w_en);
    w_sel(25) <= (reg_sel(25) and w_en);
    w_sel(26) <= (reg_sel(26) and w_en);
    w_sel(27) <= (reg_sel(27) and w_en);
    w_sel(28) <= (reg_sel(28) and w_en);
    w_sel(29) <= (reg_sel(29) and w_en);
    w_sel(30) <= (reg_sel(30) and w_en);

    --Registers. I know that there is a way to generate these simpler with indexing, but we couldn't get it to work.
    register0 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data0, sel => w_sel(0));
    register1 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data1, sel => w_sel(1));
    register2 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data2, sel => w_sel(2));
    register3 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data3, sel => w_sel(3));
    register4 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data4, sel => w_sel(4));
    register5 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data5, sel => w_sel(5));
    register6 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data6, sel => w_sel(6));
    register7 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data7, sel => w_sel(7));
    register8 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data8, sel => w_sel(8));
    register9 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data9, sel => w_sel(9));
    register10 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data10, sel => w_sel(10));
    register11 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data11, sel => w_sel(11));
    register12 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data12, sel => w_sel(12));
    register13 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data13, sel => w_sel(13));
    register14 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data14, sel => w_sel(14));
    register15 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data15, sel => w_sel(15));
    register16 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data16, sel => w_sel(16));
    register17 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data17, sel => w_sel(17));
    register18 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data18, sel => w_sel(18));
    register19 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data19, sel => w_sel(19));
    register20 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data20, sel => w_sel(20));
    register21 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data21, sel => w_sel(21));
    register22 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data22, sel => w_sel(22));
    register23 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data23, sel => w_sel(23));
    register24 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data24, sel => w_sel(24));
    register25 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data25, sel => w_sel(25));
    register26 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data26, sel => w_sel(26));
    register27 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data27, sel => w_sel(27));
    register28 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data28, sel => w_sel(28));
    register29 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data29, sel => w_sel(29));
    register30 : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data30, sel => w_sel(30));
    register31 : newRegister port map( clk => clk, reset => reset, w_en => '0', w_data => w_data , r_data => reg_data31, sel => '0');

end Behavioral;

Декодер:

entity decoder is
    Port ( reg_addr : in STD_LOGIC_VECTOR (4 downto 0);
           w : in std_logic;
           found : out STD_LOGIC_VECTOR (31 downto 0)
         ) ;
end decoder;

architecture Behavioral of decoder is

begin
    process(reg_addr)
    begin

            case reg_addr is
                when "00000" =>  found <= x"00000001";
                when "00001" =>  found <= x"00000002";
                when "00010" =>  found <= x"00000004";
                when "00011" =>  found <= x"00000008";
                when "00100" =>  found <= x"00000010";
                when "00101" =>  found <= x"00000020";
                when "00110" =>  found <= x"00000040";
                when "00111" =>  found <= x"00000080";
                when "01000" =>  found <= x"00000100";
                when "01001" =>  found <= x"00000200";
                when "01010" =>  found <= x"00000400";
                when "01011" =>  found <= x"00000800";
                when "01100" =>  found <= x"00001000";
                when "01101" =>  found <= x"00002000";
                when "01110" =>  found <= x"00004000";
                when "01111" =>  found <= x"00008000";
                when "10000" =>  found <= x"00010000";
                when "10001" =>  found <= x"00020000";
                when "10010" =>  found <= x"00040000";
                when "10011" =>  found <= x"00080000";
                when "10100" =>  found <= x"00100000";
                when "10101" =>  found <= x"00200000";
                when "10110" =>  found <= x"00400000";
                when "10111" =>  found <= x"00800000";
                when "11000" =>  found <= x"01000000";
                when "11001" =>  found <= x"02000000";
                when "11010" =>  found <= x"04000000";
                when "11011" =>  found <= x"08000000";
                when "11100" =>  found <= x"10000000";
                when "11101" =>  found <= x"20000000";
                when "11110" =>  found <= x"40000000";
                when "11111" =>  found <= x"80000000";
                when others => found <= x"00000000";
            end case;

    end process;

end Behavioral;

Регистры:

entity newRegister is
    Port ( clk : in STD_LOGIC;
           reset : in STD_LOGIC;
           sel : in STD_LOGIC; --register select enable
           w_en : in STD_LOGIC; --write enable
           w_data : in STD_LOGIC_VECTOR (63 downto 0);
           r_data : out STD_LOGIC_VECTOR (63 downto 0)
           );
end newRegister;

architecture Behavioral of newRegister is
    signal reg: std_logic_vector(63 downto 0); --internal register storage

begin
    process(clk) --nothing happens if this register isn't selected
    begin
        if reset = '1' then
            reg <= x"0000000000000000";
        end if;
        if rising_edge(clk) then
        if sel='1' then
                reg <= w_data; --load new data into register memory
        end if;

        end if;
    end process;
    r_data <= reg ;
end Behavioral;

Пакет:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package RegPackage is
    component newRegister is
    Port ( clk : in STD_LOGIC;
           reset : in STD_LOGIC;
           sel : in STD_LOGIC; --register select enable
           w_en : in STD_LOGIC; --write enable
           w_data : in STD_LOGIC_VECTOR (63 downto 0);
           r_data : out STD_LOGIC_VECTOR (63 downto 0)
           );
    end component;

    component decoder is
        Port ( reg_addr : in STD_LOGIC_VECTOR (4 downto 0);
               w : in std_logic;
               found : out STD_LOGIC_VECTOR (31 downto 0)
             ) ;
    end component;

end RegPackage;

Тестовый стенд предназначен для имитации того, что будет происходить в регистрах для следующего кода сборки ARMv8:

ADDI X24, XZR, #2048    // Address 2048 is stored in X24
ADDI X19, XZR, #10  // X19 = a = 10
ADDI X20, XZR, #5   // X20 = b = 5
ADD X21, X19, X20   // X21 = a + b = 10 + 5 = 15
STUR X21, [X24, #0] // send value X21 to 7 seg display
END

и:

entity testbench1 is
--  Port ( );
end testbench1;

architecture Behavioral of testbench1 is
 component register_file1 is 
    Port(   clk : in STD_LOGIC;
            reset : in STD_LOGIC;
            w_en : in STD_LOGIC;
            w_data : in STD_LOGIC_VECTOR (63 downto 0);
            r_data1 : out STD_LOGIC_VECTOR (63 downto 0);
            r_data2 : out STD_LOGIC_VECTOR (63 downto 0);
            w_reg : in STD_LOGIC_VECTOR (4 downto 0);
            r_reg1 : in STD_LOGIC_VECTOR (4 downto 0);
            r_reg2 : in STD_LOGIC_VECTOR (4 downto 0);
            r_data19 : out STD_LOGIC_VECTOR (63 downto 0);
                       r_data20 : out STD_LOGIC_VECTOR (63 downto 0);
                       r_data21 : out STD_LOGIC_VECTOR (63 downto 0);
                       r_data24 : out STD_LOGIC_VECTOR (63 downto 0));
 end component;

        signal clk : STD_LOGIC := '0';
        signal reset : STD_LOGIC := '0';
        signal w_en : STD_LOGIC := '0';
        signal w_data : STD_LOGIC_VECTOR (63 downto 0) := x"ABCDEF0123456789";
        signal r_data1 : STD_LOGIC_VECTOR (63 downto 0) := x"0000000000000000";
        signal r_data2 : STD_LOGIC_VECTOR (63 downto 0) := x"0000000000000000";
        signal w_reg : STD_LOGIC_VECTOR (4 downto 0) := "00000";
        signal r_reg1 : STD_LOGIC_VECTOR (4 downto 0) := "00000";
        signal r_reg2 : STD_LOGIC_VECTOR (4 downto 0) := "00000";
        signal r_data19 : STD_LOGIC_VECTOR (63 downto 0);
        signal r_data20 : STD_LOGIC_VECTOR (63 downto 0);
        signal r_data21 : STD_LOGIC_VECTOR (63 downto 0);
        signal r_data24 : STD_LOGIC_VECTOR (63 downto 0);

begin 


uut: register_file1 PORT MAP (     
            clk => clk,
            reset => reset,
            w_en  => w_en, 
            w_data => w_data, 
            r_data1 => r_data1,
            r_data2 => r_data2,
            w_reg => w_reg,
            r_reg1 => r_reg1, 
            r_reg2 => r_reg2,
            r_data19 => r_data19,
            r_data20 => r_data20,
            r_data21 => r_data21,
            r_data24 => r_data24);
process
 begin
   wait for 10 ns;        
   clk <= not clk;
   w_en <= '1';
   w_data <= x"0000000000000800";
   w_reg <= "11000";
   wait for 10 ns;           
   clk <= not clk;
   w_en <= '0';
   wait for 10 ns;
   clk <= not clk;
   w_en <= '1';
   w_data <= x"000000000000000A";
   w_reg <= "10011";
   wait for 10ns;
   clk <= not clk;
   w_en <= '0';
   wait for 10ns;
   clk <= not clk;
   w_en <= '1';
   w_data <= x"0000000000000005";
   w_reg <= "10100";
   wait for 10ns;
   clk <= not clk;
   wait for 10ns;
   clk <= not clk;
   w_en <= '0';
   r_reg1 <= "10011";
   r_reg2 <= "10100";
   wait for 10ns;
   clk <= not clk;
   wait for 10ns;
   clk <= not clk;
   w_en <= '1';
   w_data <= x"000000000000000F";
   w_reg <= "10101";
   wait for 10ns;
   clk <= not clk;
   wait for 10ns;
   clk <= not clk;
   w_en <= '0';
   r_reg1 <= "10101";
   r_reg2 <= "11000";
   wait for 10ns;       


   wait;
   end process;

end Behavioral;

Что приводит к следующему: RegisterFileTestBench

Кажется, иногда пишут, а иногда нет, и я не знаю, в чем разница между тем, когда это происходит икогда это не так.Похоже, что он всегда читает нормально.

Кажется, что между считыванием вновь записанных данных существует задержка в один такт, чего я не ожидал, но сейчас я не беспокоюсь.

1 Ответ

0 голосов
/ 14 декабря 2018

Ничего общего с вашим вопросом, просто предложение уменьшить количество строк: VHDL - это язык программирования высокого уровня .Он поддерживает множество функций, которые вы можете найти во многих более классических языках программирования.Вы можете использовать их для улучшения вашего кода.Пример:

-- File RegPackage.vhd
...
subtype word64 is std_logic_vector(63 downto 0);
type word64_array is array(natural range <>) of word64;
...

-- File register_file1.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
use work.RegPackage.all;

entity register_file1 is
    Port ( clk : in STD_LOGIC;
           reset : in STD_LOGIC;
           w_en : in STD_LOGIC;
           w_data : in word64;
           r_dataA : out word64_array(1 to 2);
           w_reg : in STD_LOGIC_VECTOR (4 downto 0);
           r_reg1 : in STD_LOGIC_VECTOR (4 downto 0);
           r_reg2 : in STD_LOGIC_VECTOR (4 downto 0);
           r_dataB : out word64_array(19 to 24));
end register_file1;

architecture Behavioral of register_file1 is
    signal reg_sel : STD_LOGIC_VECTOR (31 downto 0);
    signal w_sel: STD_LOGIC_VECTOR(31 downto 0);
    signal reg_data : word64_array(0 to 31);
 begin
    --These are signals for the test bench to track if they are being properly written to
    r_dataA <= reg_data (19 to 24);

    --mux for read dataB(1 to 2)
    r_dataB(1) <= reg_data(to_integer(unsigned(r_reg1)));
    r_dataB(2) <= reg_data(to_integer(unsigned(r_reg2)));

    decoder1 : decoder port map(reg_addr => w_reg, w => w_en, found => reg_sel);

    --write select signal. Takes the write enable (w_en) and the selected register from the decoder and uses that to determine which, if any, register is to be written to. Register 31 is never selected, because it is the zero register and cannot be written to.
    w_sel(30 downto 0) <= reg_sel(30 downto 0) and w_en;

    --Registers. I know that there is a way to generate these simpler with indexing, but we couldn't get it to work.
    g_register: for i in 0 to 31 generate
      register : newRegister port map( clk => clk, reset => reset, w_en => w_en, w_data => w_data , r_data => reg_data(i), sel => w_sel(i));
    end generate g_register;

end Behavioral;

Примечания:

  1. Если используемая вами версия VHDL еще не поддерживает vector and scalar, замените:

    w_sel(30 downto 0) <= reg_sel(30 downto 0) and w_en;
    

    по:

    g_w_sel: for i in 0 to 30 generate
      w_sel(i) <= reg_sel(i) and w_en;
    end generate g_w_sel;
    

    или по:

    process(reg_sel, w_en)
    begin
      for i in 30 downto 0 loop
        w_sel(i) <= reg_sel(i) and w_en;
      end loop;
    end process;
    

    Кстати, вы уверены, что не забыли индекс 31?

  2. А в случае, если ваш логический синтезатор жалуется на:

    r_dataB(1) <= reg_data(to_integer(unsigned(r_reg1)));
    r_dataB(2) <= reg_data(to_integer(unsigned(r_reg2)));
    

    , замените эти две строки на:

    process(reg_data, r_reg1, r_reg2)
    begin
      r_dataB <= (others => (others => '0'));
      for i in 0 to 31 loop
        if to_integer(unsigned(r_reg1)) = i then
          r_dataB(1) <= reg_data(i);
        end if;
        if to_integer(unsigned(r_reg2)) = i then
          r_dataB(2) <= reg_data(i);
        end if;
      end loop;
    end process;
    

    и рассмотрите возможность обновления до более новой версии вашего синтезатора или покупки другойone.

  3. Использование разрешенных типов STD_LOGIC и STD_LOGIC_VECTOR, когда вы не намерены использовать логику нескольких дисков (буферы в древовидном состоянии ...), является плохой идеей.Вам следует рассмотреть возможность использования неразрешенных типов STD_ULOGIC, STD_ULOGIC_VECTOR.Даже если многие профессионалы на самом деле не понимают разницу и всегда используют прежние типы ", потому что мы всегда так делали ".

...