summaryrefslogtreecommitdiff
path: root/hdl/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/utils.py')
-rw-r--r--hdl/utils.py57
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