decode1: Add a stash buffer to the output
authorPaul Mackerras <paulus@ozlabs.org>
Sun, 14 Jun 2020 23:28:03 +0000 (09:28 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Sun, 14 Jun 2020 23:28:03 +0000 (09:28 +1000)
This means that the busy signal from execute1 (which can be driven
combinatorially from mmu or dcache) now stops at decode1 and doesn't
go on to icache or fetch1.  This helps with timing.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
core.vhdl
decode1.vhdl

index 13f3ce70fdc27e4a6de7b96de05cdba803e0d813..019660cbb8795f8538e4de9eb6fd9a6d71293bcd 100644 (file)
--- a/core.vhdl
+++ b/core.vhdl
@@ -82,6 +82,7 @@ architecture behave of core is
     signal icache_stall_out : std_ulogic;
     signal icache_stall_in : std_ulogic;
     signal decode1_stall_in : std_ulogic;
+    signal decode1_busy     : std_ulogic;
     signal decode2_busy_in : std_ulogic;
     signal decode2_stall_out : std_ulogic;
     signal ex1_icache_inval: std_ulogic;
@@ -188,7 +189,7 @@ begin
             log_out => log_data(42 downto 0)
             );
 
-    fetch1_stall_in <= icache_stall_out or decode2_stall_out;
+    fetch1_stall_in <= icache_stall_out or decode1_busy;
 
     icache_0: entity work.icache
         generic map(
@@ -212,7 +213,7 @@ begin
             log_out => log_data(96 downto 43)
             );
 
-    icache_stall_in <= decode2_stall_out;
+    icache_stall_in <= decode1_busy;
 
     decode1_0: entity work.decode1
         port map (
@@ -220,6 +221,7 @@ begin
             rst => rst_dec1,
             stall_in => decode1_stall_in,
             flush_in => flush,
+            busy_out => decode1_busy,
             f_in => icache_to_decode1,
             d_out => decode1_to_decode2,
             log_out => log_data(109 downto 97)
index ae3e97084d294df9a277161a67a47162ea0e0661..21596f60c1f242677de58862ba4f9803e8c80a44 100644 (file)
@@ -13,6 +13,7 @@ entity decode1 is
 
         stall_in : in std_ulogic;
         flush_in : in std_ulogic;
+        busy_out : out std_ulogic;
 
         f_in     : in IcacheToDecode1Type;
         d_out    : out Decode1ToDecode2Type;
@@ -22,6 +23,7 @@ end entity decode1;
 
 architecture behaviour of decode1 is
     signal r, rin : Decode1ToDecode2Type;
+    signal s      : Decode1ToDecode2Type;
 
     subtype major_opcode_t is unsigned(5 downto 0);
     type major_rom_array_t is array(0 to 63) of decode_rom_t;
@@ -359,12 +361,27 @@ begin
     decode1_0: process(clk)
     begin
         if rising_edge(clk) then
-            -- Output state remains unchanged on stall, unless we are flushing
-            if rst = '1' or flush_in = '1' or stall_in = '0' then
-                r <= rin;
+            if rst = '1' then
+                r <= Decode1ToDecode2Init;
+                s <= Decode1ToDecode2Init;
+            elsif flush_in = '1' then
+                r.valid <= '0';
+                s.valid <= '0';
+            elsif s.valid = '1' then
+                if stall_in = '0' then
+                    r <= s;
+                    s.valid <= '0';
+                end if;
+            else
+                s <= rin;
+                s.valid <= rin.valid and r.valid and stall_in;
+                if r.valid = '0' or stall_in = '0' then
+                    r <= rin;
+                end if;
             end if;
         end if;
     end process;
+    busy_out <= s.valid;
 
     decode1_1: process(all)
         variable v : Decode1ToDecode2Type;
@@ -472,14 +489,6 @@ begin
             end if;
         end if;
 
-        if flush_in = '1' then
-            v.valid := '0';
-        end if;
-
-        if rst = '1' then
-            v := Decode1ToDecode2Init;
-        end if;
-
         -- Update registers
         rin <= v;