Add Tercel PHY reset synchronization
[microwatt.git] / register_file.vhdl
index 10f28a40a3fc8dea7b1dcbed3a97027df19f7aa8..32c84901e09a1bad8023a37859011342b113a3a1 100644 (file)
@@ -8,6 +8,7 @@ use work.common.all;
 entity register_file is
     generic (
         SIM : boolean := false;
+        HAS_FPU : boolean := true;
         -- Non-zero to enable log data collection
         LOG_LENGTH : natural := 0
         );
@@ -28,12 +29,12 @@ entity register_file is
         sim_dump      : in std_ulogic;
         sim_dump_done : out std_ulogic;
 
-        log_out       : out std_ulogic_vector(70 downto 0)
+        log_out       : out std_ulogic_vector(71 downto 0)
         );
 end entity register_file;
 
 architecture behaviour of register_file is
-    type regfile is array(0 to 63) of std_ulogic_vector(63 downto 0);
+    type regfile is array(0 to 127) of std_ulogic_vector(63 downto 0);
     signal registers : regfile := (others => (others => '0'));
     signal rd_port_b : std_ulogic_vector(63 downto 0);
     signal dbg_data : std_ulogic_vector(63 downto 0);
@@ -41,53 +42,73 @@ architecture behaviour of register_file is
 begin
     -- synchronous writes
     register_write_0: process(clk)
+        variable w_addr : gspr_index_t;
     begin
         if rising_edge(clk) then
             if w_in.write_enable = '1' then
-               if w_in.write_reg(5) = '0' then
-                   report "Writing GPR " & to_hstring(w_in.write_reg) & " " & to_hstring(w_in.write_data);
-               else
-                   report "Writing GSPR " & to_hstring(w_in.write_reg) & " " & to_hstring(w_in.write_data);
-               end if;
+                w_addr := w_in.write_reg;
+                if HAS_FPU and w_addr(6) = '1' then
+                    report "Writing FPR " & to_hstring(w_addr(4 downto 0)) & " " & to_hstring(w_in.write_data);
+                else
+                    w_addr(6) := '0';
+                    if w_addr(5) = '0' then
+                        report "Writing GPR " & to_hstring(w_addr) & " " & to_hstring(w_in.write_data);
+                    else
+                        report "Writing GSPR " & to_hstring(w_addr) & " " & to_hstring(w_in.write_data);
+                    end if;
+                end if;
                 assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
-                registers(to_integer(unsigned(w_in.write_reg))) <= w_in.write_data;
+                registers(to_integer(unsigned(w_addr))) <= w_in.write_data;
             end if;
         end if;
     end process register_write_0;
 
     -- asynchronous reads
     register_read_0: process(all)
-        variable b_addr : gspr_index_t;
+        variable a_addr, b_addr, c_addr : gspr_index_t;
+        variable w_addr : gspr_index_t;
     begin
+        a_addr := d_in.read1_reg;
+        b_addr := d_in.read2_reg;
+        c_addr := d_in.read3_reg;
+        w_addr := w_in.write_reg;
+        if not HAS_FPU then
+            -- Make it obvious that we only want 64 GSPRs for a no-FPU implementation
+            a_addr(6) := '0';
+            b_addr(6) := '0';
+            c_addr(6) := '0';
+            w_addr(6) := '0';
+        end if;
         if d_in.read1_enable = '1' then
-            report "Reading GPR " & to_hstring(d_in.read1_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read1_reg))));
+            report "Reading GPR " & to_hstring(a_addr) & " " & to_hstring(registers(to_integer(unsigned(a_addr))));
         end if;
         if d_in.read2_enable = '1' then
-            report "Reading GPR " & to_hstring(d_in.read2_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read2_reg))));
+            report "Reading GPR " & to_hstring(b_addr) & " " & to_hstring(registers(to_integer(unsigned(b_addr))));
         end if;
         if d_in.read3_enable = '1' then
-            report "Reading GPR " & to_hstring(d_in.read3_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read3_reg))));
+            report "Reading GPR " & to_hstring(c_addr) & " " & to_hstring(registers(to_integer(unsigned(c_addr))));
         end if;
-        d_out.read1_data <= registers(to_integer(unsigned(d_in.read1_reg)));
+        d_out.read1_data <= registers(to_integer(unsigned(a_addr)));
         -- B read port is multiplexed with reads from the debug circuitry
         if d_in.read2_enable = '0' and dbg_gpr_req = '1' and dbg_ack = '0' then
             b_addr := dbg_gpr_addr;
-        else
-            b_addr := d_in.read2_reg;
+            if not HAS_FPU then
+                b_addr(6) := '0';
+            end if;
         end if;
         rd_port_b <= registers(to_integer(unsigned(b_addr)));
         d_out.read2_data <= rd_port_b;
-        d_out.read3_data <= registers(to_integer(unsigned(gpr_to_gspr(d_in.read3_reg))));
+        d_out.read3_data <= registers(to_integer(unsigned(c_addr)));
 
         -- Forward any written data
         if w_in.write_enable = '1' then
-            if d_in.read1_reg = w_in.write_reg then
+            if a_addr = w_addr then
                 d_out.read1_data <= w_in.write_data;
             end if;
-            if d_in.read2_reg = w_in.write_reg then
+            if b_addr = w_addr then
                 d_out.read2_data <= w_in.write_data;
             end if;
-            if gpr_to_gspr(d_in.read3_reg) = w_in.write_reg then
+            if c_addr = w_addr then
                 d_out.read3_data <= w_in.write_data;
             end if;
         end if;
@@ -136,7 +157,7 @@ begin
     end generate;
 
     rf_log: if LOG_LENGTH > 0 generate
-        signal log_data : std_ulogic_vector(70 downto 0);
+        signal log_data : std_ulogic_vector(71 downto 0);
     begin
         reg_log: process(clk)
         begin