soc/core: Add reset latches
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 15 May 2020 03:30:01 +0000 (13:30 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sat, 16 May 2020 02:42:58 +0000 (12:42 +1000)
This adds one-cycle latches to the various resets out of the soc and
into the various core modules. It *seems* to help vivado P&R a bit
and has shown to avoid timing violations under some circumstances.

Interestingly those resets never seem to appear in the bad timing
path. It looks like those long resets simply impose placement
constraints that Vivado satisfies at the expense of timing elsewhere.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
core.vhdl
soc.vhdl

index 9895dc8df8442366695fb5b2d364167267fd4b62..0664c7334167b7f71707a7082e252e17cda0bccd 100644 (file)
--- a/core.vhdl
+++ b/core.vhdl
@@ -91,7 +91,19 @@ architecture behave of core is
     signal complete: std_ulogic;
     signal terminate: std_ulogic;
     signal core_rst: std_ulogic;
-    signal icache_rst: std_ulogic;
+    signal icache_inv: std_ulogic;
+
+    -- Delayed/Latched resets and alt_reset
+    signal rst_fetch1  : std_ulogic := '1';
+    signal rst_fetch2  : std_ulogic := '1';
+    signal rst_icache  : std_ulogic := '1';
+    signal rst_dcache  : std_ulogic := '1';
+    signal rst_dec1    : std_ulogic := '1';
+    signal rst_dec2    : std_ulogic := '1';
+    signal rst_ex1     : std_ulogic := '1';
+    signal rst_ls1     : std_ulogic := '1';
+    signal rst_dbg     : std_ulogic := '1';
+    signal alt_reset_d : std_ulogic;
 
     signal sim_cr_dump: std_ulogic;
 
@@ -128,6 +140,22 @@ begin
 
     core_rst <= dbg_core_rst or rst;
 
+    resets: process(clk)
+    begin
+        if rising_edge(clk) then
+            rst_fetch1  <= core_rst;
+            rst_fetch2  <= core_rst;
+            rst_icache  <= core_rst or dbg_icache_rst or ex1_icache_inval;
+            rst_dcache  <= core_rst;
+            rst_dec1    <= core_rst;
+            rst_dec2    <= core_rst;
+            rst_ex1     <= core_rst;
+            rst_ls1     <= core_rst;
+            rst_dbg     <= rst;
+            alt_reset_d <= alt_reset;
+        end if;
+    end process;
+
     fetch1_0: entity work.fetch1
         generic map (
             RESET_ADDRESS => (others => '0'),
@@ -135,8 +163,8 @@ begin
             )
         port map (
             clk => clk,
-            rst => core_rst,
-           alt_reset_in => alt_reset,
+            rst => rst_fetch1,
+           alt_reset_in => alt_reset_d,
             stall_in => fetch1_stall_in,
             flush_in => flush,
            stop_in => dbg_core_stop,
@@ -155,7 +183,7 @@ begin
             )
         port map(
             clk => clk,
-            rst => icache_rst,
+            rst => rst_icache,
             i_in => fetch1_to_icache,
             i_out => icache_to_fetch2,
             flush_in => flush,
@@ -164,12 +192,10 @@ begin
             wishbone_in => wishbone_insn_in
             );
 
-    icache_rst <= rst or dbg_icache_rst or ex1_icache_inval;
-
     fetch2_0: entity work.fetch2
         port map (
             clk => clk,
-            rst => core_rst,
+            rst => rst_fetch2,
             stall_in => fetch2_stall_in,
             flush_in => flush,
             i_in => icache_to_fetch2,
@@ -181,7 +207,7 @@ begin
     decode1_0: entity work.decode1
         port map (
             clk => clk,
-            rst => core_rst,
+            rst => rst_dec1,
             stall_in => decode1_stall_in,
             flush_in => flush,
             f_in => fetch2_to_decode1,
@@ -196,7 +222,7 @@ begin
             )
         port map (
             clk => clk,
-            rst => core_rst,
+            rst => rst_dec2,
            stall_in => decode2_stall_in,
             stall_out => decode2_stall_out,
             flush_in => flush,
@@ -242,7 +268,7 @@ begin
             )
         port map (
             clk => clk,
-            rst => core_rst,
+            rst => rst_ex1,
             flush_out => flush,
            stall_out => ex1_stall_out,
             e_in => decode2_to_execute1,
@@ -257,7 +283,7 @@ begin
     loadstore1_0: entity work.loadstore1
         port map (
             clk => clk,
-            rst => core_rst,
+            rst => rst_ls1,
             l_in => execute1_to_loadstore1,
             l_out => loadstore1_to_writeback,
             d_out => loadstore1_to_dcache,
@@ -274,7 +300,7 @@ begin
             )
         port map (
             clk => clk,
-           rst => core_rst,
+           rst => rst_dcache,
             d_in => loadstore1_to_dcache,
             d_out => dcache_to_loadstore1,
             stall_out => dcache_stall_out,
@@ -295,7 +321,7 @@ begin
     debug_0: entity work.core_debug
        port map (
            clk => clk,
-           rst => rst,
+           rst => rst_dbg,
            dmi_addr => dmi_addr,
            dmi_din => dmi_din,
            dmi_dout => dmi_dout,
index 212314bf56fcc7f038c43bfbbf4d85b22de9e9c6..e9e947075593225baeff282cccf640316c66fb92 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -109,8 +109,33 @@ architecture behaviour of soc is
     signal dmi_core_dout  : std_ulogic_vector(63 downto 0);
     signal dmi_core_req   : std_ulogic;
     signal dmi_core_ack   : std_ulogic;
+
+    -- Delayed/latched resets and alt_reset
+    signal rst_core    : std_ulogic := '1';
+    signal rst_uart    : std_ulogic := '1';
+    signal rst_xics    : std_ulogic := '1';
+    signal rst_bram    : std_ulogic := '1';
+    signal rst_dtm     : std_ulogic := '1';
+    signal rst_wbar    : std_ulogic := '1';
+    signal rst_wbdb    : std_ulogic := '1';
+    signal alt_reset_d : std_ulogic;
+
 begin
 
+    resets: process(system_clk)
+    begin
+        if rising_edge(system_clk) then
+            rst_core    <= rst or core_reset;
+            rst_uart    <= rst;
+            rst_xics    <= rst;
+            rst_bram    <= rst;
+            rst_dtm     <= rst;
+            rst_wbar    <= rst;
+            rst_wbdb    <= rst;
+            alt_reset_d <= alt_reset;
+        end if;
+    end process;
+
     -- Processor core
     processor: entity work.core
        generic map(
@@ -120,8 +145,8 @@ begin
            )
        port map(
            clk => system_clk,
-           rst => rst or core_reset,
-           alt_reset => alt_reset,
+           rst => rst_core,
+           alt_reset => alt_reset_d,
            wishbone_insn_in => wishbone_icore_in,
            wishbone_insn_out => wishbone_icore_out,
            wishbone_data_in => wishbone_dcore_in,
@@ -147,7 +172,8 @@ begin
            NUM_MASTERS => NUM_WB_MASTERS
            )
        port map(
-           clk => system_clk, rst => rst,
+           clk => system_clk,
+            rst => rst_wbar,
            wb_masters_in => wb_masters_out,
            wb_masters_out => wb_masters_in,
            wb_slave_out => wb_master_out,
@@ -271,7 +297,7 @@ begin
            )
        port map(
            clk => system_clk,
-           reset => rst,
+           reset => rst_uart,
            txd => uart0_txd,
            rxd => uart0_rxd,
            irq => int_level_in(0),
@@ -292,7 +318,7 @@ begin
            )
        port map(
            clk => system_clk,
-           rst => rst,
+           rst => rst_xics,
            wb_in => wb_xics0_in,
            wb_out => wb_xics0_out,
            int_level_in => int_level_in,
@@ -307,7 +333,7 @@ begin
            )
        port map(
            clk => system_clk,
-           rst => rst,
+           rst => rst_bram,
            wishbone_in => wb_bram_in,
            wishbone_out => wb_bram_out
            );
@@ -320,7 +346,7 @@ begin
            )
        port map(
            sys_clk     => system_clk,
-           sys_reset   => rst,
+           sys_reset   => rst_dtm,
            dmi_addr    => dmi_addr,
            dmi_din     => dmi_din,
            dmi_dout    => dmi_dout,
@@ -378,7 +404,8 @@ begin
 
     -- Wishbone debug master (TODO: Add a DMI address decoder)
     wishbone_debug: entity work.wishbone_debug_master
-       port map(clk => system_clk, rst => rst,
+       port map(clk => system_clk,
+                 rst => rst_wbdb,
                 dmi_addr => dmi_addr(1 downto 0),
                 dmi_dout => dmi_wb_dout,
                 dmi_din => dmi_dout,