gateware: fix dumb mistakes
Bus widths should now all be correct. (addresses and sizes in amaranth take into account the granularity selection, so granularity acts like two extra bits on the bus address line) Also don't ignore a warning about undriven resets. Turns out that can gate *everything* off in your design.
This commit is contained in:
parent
60b7b485da
commit
8d00e15835
@ -12,10 +12,10 @@ class LiteEth(Elaboratable, Interface):
|
|||||||
def __init__(self, eth_interface):
|
def __init__(self, eth_interface):
|
||||||
self.eth_interface = eth_interface
|
self.eth_interface = eth_interface
|
||||||
|
|
||||||
# Addr width is 13 bits to accomodate 0x1FFF, which is well p
|
# Addr width is 13 bits to accomodate 0x1FFF, which is well past what we care about
|
||||||
Interface.__init__(self, addr_width=13, data_width=32, granularity=8, features=["cti", "bte", "err"])
|
Interface.__init__(self, addr_width=15, data_width=32, granularity=8, features=["cti", "bte", "err"])
|
||||||
# TODO I need to understand the semantics here better
|
# TODO I need to understand the semantics here better
|
||||||
memory_map = MemoryMap(addr_width=15, data_width=8)
|
memory_map = MemoryMap(addr_width=17, data_width=8)
|
||||||
#memory_map.add_resource(self, name="LiteETH", size=0x2000)
|
#memory_map.add_resource(self, name="LiteETH", size=0x2000)
|
||||||
self.memory_map = memory_map
|
self.memory_map = memory_map
|
||||||
|
|
||||||
@ -25,7 +25,8 @@ class LiteEth(Elaboratable, Interface):
|
|||||||
# TODO this really shouldn't technically happen here, because we can elaborate one module multiple times,
|
# TODO this really shouldn't technically happen here, because we can elaborate one module multiple times,
|
||||||
# but since I use it once it isn't actually a problem.
|
# but since I use it once it isn't actually a problem.
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
platform.add_file("liteeth_core.v", open("liteeth/gateware/liteeth_core.v", 'r').read())
|
if platform is not None:
|
||||||
|
platform.add_file("liteeth_core.v", open("liteeth/gateware/liteeth_core.v", 'r').read())
|
||||||
|
|
||||||
m = Module()
|
m = Module()
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ class LiteEth(Elaboratable, Interface):
|
|||||||
core = Instance(
|
core = Instance(
|
||||||
"liteeth_core",
|
"liteeth_core",
|
||||||
i_sys_clock=ClockSignal(),
|
i_sys_clock=ClockSignal(),
|
||||||
|
i_sys_reset=Const(0),
|
||||||
|
|
||||||
# RGMII signals
|
# RGMII signals
|
||||||
o_rgmii_eth_clocks_tx=self.eth_interface.tx_clk,
|
o_rgmii_eth_clocks_tx=self.eth_interface.tx_clk,
|
||||||
@ -54,6 +56,7 @@ class LiteEth(Elaboratable, Interface):
|
|||||||
o_wishbone_dat_r=self.dat_r,
|
o_wishbone_dat_r=self.dat_r,
|
||||||
i_wishbone_sel=self.sel,
|
i_wishbone_sel=self.sel,
|
||||||
i_wishbone_cyc=self.cyc,
|
i_wishbone_cyc=self.cyc,
|
||||||
|
i_wishbone_stb=self.stb,
|
||||||
o_wishbone_ack=self.ack,
|
o_wishbone_ack=self.ack,
|
||||||
i_wishbone_we=self.we,
|
i_wishbone_we=self.we,
|
||||||
i_wishbone_cti=self.cti,
|
i_wishbone_cti=self.cti,
|
||||||
|
@ -5,8 +5,8 @@ from amaranth_soc.memory import *
|
|||||||
|
|
||||||
class LEDPeripheral(Elaboratable, Interface):
|
class LEDPeripheral(Elaboratable, Interface):
|
||||||
def __init__(self, led_signal):
|
def __init__(self, led_signal):
|
||||||
Interface.__init__(self, addr_width=1, data_width=32)
|
Interface.__init__(self, addr_width=1, data_width=32, granularity=8)
|
||||||
memory_map = MemoryMap(addr_width=1, data_width=32)
|
memory_map = MemoryMap(addr_width=3, data_width=8)
|
||||||
#memory_map.add_resource("my_led", name="led_peripheral", size=1)
|
#memory_map.add_resource("my_led", name="led_peripheral", size=1)
|
||||||
self.memory_map = memory_map
|
self.memory_map = memory_map
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ def load_firmware_for_mem() -> List[int]:
|
|||||||
class Core(Elaboratable):
|
class Core(Elaboratable):
|
||||||
def __init__(self, clk25, led_signal, eth_interface):
|
def __init__(self, clk25, led_signal, eth_interface):
|
||||||
self.count = Signal(64)
|
self.count = Signal(64)
|
||||||
self.cpu = Minerva(reset_address=0x01000000)
|
self.cpu = Minerva(reset_address=0x01000000, with_debug=False)
|
||||||
self.arbiter = Arbiter(addr_width=32, data_width=32)
|
self.arbiter = Arbiter(addr_width=30, data_width=32, granularity=8)
|
||||||
self.decoder = Decoder(addr_width=32, data_width=32, features=["err"])
|
self.decoder = Decoder(addr_width=30, data_width=32, granularity=8, features=["err"])
|
||||||
self.clk25 = clk25
|
self.clk25 = clk25
|
||||||
self.led_signal = led_signal
|
self.led_signal = led_signal
|
||||||
self.eth_interface = eth_interface
|
self.eth_interface = eth_interface
|
||||||
@ -55,7 +55,8 @@ class Core(Elaboratable):
|
|||||||
m.submodules.decoder = self.decoder
|
m.submodules.decoder = self.decoder
|
||||||
|
|
||||||
# Create main and sampling clock, using PLL and 25MHz input clock
|
# Create main and sampling clock, using PLL and 25MHz input clock
|
||||||
platform.add_file("pll.v", open("pll.v", "r").read())
|
if platform is not None:
|
||||||
|
platform.add_file("pll.v", open("pll.v", "r").read())
|
||||||
sys_clk = Signal()
|
sys_clk = Signal()
|
||||||
sample_clk = Signal()
|
sample_clk = Signal()
|
||||||
pll = Instance(
|
pll = Instance(
|
||||||
@ -79,16 +80,15 @@ class Core(Elaboratable):
|
|||||||
|
|
||||||
# Connect ibus and dbus together for simplicity for now
|
# Connect ibus and dbus together for simplicity for now
|
||||||
minerva_wb_features = ["cti", "bte", "err"]
|
minerva_wb_features = ["cti", "bte", "err"]
|
||||||
self.ibus = Interface(addr_width=32, data_width=32, features=minerva_wb_features)
|
self.ibus = Interface(addr_width=30, data_width=32, granularity=8, features=minerva_wb_features)
|
||||||
# Note this is a set of statements! without assigning to the comb domain, this will do nothing
|
# Note this is a set of statements! without assigning to the comb domain, this will do nothing
|
||||||
m.d.comb += self.cpu.ibus.connect(self.ibus)
|
m.d.comb += self.cpu.ibus.connect(self.ibus)
|
||||||
self.arbiter.add(self.ibus)
|
self.arbiter.add(self.ibus)
|
||||||
|
|
||||||
self.dbus = Interface(addr_width=32, data_width=32, features=minerva_wb_features)
|
self.dbus = Interface(addr_width=30, data_width=32, granularity=8, features=minerva_wb_features)
|
||||||
m.d.comb += self.cpu.dbus.connect(self.dbus) # Don't use .eq, use .connect, which will appropriately assign signals
|
m.d.comb += self.cpu.dbus.connect(self.dbus) # Don't use .eq, use .connect, which will appropriately assign signals
|
||||||
# using .eq() gave me Multiple Driven errors
|
# using .eq() gave me Multiple Driven errors
|
||||||
self.arbiter.add(self.dbus)
|
self.arbiter.add(self.dbus)
|
||||||
|
|
||||||
# TODO do something with interrupts
|
# TODO do something with interrupts
|
||||||
# These are interrupts headed into the CPU
|
# These are interrupts headed into the CPU
|
||||||
self.interrupts = Signal(32)
|
self.interrupts = Signal(32)
|
||||||
@ -111,7 +111,7 @@ class Core(Elaboratable):
|
|||||||
m.submodules.rom = self.rom
|
m.submodules.rom = self.rom
|
||||||
# Problem: not sure to handle how we do byte vs word addressing properly
|
# Problem: not sure to handle how we do byte vs word addressing properly
|
||||||
# So doing this shift is a bit of a hacky way to impl anything
|
# So doing this shift is a bit of a hacky way to impl anything
|
||||||
start, _stop, _step = self.decoder.add(self.rom, addr=(0x01000000 >> 2))
|
start, _stop, _step = self.decoder.add(self.rom, addr=0x01000000)
|
||||||
print(f"ROM added at 0x{start:08x}")
|
print(f"ROM added at 0x{start:08x}")
|
||||||
|
|
||||||
self.ram = RAM()
|
self.ram = RAM()
|
||||||
@ -129,7 +129,7 @@ class Core(Elaboratable):
|
|||||||
# Ethernet
|
# Ethernet
|
||||||
self.eth = LiteEth(self.eth_interface)
|
self.eth = LiteEth(self.eth_interface)
|
||||||
m.submodules.eth = self.eth
|
m.submodules.eth = self.eth
|
||||||
start, _stop, _step = self.decoder.add(self.eth, addr=0x00500000)
|
start, _stop, _step = self.decoder.add(self.eth, addr=0x02000000)
|
||||||
print(f"LiteETH added at 0x{start:08x}")
|
print(f"LiteETH added at 0x{start:08x}")
|
||||||
|
|
||||||
# Connect arbiter to decoder
|
# Connect arbiter to decoder
|
||||||
@ -167,12 +167,12 @@ def run_sim():
|
|||||||
sim = Simulator(dut)
|
sim = Simulator(dut)
|
||||||
|
|
||||||
def proc():
|
def proc():
|
||||||
for i in range(10000):
|
for i in range(1000):
|
||||||
yield Tick()
|
yield Tick()
|
||||||
|
|
||||||
sim.add_clock(1e-6)
|
sim.add_clock(1e-6)
|
||||||
sim.add_sync_process(proc)
|
sim.add_sync_process(proc)
|
||||||
with sim.write_vcd('test.vcd', gtkw_file='test.gtkw'):
|
with sim.write_vcd('sim.vcd', gtkw_file='sim.gtkw'):
|
||||||
sim.reset()
|
sim.reset()
|
||||||
sim.run()
|
sim.run()
|
||||||
|
|
||||||
@ -184,6 +184,7 @@ if __name__ == "__main__":
|
|||||||
# TODO maybe allow an optional arg to specify an individual test to run?
|
# TODO maybe allow an optional arg to specify an individual test to run?
|
||||||
args.add_argument("--test", action="store_true", help="Run RTL test suite and report results.")
|
args.add_argument("--test", action="store_true", help="Run RTL test suite and report results.")
|
||||||
args.add_argument("--save-vcd", action="store_true", help="Save VCD waveforms from test(s).")
|
args.add_argument("--save-vcd", action="store_true", help="Save VCD waveforms from test(s).")
|
||||||
|
args.add_argument("--sim", action="store_true", help="Run overall simulation")
|
||||||
args = args.parse_args()
|
args = args.parse_args()
|
||||||
|
|
||||||
if args.build:
|
if args.build:
|
||||||
@ -203,3 +204,6 @@ if __name__ == "__main__":
|
|||||||
for mod in test_modules:
|
for mod in test_modules:
|
||||||
unittest.main(module=mod, argv=[sys.argv[0]])
|
unittest.main(module=mod, argv=[sys.argv[0]])
|
||||||
|
|
||||||
|
if args.sim:
|
||||||
|
run_sim()
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ from amaranth import *
|
|||||||
from amaranth_soc.wishbone import *
|
from amaranth_soc.wishbone import *
|
||||||
from amaranth_soc.memory import *
|
from amaranth_soc.memory import *
|
||||||
|
|
||||||
|
# TODO impl select
|
||||||
|
|
||||||
|
|
||||||
# We sub-class wishbone.Interface here because it needs to be a bus object to be added as a window to Wishbone stuff
|
# We sub-class wishbone.Interface here because it needs to be a bus object to be added as a window to Wishbone stuff
|
||||||
class ROM(Elaboratable, Interface):
|
class ROM(Elaboratable, Interface):
|
||||||
@ -11,11 +13,11 @@ class ROM(Elaboratable, Interface):
|
|||||||
self.r = self.data.read_port()
|
self.r = self.data.read_port()
|
||||||
|
|
||||||
# Need to init Interface
|
# Need to init Interface
|
||||||
Interface.__init__(self, addr_width=10, data_width=32)
|
Interface.__init__(self, addr_width=10, data_width=32, granularity=8)
|
||||||
|
|
||||||
# This is effectively a "window", and it has a certain set of resources
|
# This is effectively a "window", and it has a certain set of resources
|
||||||
# 12 = log2(4096)
|
# 12 = log2(4096)
|
||||||
memory_map = MemoryMap(addr_width=10, data_width=32)
|
memory_map = MemoryMap(addr_width=12, data_width=8)
|
||||||
# TODO need to unify how I deal with size
|
# TODO need to unify how I deal with size
|
||||||
# In this case, one resource, which is out memory
|
# In this case, one resource, which is out memory
|
||||||
memory_map.add_resource(self.data, name="rom_data", size=(4096 >> 2))
|
memory_map.add_resource(self.data, name="rom_data", size=(4096 >> 2))
|
||||||
@ -57,11 +59,11 @@ class RAM(Elaboratable, Interface):
|
|||||||
self.w = self.data.write_port()
|
self.w = self.data.write_port()
|
||||||
|
|
||||||
# Need to init Interface
|
# Need to init Interface
|
||||||
Interface.__init__(self, addr_width=10, data_width=32)
|
Interface.__init__(self, addr_width=10, data_width=32, granularity=8)
|
||||||
|
|
||||||
# This is effectively a "window", and it has a certain set of resources
|
# This is effectively a "window", and it has a certain set of resources
|
||||||
# 12 = log2(4096)
|
# 12 = log2(4096)
|
||||||
memory_map = MemoryMap(addr_width=10, data_width=32)
|
memory_map = MemoryMap(addr_width=12, data_width=8)
|
||||||
# TODO need to unify how I deal with size
|
# TODO need to unify how I deal with size
|
||||||
# In this case, one resource, which is out memory
|
# In this case, one resource, which is out memory
|
||||||
memory_map.add_resource(self.data, name="ram_data", size=(4096 >> 2))
|
memory_map.add_resource(self.data, name="ram_data", size=(4096 >> 2))
|
||||||
|
Loading…
Reference in New Issue
Block a user