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