diff --git a/doc/getting_started.md b/doc/getting_started.md index 2de3e05..e6b3141 100644 --- a/doc/getting_started.md +++ b/doc/getting_started.md @@ -58,34 +58,19 @@ This Manta instance has an IO Core and a Logic Analyzer, each containing a numbe ## Example Instantiation -The Verilog file generated by `manta gen` contains some information at the top of the file. This includes an example instantiation for the `manta` module that's been configured, which you can copy paste into your source code. Here's what that looks like for the configuration above: - -```c -/* -This module was generated with Manta v0.0.5 on 11 Sep 2023 at 17:52:28 by fischerm - -If this breaks or if you've got spicy formal verification memes, contact fischerm [at] mit.edu - -Provided under a GNU GPLv3 license. Go wild. - -Here's an example instantiation of the Manta module you configured, feel free to copy-paste -this into your source! +Lastly, we Manta can automatically generate a copy-pasteable Verilog snippet to instantiate Manta in your design. This is done by running `manta inst` with the path to the configuration file describing the Manta core you'd like to instantiate. For example, the following snippet is generated for the configuration above: +```verilog manta manta_inst ( .clk(clk), - + .rst(rst) .rx(rx), .tx(tx), - .probe_0_in(probe_0_in), .probe_1_in(probe_1_in), .probe_2_out(probe_2_out), .probe_3_out(probe_3_out), - - .larry(larry), .curly(curly), .moe(moe)); - -*/ ``` \ No newline at end of file diff --git a/doc/logic_analyzer_core.md b/doc/logic_analyzer_core.md index bcf0a4b..50debe6 100644 --- a/doc/logic_analyzer_core.md +++ b/doc/logic_analyzer_core.md @@ -116,7 +116,7 @@ If the file `manta.yaml` contained the configuration above, then running: manta capture manta.yaml my_logic_analyzer capture.v ``` -Generates a Verilog module at `capture.v` which can then be instantiated in the testbench or FPGA design in which it is needed. An example instantiation is provided at the top of the output verilog, so a simple copy-paste into the testbench is all that's necessary to use the module. +Generates a Verilog module at `capture.v` which can then be instantiated in the testbench or FPGA design in which it is needed. This is useful for two situations in particular: diff --git a/src/manta/cli.py b/src/manta/cli.py index e629064..610ec13 100644 --- a/src/manta/cli.py +++ b/src/manta/cli.py @@ -1,5 +1,5 @@ from .manta import Manta -from warnings import warn +from .utils import * from sys import argv from pkg_resources import get_distribution @@ -37,6 +37,10 @@ Usage: Generate a verilog file specifying the Manta module from a given configuration file, and save to the provided path. + inst [config_file] + Generate a copy-pasteable Verilog snippet to instantiate Manta + in your design. + capture [config_file] [la_core_name] [vcd_file] [verilog_file] Start a capture on the specified core, and save the results to a .vcd or .v file at the provided path(s). @@ -61,6 +65,7 @@ def version(): def wrong_args(): print('Wrong number of arguments, run "manta help" for usage.') + exit(1) def gen(config_path, output_path): @@ -79,9 +84,23 @@ def gen(config_path, output_path): ) +def inst(config_path): + m = Manta(config_path) + ports = m.get_top_level_ports() + hdl = ",\n ".join([f".{p.name}({p.name})" for p in ports]) + + foo = """ +manta manta_inst( + .clk(clk), + .rst(rst), + """ + + print(foo + hdl + ");\n") + + def capture(config_path, logic_analyzer_name, export_paths): m = Manta(config_path) - la = getattr(s, logic_analyzer_name) + la = getattr(m, logic_analyzer_name) cap = la.capture() for path in export_paths: @@ -129,20 +148,16 @@ def main(): wrong_args() gen(argv[2], argv[3]) + elif argv[1] == "inst": + if len(argv) != 3: + wrong_args() + + inst(argv[2]) + elif argv[1] == "capture": if len(argv) < 5: wrong_args() - capture(argv[2], argv[3], argv[4]) - - elif argv[1] == "playback": - if len(argv) != 5: - wrong_args() - playback(argv[2], argv[3], argv[4]) - - elif argv[1] == "mmap": - if len(argv) != 3: - wrong_args() - mmap(argv[2]) + capture(argv[2], argv[3], argv[4:]) elif argv[1] == "ports": ports() diff --git a/src/manta/io_core.py b/src/manta/io_core.py index 98ce631..08e7633 100644 --- a/src/manta/io_core.py +++ b/src/manta/io_core.py @@ -1,5 +1,4 @@ from amaranth import * -from warnings import warn from .utils import * from math import ceil diff --git a/src/manta/logic_analyzer/__init__.py b/src/manta/logic_analyzer/__init__.py index e78f634..fd8dece 100644 --- a/src/manta/logic_analyzer/__init__.py +++ b/src/manta/logic_analyzer/__init__.py @@ -1,5 +1,4 @@ from amaranth import * -from warnings import warn from ..utils import * from .trigger_block import LogicAnalyzerTriggerBlock from .fsm import LogicAnalyzerFSM, States, TriggerModes @@ -306,7 +305,11 @@ class LogicAnalyzerCapture: ---------- The trigger location as an `int`. """ - return self.config["trigger_location"] + if "trigger_location" in self.config: + return self.config["trigger_location"] + + else: + return self.config["sample_depth"] // 2 def get_trace(self, probe_name): """Gets the value of a single probe over the capture. @@ -373,7 +376,10 @@ class LogicAnalyzerCapture: clock = writer.register_var("manta", "clk", "wire", size=1) # include a trigger signal such would be meaningful (ie, we didn't trigger immediately) - if self.config["trigger_mode"] != "immediate": + if ( + "trigger_mode" not in self.config + or self.config["trigger_mode"] == "single_shot" + ): trigger = writer.register_var("manta", "trigger", "wire", size=1) # add the data to each probe in the vcd file @@ -382,7 +388,10 @@ class LogicAnalyzerCapture: writer.change(clock, timestamp, timestamp % 2 == 0) # set the trigger (if there is one) - if self.config["trigger_mode"] != "immediate": + if ( + "trigger_mode" not in self.config + or self.config["trigger_mode"] == "single_shot" + ): triggered = (timestamp // 2) >= self.get_trigger_location() writer.change(trigger, timestamp, triggered) diff --git a/src/manta/manta.py b/src/manta/manta.py index a86150a..8e9e997 100644 --- a/src/manta/manta.py +++ b/src/manta/manta.py @@ -1,5 +1,4 @@ from amaranth import * -from warnings import warn from .uart import UARTInterface # from .ethernet import EthernetInterface @@ -70,7 +69,7 @@ class Manta(Elaboratable): return EthernetInterface(self.config["ethernet"]) else: - raise ValueError("Unrecognized interface specified.") + raise ValueError("No recognized interface specified.") def get_cores(self): """ """ diff --git a/src/manta/memory_core.py b/src/manta/memory_core.py index db54a36..17bfd33 100644 --- a/src/manta/memory_core.py +++ b/src/manta/memory_core.py @@ -1,5 +1,4 @@ from amaranth import * -from warnings import warn from .utils import * from math import ceil diff --git a/src/manta/uart/__init__.py b/src/manta/uart/__init__.py index 7540c93..4cfbeef 100644 --- a/src/manta/uart/__init__.py +++ b/src/manta/uart/__init__.py @@ -1,5 +1,4 @@ from amaranth import * -from warnings import warn from ..utils import * from .receiver import UARTReceiver from .receive_bridge import ReceiveBridge diff --git a/src/manta/utils.py b/src/manta/utils.py index 9773a57..98ae766 100644 --- a/src/manta/utils.py +++ b/src/manta/utils.py @@ -5,13 +5,25 @@ import os class InternalBus(data.StructLayout): - """Describes the layout of Manta's internal bus, such that signals of - the appropriate dimension can be instantiated with Signal(InternalBus()).""" + """ + Describes the layout of Manta's internal bus, such that signals of + the appropriate dimension can be instantiated with Signal(InternalBus()). + """ def __init__(self): super().__init__({"addr": 16, "data": 16, "rw": 1, "valid": 1}) +def warn(message): + """ + Prints a warning to the user's terminal. Originally the warn() method + from the builtin warnings module was used for this, but I don't think the + way it outputs on the command line is the most helpful for the users. + (They don't care about the stacktrace or the filename/line number, for example.) + """ + print("Warning: " + message) + + def words_to_value(data): """ Takes a list of integers, interprets them as 16-bit integers, and