soc: Expose sw_soc_reset for syscon reset
authorMatt Johnston <matt@codeconstruct.com.au>
Thu, 29 Sep 2022 04:20:40 +0000 (12:20 +0800)
committerMatt Johnston <matt@codeconstruct.com.au>
Mon, 31 Oct 2022 06:41:15 +0000 (14:41 +0800)
The soc itself will be reset when a syscon soc reset is triggered.

Separately, top- board files can use the sw_soc_rst signal
if they need to reset other peripherals

Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
soc.vhdl

index 3282ca9d90d58be4b313df8dfc4f5849819618d3..4c756ca2f543f2df0eb3c346366481cbbc7cb80f 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -51,6 +51,16 @@ use work.wishbone_types.all;
 --   3  : SD card
 --   4  : GPIO
 
+-- Resets:
+-- The soc can be reset externally by its parent top- entity (via rst port),
+-- or can be reset by software via syscon. In the software reset case
+-- the reset signal will also be exposed via sw_soc_reset port - toplevels
+-- can use that to reset other peripherals if required.
+--
+-- When using DRAM the alt_reset signal will be high after soc reset, to
+-- run sdram init routines. After startup software will switch alt_reset to
+-- low, so a core reset will use the non-alt reset address.
+
 entity soc is
     generic (
        MEMORY_SIZE        : natural;
@@ -127,12 +137,18 @@ entity soc is
         -- GPIO signals
         gpio_out : out std_ulogic_vector(NGPIO - 1 downto 0);
         gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0);
-        gpio_in  : in  std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0')
+        gpio_in  : in  std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0');
+
+        -- SOC reset trigger from syscon
+        sw_soc_reset : out std_ulogic
        );
 end entity soc;
 
 architecture behaviour of soc is
 
+    -- internal reset
+    signal soc_reset : std_ulogic;
+
     -- Wishbone master signals:
     signal wishbone_dcore_in  : wishbone_slave_out;
     signal wishbone_dcore_out : wishbone_master_out;
@@ -310,18 +326,21 @@ architecture behaviour of soc is
 
 begin
 
+    -- either external reset, or from syscon
+    soc_reset <= rst or sw_soc_reset;
+
     resets: process(system_clk)
     begin
         if rising_edge(system_clk) then
-            rst_core    <= rst or do_core_reset;
-            rst_uart    <= rst;
-            rst_spi     <= rst;
-            rst_xics    <= rst;
-            rst_gpio    <= rst;
-            rst_bram    <= rst;
-            rst_dtm     <= rst;
-            rst_wbar    <= rst;
-            rst_wbdb    <= rst;
+            rst_core    <= soc_reset or do_core_reset;
+            rst_uart    <= soc_reset;
+            rst_spi     <= soc_reset;
+            rst_xics    <= soc_reset;
+            rst_gpio    <= soc_reset;
+            rst_bram    <= soc_reset;
+            rst_dtm     <= soc_reset;
+            rst_wbar    <= soc_reset;
+            rst_wbdb    <= soc_reset;
             alt_reset_d <= alt_reset;
         end if;
     end process;
@@ -478,7 +497,7 @@ begin
         if rising_edge(system_clk) then
             do_cyc := '0';
             end_cyc := '0';
-            if (rst) then
+            if (soc_reset) then
                 state := IDLE;
                 wb_io_out.ack <= '0';
                 wb_io_out.stall <= '0';
@@ -761,12 +780,12 @@ begin
        )
        port map(
            clk => system_clk,
-           rst => rst,
+           rst => soc_reset,
            wishbone_in => wb_syscon_in,
            wishbone_out => wb_syscon_out,
            dram_at_0 => dram_at_0,
            core_reset => do_core_reset,
-           soc_reset => open, -- XXX TODO
+           soc_reset => sw_soc_reset,
            alt_reset => alt_reset
            );
 
@@ -1063,7 +1082,7 @@ begin
     wb_x_state: process(system_clk)
     begin
         if rising_edge(system_clk) then
-            if not rst then
+            if not soc_reset then
                 -- Wishbone arbiter
                 assert not(is_x(wb_masters_out(0).cyc)) and not(is_x(wb_masters_out(0).stb)) severity failure;
                 assert not(is_x(wb_masters_out(1).cyc)) and not(is_x(wb_masters_out(1).stb)) severity failure;