diff options
Diffstat (limited to 'hdl/utils.py')
-rw-r--r-- | hdl/utils.py | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/hdl/utils.py b/hdl/utils.py index 249167a..80dc3ee 100644 --- a/hdl/utils.py +++ b/hdl/utils.py @@ -1,57 +1,52 @@ import sys +from inspect import stack # get name of caller function from typing import Callable from amaranth import * from amaranth import Elaboratable from amaranth.back import verilog, cxxrtl +from amaranth.sim import Settle, Delay, Simulator -def cmd(hdl, tb:Callable): +from hdl.config import * + + +def cmd(hdl): ''' Very simple command line interface - Accepts a Elaboratable class and a testbench function The elaboratable class must have a ports attribute that is a dict of in and out ports {'in': [Signals()], 'out': [Signals()]} - The testbench function should only expect one argument: path to save .vcd file ''' if len(sys.argv) <= 1: + print('Usage: v|cc v = generate verilog, cc = generate cxxrtl') exit() if sys.argv[1] == "sim": - tb(sys.argv[0].replace('.py', '.vcd')) - exit() + # tb(sys.argv[0].replace('.py', '.vcd')) + # exit() + assert "sim option deprecated, use pytest command instead" if sys.argv[1] == "v": out = verilog.convert(hdl, ports=hdl.ports['in'] + hdl.ports['out']) - with open(sys.argv[0].replace('.py', '.v'), 'w') as f: + with open(os.path.join(VERILOG_DIR, sys.argv[0].replace('.py', '.v')), 'w') as f: f.write(out) elif sys.argv[1] == "cc": out = cxxrtl.convert(hdl, ports=hdl.ports['in'] + hdl.ports['out']) - with open(sys.argv[0].replace('.py', '.cc'), 'w') as f: + with open(os.path.join(CXXRTL_DIR, sys.argv[0].replace('.py', '.cc')), 'w') as f: f.write(out) -class DubbleBuff(Elaboratable): - ''' - This module wraps another modules input and output with a buffer - This is usefull for doing timeing analysis on combinational logic - - An instance of a module should be passed, not the module itself - ''' - def __init__(self, sub_module: Elaboratable): - assert sub_module.ports is not None, 'sub_module must have ports' - - self.sub_module = sub_module - ports_in = [Signal(port.width, name=port.name + '_inbuf') for port in sub_module.ports['in']] - ports_out = [Signal(port.width, name=port.name + '_outbuf') for port in sub_module.ports['out']] - self.ports = {'in': ports_in, 'out': ports_out} - - def elaborate(self, platform): - m = Module() - m.submodules.sub = self.sub_module - for i in range(len(self.ports['in'])): - m.d.sync += self.sub_module.ports['in'][i].eq(self.ports['in'][i]) - for i in range(len(self.ports['out'])): - m.d.sync += self.ports['out'][i].eq(self.sub_module.ports['out'][i]) - - return m
\ No newline at end of file +def sim(dut:Elaboratable, proc: Callable): + sim = Simulator(dut) + sim.add_clock(1e-6) + sim.add_sync_process(proc) + + with sim.write_vcd(os.path.join(VCD_DIR, stack()[1].function + '.vcd')): + sim.run() + +def step(cycles=1): + for _ in range(cycles): + yield Settle() # settle comb logic before clock + yield # clock edge + yield Settle() # settle comb logic after clock + yield Delay(5e-7) # used for debugging, change values on neg edge of clock
\ No newline at end of file |