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: 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 ## Usage

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


build --build-dir=./build --src-dir=./microwatt-src build --build-dir=./build --src-dir=./src
exit 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 import *
from amaranth.asserts import * from amaranth.asserts import *
from amaranth_soc import wishbone


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




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




class MicrowattWrapper(Elaboratable): class MicrowattWrapper(Elaboratable):
@ -134,50 +134,59 @@ class MicrowattWrapper(Elaboratable):
""") """)


def __init__(self, **kwargs): def __init__(self, **kwargs):
self.pfv = pfv.Interface() 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): def keep_wb_fanout(wb_bus):
return self.MICROWATT_TOPLEVEL.format(**self._kwargs) 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): def elaborate(self, platform):
m = Module() m = Module()


wb_insn_dat_r = AnySeq(64) wb_snoop = wishbone.Interface(addr_width=29, data_width=64, granularity=8)
wb_insn_ack = AnySeq( 1) dmi = Record([
wb_insn_stall = AnySeq( 1) ("addr", unsigned( 4)),
wb_insn_adr = Signal(29, attrs={"keep": True}) ("din", unsigned(64)),
wb_insn_dat_w = Signal(64, attrs={"keep": True}) ("dout", unsigned(64)),
wb_insn_sel = Signal( 8, attrs={"keep": True}) ("req", unsigned( 1)),
wb_insn_cyc = Signal( attrs={"keep": True}) ("wr", unsigned( 1)),
wb_insn_stb = Signal( attrs={"keep": True}) ("ack", unsigned( 1)),
wb_insn_we = Signal( attrs={"keep": True}) ])

terminated = Signal(attrs={"keep": True})
wb_data_dat_r = AnySeq(64)
wb_data_ack = AnySeq( 1) dmi.dout.attrs["keep"] = True
wb_data_stall = AnySeq( 1) dmi.ack .attrs["keep"] = True
wb_data_adr = Signal(29, attrs={"keep": True})
wb_data_dat_w = Signal(64, attrs={"keep": True}) m.d.comb += [
wb_data_sel = Signal( 8, attrs={"keep": True}) self.wb_insn.dat_r.eq(AnySeq(64)),
wb_data_cyc = Signal( 1, attrs={"keep": True}) self.wb_insn.ack .eq(AnySeq( 1)),
wb_data_stb = Signal( 1, attrs={"keep": True}) self.wb_insn.stall.eq(AnySeq( 1)),
wb_data_we = Signal( 1, attrs={"keep": True})

self.wb_data.dat_r.eq(AnySeq(64)),
wb_snoop_adr = AnySeq(29) self.wb_data.ack .eq(AnySeq( 1)),
wb_snoop_dat_w = AnySeq(64) self.wb_data.stall.eq(AnySeq( 1)),
wb_snoop_sel = AnySeq( 8)
wb_snoop_cyc = AnySeq( 1) wb_snoop.adr .eq(AnySeq(29)),
wb_snoop_stb = AnySeq( 1) wb_snoop.dat_w.eq(AnySeq(64)),
wb_snoop_we = AnySeq( 1) wb_snoop.sel .eq(AnySeq( 8)),

wb_snoop.cyc .eq(AnySeq( 1)),
dmi_addr = AnySeq( 4) wb_snoop.stb .eq(AnySeq( 1)),
dmi_din = AnySeq(64) wb_snoop.we .eq(AnySeq( 1)),
dmi_req = AnySeq( 1)
dmi_wr = AnySeq( 1) dmi.addr.eq(AnySeq( 4)),
dmi_dout = Signal(64, attrs={"keep": True}) dmi.din .eq(AnySeq(64)),
dmi_ack = Signal( attrs={"keep": True}) dmi.req .eq(AnySeq( 1)),

dmi.wr .eq(AnySeq( 1)),
terminated = Signal( attrs={"keep": True}) ]


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


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


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


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


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


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


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


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


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


top_filename = "top-powerfv.vhdl" top_filename = "top-powerfv.vhdl"
top_contents = wrapper._render_toplevel() top_contents = wrapper._toplevel_src
platform.add_file(top_filename, top_contents) 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]] [[package]]
name = "amaranth" name = "amaranth"
version = "0.4.dev11+g85d56a7" version = "0.4.dev21+gdb49294"
description = "Amaranth hardware definition language" description = "Amaranth hardware definition language"
category = "main" category = "main"
optional = false optional = false
python-versions = "~=3.6" python-versions = "~=3.7"
develop = false develop = false


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


[package.extras] [package.extras]
builtin-yosys = ["amaranth-yosys (>=0.10)"] builtin-yosys = ["amaranth-yosys (>=0.10)"]
@ -20,11 +20,29 @@ remote-build = ["paramiko (>=2.7,<3.0)"]
type = "git" type = "git"
url = "https://github.com/amaranth-lang/amaranth.git" url = "https://github.com/amaranth-lang/amaranth.git"
reference = "main" 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]] [[package]]
name = "importlib-resources" name = "importlib-resources"
version = "5.6.0" version = "5.8.0"
description = "Read resources from Python packages" description = "Read resources from Python packages"
category = "main" category = "main"
optional = false optional = false
@ -61,7 +79,7 @@ python-versions = ">=3.7"


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


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


[package.extras] [package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] 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"] 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] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.8" python-versions = "^3.8"
content-hash = "8fbc350384d13e8a190df593335a502436e6b99dbf5aafefa5167db8c09206d6" content-hash = "1c881976fce28a8b6924ba8df05bfa648b0c6098b5489df50523e968a6bfce73"


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

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


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


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


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


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


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

@ -9,6 +9,7 @@ license = "BSD"
python = "^3.8" python = "^3.8"
jinja2 = "~3.0" jinja2 = "~3.0"
amaranth = {git = "https://github.com/amaranth-lang/amaranth.git", branch="main"} 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] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]

Loading…
Cancel
Save