soc/SoCController: Add separate fields for SoC and CPU resets.

As discussed in #909, in some specific cases, it can be interesting to be able
to keep the CPU in reset while the rest of the SoC is still operating (ex the
peripherals/bridges).

With theses changes, the old behaviour is preserved to do a full SoC Reset (at
the exception that writing a 1 is now mandatory) and a separate field specific
to the CPU reset is added.

The SoC Reset is a pulse (otherwise the system would be stuck in Reset) while
the CPU Reset is based on the register value (so can be pulse or hold).
This commit is contained in:
Florent Kermarrec 2021-05-17 11:42:01 +02:00
parent 06f4658174
commit d0e8de077c
2 changed files with 17 additions and 10 deletions

View File

@ -8,6 +8,7 @@
[> Added Features [> Added Features
----------------- -----------------
- cpu/vexriscv: Add CFU support. - cpu/vexriscv: Add CFU support.
- soc/controller: Add separate SoC/CPU reset fields.
[> API changes/Deprecation [> API changes/Deprecation
-------------------------- --------------------------

View File

@ -658,7 +658,10 @@ class SoCIRQHandler(SoCLocHandler):
class SoCController(Module, AutoCSR): class SoCController(Module, AutoCSR):
def __init__(self, with_reset=True, with_scratch=True, with_errors=True): def __init__(self, with_reset=True, with_scratch=True, with_errors=True):
if with_reset: if with_reset:
self._reset = CSRStorage(1, description="""Any write to this register will reset the SoC.""") self._reset = CSRStorage(fields=[
CSRField("soc_rst", size=1, offset=0, pulse=True, description="""Write `1` to this register to reset the full SoC (Pulse Reset)"""),
CSRField("cpu_rst", size=1, offset=1, description="""Write `1` to this register to reset the CPU(s) of the SoC (Hold Reset)"""),
])
if with_scratch: if with_scratch:
self._scratch = CSRStorage(32, reset=0x12345678, description=""" self._scratch = CSRStorage(32, reset=0x12345678, description="""
Use this register as a scratch space to verify that software read/write accesses Use this register as a scratch space to verify that software read/write accesses
@ -671,8 +674,8 @@ class SoCController(Module, AutoCSR):
# Reset # Reset
if with_reset: if with_reset:
self.reset = Signal() self.soc_rst = self._reset.fields.soc_rst
self.comb += self.reset.eq(self._reset.re) self.cpu_rst = self._reset.fields.cpu_rst
# Errors # Errors
if with_errors: if with_errors:
@ -918,8 +921,11 @@ class SoC(Module):
# Connect SoCController's reset to CPU reset. # Connect SoCController's reset to CPU reset.
if hasattr(self, "ctrl"): if hasattr(self, "ctrl"):
if hasattr(self.ctrl, "reset"): self.comb += self.cpu.reset.eq(
self.comb += self.cpu.reset.eq(self.ctrl.reset) # Reset the CPU on...
getattr(self.ctrl, "soc_rst", 0) | # Full SoC Reset command...
getattr(self.ctrl, "cpu_rst", 0) # or on CPU Reset command.
)
self.add_config("CPU_RESET_ADDR", reset_address) self.add_config("CPU_RESET_ADDR", reset_address)
# Add CPU's SoC components (if any). # Add CPU's SoC components (if any).
@ -952,11 +958,11 @@ class SoC(Module):
}[self.bus.standard] }[self.bus.standard]
# SoC Reset -------------------------------------------------------------------------------- # SoC Reset --------------------------------------------------------------------------------
# Connect SoCController's reset to CRG's reset if presents. # Connect soc_rst to CRG's rst if presents.
if hasattr(self, "ctrl") and hasattr(self, "crg"): if hasattr(self, "ctrl") and hasattr(self, "crg"):
if hasattr(self.ctrl, "_reset") and hasattr(self.crg, "rst"): crg_rst = getattr(self.crg, "rst", None)
if isinstance(self.crg.rst, Signal): if isinstance(crg_rst, Signal):
self.comb += self.crg.rst.eq(self.ctrl._reset.re) self.comb += crg_rst.eq(getattr(self.ctrl, "soc_rst", 0))
# SoC CSR bridge --------------------------------------------------------------------------- # SoC CSR bridge ---------------------------------------------------------------------------
# FIXME: for now, use registered CSR bridge when SDRAM is present; find the best compromise. # FIXME: for now, use registered CSR bridge when SDRAM is present; find the best compromise.