From 7cb913ed2a3d2ce87083c6d6c97aba42150481c1 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Tue, 5 Dec 2023 16:11:23 -0800 Subject: [PATCH 01/19] [magma v3.0.0] Upgrade to magma v3.0.0 --- examples/sv_tb/sv_tb.py | 2 +- fault/assert_immediate.py | 2 +- fault/property.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/sv_tb/sv_tb.py b/examples/sv_tb/sv_tb.py index c52da14c..9e2a8338 100644 --- a/examples/sv_tb/sv_tb.py +++ b/examples/sv_tb/sv_tb.py @@ -5,7 +5,7 @@ import fault -class Queue(m.Generator2): +class Queue(m.Generator): def __init__(self, T, entries, with_bug=False): assert entries >= 0 self.io = m.IO( diff --git a/fault/assert_immediate.py b/fault/assert_immediate.py index 699ffd85..c83215fc 100644 --- a/fault/assert_immediate.py +++ b/fault/assert_immediate.py @@ -36,7 +36,7 @@ def _make_assert(type_, cond, success_msg=None, failure_msg=None, end """ assert_str = add_compile_guards(compile_guard, assert_str) - m.inline_verilog2(assert_str, **format_args, type_=type_) + m.inline_verilog(assert_str, **format_args, type_=type_) def _add_docstr(fn): diff --git a/fault/property.py b/fault/property.py index be3ed613..6a6ddc76 100644 --- a/fault/property.py +++ b/fault/property.py @@ -264,7 +264,7 @@ def _make_statement(statement, prop, on, disable_iff, compile_guard, name): raise TypeError("Expected string for name") prop_str = f"{name}: {prop_str}" prop_str = add_compile_guards(compile_guard, prop_str) - m.inline_verilog2(prop_str, **format_args) + m.inline_verilog(prop_str, **format_args) def assert_(prop, on, disable_iff=None, compile_guard=None, name=None): From 29b03727e89c49c7e2e9d35bf9ce92681a9b88f0 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Wed, 6 Dec 2023 14:39:14 -0800 Subject: [PATCH 02/19] Upgrade magma dependency to 3.0.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e665a8b3..1d178562 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ "astor", "z3-solver", "hwtypes", - "magma-lang>=2.2.3", + "magma-lang>=3.0.0", "pyyaml", "scipy", "numpy", From 3388e1138538af860dc96bdb561e755f1d2e69e1 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Wed, 6 Dec 2023 14:43:20 -0800 Subject: [PATCH 03/19] Explicitly pip install importlib_resources --- .github/workflows/deploy.yml | 1 + .github/workflows/linux.yml | 1 + .github/workflows/macos.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 76c8d877..c4ef57be 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,6 +30,7 @@ jobs: - name: Install Python packages shell: bash -l {0} run: | + pip install importlib_resources pip install "pytest<6" pip install pytest-cov pytest-pycodestyle pip install mantle>=2.0.0 # for tests.common diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c8c659c4..624670d5 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -21,6 +21,7 @@ jobs: - name: Install Python packages shell: bash -l {0} run: | + pip install importlib_resources pip install "pytest<6" pip install pytest-cov pytest-pycodestyle pip install mantle>=2.0.0 # for tests.common diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index f6edf53e..b77b3eb0 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -31,6 +31,7 @@ jobs: - name: Install Python packages shell: bash -l {0} run: | + pip install importlib_resources pip install "pytest<6" pip install pytest-cov pytest-pycodestyle pip install mantle>=2.0.0 # for tests.common From bf45ecbf984a5140383606150f6791b9bbd68d66 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Wed, 6 Dec 2023 19:00:30 -0800 Subject: [PATCH 04/19] Remove mantle dependencies --- README.md | 2 +- examples/sv_tb/sv_tb.py | 2 +- examples/test_simple_alu.py | 2 +- tests/common.py | 8 ++++---- tests/test_env_mod.py | 2 +- tests/test_expressions.py | 2 +- tests/test_functional_tester.py | 4 ++-- tests/test_power_domains.py | 2 +- tests/test_select_model.py | 2 +- tests/test_test_vectors.py | 2 +- tests/test_tester/test_interactive.py | 4 ++-- tutorial/README.md | 6 +++--- tutorial/exercise_1.py | 2 +- tutorial/exercise_2.py | 2 +- tutorial/tff.py | 2 +- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 16f5a05d..1feac653 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Check out the [fault tutorial](https://github.com/leonardt/fault/tree/master/tut Here is a simple ALU defined in magma. ```python import magma as m -import mantle +# import mantle class ConfigReg(m.Circuit): diff --git a/examples/sv_tb/sv_tb.py b/examples/sv_tb/sv_tb.py index 9e2a8338..4293f863 100644 --- a/examples/sv_tb/sv_tb.py +++ b/examples/sv_tb/sv_tb.py @@ -1,7 +1,7 @@ import random import magma as m -import mantle +# import mantle import fault diff --git a/examples/test_simple_alu.py b/examples/test_simple_alu.py index 258f6a1e..ec14277b 100644 --- a/examples/test_simple_alu.py +++ b/examples/test_simple_alu.py @@ -1,5 +1,5 @@ import magma as m -import mantle +# import mantle import operator import fault import pytest diff --git a/tests/common.py b/tests/common.py index 4359de05..a889583b 100644 --- a/tests/common.py +++ b/tests/common.py @@ -1,6 +1,6 @@ import shutil import magma as m -import mantle +# import mantle def pytest_sim_params(metafunc, *args, exclude=None): @@ -93,9 +93,9 @@ class TestPeekCircuit(m.Circuit): class ConfigReg(m.Circuit): io = m.IO(D=m.In(m.Bits[2]), Q=m.Out(m.Bits[2])) + \ - m.ClockIO(has_ce=True) + m.ClockIO(has_enable=True) - reg = mantle.Register(2, has_ce=True, name="conf_reg") + reg = m.Register(m.Bits[2], has_enable=True)(name="conf_reg") io.Q @= reg(io.D, CE=io.CE) @@ -108,7 +108,7 @@ class SimpleALU(m.Circuit): ) + m.ClockIO() opcode = ConfigReg(name="config_reg")(io.config_data, CE=io.config_en) - io.c @= mantle.mux( + io.c @= m.mux( # udiv not implemented # [io.a + io.b, io.a - io.b, io.a * io.b, io.a / io.b], opcode) # use arbitrary fourth op diff --git a/tests/test_env_mod.py b/tests/test_env_mod.py index 5736fad5..bd1a91aa 100644 --- a/tests/test_env_mod.py +++ b/tests/test_env_mod.py @@ -1,5 +1,5 @@ import fault -import mantle +# import mantle import magma as m from .common import pytest_sim_params diff --git a/tests/test_expressions.py b/tests/test_expressions.py index 749fc242..04080dfe 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -8,7 +8,7 @@ import fault import magma as m -import mantle +# import mantle import hwtypes diff --git a/tests/test_functional_tester.py b/tests/test_functional_tester.py index dce5e8f1..07c33415 100644 --- a/tests/test_functional_tester.py +++ b/tests/test_functional_tester.py @@ -2,7 +2,7 @@ from hwtypes import BitVector from fault.functional_tester import FunctionalTester import magma as m -import mantle +# import mantle import tempfile import pytest @@ -24,7 +24,7 @@ class Configurable(m.Circuit): config_en=m.In(m.Enable), O=m.Out(m.Bits[32]) ) + m.ClockIO() - reg = mantle.Register(32, has_ce=True) + reg = m.Register(m.Bits[32], has_enable=True)() reg(io.config_data, CE=(io.config_addr == m.bits(1, 32)) & m.bit(io.config_en)) diff --git a/tests/test_power_domains.py b/tests/test_power_domains.py index 5eeed0af..313066b5 100644 --- a/tests/test_power_domains.py +++ b/tests/test_power_domains.py @@ -1,5 +1,5 @@ import magma as m -import mantle +# import mantle import fault from hwtypes import BitVector import pytest diff --git a/tests/test_select_model.py b/tests/test_select_model.py index 8d28638f..e7bd9860 100644 --- a/tests/test_select_model.py +++ b/tests/test_select_model.py @@ -3,7 +3,7 @@ subcomponents of a DUT) """ import magma as m -import mantle +# import mantle import fault import hwtypes as ht import os diff --git a/tests/test_test_vectors.py b/tests/test_test_vectors.py index 464898b8..ddbab618 100644 --- a/tests/test_test_vectors.py +++ b/tests/test_test_vectors.py @@ -2,7 +2,7 @@ import pytest from hwtypes import Bit import magma as m -import mantle +# import mantle from fault.test_vectors import (generate_function_test_vectors, generate_simulator_test_vectors) from fault.value import AnyValue diff --git a/tests/test_tester/test_interactive.py b/tests/test_tester/test_interactive.py index 2eb4ae1f..df6fda9b 100644 --- a/tests/test_tester/test_interactive.py +++ b/tests/test_tester/test_interactive.py @@ -2,7 +2,7 @@ from ..common import AndCircuit, SimpleALU, TestTupleCircuit, \ TestNestedArraysCircuit, TestNestedArrayTupleCircuit from hwtypes import BitVector -from mantle import DefineCounter +import magma as m def test_interactive_basic(capsys): @@ -38,7 +38,7 @@ def test_interactive_clock(): def test_counter(): - Counter4 = DefineCounter(4) + Counter4 = m.mantle.Counter(4) tester = PythonTester(Counter4, Counter4.CLK) tester.CLK = 0 tester.wait_until_high(Counter4.O[3]) diff --git a/tutorial/README.md b/tutorial/README.md index 217ab1f8..d03c4fca 100644 --- a/tutorial/README.md +++ b/tutorial/README.md @@ -191,7 +191,7 @@ Here's an example: ```python import magma as m -import mantle +# import mantle import fault @@ -307,7 +307,7 @@ Suppose you had the following definition of a simple, configurable ALU in magma (source: [fault/tutorial/exercise_1.py](./exercise_1.py)): ```python import magma as m -import mantle +# import mantle class ConfigReg(m.Circuit): @@ -405,7 +405,7 @@ Suppose you have the following two memory modules defined in magma (source: [fault/tutorial/exercise_2.py](./exercise_2.py)): ```python import magma as m -import mantle +# import mantle import fault diff --git a/tutorial/exercise_1.py b/tutorial/exercise_1.py index b54d3261..ef0e73a0 100644 --- a/tutorial/exercise_1.py +++ b/tutorial/exercise_1.py @@ -1,5 +1,5 @@ import magma as m -import mantle +# import mantle class ConfigReg(m.Circuit): diff --git a/tutorial/exercise_2.py b/tutorial/exercise_2.py index cd0d7cbd..c21d2e1e 100644 --- a/tutorial/exercise_2.py +++ b/tutorial/exercise_2.py @@ -1,5 +1,5 @@ import magma as m -import mantle +# import mantle import fault from reset_tester import ResetTester diff --git a/tutorial/tff.py b/tutorial/tff.py index c32f217b..5792b3d0 100644 --- a/tutorial/tff.py +++ b/tutorial/tff.py @@ -1,5 +1,5 @@ import magma as m -import mantle +# import mantle import fault From dd920cd8accc77fccf4d43e72f5ab20e9a6a93e8 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:10:16 -0800 Subject: [PATCH 05/19] Install importlib_resources on buildkite --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 2ca34770..b2191406 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -15,7 +15,7 @@ steps: pip install "pytest<6" pip install coverage pytest-pycodestyle pip install --upgrade "mantle>=2.0.0" - pip install vcdvcd decorator kratos + pip install vcdvcd decorator kratos importlib_resources pip install DeCiDa scipy numpy # install fault From 43b5463722c2ff424f058431dacfb05e988edfaf Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:12:10 -0800 Subject: [PATCH 06/19] Update readme code --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1feac653..ad50470a 100644 --- a/README.md +++ b/README.md @@ -45,14 +45,13 @@ Check out the [fault tutorial](https://github.com/leonardt/fault/tree/master/tut Here is a simple ALU defined in magma. ```python import magma as m -# import mantle class ConfigReg(m.Circuit): io = m.IO(D=m.In(m.Bits[2]), Q=m.Out(m.Bits[2])) + \ m.ClockIO(has_ce=True) - reg = mantle.Register(2, has_ce=True, name="conf_reg") + reg = m.Register(m.Bits[2], has_enable=True)(name="conf_reg") io.Q @= reg(io.D, CE=io.CE) @@ -66,7 +65,7 @@ class SimpleALU(m.Circuit): ) + m.ClockIO() opcode = ConfigReg(name="config_reg")(io.config_data, CE=io.config_en) - io.c @= mantle.mux( + io.c @= m.mux( [io.a + io.b, io.a - io.b, io.a * io.b, io.a ^ io.b], opcode) ``` From 778487ceec0d2ea24a8623935518ea046bc241db Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:21:50 -0800 Subject: [PATCH 07/19] Update example --- examples/sv_tb/sv_tb.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/sv_tb/sv_tb.py b/examples/sv_tb/sv_tb.py index 4293f863..3806280f 100644 --- a/examples/sv_tb/sv_tb.py +++ b/examples/sv_tb/sv_tb.py @@ -1,24 +1,26 @@ import random import magma as m -# import mantle import fault class Queue(m.Generator): - def __init__(self, T, entries, with_bug=False): - assert entries >= 0 + def __init__(self, T, num_bits, with_bug=False): + assert num_bits >= 0 self.io = m.IO( # Flipped since enq/deq is from perspective of the client enq=m.DeqIO[T], deq=m.EnqIO[T] ) + m.ClockIO() - ram = m.Memory(entries, T)() - enq_ptr = mantle.CounterModM(entries, entries.bit_length(), - has_ce=True, cout=False) - deq_ptr = mantle.CounterModM(entries, entries.bit_length(), - has_ce=True, cout=False) + ram = m.Memory(2 ** num_bits, T)() + _Pointer = m.mantle.Counter( + (2 ** (num_bits + 1)), + has_enable=True, + has_cout=False + ) + enq_ptr = _Pointer() + deq_ptr = _Pointer() maybe_full = m.Register(init=False, has_enable=True)() ptr_match = enq_ptr.O == deq_ptr.O @@ -50,7 +52,7 @@ def ispow2(n): def test_queue(with_bug): T = m.Bits[8] - Queue4x8 = Queue(T, 4, with_bug=with_bug) + Queue4x8 = Queue(T, 2, with_bug=with_bug) class Monitor(m.Circuit): io = m.IO( @@ -111,8 +113,11 @@ class DUT(m.Circuit): tester.circuit.deq.ready = random.randint(0, 1) tester.advance_cycle() try: - tester.compile_and_run("verilator", flags=["--assert"], - magma_opts={"inline": True}) + tester.compile_and_run( + "verilator", + flags=["--assert"], + magma_output="mlir-verilog" + ) assert not with_bug except AssertionError: assert with_bug From 1affb0ed2d5b96f8f3ddd81a445b38ee337dda3c Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:24:00 -0800 Subject: [PATCH 08/19] Update example --- examples/test_simple_alu.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/test_simple_alu.py b/examples/test_simple_alu.py index ec14277b..81fe74c6 100644 --- a/examples/test_simple_alu.py +++ b/examples/test_simple_alu.py @@ -1,5 +1,4 @@ import magma as m -# import mantle import operator import fault import pytest @@ -11,7 +10,7 @@ class ConfigReg(m.Circuit): io = m.IO(D=m.In(m.Bits[2]), Q=m.Out(m.Bits[2])) + \ m.ClockIO(has_ce=True) - reg = mantle.Register(2, has_ce=True, name="conf_reg") + reg = m.Register(m.Bits[2], has_enable=True)(name="conf_reg") io.Q @= reg(io.D, CE=io.CE) @@ -24,7 +23,7 @@ class SimpleALU(m.Circuit): ) + m.ClockIO() opcode = ConfigReg(name="config_reg")(io.config_data, CE=io.config_en) - io.c @= mantle.mux( + io.c @= m.mux( [io.a + io.b, io.a - io.b, io.a * io.b, io.a ^ io.b], opcode) From eb7aab3a84a2df18d3e20b14420975061b606d97 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:24:45 -0800 Subject: [PATCH 09/19] remove comment --- tests/common.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/common.py b/tests/common.py index a889583b..a4d62f7d 100644 --- a/tests/common.py +++ b/tests/common.py @@ -1,6 +1,5 @@ import shutil import magma as m -# import mantle def pytest_sim_params(metafunc, *args, exclude=None): From 8b8a6f910ee004c815e1a54f956995f6c7bdf8d4 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:24:56 -0800 Subject: [PATCH 10/19] Remove comment --- tests/test_env_mod.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_env_mod.py b/tests/test_env_mod.py index bd1a91aa..d59f21b8 100644 --- a/tests/test_env_mod.py +++ b/tests/test_env_mod.py @@ -1,5 +1,4 @@ import fault -# import mantle import magma as m from .common import pytest_sim_params From b561d653268bd4f368c79cb770a311f77da64c9b Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:25:08 -0800 Subject: [PATCH 11/19] Remove comment --- tests/test_expressions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_expressions.py b/tests/test_expressions.py index 04080dfe..07385328 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -8,7 +8,6 @@ import fault import magma as m -# import mantle import hwtypes From 072672af9eb29c7362bd93275f0a871bca301ee3 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:25:18 -0800 Subject: [PATCH 12/19] Remove comment --- tests/test_functional_tester.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_functional_tester.py b/tests/test_functional_tester.py index 07c33415..e2c421b1 100644 --- a/tests/test_functional_tester.py +++ b/tests/test_functional_tester.py @@ -2,7 +2,6 @@ from hwtypes import BitVector from fault.functional_tester import FunctionalTester import magma as m -# import mantle import tempfile import pytest From bbe5fc214862f70acea25f47399cf2032155ea4f Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:25:35 -0800 Subject: [PATCH 13/19] Remove comment --- tests/test_power_domains.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_power_domains.py b/tests/test_power_domains.py index 313066b5..7baba9c4 100644 --- a/tests/test_power_domains.py +++ b/tests/test_power_domains.py @@ -1,5 +1,4 @@ import magma as m -# import mantle import fault from hwtypes import BitVector import pytest From 43162d4bca5f07785d762bd5e4f02c1b94827027 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:31:08 -0800 Subject: [PATCH 14/19] Update test --- tests/test_select_model.py | 333 ++++++++++++------------------------- 1 file changed, 102 insertions(+), 231 deletions(-) diff --git a/tests/test_select_model.py b/tests/test_select_model.py index e7bd9860..4cf4bbe0 100644 --- a/tests/test_select_model.py +++ b/tests/test_select_model.py @@ -3,13 +3,25 @@ subcomponents of a DUT) """ import magma as m -# import mantle import fault import hwtypes as ht import os import tempfile +class FullAdder(m.Circuit): + io = m.IO(I0=m.In(m.Bit), I1=m.In(m.Bit), CIN=m.In(m.Bit), + O=m.Out(m.Bit), COUT=m.Out(m.Bit)) + + # Generate the sum + m.wire(io.I0 ^ io.I1 ^ io.CIN, io.O) + # Generate the carry + m.wire( + (io.I0 & io.I1) | (io.I1 & io.CIN) | (io.I0 & io.CIN), + io.COUT + ) + + def test_top(): # First, we define an interface generator for an N-bit adder def DeclareAdder(N): @@ -34,7 +46,7 @@ def DefineAdderStructural(N): class Adder(m.Circuit): io = m.IO(I0=m.In(T), I1=m.In(T), CIN=m.In(m.Bit), O=m.Out(T), COUT=m.Out(m.Bit)) - adders = [mantle.FullAdder() for _ in range(N)] + adders = [FullAdder() for _ in range(N)] adders = m.fold(adders, foldargs={"CIN": "COUT"}) COUT, O = adders(I0=io.I0, I1=io.I1, CIN=io.CIN) m.wire(O, io.O) @@ -94,248 +106,107 @@ class DUT(m.Circuit): tester.circuit.COUT.expect(COUT) with tempfile.TemporaryDirectory() as directory: - tester.compile_and_run(target="verilator", directory=directory) + tester.compile_and_run(target="verilator", directory=directory, + magma_output="mlir-verilog") # Assert that the generated verilog generates two different adders with open(os.path.join(directory, "DUT.v"), "r") as f: assert f.read() == """\ -module coreir_orr #( - parameter width = 1 -) ( - input [width-1:0] in, - output out +module Adder( + input [3:0] I0, + I1, + input CIN, + output [3:0] O, + output COUT ); - assign out = |in; -endmodule -module coreir_add #( - parameter width = 1 -) ( - input [width-1:0] in0, - input [width-1:0] in1, - output [width-1:0] out -); - assign out = in0 + in1; + wire [4:0] _GEN = {1'h0, I0} + {1'h0, I1} + {4'h0, CIN}; + assign O = _GEN[3:0]; + assign COUT = _GEN[4]; endmodule -module corebit_xor ( - input in0, - input in1, - output out +module FullAdder( + input I0, + I1, + CIN, + output O, + COUT ); - assign out = in0 ^ in1; -endmodule -module fold_xor3None ( - input I0, - input I1, - input I2, - output O -); -wire xor_inst0_out; -wire xor_inst1_out; -corebit_xor xor_inst0 ( - .in0(I0), - .in1(I1), - .out(xor_inst0_out) -); -corebit_xor xor_inst1 ( - .in0(xor_inst0_out), - .in1(I2), - .out(xor_inst1_out) -); -assign O = xor_inst1_out; + assign O = I0 ^ I1 ^ CIN; + assign COUT = I0 & I1 | I1 & CIN | I0 & CIN; endmodule -module corebit_const #( - parameter value = 1 -) ( - output out -); - assign out = value; +module Adder_unq1( + input [3:0] I0, + I1, + input CIN, + output [3:0] O, + output COUT +); + + wire _FullAdder_inst3_O; + wire _FullAdder_inst2_O; + wire _FullAdder_inst2_COUT; + wire _FullAdder_inst1_O; + wire _FullAdder_inst1_COUT; + wire _FullAdder_inst0_O; + wire _FullAdder_inst0_COUT; + FullAdder FullAdder_inst0 ( + .I0 (I0[0]), + .I1 (I1[0]), + .CIN (CIN), + .O (_FullAdder_inst0_O), + .COUT (_FullAdder_inst0_COUT) + ); + FullAdder FullAdder_inst1 ( + .I0 (I0[1]), + .I1 (I1[1]), + .CIN (_FullAdder_inst0_COUT), + .O (_FullAdder_inst1_O), + .COUT (_FullAdder_inst1_COUT) + ); + FullAdder FullAdder_inst2 ( + .I0 (I0[2]), + .I1 (I1[2]), + .CIN (_FullAdder_inst1_COUT), + .O (_FullAdder_inst2_O), + .COUT (_FullAdder_inst2_COUT) + ); + FullAdder FullAdder_inst3 ( + .I0 (I0[3]), + .I1 (I1[3]), + .CIN (_FullAdder_inst2_COUT), + .O (_FullAdder_inst3_O), + .COUT (COUT) + ); + assign O = + {_FullAdder_inst3_O, _FullAdder_inst2_O, _FullAdder_inst1_O, _FullAdder_inst0_O}; endmodule -module corebit_and ( - input in0, - input in1, - output out -); - assign out = in0 & in1; -endmodule - -module Or3xNone ( - input I0, - input I1, - input I2, - output O -); -wire orr_inst0_out; -wire [2:0] orr_inst0_in; -assign orr_inst0_in = {I2,I1,I0}; -coreir_orr #( - .width(3) -) orr_inst0 ( - .in(orr_inst0_in), - .out(orr_inst0_out) -); -assign O = orr_inst0_out; -endmodule - -module FullAdder ( - input I0, - input I1, - input CIN, - output O, - output COUT -); -wire Or3xNone_inst0_O; -wire and_inst0_out; -wire and_inst1_out; -wire and_inst2_out; -wire fold_xor3None_inst0_O; -Or3xNone Or3xNone_inst0 ( - .I0(and_inst0_out), - .I1(and_inst1_out), - .I2(and_inst2_out), - .O(Or3xNone_inst0_O) -); -corebit_and and_inst0 ( - .in0(I0), - .in1(I1), - .out(and_inst0_out) -); -corebit_and and_inst1 ( - .in0(I1), - .in1(CIN), - .out(and_inst1_out) -); -corebit_and and_inst2 ( - .in0(I0), - .in1(CIN), - .out(and_inst2_out) -); -fold_xor3None fold_xor3None_inst0 ( - .I0(I0), - .I1(I1), - .I2(CIN), - .O(fold_xor3None_inst0_O) -); -assign O = fold_xor3None_inst0_O; -assign COUT = Or3xNone_inst0_O; -endmodule - -module Adder_unq1 ( - input [3:0] I0, - input [3:0] I1, - input CIN, - output [3:0] O, - output COUT -); -wire FullAdder_inst0_O; -wire FullAdder_inst0_COUT; -wire FullAdder_inst1_O; -wire FullAdder_inst1_COUT; -wire FullAdder_inst2_O; -wire FullAdder_inst2_COUT; -wire FullAdder_inst3_O; -wire FullAdder_inst3_COUT; -FullAdder FullAdder_inst0 ( - .I0(I0[0]), - .I1(I1[0]), - .CIN(CIN), - .O(FullAdder_inst0_O), - .COUT(FullAdder_inst0_COUT) -); -FullAdder FullAdder_inst1 ( - .I0(I0[1]), - .I1(I1[1]), - .CIN(FullAdder_inst0_COUT), - .O(FullAdder_inst1_O), - .COUT(FullAdder_inst1_COUT) -); -FullAdder FullAdder_inst2 ( - .I0(I0[2]), - .I1(I1[2]), - .CIN(FullAdder_inst1_COUT), - .O(FullAdder_inst2_O), - .COUT(FullAdder_inst2_COUT) -); -FullAdder FullAdder_inst3 ( - .I0(I0[3]), - .I1(I1[3]), - .CIN(FullAdder_inst2_COUT), - .O(FullAdder_inst3_O), - .COUT(FullAdder_inst3_COUT) -); -assign O = {FullAdder_inst3_O,FullAdder_inst2_O,FullAdder_inst1_O,FullAdder_inst0_O}; -assign COUT = FullAdder_inst3_COUT; -endmodule - -module Adder ( - input [3:0] I0, - input [3:0] I1, - input CIN, - output [3:0] O, - output COUT -); -wire bit_const_0_None_out; -wire [4:0] magma_UInt_5_add_inst0_out; -wire [4:0] magma_UInt_5_add_inst1_out; -corebit_const #( - .value(1'b0) -) bit_const_0_None ( - .out(bit_const_0_None_out) -); -wire [4:0] magma_UInt_5_add_inst0_in0; -assign magma_UInt_5_add_inst0_in0 = {bit_const_0_None_out,I0}; -wire [4:0] magma_UInt_5_add_inst0_in1; -assign magma_UInt_5_add_inst0_in1 = {bit_const_0_None_out,I1}; -coreir_add #( - .width(5) -) magma_UInt_5_add_inst0 ( - .in0(magma_UInt_5_add_inst0_in0), - .in1(magma_UInt_5_add_inst0_in1), - .out(magma_UInt_5_add_inst0_out) -); -wire [4:0] magma_UInt_5_add_inst1_in1; -assign magma_UInt_5_add_inst1_in1 = {bit_const_0_None_out,bit_const_0_None_out,bit_const_0_None_out,bit_const_0_None_out,CIN}; -coreir_add #( - .width(5) -) magma_UInt_5_add_inst1 ( - .in0(magma_UInt_5_add_inst0_out), - .in1(magma_UInt_5_add_inst1_in1), - .out(magma_UInt_5_add_inst1_out) -); -assign O = magma_UInt_5_add_inst1_out[3:0]; -assign COUT = magma_UInt_5_add_inst1_out[4]; -endmodule - -module DUT ( - input [3:0] I0, - input [3:0] I1, - input CIN, - output [3:0] O, - output COUT -); -wire [3:0] adder0_O; -wire adder0_COUT; -wire [3:0] adder1_O; -wire adder1_COUT; -Adder adder0 ( - .I0(I0), - .I1(I1), - .CIN(CIN), - .O(adder0_O), - .COUT(adder0_COUT) -); -Adder_unq1 adder1 ( - .I0(adder0_O), - .I1(adder0_O), - .CIN(adder0_COUT), - .O(adder1_O), - .COUT(adder1_COUT) -); -assign O = adder1_O; -assign COUT = adder1_COUT; +module DUT( + input [3:0] I0, + I1, + input CIN, + output [3:0] O, + output COUT +); + + wire [3:0] _adder0_O; + wire _adder0_COUT; + Adder adder0 ( + .I0 (I0), + .I1 (I1), + .CIN (CIN), + .O (_adder0_O), + .COUT (_adder0_COUT) + ); + Adder_unq1 adder1 ( + .I0 (_adder0_O), + .I1 (_adder0_O), + .CIN (_adder0_COUT), + .O (O), + .COUT (COUT) + ); endmodule """ # noqa From f3c6af7987513238907e642645dd6e72a5445684 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:32:42 -0800 Subject: [PATCH 15/19] Update test --- tests/test_test_vectors.py | 1 - tests/test_tester/test_interactive.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_test_vectors.py b/tests/test_test_vectors.py index ddbab618..26f2622b 100644 --- a/tests/test_test_vectors.py +++ b/tests/test_test_vectors.py @@ -2,7 +2,6 @@ import pytest from hwtypes import Bit import magma as m -# import mantle from fault.test_vectors import (generate_function_test_vectors, generate_simulator_test_vectors) from fault.value import AnyValue diff --git a/tests/test_tester/test_interactive.py b/tests/test_tester/test_interactive.py index df6fda9b..e0eb8fec 100644 --- a/tests/test_tester/test_interactive.py +++ b/tests/test_tester/test_interactive.py @@ -38,7 +38,7 @@ def test_interactive_clock(): def test_counter(): - Counter4 = m.mantle.Counter(4) + Counter4 = m.mantle.Counter(2**4) tester = PythonTester(Counter4, Counter4.CLK) tester.CLK = 0 tester.wait_until_high(Counter4.O[3]) From 45fb57248380865599313189c4159a069b78d7ea Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:37:46 -0800 Subject: [PATCH 16/19] Update tutorial --- tutorial/README.md | 122 ++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 67 deletions(-) diff --git a/tutorial/README.md b/tutorial/README.md index d03c4fca..e1238599 100644 --- a/tutorial/README.md +++ b/tutorial/README.md @@ -104,11 +104,11 @@ to PATH in your /Users/yourusername/.bash_profile ? [yes|no] ``` ### Using pip -The simplest way to get started for this tutorial is to install fault, magma, -and mantle using `pip`. +The simplest way to get started for this tutorial is to install fault, and +magma using `pip`. ``` -pip install fault magma-lang mantle +pip install fault magma-lang ``` ### From source @@ -120,8 +120,6 @@ git clone https://github.com/leonardt/fault cd fault && pip install -e . && cd .. git clone https://github.com/phanrahan/magma cd magma && pip install -e . && cd .. -git clone https://github.com/phanrahan/mantle -cd mantle && pip install -e . && cd .. ``` ## CoreIR @@ -175,11 +173,9 @@ import fault class Passthrough(m.Circuit): - IO = ["I", m.In(m.Bit), "O", m.Out(m.Bit)] + io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) - @classmethod - def definition(io): - io.O <= io.I + io.O @= io.I passthrough_tester = fault.Tester(Passthrough) @@ -191,19 +187,16 @@ Here's an example: ```python import magma as m -# import mantle import fault class TFF(m.Circuit): - IO = ["O", m.Out(m.Bit), "CLK", m.In(m.Clock)] + io = m.IO(O=m.Out(m.Bit), CLK=m.In(m.Clock)) - @classmethod - def definition(io): - reg = mantle.Register(None, name="tff_reg") - reg.CLK <= io.CLK - reg.I <= ~reg.O - io.O <= reg.O + reg = m.Register(m.Bit)(name="tff_reg") + reg.CLK @= io.CLK + reg.I @= ~reg.O + io.O @= reg.O tff_tester = fault.Tester(TFF, clock=TFF.CLK) @@ -232,7 +225,7 @@ passthrough_tester.circuit.I = 1 ``` The `poke` (`setattr`) pattern supports poking internal instances of the -`mantle.Register` circuit using the `value` attribute. This can be done at +`m.Register` circuit using the `value` attribute. This can be done at arbitrary depths in the instance hierarchy. An instance can be referred to as an attribute of the top level `circuit` attribute or as an attribute of a nested instance. Here's an example using the `tff_tester`: @@ -307,32 +300,32 @@ Suppose you had the following definition of a simple, configurable ALU in magma (source: [fault/tutorial/exercise_1.py](./exercise_1.py)): ```python import magma as m -# import mantle class ConfigReg(m.Circuit): IO = ["D", m.In(m.Bits[2]), "Q", m.Out(m.Bits[2])] + \ m.ClockInterface(has_ce=True) + io = m.IO( + D=m.In(m.Bits[2]), + Q=m.Out(m.Bits[2]), + ) + m.ClockIO() - @classmethod - def definition(io): - reg = mantle.Register(2, has_ce=True, name="config_reg") - io.Q <= reg(io.D, CE=io.CE) + reg = m.Register(m.Bits[2], has_enable=True)(name="config_reg") + io.Q @= reg(io.D, CE=io.CE) class SimpleALU(m.Circuit): - IO = ["a", m.In(m.UInt[16]), - "b", m.In(m.UInt[16]), - "c", m.Out(m.UInt[16]), - "config_data", m.In(m.Bits[2]), - "config_en", m.In(m.Enable), - ] + m.ClockInterface() - - @classmethod - def definition(io): - opcode = ConfigReg(name="opcode_reg")(io.config_data, CE=io.config_en) - io.c <= mantle.mux( - [io.a + io.b, io.a - io.b, io.a * io.b, io.b - io.a], opcode) + io = m.IO( + a=m.In(m.UInt[16]), + b=m.In(m.UInt[16]), + c=m.Out(m.UInt[16]), + config_data=m.In(m.Bits[2]), + config_en=m.In(m.Enable) + ) + m.ClockIO() + + opcode = ConfigReg(name="opcode_reg")(io.config_data, CE=io.config_en) + io.c @= m.mux( + [io.a + io.b, io.a - io.b, io.a * io.b, io.b - io.a], opcode) ``` Study the implementation so you understand how it works (ask for help if you @@ -405,7 +398,6 @@ Suppose you have the following two memory modules defined in magma (source: [fault/tutorial/exercise_2.py](./exercise_2.py)): ```python import magma as m -# import mantle import fault @@ -417,41 +409,37 @@ init = [fault.random.random_bv(data_width) for _ in range(1 << addr_width)] class ROM(m.Circuit): - IO = [ - "RADDR", m.In(m.Bits[addr_width]), - "RDATA", m.Out(m.Bits[data_width]), - "CLK", m.In(m.Clock) - ] + io = m.IO( + RADDR=m.In(m.Bits[addr_width]), + RDATA=m.Out(m.BIts[data_width]), + CLK=m.In(m.Clock) + ) - @classmethod - def definition(io): - regs = [mantle.Register(data_width, init=int(init[i])) - for i in range(1 << addr_width)] - for reg in regs: - reg.I <= reg.O - io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR) + regs = [m.Register(m.Bits[data_width], init=int(init[i]))() + for i in range(1 << addr_width)] + for reg in regs: + reg.I @= reg.O + io.RDATA @= m.mux([reg.O for reg in regs], io.RADDR) class RAM(m.Circuit): - IO = [ - "RADDR", m.In(m.Bits[addr_width]), - "RDATA", m.Out(m.Bits[data_width]), - "WADDR", m.In(m.Bits[addr_width]), - "WDATA", m.In(m.Bits[data_width]), - "WE", m.In(m.Bit), - "CLK", m.In(m.Clock), - "RESET", m.In(m.Reset) - ] - - @classmethod - def definition(io): - regs = [mantle.Register(data_width, init=int(init[i]), has_ce=True, - has_reset=True) - for i in range(1 << addr_width)] - for i, reg in enumerate(regs): - reg.I <= io.WDATA - reg.CE <= (io.WADDR == m.bits(i, addr_width)) & io.WE - io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR) + io = m.IO( + RADDR=m.In(m.Bits[addr_width]), + RDATA=m.Out(m.BIts[data_width]), + WADDR=m.In(m.Bits[addr_width]), + WDATA=m.In(m.BIts[data_width]), + WE=m.In(m.Bit), + CLK=m.In(m.Clock), + RESET=m.In(m.Reset), + ) + + regs = [m.Register(m.Bits[data_width], init=int(init[i]), + has_enable=True, reset_type=m.Reset) + for i in range(1 << addr_width)] + for i, reg in enumerate(regs): + reg.I @= io.WDATA + reg.CE @= (io.WADDR == m.bits(i, addr_width)) & io.WE + io.RDATA @= m.mux([reg.O for reg in regs], io.RADDR) ``` First, define a subclass `ReadTester` of `fault.Tester` that provides an From 1c08e42ebd0e3621858dab6e8ce6bb05dc750006 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 19:38:55 -0800 Subject: [PATCH 17/19] Update code --- tutorial/exercise_1.py | 5 ++--- tutorial/exercise_2.py | 11 +++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tutorial/exercise_1.py b/tutorial/exercise_1.py index ef0e73a0..89a823a5 100644 --- a/tutorial/exercise_1.py +++ b/tutorial/exercise_1.py @@ -1,12 +1,11 @@ import magma as m -# import mantle class ConfigReg(m.Circuit): io = m.IO(D=m.In(m.Bits[2]), Q=m.Out(m.Bits[2])) + \ m.ClockIO(has_ce=True) - reg = mantle.Register(2, has_ce=True, name="config_reg") + reg = m.Register(m.Bits[2], has_enable=True)(name="config_reg") io.Q <= reg(io.D, CE=io.CE) @@ -19,5 +18,5 @@ class SimpleALU(m.Circuit): ) + m.ClockIO() opcode = ConfigReg(name="opcode_reg")(io.config_data, CE=io.config_en) - io.c <= mantle.mux( + io.c <= m.mux( [io.a + io.b, io.a - io.b, io.a * io.b, io.b - io.a], opcode) diff --git a/tutorial/exercise_2.py b/tutorial/exercise_2.py index c21d2e1e..bc14f876 100644 --- a/tutorial/exercise_2.py +++ b/tutorial/exercise_2.py @@ -1,5 +1,4 @@ import magma as m -# import mantle import fault from reset_tester import ResetTester @@ -18,11 +17,11 @@ class ROM(m.Circuit): CLK=m.In(m.Clock) ) - regs = [mantle.Register(data_width, init=int(init[i])) + regs = [m.Register(m.Bits[data_width], init=int(init[i]))() for i in range(1 << addr_width)] for reg in regs: reg.I <= reg.O - io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR) + io.RDATA <= m.mux([reg.O for reg in regs], io.RADDR) class RAM(m.Circuit): @@ -36,10 +35,10 @@ class RAM(m.Circuit): RESET=m.In(m.Reset) ) - regs = [mantle.Register(data_width, init=int(init[i]), has_ce=True, - has_reset=True) + regs = [m.Register(m.Bits[data_width], init=int(init[i]), has_enable=True, + reset_type=m.Reset) for i in range(1 << addr_width)] for i, reg in enumerate(regs): reg.I <= io.WDATA reg.CE <= (io.WADDR == m.bits(i, addr_width)) & io.WE - io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR) + io.RDATA <= m.mux([reg.O for reg in regs], io.RADDR) From e44b6716acda01b85d6a36af20e82a3280191cbb Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 20:05:32 -0800 Subject: [PATCH 18/19] Skip internal register hack --- tests/test_setattr_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_setattr_interface.py b/tests/test_setattr_interface.py index d892733c..76bba683 100644 --- a/tests/test_setattr_interface.py +++ b/tests/test_setattr_interface.py @@ -65,6 +65,7 @@ def test_tester_magma_internal_signals(target, simulator, capsys): assert expected == actual, "Print of internal register value did not work" +@pytest.mark.skip("Unsupported for MLIR") def test_tester_poke_internal_register(target, simulator, capsys): if target == "python": pytest.skip("Wrapped verilog not supported by Python simulator") From ff7d8897738178cc0ee2967bcdb9c471ca84a1a8 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 6 Dec 2023 20:06:33 -0800 Subject: [PATCH 19/19] Use mlir verilog output --- tests/test_tester/test_synchronous.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_tester/test_synchronous.py b/tests/test_tester/test_synchronous.py index 52cb1d3d..6b7c05bb 100644 --- a/tests/test_tester/test_synchronous.py +++ b/tests/test_tester/test_synchronous.py @@ -33,7 +33,8 @@ def test_synchronous_basic(target, simulator): if target == "verilator": with tempfile.TemporaryDirectory(dir=".") as tempdir: - tester.compile_and_run("verilator", directory=tempdir) + tester.compile_and_run("verilator", directory=tempdir, + magma_output="mlir-verilog") else: tester.compile_and_run(target, simulator=simulator, magma_opts={"sv": True})