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:
parent
06f4658174
commit
d0e8de077c
3
CHANGES
3
CHANGES
|
@ -7,7 +7,8 @@
|
|||
|
||||
[> Added Features
|
||||
-----------------
|
||||
- cpu/vexriscv: Add CFU support.
|
||||
- cpu/vexriscv: Add CFU support.
|
||||
- soc/controller: Add separate SoC/CPU reset fields.
|
||||
|
||||
[> API changes/Deprecation
|
||||
--------------------------
|
||||
|
|
|
@ -658,7 +658,10 @@ class SoCIRQHandler(SoCLocHandler):
|
|||
class SoCController(Module, AutoCSR):
|
||||
def __init__(self, with_reset=True, with_scratch=True, with_errors=True):
|
||||
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:
|
||||
self._scratch = CSRStorage(32, reset=0x12345678, description="""
|
||||
Use this register as a scratch space to verify that software read/write accesses
|
||||
|
@ -671,8 +674,8 @@ class SoCController(Module, AutoCSR):
|
|||
|
||||
# Reset
|
||||
if with_reset:
|
||||
self.reset = Signal()
|
||||
self.comb += self.reset.eq(self._reset.re)
|
||||
self.soc_rst = self._reset.fields.soc_rst
|
||||
self.cpu_rst = self._reset.fields.cpu_rst
|
||||
|
||||
# Errors
|
||||
if with_errors:
|
||||
|
@ -918,8 +921,11 @@ class SoC(Module):
|
|||
|
||||
# Connect SoCController's reset to CPU reset.
|
||||
if hasattr(self, "ctrl"):
|
||||
if hasattr(self.ctrl, "reset"):
|
||||
self.comb += self.cpu.reset.eq(self.ctrl.reset)
|
||||
self.comb += self.cpu.reset.eq(
|
||||
# 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)
|
||||
|
||||
# Add CPU's SoC components (if any).
|
||||
|
@ -952,11 +958,11 @@ class SoC(Module):
|
|||
}[self.bus.standard]
|
||||
|
||||
# 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, "_reset") and hasattr(self.crg, "rst"):
|
||||
if isinstance(self.crg.rst, Signal):
|
||||
self.comb += self.crg.rst.eq(self.ctrl._reset.re)
|
||||
crg_rst = getattr(self.crg, "rst", None)
|
||||
if isinstance(crg_rst, Signal):
|
||||
self.comb += crg_rst.eq(getattr(self.ctrl, "soc_rst", 0))
|
||||
|
||||
# SoC CSR bridge ---------------------------------------------------------------------------
|
||||
# FIXME: for now, use registered CSR bridge when SDRAM is present; find the best compromise.
|
||||
|
|
Loading…
Reference in New Issue