From 49b6fa14ecc33319e64d05b3774cd49d694413e6 Mon Sep 17 00:00:00 2001 From: Retro <yann.roberge@polymtl.ca> Date: Mon, 22 Nov 2021 17:09:08 -0500 Subject: [PATCH] =?UTF-8?q?Premi=C3=A8re=20mouture=20du=20register=20file.?= =?UTF-8?q?=20Il=20donne=20du=20nimp=20en=20simulation=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/riscv_rf.vhd | 82 +++++++++++++++++++++++++++++++++++++++++ sources/riscv_rf_tb.vhd | 19 +++++----- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/sources/riscv_rf.vhd b/sources/riscv_rf.vhd index 65bed80..05218ae 100644 --- a/sources/riscv_rf.vhd +++ b/sources/riscv_rf.vhd @@ -20,12 +20,94 @@ use work.riscv_pkg.all; entity riscv_rf is port ( + i_clk : in std_logic; + i_rstn : in std_logic; + i_we : in std_logic; + + i_addr_ra : in std_logic_vector(REG_WIDTH-1 downto 0); + o_data_ra : out std_logic_vector(XLEN-1 downto 0); + + i_addr_rb : in std_logic_vector(REG_WIDTH-1 downto 0); + o_data_rb : out std_logic_vector(XLEN-1 downto 0); + + i_addr_w : in std_logic_vector(REG_WIDTH-1 downto 0); + i_data_w : in std_logic_vector(XLEN-1 downto 0)); end entity riscv_rf; architecture beh of riscv_rf is + -- Type des signaux du banc de registres + type reg_file_t is array (0 to 2**(REG_WIDTH)-1) of std_logic_vector(XLEN-1 downto 0); + signal reg_file : reg_file_t; + -- Registres tampons + signal write_buffer : std_logic_vector(XLEN-1 downto 0); + signal read_buffer_a : std_logic_vector(XLEN-1 downto 0); + signal read_buffer_b : std_logic_vector(XLEN-1 downto 0); + + -- Signaux internes + signal reg_file_wr_en: std_logic; + signal read_value_a : std_logic_vector(XLEN-1 downto 0); + signal read_value_b : std_logic_vector(XLEN-1 downto 0); + + constant ALL_ZEROES : std_logic_vector(REG_WIDTH-1 downto 0) := (others => '0'); begin + -- Générer le signal write enable si l'adresse est pas 0 + reg_file_wr_en <= '1' when ((i_we = '1') and (i_addr_w /= ALL_ZEROES)) else '0'; + + -- Écrire le registre pointé + write_reg_file: + process (i_clk, reg_file_wr_en) is + begin + if reg_file_wr_en = '1' then + if rising_edge(i_clk) then + if i_rstn = '1' then + reg_file(to_integer(unsigned(i_addr_w))) <= i_data_w; + else + reg_file <= (others => (others => '0')); + end if; + end if; + else + reg_file <= reg_file; + end if; + end process write_reg_file; + + -- Sélectionner les sorties des registres à lire + read_value_a <= reg_file(to_integer(unsigned(i_addr_ra))); + read_value_b <= reg_file(to_integer(unsigned(i_addr_rb))); + + -- Transférer la valeur écrite vers un tampon + transfer_write_buffers: + process (i_clk) is + begin + if rising_edge(i_clk) then + if i_rstn = '1' then + write_buffer <= i_data_w; + else + write_buffer <= (others => '0'); + end if; + end if; + end process transfer_write_buffers; + + -- Transférer le contenu des registres lus vers les registres tampons + transfer_read_buffers: + process (i_clk) is + begin + if rising_edge(i_clk) then + if i_rstn = '1' then + read_buffer_a <= read_value_a; + read_buffer_b <= read_value_b; + else + read_buffer_a <= (others => '0'); + read_buffer_b <= (others => '0'); + end if; + end if; + end process transfer_read_buffers; + + -- Si on lit et écrit le même registre en même temps, retourner la valeur écrite + -- Sinon retouner la valeur lue + o_data_ra <= write_buffer when (i_addr_w = i_addr_ra) else read_buffer_a; + o_data_rb <= write_buffer when (i_addr_w = i_addr_rb) else read_buffer_b; end architecture beh; diff --git a/sources/riscv_rf_tb.vhd b/sources/riscv_rf_tb.vhd index 5fe1d3f..da23323 100644 --- a/sources/riscv_rf_tb.vhd +++ b/sources/riscv_rf_tb.vhd @@ -108,7 +108,6 @@ architecture tb of riscv_rf_tb is end procedure test_vector; - constant PERIOD : time := 10 ns; begin @@ -143,19 +142,19 @@ begin -- Tests des cas représentatif report "BEGIN SIMULATION"; rstn <= '0'; - addr_ra <= (others => '0'); - addr_rb <= (others => '0'); + addr_ra <= (others => '-'); + addr_rb <= (others => '-'); - addr_w <= (others => '0'); - data_w <= (others => '0'); - we <= '0'; + addr_w <= (others => '-'); + data_w <= (others => '-'); + we <= '-'; wait for PERIOD; rstn <= '1'; wait for 2*PERIOD; -- Write all registers report "Write all registers including 0x00"; - for i in 1 to 2**(REG_WIDTH-1)-1 loop + for i in 1 to 2**(REG_WIDTH)-1 loop write_reg( rstn => rstn, addr_ra => addr_ra, @@ -198,7 +197,7 @@ begin period => PERIOD ); - for i in 1 to 2**(REG_WIDTH-1)-2 loop + for i in 1 to 2**(REG_WIDTH)-2 loop test_vector( rstn => rstn, addr_ra => addr_ra, @@ -227,7 +226,7 @@ begin -- Read & Write all registers at the same time -- Note: Can't write into 0 report "Read & Write at the same time"; - for i in 1 to 2**(REG_WIDTH-1)-2 loop + for i in 1 to 2**(REG_WIDTH)-2 loop test_vector( rstn => rstn, addr_ra => addr_ra, @@ -262,7 +261,7 @@ begin -- Read all registers report "Verify reset worked"; - for i in 0 to 2**(REG_WIDTH-1)-2 loop + for i in 0 to 2**(REG_WIDTH)-2 loop test_vector( rstn => rstn, addr_ra => addr_ra, -- GitLab