Correctly finalize picorv32 module
I think LiteX's SoCIORegions are reserved regions. Non-cached regions are then placed inside these reserved regions. Each module also has a "do_finalize" method that runs at code generation.
This commit is contained in:
parent
9f76e03028
commit
c3980f64da
|
@ -47,8 +47,9 @@ hardware-shell:
|
||||||
hardware-get:
|
hardware-get:
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/build/digilent_arty/gateware/digilent_arty.bit ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/build/digilent_arty/gateware/digilent_arty.bit ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/arty.dtb ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/arty.dtb ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/mmio.py ../boot/
|
# docker cp upsilon-hardware:/home/user/upsilon/gateware/mmio.py ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/csr.json ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/csr.json ../boot/
|
||||||
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/picorv32.json ../boot/
|
||||||
hardware-clean:
|
hardware-clean:
|
||||||
-docker container stop upsilon-hardware
|
-docker container stop upsilon-hardware
|
||||||
-docker container rm upsilon-hardware
|
-docker container rm upsilon-hardware
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
DEVICETREE_GEN_DIR=.
|
DEVICETREE_GEN_DIR=.
|
||||||
|
|
||||||
all: rtl_codegen build/digilent_arty/digilent_arty.bit arty.dtb mmio.py
|
all: rtl_codegen build/digilent_arty/digilent_arty.bit arty.dtb# mmio.py
|
||||||
|
|
||||||
rtl_codegen:
|
rtl_codegen:
|
||||||
cd rtl && make
|
cd rtl && make
|
||||||
|
|
|
@ -193,6 +193,7 @@ class SPIMaster(Module):
|
||||||
):
|
):
|
||||||
|
|
||||||
self.bus = Interface(data_width = 32, address_width=32, addressing="word")
|
self.bus = Interface(data_width = 32, address_width=32, addressing="word")
|
||||||
|
self.region = SoCIORegion(size=0x10, cached=False)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.bus.cti.eq(0),
|
self.bus.cti.eq(0),
|
||||||
self.bus.bte.eq(0),
|
self.bus.bte.eq(0),
|
||||||
|
@ -238,7 +239,7 @@ class ControlLoopParameters(Module, AutoCSR):
|
||||||
self.zpos = CSRStatus(32, description='Measured Z position')
|
self.zpos = CSRStatus(32, description='Measured Z position')
|
||||||
|
|
||||||
self.bus = Interface(data_width = 32, address_width = 32, addressing="word")
|
self.bus = Interface(data_width = 32, address_width = 32, addressing="word")
|
||||||
self.region = SoCIORegion(size=minbits(0x14), cached=False)
|
self.region = SoCRegion(size=minbits(0x14), cached=False)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.bus.cti.eq(0),
|
self.bus.cti.eq(0),
|
||||||
self.bus.bte.eq(0),
|
self.bus.bte.eq(0),
|
||||||
|
@ -271,15 +272,17 @@ class BRAM(Module):
|
||||||
""" A BRAM (block ram) is a memory store that is completely separate from
|
""" A BRAM (block ram) is a memory store that is completely separate from
|
||||||
the system RAM. They are much smaller.
|
the system RAM. They are much smaller.
|
||||||
"""
|
"""
|
||||||
def __init__(self, addr_mask):
|
def __init__(self, addr_mask, origin=None):
|
||||||
"""
|
"""
|
||||||
:param addr_mask: Mask which defines the amount of bytes accessable
|
:param addr_mask: Mask which defines the amount of bytes accessable
|
||||||
by the BRAM.
|
by the BRAM.
|
||||||
|
:param origin: Origin of the BRAM module region. This is seen by the
|
||||||
|
subordinate master, not the usual master.
|
||||||
"""
|
"""
|
||||||
self.bus = Interface(data_width=32, address_width=32, addressing="byte")
|
self.bus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||||
|
|
||||||
# Non-IO (i.e. MMIO) regions need to be cached
|
# Non-IO (i.e. MMIO) regions need to be cached
|
||||||
self.region = SoCRegion(size=addr_mask+1, cached=True)
|
self.region = SoCRegion(origin=origin, size=addr_mask+1, cached=True)
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.bus.cti.eq(0),
|
self.bus.cti.eq(0),
|
||||||
|
@ -301,15 +304,16 @@ class BRAM(Module):
|
||||||
class PicoRV32(Module, AutoCSR):
|
class PicoRV32(Module, AutoCSR):
|
||||||
def __init__(self, bramwid=0x1000):
|
def __init__(self, bramwid=0x1000):
|
||||||
self.submodules.params = params = ControlLoopParameters()
|
self.submodules.params = params = ControlLoopParameters()
|
||||||
self.submodules.bram = self.bram = bram = BRAM(bramwid-1)
|
self.submodules.bram = self.bram = bram = BRAM(bramwid-1, origin=0x10000)
|
||||||
self.submodules.bram_iface = self.bram_iface = bram_iface = PreemptiveInterface(2, bram)
|
self.submodules.bram_iface = self.bram_iface = bram_iface = PreemptiveInterface(2, bram)
|
||||||
|
|
||||||
|
# This is the PicoRV32 master
|
||||||
self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||||
|
|
||||||
self.resetpin = CSRStorage(1, name="picorv32_reset", description="PicoRV32 reset")
|
self.resetpin = CSRStorage(1, name="picorv32_reset", description="PicoRV32 reset")
|
||||||
self.trap = CSRStatus(1, name="picorv32_trap", description="Trap bit")
|
self.trap = CSRStatus(1, name="picorv32_trap", description="Trap bit")
|
||||||
|
|
||||||
ic = SoCBusHandler(
|
self.ic = ic = SoCBusHandler(
|
||||||
standard="wishbone",
|
standard="wishbone",
|
||||||
data_width=32,
|
data_width=32,
|
||||||
address_width=32,
|
address_width=32,
|
||||||
|
@ -318,18 +322,25 @@ class PicoRV32(Module, AutoCSR):
|
||||||
interconnect="shared",
|
interconnect="shared",
|
||||||
interconnect_register=True,
|
interconnect_register=True,
|
||||||
reserved_regions={
|
reserved_regions={
|
||||||
"picorv32_null_region": SoCRegion(origin=0,size=0xFFFF, mode="ro", cached=True, decode=False)
|
"picorv32_null_region": SoCRegion(origin=0,size=0x10000, mode="ro", cached=True),
|
||||||
|
"picorv32_io": SoCIORegion(origin=0x100000, size=0x100, mode="rw", cached=False),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ic.add_slave("picorv32_params", params.bus, params.region)
|
|
||||||
ic.add_slave("picorv32_bram", bram_iface.buses[1], bram.region)
|
ic.add_slave("picorv32_bram", bram_iface.buses[1], bram.region)
|
||||||
|
ic.add_slave("picorv32_params", params.bus, params.region)
|
||||||
ic.add_master("picorv32_master", self.masterbus)
|
ic.add_master("picorv32_master", self.masterbus)
|
||||||
|
|
||||||
|
# NOTE: need to compile to these extact instructions
|
||||||
self.specials += Instance("picorv32_wb",
|
self.specials += Instance("picorv32_wb",
|
||||||
|
p_COMPRESSED_ISA = 1,
|
||||||
|
p_ENABLE_MUL = 1,
|
||||||
|
p_PROGADDR_RESET=0x10000,
|
||||||
|
p_PROGADDR_IRQ=0x100010,
|
||||||
|
p_REGS_INIT_ZERO = 1,
|
||||||
o_trap = self.trap.status,
|
o_trap = self.trap.status,
|
||||||
|
|
||||||
i_wb_rst_i = self.resetpin.storage,
|
i_wb_rst_i = ~self.resetpin.storage,
|
||||||
i_wb_clk_i = ClockSignal(),
|
i_wb_clk_i = ClockSignal(),
|
||||||
o_wbm_adr_o = self.masterbus.adr,
|
o_wbm_adr_o = self.masterbus.adr,
|
||||||
o_wbm_dat_o = self.masterbus.dat_r,
|
o_wbm_dat_o = self.masterbus.dat_r,
|
||||||
|
@ -356,6 +367,21 @@ class PicoRV32(Module, AutoCSR):
|
||||||
o_trace_data = Signal(36),
|
o_trace_data = Signal(36),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def do_finalize(self):
|
||||||
|
self.ic.finalize()
|
||||||
|
jsondata = {}
|
||||||
|
|
||||||
|
for region in self.ic.regions:
|
||||||
|
d = self.ic.regions[region]
|
||||||
|
jsondata[region] = {
|
||||||
|
"origin": d.origin,
|
||||||
|
"size": d.size,
|
||||||
|
}
|
||||||
|
|
||||||
|
with open('picorv32.json', 'w') as f:
|
||||||
|
import json
|
||||||
|
json.dump(jsondata, f)
|
||||||
|
|
||||||
# Clock and Reset Generator
|
# Clock and Reset Generator
|
||||||
# I don't know how this works, I only know that it does.
|
# I don't know how this works, I only know that it does.
|
||||||
class _CRG(Module):
|
class _CRG(Module):
|
||||||
|
@ -396,7 +422,8 @@ class UpsilonSoC(SoCCore):
|
||||||
|
|
||||||
def add_picorv32(self):
|
def add_picorv32(self):
|
||||||
self.submodules.picorv32 = pr = PicoRV32()
|
self.submodules.picorv32 = pr = PicoRV32()
|
||||||
self.bus.add_slave("picorv32_master_bram", pr.bram_iface.buses[0], pr.bram.region)
|
self.bus.add_slave("picorv32_master_bram", pr.bram_iface.buses[0],
|
||||||
|
SoCRegion(size=pr.bram.region.size, cached=True))
|
||||||
pr.finalize()
|
pr.finalize()
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
|
Loading…
Reference in New Issue