141 lines
4.5 KiB
Python
141 lines
4.5 KiB
Python
|
|
from amaranth.sim import Simulator
|
||
|
|
from manta.logic_analyzer_core import LogicAnalyzerCore
|
||
|
|
from manta.utils import *
|
||
|
|
from random import sample
|
||
|
|
|
||
|
|
config = {
|
||
|
|
"type": "logic_analyzer",
|
||
|
|
"sample_depth": 1024,
|
||
|
|
"trigger_loc": 500,
|
||
|
|
"probes": {"larry": 1, "curly": 3, "moe": 9},
|
||
|
|
"triggers": ["moe RISING"],
|
||
|
|
}
|
||
|
|
|
||
|
|
# class SimulatedBusInterface():
|
||
|
|
# def __init__(self, core):
|
||
|
|
# self.core = core
|
||
|
|
|
||
|
|
# def write(self, addrs, datas):
|
||
|
|
# # Handle a single integer address and data
|
||
|
|
# if isinstance(addrs, int) and isinstance(datas, int):
|
||
|
|
# return self.write([addrs], [datas])
|
||
|
|
|
||
|
|
# # Make sure address and datas are all integers
|
||
|
|
# if not isinstance(addrs, list) or not isinstance(datas, list):
|
||
|
|
# raise ValueError(
|
||
|
|
# "Write addresses and data must be an integer or list of integers."
|
||
|
|
# )
|
||
|
|
|
||
|
|
# if not all(isinstance(a, int) for a in addrs):
|
||
|
|
# raise ValueError("Write addresses must be all be integers.")
|
||
|
|
|
||
|
|
# if not all(isinstance(d, int) for d in datas):
|
||
|
|
# raise ValueError("Write data must all be integers.")
|
||
|
|
|
||
|
|
# # I'm not sure if it's necessary to split outputs into chunks
|
||
|
|
# # I think the output buffer doesn't really drop stuff, just the input buffer
|
||
|
|
|
||
|
|
# for addr, data in zip(addrs, datas):
|
||
|
|
# yield from write_register(self.core, addr, data)
|
||
|
|
|
||
|
|
# def read(self, addrs):
|
||
|
|
# # Handle a single integer address
|
||
|
|
# if isinstance(addrs, int):
|
||
|
|
# return self.read([addrs])[0]
|
||
|
|
|
||
|
|
# # Make sure all list elements are integers
|
||
|
|
# if not all(isinstance(a, int) for a in addrs):
|
||
|
|
# raise ValueError("Read address must be an integer or list of integers.")
|
||
|
|
|
||
|
|
# datas = []
|
||
|
|
# for addr in addrs:
|
||
|
|
# 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
|
||
|
|
# yield la.addr_i.eq(0)
|
||
|
|
# yield la.valid_i.eq(0)
|
||
|
|
|
||
|
|
# # wait for output to be valid
|
||
|
|
# while not (yield la.valid_o):
|
||
|
|
# yield
|
||
|
|
|
||
|
|
# datas.append( (yield la.data_o) )
|
||
|
|
|
||
|
|
# return datas
|
||
|
|
|
||
|
|
la = LogicAnalyzerCore(config, base_addr=0, interface=None)
|
||
|
|
# interface = SimulatedBusInterface(la)
|
||
|
|
# la.registers.interface = interface # unironically the least cursed part of this
|
||
|
|
# la.sample_mem.interface = interface # unironically the least cursed part of this
|
||
|
|
|
||
|
|
|
||
|
|
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
|
||
|
|
yield la.addr_i.eq(0)
|
||
|
|
yield la.valid_i.eq(0)
|
||
|
|
|
||
|
|
# wait for output to be valid
|
||
|
|
while not (yield la.valid_o):
|
||
|
|
yield
|
||
|
|
|
||
|
|
print(f"addr: {hex(addr)} data: {hex((yield la.data_o))}")
|
||
|
|
|
||
|
|
|
||
|
|
def set_logic_analyzer_register(name, data):
|
||
|
|
addr = la.registers.mmap[f"{name}_buf"]["addrs"][0]
|
||
|
|
|
||
|
|
yield from write_register(la, 0, 0)
|
||
|
|
yield from write_register(la, addr, data)
|
||
|
|
yield from write_register(la, 0, 1)
|
||
|
|
yield from write_register(la, 0, 0)
|
||
|
|
|
||
|
|
|
||
|
|
def test_do_you_fucking_work():
|
||
|
|
def testbench():
|
||
|
|
# # ok nice what happens if we try to run the core, which includes:
|
||
|
|
yield from set_logic_analyzer_register("request_stop", 1)
|
||
|
|
yield from set_logic_analyzer_register("request_stop", 0)
|
||
|
|
|
||
|
|
# setting triggers
|
||
|
|
yield from set_logic_analyzer_register("curly_op", la.operations["EQ"])
|
||
|
|
yield from set_logic_analyzer_register("curly_arg", 4)
|
||
|
|
|
||
|
|
# setting trigger mode
|
||
|
|
yield from set_logic_analyzer_register(
|
||
|
|
"trigger_mode", 0
|
||
|
|
) # right now this is not actually respected...oops
|
||
|
|
|
||
|
|
# setting trigger location
|
||
|
|
yield from set_logic_analyzer_register("trigger_loc", 500)
|
||
|
|
|
||
|
|
# starting capture
|
||
|
|
yield from set_logic_analyzer_register("request_start", 1)
|
||
|
|
yield from set_logic_analyzer_register("request_start", 0)
|
||
|
|
|
||
|
|
# wait a few hundred clock cycles, see what happens
|
||
|
|
for _ in range(700):
|
||
|
|
yield
|
||
|
|
|
||
|
|
# provide the trigger condition
|
||
|
|
yield la.probe_signals["curly"]["top_level"].eq(4)
|
||
|
|
|
||
|
|
for _ in range(700):
|
||
|
|
yield
|
||
|
|
|
||
|
|
# dump sample memory contents
|
||
|
|
yield from write_register(la, 0, 0)
|
||
|
|
yield from write_register(la, 0, 1)
|
||
|
|
yield from write_register(la, 0, 0)
|
||
|
|
|
||
|
|
for addr in range(la.get_max_addr()):
|
||
|
|
yield from print_data_at_addr(addr)
|
||
|
|
|
||
|
|
simulate(la, testbench, "la_core.vcd")
|