cores/microwatt: move microwatt.py to its own python module.

Also:
* update dependencies.
* add amaranth-soc as a dependency, in order to reuse its bus
  interfaces (e.g. Wishbone).
* add a `prog` argument to PowerFVSession that overrides the name of
  its CLI.
main
Jean-François Nguyen 2 years ago
parent a5e69954a4
commit ec7cfdd719

@ -7,7 +7,7 @@
Get Microwatt:

```
git clone git@git.openpower.foundation:jfng/microwatt -b powerfv microwatt-src
git clone git@git.openpower.foundation:jfng/microwatt -b powerfv src
```

## Usage

@ -3,5 +3,5 @@ check cia --depth=15
check gpr --depth=15
check insn --depth=15

build --build-dir=./build --src-dir=./microwatt-src
build --build-dir=./build --src-dir=./src
exit

@ -0,0 +1,13 @@
from pathlib import PurePath
from power_fv.session import PowerFVSession

from .core import MicrowattCore


class MicrowattSession(PowerFVSession, core_cls=MicrowattCore):
pass


if __name__ == "__main__":
PROG = "python -m {}".format(PurePath(__file__).parent.name)
MicrowattSession(prog=PROG).main()

@ -4,13 +4,13 @@ import textwrap

from amaranth import *
from amaranth.asserts import *
from amaranth_soc import wishbone

from power_fv import pfv
from power_fv.core import PowerFVCore
from power_fv.session import PowerFVSession


__all__ = ["MicrowattWrapper", "MicrowattCore", "MicrowattSession"]
__all__ = ["MicrowattWrapper", "MicrowattCore"]


class MicrowattWrapper(Elaboratable):
@ -135,49 +135,58 @@ class MicrowattWrapper(Elaboratable):

def __init__(self, **kwargs):
self.pfv = pfv.Interface()
self._kwargs = kwargs
self.wb_insn = wishbone.Interface(addr_width=29, data_width=64, granularity=8,
features=("stall",))
self.wb_data = wishbone.Interface(addr_width=29, data_width=64, granularity=8,
features=("stall",))

def _render_toplevel(self):
return self.MICROWATT_TOPLEVEL.format(**self._kwargs)
def keep_wb_fanout(wb_bus):
for field_name in ("adr", "dat_w", "sel", "cyc", "stb", "we"):
wb_bus[field_name].attrs["keep"] = True

keep_wb_fanout(self.wb_insn)
keep_wb_fanout(self.wb_data)

self._toplevel_src = self.MICROWATT_TOPLEVEL.format(**kwargs)

def elaborate(self, platform):
m = Module()

wb_insn_dat_r = AnySeq(64)
wb_insn_ack = AnySeq( 1)
wb_insn_stall = AnySeq( 1)
wb_insn_adr = Signal(29, attrs={"keep": True})
wb_insn_dat_w = Signal(64, attrs={"keep": True})
wb_insn_sel = Signal( 8, attrs={"keep": True})
wb_insn_cyc = Signal( attrs={"keep": True})
wb_insn_stb = Signal( attrs={"keep": True})
wb_insn_we = Signal( attrs={"keep": True})

wb_data_dat_r = AnySeq(64)
wb_data_ack = AnySeq( 1)
wb_data_stall = AnySeq( 1)
wb_data_adr = Signal(29, attrs={"keep": True})
wb_data_dat_w = Signal(64, attrs={"keep": True})
wb_data_sel = Signal( 8, attrs={"keep": True})
wb_data_cyc = Signal( 1, attrs={"keep": True})
wb_data_stb = Signal( 1, attrs={"keep": True})
wb_data_we = Signal( 1, attrs={"keep": True})

wb_snoop_adr = AnySeq(29)
wb_snoop_dat_w = AnySeq(64)
wb_snoop_sel = AnySeq( 8)
wb_snoop_cyc = AnySeq( 1)
wb_snoop_stb = AnySeq( 1)
wb_snoop_we = AnySeq( 1)

dmi_addr = AnySeq( 4)
dmi_din = AnySeq(64)
dmi_req = AnySeq( 1)
dmi_wr = AnySeq( 1)
dmi_dout = Signal(64, attrs={"keep": True})
dmi_ack = Signal( attrs={"keep": True})

terminated = Signal( attrs={"keep": True})
wb_snoop = wishbone.Interface(addr_width=29, data_width=64, granularity=8)
dmi = Record([
("addr", unsigned( 4)),
("din", unsigned(64)),
("dout", unsigned(64)),
("req", unsigned( 1)),
("wr", unsigned( 1)),
("ack", unsigned( 1)),
])
terminated = Signal(attrs={"keep": True})

dmi.dout.attrs["keep"] = True
dmi.ack .attrs["keep"] = True

m.d.comb += [
self.wb_insn.dat_r.eq(AnySeq(64)),
self.wb_insn.ack .eq(AnySeq( 1)),
self.wb_insn.stall.eq(AnySeq( 1)),

self.wb_data.dat_r.eq(AnySeq(64)),
self.wb_data.ack .eq(AnySeq( 1)),
self.wb_data.stall.eq(AnySeq( 1)),

wb_snoop.adr .eq(AnySeq(29)),
wb_snoop.dat_w.eq(AnySeq(64)),
wb_snoop.sel .eq(AnySeq( 8)),
wb_snoop.cyc .eq(AnySeq( 1)),
wb_snoop.stb .eq(AnySeq( 1)),
wb_snoop.we .eq(AnySeq( 1)),

dmi.addr.eq(AnySeq( 4)),
dmi.din .eq(AnySeq(64)),
dmi.req .eq(AnySeq( 1)),
dmi.wr .eq(AnySeq( 1)),
]

m.submodules.dut = Instance("toplevel",
("i", "clk", ClockSignal()),
@ -185,39 +194,39 @@ class MicrowattWrapper(Elaboratable):
("i", "alt_reset", Const(0)),
("i", "ext_irq", Const(0)),

("i", "wishbone_insn_in.dat" , wb_insn_dat_r),
("i", "wishbone_insn_in.ack" , wb_insn_ack ),
("i", "wishbone_insn_in.stall", wb_insn_stall),
("o", "wishbone_insn_out.adr" , wb_insn_adr ),
("o", "wishbone_insn_out.dat" , wb_insn_dat_w),
("o", "wishbone_insn_out.sel" , wb_insn_sel ),
("o", "wishbone_insn_out.cyc" , wb_insn_cyc ),
("o", "wishbone_insn_out.stb" , wb_insn_stb ),
("o", "wishbone_insn_out.we" , wb_insn_we ),

("i", "wishbone_data_in.dat" , wb_data_dat_r),
("i", "wishbone_data_in.ack" , wb_data_ack ),
("i", "wishbone_data_in.stall", wb_data_stall),
("o", "wishbone_data_out.adr" , wb_data_adr ),
("o", "wishbone_data_out.dat" , wb_data_dat_w),
("o", "wishbone_data_out.sel" , wb_data_sel ),
("o", "wishbone_data_out.cyc" , wb_data_cyc ),
("o", "wishbone_data_out.stb" , wb_data_stb ),
("o", "wishbone_data_out.we" , wb_data_we ),

("i", "wb_snoop_in.adr", wb_snoop_adr ),
("i", "wb_snoop_in.dat", wb_snoop_dat_w),
("i", "wb_snoop_in.sel", wb_snoop_sel ),
("i", "wb_snoop_in.cyc", wb_snoop_cyc ),
("i", "wb_snoop_in.stb", wb_snoop_stb ),
("i", "wb_snoop_in.we" , wb_snoop_we ),

("i", "dmi_addr", dmi_addr),
("i", "dmi_din" , dmi_din ),
("o", "dmi_dout", dmi_dout),
("i", "dmi_req" , dmi_req ),
("i", "dmi_wr" , dmi_wr ),
("o", "dmi_ack" , dmi_ack ),
("i", "wishbone_insn_in.dat" , self.wb_insn.dat_r),
("i", "wishbone_insn_in.ack" , self.wb_insn.ack ),
("i", "wishbone_insn_in.stall", self.wb_insn.stall),
("o", "wishbone_insn_out.adr" , self.wb_insn.adr ),
("o", "wishbone_insn_out.dat" , self.wb_insn.dat_w),
("o", "wishbone_insn_out.sel" , self.wb_insn.sel ),
("o", "wishbone_insn_out.cyc" , self.wb_insn.cyc ),
("o", "wishbone_insn_out.stb" , self.wb_insn.stb ),
("o", "wishbone_insn_out.we" , self.wb_insn.we ),

("i", "wishbone_data_in.dat" , self.wb_data.dat_r),
("i", "wishbone_data_in.ack" , self.wb_data.ack ),
("i", "wishbone_data_in.stall", self.wb_data.stall),
("o", "wishbone_data_out.adr" , self.wb_data.adr ),
("o", "wishbone_data_out.dat" , self.wb_data.dat_w),
("o", "wishbone_data_out.sel" , self.wb_data.sel ),
("o", "wishbone_data_out.cyc" , self.wb_data.cyc ),
("o", "wishbone_data_out.stb" , self.wb_data.stb ),
("o", "wishbone_data_out.we" , self.wb_data.we ),

("i", "wb_snoop_in.adr", wb_snoop.adr ),
("i", "wb_snoop_in.dat", wb_snoop.dat_w),
("i", "wb_snoop_in.sel", wb_snoop.sel ),
("i", "wb_snoop_in.cyc", wb_snoop.cyc ),
("i", "wb_snoop_in.stb", wb_snoop.stb ),
("i", "wb_snoop_in.we" , wb_snoop.we ),

("i", "dmi_addr", dmi.addr),
("i", "dmi_din" , dmi.din ),
("o", "dmi_dout", dmi.dout),
("i", "dmi_req" , dmi.req ),
("i", "dmi_wr" , dmi.wr ),
("o", "dmi_ack" , dmi.ack ),

("o", "terminated_out", terminated),

@ -231,6 +240,7 @@ class MicrowattWrapper(Elaboratable):
("o", "pfv_out.rb" , self.pfv.rb ),
("o", "pfv_out.rs" , self.pfv.rs ),
("o", "pfv_out.rt" , self.pfv.rt ),
("o", "pfv_out.mem" , self.pfv.mem ),
("o", "pfv_out.cr" , self.pfv.cr ),
("o", "pfv_out.msr" , self.pfv.msr ),
("o", "pfv_out.lr" , self.pfv.lr ),
@ -242,7 +252,7 @@ class MicrowattWrapper(Elaboratable):
)

m.d.comb += [
Assume(~dmi_req),
Assume(~dmi.req),
Assume(~terminated),
]

@ -301,7 +311,7 @@ class MicrowattCore(PowerFVCore):
super().add_build_arguments(parser)
group = parser.add_argument_group(title="microwatt options")
group.add_argument(
"--src-dir", type=pathlib.Path, default=pathlib.Path("./microwatt-src"),
"--src-dir", type=pathlib.Path, default=pathlib.Path("./src"),
help="microwatt directory (default: %(default)s)")
group.add_argument(
"--ghdl-opts", type=str, default="--std=08",
@ -316,13 +326,5 @@ class MicrowattCore(PowerFVCore):
platform.add_file(filename, contents)

top_filename = "top-powerfv.vhdl"
top_contents = wrapper._render_toplevel()
top_contents = wrapper._toplevel_src
platform.add_file(top_filename, top_contents)


class MicrowattSession(PowerFVSession, core_cls=MicrowattCore):
pass


if __name__ == "__main__":
MicrowattSession().main()

51
poetry.lock generated

@ -1,16 +1,16 @@
[[package]]
name = "amaranth"
version = "0.4.dev11+g85d56a7"
version = "0.4.dev21+gdb49294"
description = "Amaranth hardware definition language"
category = "main"
optional = false
python-versions = "~=3.6"
python-versions = "~=3.7"
develop = false

[package.dependencies]
importlib-resources = {version = "*", markers = "python_version < \"3.9\""}
Jinja2 = ">=3.0,<4.0"
pyvcd = ">=0.2.2,<0.3.0"
pyvcd = ">=0.2.2,<0.4"

[package.extras]
builtin-yosys = ["amaranth-yosys (>=0.10)"]
@ -20,11 +20,29 @@ remote-build = ["paramiko (>=2.7,<3.0)"]
type = "git"
url = "https://github.com/amaranth-lang/amaranth.git"
reference = "main"
resolved_reference = "85d56a74a595bac5b4423ace5462bc7452cfacbb"
resolved_reference = "db49294cf722e9463666bd06f81a86f930b8707c"

[[package]]
name = "amaranth-soc"
version = "0.1.dev49+g217d4ea"
description = "System on Chip toolkit for Amaranth HDL"
category = "main"
optional = false
python-versions = "*"
develop = false

[package.dependencies]
amaranth = ">=0.2,<0.5"

[package.source]
type = "git"
url = "https://github.com/amaranth-lang/amaranth-soc.git"
reference = "main"
resolved_reference = "217d4ea76ad3b3bbf146980d168bc7b3b9d95a18"

[[package]]
name = "importlib-resources"
version = "5.6.0"
version = "5.8.0"
description = "Read resources from Python packages"
category = "main"
optional = false
@ -61,7 +79,7 @@ python-versions = ">=3.7"

[[package]]
name = "pyvcd"
version = "0.2.4"
version = "0.3.0"
description = "Python VCD file support"
category = "main"
optional = false
@ -69,26 +87,27 @@ python-versions = ">=3.6"

[[package]]
name = "zipp"
version = "3.7.0"
version = "3.8.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "main"
optional = false
python-versions = ">=3.7"

[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]

[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "8fbc350384d13e8a190df593335a502436e6b99dbf5aafefa5167db8c09206d6"
content-hash = "1c881976fce28a8b6924ba8df05bfa648b0c6098b5489df50523e968a6bfce73"

[metadata.files]
amaranth = []
amaranth-soc = []
importlib-resources = [
{file = "importlib_resources-5.6.0-py3-none-any.whl", hash = "sha256:a9dd72f6cc106aeb50f6e66b86b69b454766dd6e39b69ac68450253058706bcc"},
{file = "importlib_resources-5.6.0.tar.gz", hash = "sha256:1b93238cbf23b4cde34240dd8321d99e9bf2eb4bc91c0c99b2886283e7baad85"},
{file = "importlib_resources-5.8.0-py3-none-any.whl", hash = "sha256:7952325ffd516c05a8ad0858c74dff2c3343f136fe66a6002b2623dd1d43f223"},
{file = "importlib_resources-5.8.0.tar.gz", hash = "sha256:568c9f16cb204f9decc8d6d24a572eeea27dacbb4cee9e6b03a8025736769751"},
]
jinja2 = [
{file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"},
@ -137,10 +156,10 @@ markupsafe = [
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
]
pyvcd = [
{file = "pyvcd-0.2.4-py2.py3-none-any.whl", hash = "sha256:c40b0e586a74cddaf82e6989f0168ae7f9b4f182a9a106a0da9df0d11a9c6b3b"},
{file = "pyvcd-0.2.4.tar.gz", hash = "sha256:071e51a8362908ad5a2a12f078185639b98b20b653a56f01679de169d0fa425d"},
{file = "pyvcd-0.3.0-py2.py3-none-any.whl", hash = "sha256:971dfe5a3e68663115c6edf3f0b611ff9e8427513db16281eb4516ebcd65a336"},
{file = "pyvcd-0.3.0.tar.gz", hash = "sha256:ec4d9198bd20f9e07d78f6558ff8bcd45b172ee332e7e8a4588727eeb6a362bc"},
]
zipp = [
{file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"},
{file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"},
{file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
{file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
]

@ -37,8 +37,8 @@ class PowerFVSession:
.format(core_cls))
cls.core_cls = core_cls

def __init__(self):
self.parser = _ArgumentParser(add_help=False)
def __init__(self, prog=None):
self.parser = _ArgumentParser(prog=prog, add_help=False)
self.subparsers = self.parser.add_subparsers(help="commands")
self.namespace = dict()

@ -50,7 +50,7 @@ class PowerFVSession:
self.add_exit_subparser()

def main(self):
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(prog=self.parser.prog)
group = parser.add_mutually_exclusive_group()
group.add_argument(
"-i", dest="interact", action="store_true",
@ -60,7 +60,10 @@ class PowerFVSession:
help="run commands from CMDFILE")

args = parser.parse_args()
try:
self._loop(args)
except EOFError:
pass

def _loop(self, args):
if args.cmdfile is None:

@ -9,6 +9,7 @@ license = "BSD"
python = "^3.8"
jinja2 = "~3.0"
amaranth = {git = "https://github.com/amaranth-lang/amaranth.git", branch="main"}
amaranth_soc = {git = "https://github.com/amaranth-lang/amaranth-soc.git", branch="main"}

[build-system]
requires = ["poetry-core"]

Loading…
Cancel
Save