From acbdd396a5fedbe160bcb1271b37e941f3eaa45c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 15 May 2020 13:30:01 +1000 Subject: [PATCH] soc/core: Add reset latches 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 --- core.vhdl | 52 +++++++++++++++++++++++++++++++++++++++------------- soc.vhdl | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 21 deletions(-) diff --git a/core.vhdl b/core.vhdl index 9895dc8..0664c73 100644 --- 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, diff --git a/soc.vhdl b/soc.vhdl index 212314b..e9e9470 100644 --- 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,