diff --git a/src/manta/io_core.py b/src/manta/io_core.py index c12096a..98ce631 100644 --- a/src/manta/io_core.py +++ b/src/manta/io_core.py @@ -87,16 +87,9 @@ class IOCore(Elaboratable): ) def define_signals(self): - # Bus Ports - self.addr_i = Signal(16) - self.data_i = Signal(16) - self.rw_i = Signal() - self.valid_i = Signal() - - self.addr_o = Signal(16) - self.data_o = Signal(16) - self.rw_o = Signal() - self.valid_o = Signal() + # Bus Input/Output + self.bus_i = Signal(InternalBus()) + self.bus_o = Signal(InternalBus()) # Input Probes (and buffers) if "inputs" in self.config: @@ -187,10 +180,7 @@ class IOCore(Elaboratable): m = Module() # Shuffle bus transactions along - m.d.sync += self.addr_o.eq(self.addr_i) - m.d.sync += self.data_o.eq(self.data_i) - m.d.sync += self.rw_o.eq(self.rw_i) - m.d.sync += self.valid_o.eq(self.valid_i) + m.d.sync += self.bus_o.eq(self.bus_i) # Update buffers from probes with m.If(self.strobe): @@ -209,17 +199,17 @@ class IOCore(Elaboratable): m.d.sync += output_probe.eq(output_probe_buf) # Handle register reads and writes - with m.If((self.addr_i >= self.base_addr)): - with m.If((self.addr_o <= self.max_addr)): + with m.If((self.bus_i.addr >= self.base_addr)): + with m.If((self.bus_o.addr <= self.max_addr)): for entry in self.mmap.values(): for addr, signal in zip(entry["addrs"], entry["signals"]): - with m.If(self.rw_i): - with m.If(self.addr_i == addr): - m.d.sync += signal.eq(self.data_i) + with m.If(self.bus_i.rw): + with m.If(self.bus_i.addr == addr): + m.d.sync += signal.eq(self.bus_i.data) with m.Else(): - with m.If(self.addr_i == addr): - m.d.sync += self.data_o.eq(signal) + with m.If(self.bus_i.addr == addr): + m.d.sync += self.bus_o.data.eq(signal) return m diff --git a/src/manta/logic_analyzer/__init__.py b/src/manta/logic_analyzer/__init__.py index fcb27d9..6e38e54 100644 --- a/src/manta/logic_analyzer/__init__.py +++ b/src/manta/logic_analyzer/__init__.py @@ -36,17 +36,9 @@ class LogicAnalyzerCore(Elaboratable): self.config = config self.check_config(config) - # Bus Input - self.addr_i = Signal(16) - self.data_i = Signal(16) - self.rw_i = Signal(1) - self.valid_i = Signal(1) - - # Bus Output - self.addr_o = Signal(16) - self.data_o = Signal(16) - self.rw_o = Signal(1) - self.valid_o = Signal(1) + # Bus Input/Output + self.bus_i = Signal(InternalBus()) + self.bus_o = Signal(InternalBus()) self.probes = [ Signal(width, name=name) for name, width in self.config["probes"].items() @@ -177,26 +169,15 @@ class LogicAnalyzerCore(Elaboratable): # Wire bus connections between internal modules m.d.comb += [ # Bus Connections - fsm.addr_i.eq(self.addr_i), - fsm.data_i.eq(self.data_i), - fsm.rw_i.eq(self.rw_i), - fsm.valid_i.eq(self.valid_i), - trig_blk.addr_i.eq(fsm.addr_o), - trig_blk.data_i.eq(fsm.data_o), - trig_blk.rw_i.eq(fsm.rw_o), - trig_blk.valid_i.eq(fsm.valid_o), - sample_mem.addr_i.eq(trig_blk.addr_o), - sample_mem.data_i.eq(trig_blk.data_o), - sample_mem.rw_i.eq(trig_blk.rw_o), - sample_mem.valid_i.eq(trig_blk.valid_o), - self.addr_o.eq(sample_mem.addr_o), - self.data_o.eq(sample_mem.data_o), - self.rw_o.eq(sample_mem.rw_o), - self.valid_o.eq(sample_mem.valid_o), + fsm.bus_i.eq(self.bus_i), + trig_blk.bus_i.eq(self.fsm.bus_o), + sample_mem.bus_i.eq(trig_blk.bus_o), + self.bus_o.eq(sample_mem.bus_o), + # Non-bus Connections fsm.trigger.eq(trig_blk.trig), sample_mem.user_addr.eq(fsm.r.write_pointer), - sample_mem.user_we.eq(fsm.write_enable), + sample_mem.user_we.eq(fsm.write_enable) ] return m diff --git a/src/manta/logic_analyzer/fsm.py b/src/manta/logic_analyzer/fsm.py index b2f0059..4d8583e 100644 --- a/src/manta/logic_analyzer/fsm.py +++ b/src/manta/logic_analyzer/fsm.py @@ -37,17 +37,9 @@ class LogicAnalyzerFSM(Elaboratable): self.r = IOCore(register_config, base_addr, interface) - # Bus Input - self.addr_i = self.r.addr_i - self.data_i = self.r.data_i - self.rw_i = self.r.rw_i - self.valid_i = self.r.valid_i - - # Bus Output - self.addr_o = self.r.addr_o - self.data_o = self.r.data_o - self.rw_o = self.r.rw_o - self.valid_o = self.r.valid_o + # Bus Input/Output + self.bus_i = self.r.bus_i + self.bus_o = self.r.bus_o def get_max_addr(self): return self.r.get_max_addr() diff --git a/src/manta/logic_analyzer/trigger_block.py b/src/manta/logic_analyzer/trigger_block.py index 2b15530..0d0a0bd 100644 --- a/src/manta/logic_analyzer/trigger_block.py +++ b/src/manta/logic_analyzer/trigger_block.py @@ -18,17 +18,9 @@ class LogicAnalyzerTriggerBlock(Elaboratable): self.r = IOCore({"outputs": outputs}, base_addr, interface) - # Bus Input - self.addr_i = self.r.addr_i - self.data_i = self.r.data_i - self.rw_i = self.r.rw_i - self.valid_i = self.r.valid_i - - # Bus Output - self.addr_o = self.r.addr_o - self.data_o = self.r.data_o - self.rw_o = self.r.rw_o - self.valid_o = self.r.valid_o + # Bus Input/Output + self.bus_i = self.r.bus_i + self.bus_o = self.r.bus_o # Global trigger. High if any probe is triggered. self.trig = Signal(1) diff --git a/src/manta/manta.py b/src/manta/manta.py index 97f1b4c..63f902b 100644 --- a/src/manta/manta.py +++ b/src/manta/manta.py @@ -136,28 +136,16 @@ class Manta(Elaboratable): core_instances = list(self.cores.values()) first_core = core_instances[0] last_core = core_instances[-1] - m.d.comb += [ - first_core.addr_i.eq(self.interface.addr_o), - first_core.data_i.eq(self.interface.data_o), - first_core.rw_i.eq(self.interface.rw_o), - first_core.valid_i.eq(self.interface.valid_o), - self.interface.addr_i.eq(last_core.addr_o), - self.interface.data_i.eq(last_core.data_o), - self.interface.rw_i.eq(last_core.rw_o), - self.interface.valid_i.eq(last_core.valid_o), - ] + + m.d.comb += first_core.bus_i.eq(self.interface.bus_o) + m.d.comb += self.interface.bus_i.eq(last_core.bus_o) # Connect output of ith core to input of (i+1)th core for i in range(len(core_instances) - 1): ith_core = core_instances[i] i_plus_oneth_core = core_instances[i + 1] - m.d.comb += [ - i_plus_oneth_core.addr_i.eq(ith_core.addr_o), - i_plus_oneth_core.data_i.eq(ith_core.data_o), - i_plus_oneth_core.rw_i.eq(ith_core.rw_o), - i_plus_oneth_core.valid_i.eq(ith_core.valid_o), - ] + m.d.comb += i_plus_oneth_core.bus_i.eq(ith_core.bus_o) return m diff --git a/src/manta/memory_core.py b/src/manta/memory_core.py index cf4d9ae..e74e32d 100644 --- a/src/manta/memory_core.py +++ b/src/manta/memory_core.py @@ -47,23 +47,10 @@ class ReadOnlyMemoryCore(Elaboratable): raise ValueError("Width of memory core must be positive. ") def define_signals(self): - # Bus Input - self.addr_i = Signal(16) - self.data_i = Signal(16) - self.rw_i = Signal(1) - self.valid_i = Signal(1) - - # Bus Pipelining - self.addr_pipe = [Signal(16) for _ in range(3)] - self.data_pipe = [Signal(16) for _ in range(3)] - self.rw_pipe = [Signal(1) for _ in range(3)] - self.valid_pipe = [Signal(1) for _ in range(3)] - - # Bus Output - self.addr_o = Signal(16, reset=0) - self.data_o = Signal(16, reset=0) - self.rw_o = Signal(1, reset=0) - self.valid_o = Signal(1, reset=0) + # Bus Input/Pipelining/Output + self.bus_i = Signal(InternalBus()) + self.bus_pipe = [Signal(InternalBus()) for _ in range(3)] + self.bus_o = Signal(InternalBus()) # User Port self.user_addr = Signal(range(self.depth)) @@ -71,22 +58,12 @@ class ReadOnlyMemoryCore(Elaboratable): self.user_we = Signal(1) def pipeline_bus(self, m): - # Pipelining - m.d.sync += self.addr_pipe[0].eq(self.addr_i) - m.d.sync += self.data_pipe[0].eq(self.data_i) - m.d.sync += self.rw_pipe[0].eq(self.rw_i) - m.d.sync += self.valid_pipe[0].eq(self.valid_i) + m.d.sync += self.bus_pipe[0].eq(self.bus_i) for i in range(1, 3): - m.d.sync += self.addr_pipe[i].eq(self.addr_pipe[i - 1]) - m.d.sync += self.data_pipe[i].eq(self.data_pipe[i - 1]) - m.d.sync += self.rw_pipe[i].eq(self.rw_pipe[i - 1]) - m.d.sync += self.valid_pipe[i].eq(self.valid_pipe[i - 1]) + m.d.sync += self.bus_pipe[i].eq(self.bus_pipe[i-1]) - m.d.sync += self.addr_o.eq(self.addr_pipe[2]) - m.d.sync += self.data_o.eq(self.data_pipe[2]) - m.d.sync += self.rw_o.eq(self.rw_pipe[2]) - m.d.sync += self.valid_o.eq(self.valid_pipe[2]) + m.d.sync += self.bus_o.eq(self.bus_pipe[2]) def define_mems(self): # ok there's three cases: @@ -122,21 +99,21 @@ class ReadOnlyMemoryCore(Elaboratable): # Throw BRAM operations into the front of the pipeline with m.If( - (self.valid_i) - & (~self.rw_i) - & (self.addr_i >= start_addr) - & (self.addr_i <= stop_addr) + (self.bus_i.valid) + & (~self.bus_i.rw) + & (self.bus_i.addr >= start_addr) + & (self.bus_i.addr <= stop_addr) ): - m.d.sync += read_port.addr.eq(self.addr_i - start_addr) + m.d.sync += read_port.addr.eq(self.bus_i.addr - start_addr) # Pull BRAM reads from the back of the pipeline with m.If( - (self.valid_pipe[2]) - & (~self.rw_pipe[2]) - & (self.addr_pipe[2] >= start_addr) - & (self.addr_pipe[2] <= stop_addr) + (self.bus_pipe[2].valid) + & (~self.bus_pipe[2].rw) + & (self.bus_pipe[2].addr >= start_addr) + & (self.bus_pipe[2].addr <= stop_addr) ): - m.d.sync += self.data_o.eq(read_port.data) + m.d.sync += self.bus_o.data.eq(read_port.data) def handle_write_ports(self, m): # These are given to the user diff --git a/src/manta/uart/__init__.py b/src/manta/uart/__init__.py index 5f1556b..a6f5c19 100644 --- a/src/manta/uart/__init__.py +++ b/src/manta/uart/__init__.py @@ -225,15 +225,8 @@ class UARTInterface(Elaboratable): self.rx = Signal() self.tx = Signal() - self.addr_o = Signal(16) - self.data_o = Signal(16) - self.rw_o = Signal() - self.valid_o = Signal() - - self.addr_i = Signal(16) - self.data_i = Signal(16) - self.rw_i = Signal() - self.valid_i = Signal() + self.bus_o = Signal(InternalBus()) + self.bus_i = Signal(InternalBus()) def elaborate(self, platform): # fancy submoduling and such goes in here @@ -249,14 +242,14 @@ class UARTInterface(Elaboratable): uart_rx.rx.eq(self.rx), bridge_rx.data_i.eq(uart_rx.data_o), bridge_rx.valid_i.eq(uart_rx.valid_o), - self.data_o.eq(bridge_rx.data_o), - self.addr_o.eq(bridge_rx.addr_o), - self.rw_o.eq(bridge_rx.rw_o), - self.valid_o.eq(bridge_rx.valid_o), + self.bus_o.data.eq(bridge_rx.data_o), + self.bus_o.addr.eq(bridge_rx.addr_o), + self.bus_o.rw.eq(bridge_rx.rw_o), + self.bus_o.valid.eq(bridge_rx.valid_o), # Internal Bus -> UART TX - bridge_tx.data_i.eq(self.data_i), - bridge_tx.rw_i.eq(self.rw_i), - bridge_tx.valid_i.eq(self.valid_i), + bridge_tx.data_i.eq(self.bus_i.data), + bridge_tx.rw_i.eq(self.bus_i.rw), + bridge_tx.valid_i.eq(self.bus_i.valid), uart_tx.data_i.eq(bridge_tx.data_o), uart_tx.start_i.eq(bridge_tx.start_o), bridge_tx.done_i.eq(uart_tx.done_o), diff --git a/src/manta/utils.py b/src/manta/utils.py index 3591165..9773a57 100644 --- a/src/manta/utils.py +++ b/src/manta/utils.py @@ -83,20 +83,20 @@ def verify_register(module, addr, expected_data): """ # place read transaction on the bus - yield module.addr_i.eq(addr) - yield module.data_i.eq(0) - yield module.rw_i.eq(0) - yield module.valid_i.eq(1) + yield module.bus_i.addr.eq(addr) + yield module.bus_i.data.eq(0) + yield module.bus_i.rw.eq(0) + yield module.bus_i.valid.eq(1) yield - yield module.addr_i.eq(0) - yield module.valid_i.eq(0) + yield module.bus_i.addr.eq(0) + yield module.bus_i.valid.eq(0) # wait for output to be valid - while not (yield module.valid_o): + while not (yield module.bus_o.valid): yield # compare returned value with expected - data = yield (module.data_o) + data = yield (module.bus_o.data) if data != expected_data: raise ValueError(f"Read from {addr} yielded {data} instead of {expected_data}") @@ -107,12 +107,12 @@ def write_register(module, addr, data): at `addr`. """ - yield module.addr_i.eq(addr) - yield module.data_i.eq(data) - yield module.rw_i.eq(1) - yield module.valid_i.eq(1) + yield module.bus_i.addr.eq(addr) + yield module.bus_i.data.eq(data) + yield module.bus_i.rw.eq(1) + yield module.bus_i.valid.eq(1) yield - yield module.valid_i.eq(0) + yield module.bus_i.valid.eq(0) yield diff --git a/test/test_logic_analyzer_sim.py b/test/test_logic_analyzer_sim.py index e69db0c..ebce934 100644 --- a/test/test_logic_analyzer_sim.py +++ b/test/test_logic_analyzer_sim.py @@ -16,19 +16,19 @@ la = LogicAnalyzerCore(config, base_addr=0, interface=None) def print_data_at_addr(addr): # place read transaction on the bus - yield la.addr_i.eq(addr) - yield la.data_i.eq(0) - yield la.rw_i.eq(0) - yield la.valid_i.eq(1) + yield la.bus_i.addr.eq(addr) + yield la.bus_i.data.eq(0) + yield la.bus_i.rw.eq(0) + yield la.bus_i.valid.eq(1) yield - yield la.addr_i.eq(0) - yield la.valid_i.eq(0) + yield la.bus_i.addr.eq(0) + yield la.bus_i.valid.eq(0) # wait for output to be valid - while not (yield la.valid_o): + while not (yield la.bus_o.valid): yield - print(f"addr: {hex(addr)} data: {hex((yield la.data_o))}") + print(f"addr: {hex(addr)} data: {hex((yield la.bus_o.data))}") def set_fsm_register(name, data):