From: whitequark Date: Sat, 22 Dec 2018 23:56:02 +0000 (+0000) Subject: cli: new module, for basic design generaton/simulation. X-Git-Tag: working~138 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cf79738744994de37b7a77666845a447d7ebe2e0;p=nmigen.git cli: new module, for basic design generaton/simulation. --- diff --git a/examples/alu.py b/examples/alu.py index 4b051c6..f75bd07 100644 --- a/examples/alu.py +++ b/examples/alu.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class ALU: @@ -23,7 +23,6 @@ class ALU: return m.lower(platform) -alu = ALU(width=16) -frag = alu.get_fragment(platform=None) -# print(rtlil.convert(frag, ports=[alu.sel, alu.a, alu.b, alu.o, alu.co])) -print(verilog.convert(frag, ports=[alu.sel, alu.a, alu.b, alu.o, alu.co])) +if __name__ == "__main__": + alu = ALU(width=16) + main(alu, ports=[alu.sel, alu.a, alu.b, alu.o, alu.co]) diff --git a/examples/alu_hier.py b/examples/alu_hier.py index 8551d38..cd31ce9 100644 --- a/examples/alu_hier.py +++ b/examples/alu_hier.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class Adder: @@ -53,7 +53,6 @@ class ALU: return m.lower(platform) -alu = ALU(width=16) -frag = alu.get_fragment(platform=None) -# print(rtlil.convert(frag, ports=[alu.op, alu.a, alu.b, alu.o])) -print(verilog.convert(frag, ports=[alu.op, alu.a, alu.b, alu.o])) +if __name__ == "__main__": + alu = ALU(width=16) + main(alu, ports=[alu.op, alu.a, alu.b, alu.o]) diff --git a/examples/arst.py b/examples/arst.py index e99fc8d..4cbdb14 100644 --- a/examples/arst.py +++ b/examples/arst.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class ClockDivisor: @@ -14,8 +14,8 @@ class ClockDivisor: return m.lower(platform) -ctr = ClockDivisor(factor=16) -frag = ctr.get_fragment(platform=None) -frag.add_domains(ClockDomain("sync", async_reset=True)) -# print(rtlil.convert(frag, ports=[ctr.o])) -print(verilog.convert(frag, ports=[ctr.o])) +if __name__ == "__main__": + ctr = ClockDivisor(factor=16) + frag = ctr.get_fragment(platform=None) + frag.add_domains(ClockDomain("sync", async_reset=True)) + main(frag, ports=[ctr.o]) diff --git a/examples/cdc.py b/examples/cdc.py index 7d2486d..80b335e 100644 --- a/examples/cdc.py +++ b/examples/cdc.py @@ -1,10 +1,10 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main i, o = Signal(name="i"), Signal(name="o") m = Module() m.submodules += MultiReg(i, o) -frag = m.lower(platform=None) -# print(rtlil.convert(frag, ports=[i, o])) -print(verilog.convert(frag, ports=[i, o])) + +if __name__ == "__main__": + main(m.lower(platform=None), ports=[i, o]) diff --git a/examples/ctr.py b/examples/ctr.py index be1bb09..f08bd04 100644 --- a/examples/ctr.py +++ b/examples/ctr.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog, pysim +from nmigen.cli import main, pysim class Counter: @@ -14,13 +14,6 @@ class Counter: return m.lower(platform) -ctr = Counter(width=16) -frag = ctr.get_fragment(platform=None) - -# print(rtlil.convert(frag, ports=[ctr.o])) -print(verilog.convert(frag, ports=[ctr.o])) - -with pysim.Simulator(frag, - vcd_file=open("ctr.vcd", "w")) as sim: - sim.add_clock(1e-6) - sim.run_until(100e-6, run_passive=True) +ctr = Counter(width=16) +if __name__ == "__main__": + main(ctr, ports=[ctr.o]) diff --git a/examples/gpio.py b/examples/gpio.py index 557a852..06caab1 100644 --- a/examples/gpio.py +++ b/examples/gpio.py @@ -1,6 +1,6 @@ from types import SimpleNamespace from nmigen import * -from nmigen.back import rtlil, verilog, pysim +from nmigen.cli import main class GPIO: @@ -16,16 +16,14 @@ class GPIO: return m.lower(platform) -# TODO: use Record -bus = SimpleNamespace( - adr=Signal(max=8), - dat_r=Signal(), - dat_w=Signal(), - we=Signal() -) -pins = Signal(8) -gpio = GPIO(Array(pins), bus) -frag = gpio.get_fragment(platform=None) - -# print(rtlil.convert(frag, ports=[pins, bus.adr, bus.dat_r, bus.dat_w, bus.we])) -print(verilog.convert(frag, ports=[pins, bus.adr, bus.dat_r, bus.dat_w, bus.we])) +if __name__ == "__main__": + # TODO: use Record + bus = SimpleNamespace( + adr =Signal(name="adr", max=8), + dat_r=Signal(name="dat_r"), + dat_w=Signal(name="dat_w"), + we =Signal(name="we"), + ) + pins = Signal(8) + gpio = GPIO(Array(pins), bus) + main(gpio, ports=[pins, bus.adr, bus.dat_r, bus.dat_w, bus.we]) diff --git a/examples/inst.py b/examples/inst.py index 5bfdaaa..28052f7 100644 --- a/examples/inst.py +++ b/examples/inst.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class System: @@ -11,7 +11,7 @@ class System: def get_fragment(self, platform): m = Module() - m.submodules += Instance("CPU", + m.submodules.cpu = Instance("CPU", p_RESET_ADDR=0xfff0, i_d_adr =self.adr, i_d_dat_r=self.dat_r, @@ -21,7 +21,6 @@ class System: return m.lower(platform) -sys = System() -frag = sys.get_fragment(platform=None) -# print(rtlil.convert(frag, ports=[sys.adr, sys.dat_r, sys.dat_w, sys.we])) -print(verilog.convert(frag, ports=[sys.adr, sys.dat_r, sys.dat_w, sys.we])) +if __name__ == "__main__": + sys = System() + main(sys, ports=[sys.adr, sys.dat_r, sys.dat_w, sys.we]) diff --git a/examples/mem.py b/examples/mem.py index 1893d90..4771eed 100644 --- a/examples/mem.py +++ b/examples/mem.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class RegisterFile: @@ -24,7 +24,6 @@ class RegisterFile: return m.lower(platform) -rf = RegisterFile() -frag = rf.get_fragment(platform=None) -# print(rtlil.convert(frag, ports=[rf.adr, rf.dat_r, rf.dat_w, rf.we])) -print(verilog.convert(frag, ports=[rf.adr, rf.dat_r, rf.dat_w, rf.we])) +if __name__ == "__main__": + rf = RegisterFile() + main(rf, ports=[rf.adr, rf.dat_r, rf.dat_w, rf.we]) diff --git a/examples/pmux.py b/examples/pmux.py index 27ec33f..2d108d6 100644 --- a/examples/pmux.py +++ b/examples/pmux.py @@ -1,5 +1,5 @@ from nmigen import * -from nmigen.back import rtlil, verilog +from nmigen.cli import main class ParMux: @@ -24,7 +24,6 @@ class ParMux: return m.lower(platform) -pmux = ParMux(width=16) -frag = pmux.get_fragment(platform=None) -# print(rtlil.convert(frag, ports=[pmux.s, pmux.a, pmux.b, pmux.c, pmux.o])) -print(verilog.convert(frag, ports=[pmux.s, pmux.a, pmux.b, pmux.c, pmux.o])) +if __name__ == "__main__": + pmux = ParMux(width=16) + main(pmux, ports=[pmux.s, pmux.a, pmux.b, pmux.c, pmux.o]) diff --git a/nmigen/cli.py b/nmigen/cli.py new file mode 100644 index 0000000..c28e296 --- /dev/null +++ b/nmigen/cli.py @@ -0,0 +1,65 @@ +import argparse + +from .back import rtlil, verilog, pysim + + +__all__ = ["main"] + + +def main_parser(parser=None): + if parser is None: + parser = argparse.ArgumentParser() + + p_action = parser.add_subparsers(dest="action") + + p_generate = p_action.add_parser("generate", + help="generate RTLIL or Verilog from the design") + p_generate.add_argument("-t", "--type", dest="generate_type", + metavar="LANGUAGE", choices=["il", "v"], default="v", + help="generate LANGUAGE (il for RTLIL, v for Verilog; default: %(default)s)") + p_generate.add_argument("generate_file", + metavar="FILE", type=argparse.FileType("w"), nargs="?", + help="write generated code to FILE") + + p_simulate = p_action.add_parser( + "simulate", help="simulate the design") + p_simulate.add_argument("-v", "--vcd-file", + metavar="VCD-FILE", type=argparse.FileType("w"), + help="write execution trace to VCD-FILE") + p_simulate.add_argument("-w", "--gtkw-file", + metavar="GTKW-FILE", type=argparse.FileType("w"), + help="write GTKWave configuration to GTKW-FILE") + p_simulate.add_argument("-p", "--period", dest="sync_period", + metavar="TIME", type=float, default=1e-6, + help="set 'sync' clock domain period to TIME (default: %(default)s)") + p_simulate.add_argument("-c", "--clocks", dest="sync_clocks", + metavar="COUNT", type=int, required=True, + help="simulate for COUNT 'sync' clock periods") + + return parser + + +def main_runner(args, design, platform=None, name="top", ports=()): + if args.action == "generate": + fragment = design.get_fragment(platform=platform) + if args.generate_type == "il": + output = rtlil.convert(fragment, name=name, ports=ports) + if args.generate_type == "v": + output = verilog.convert(fragment, name=name, ports=ports) + if args.generate_file: + args.generate_file.write(output) + else: + print(output) + + if args.action == "simulate": + fragment = design.get_fragment(platform=platform) + with pysim.Simulator(fragment, + vcd_file=args.vcd_file, + gtkw_file=args.gtkw_file, + traces=ports) as sim: + sim.add_clock(args.sync_period) + sim.run_until(args.sync_period * args.sync_clocks, run_passive=True) + + +def main(*args, **kwargs): + main_runner(main_parser().parse_args(), *args, **kwargs)