Skip to content

Commit a129df1

Browse files
Vunit buck2 and RDL buck2 improvements (#119)
* Note: can only deal with same-library VUnit projects right now. * Runs ghdl and works with waves etc * VUnit and RDL toolchains set up "properly" the buck2 way with toolchain files for python etc. * Add vunit to requirements.txt * VUnit hack to pin to repo-root unless over-ridden * Update jinja dep * Added buck2 info to the README and some basic rule docs Cleaned up references to cobalt and provided pointers to additional docs * Adjust things to work in windows also
1 parent 8d940db commit a129df1

29 files changed

+1968
-358
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@ BUILD.vars
33
/build
44
__pycache__
55

6+
# Buck2 ignores
7+
/buck-out
8+
9+
# VUnit ignores
10+
/vunit_out
11+
612
devcontainer.json
713

814
# VS Code settings
915
.vscode
1016

17+
# pycharm
18+
/.idea
19+
1120
# MacOS metadata
1221
.DS_Store

BUCK

-30
Original file line numberDiff line numberDiff line change
@@ -1,30 +0,0 @@
1-
load(":rdl.bzl", "rdl_file", "rdl_gen")
2-
3-
rdl_file(
4-
name = "gimlet_seq_fpga_regs",
5-
src = "gimlet_seq_fpga_regs.rdl",
6-
deps = [],
7-
)
8-
9-
rdl_gen(
10-
name = "gimlet_regs",
11-
srcs = [":gimlet_seq_fpga_regs"],
12-
outputs = ["gimlet.vhd", "gimlet.html", "gimlet.json", "gimlet.bsv"]
13-
)
14-
15-
rdl_file(
16-
name = "demo_rdl",
17-
src = "demo.rdl",
18-
deps = [],
19-
)
20-
rdl_file(
21-
name = "demo_top",
22-
src = "demo_top.rdl",
23-
deps = [":demo_rdl"],
24-
)
25-
26-
rdl_gen(
27-
name = "demo_test",
28-
srcs = [":demo_top"],
29-
outputs = ["demo.vhd", "demo.bsv", "demo.json", "demp_test.html"]
30-
)

BUCK_RULES.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
= Flow-specific BUCK rules
2+
3+
== VHDL files/module rule organization
4+
The expectation is that your BUCK files will have at least one entry
5+
for each vhdl "module" in your design. As a guideline, you should
6+
compose your modules such that any level that could be a dependency
7+
to some other module is factored into its own rule. It would be a
8+
common case for many VHDL package files to want be re-used in multiple
9+
places, so they would be put each in their own `vhdl_unit` rule.
10+
In cases where a package and some number of other files might make
11+
up a re-usable module all together but not separately, these could
12+
be put in a single `vhdl_unit` rule.
13+
14+
15+
The general VHDL rule in buck is defined [here](tools/hdl.bzl) as
16+
`vhdl_unit = rule(
17+
impl=_hdl_unit_impl,
18+
attrs={
19+
"deps": attrs.list(
20+
attrs.dep(doc="Dependencies as dep types (ie from another rule)"),
21+
default=[],
22+
),
23+
"srcs": attrs.list(attrs.source(doc="Expected VHDL sources")),
24+
"is_tb": attrs.bool(
25+
doc=(
26+
"Set to True when this is a top-level VUnit testbench\
27+
for which a run.py should be generate"
28+
),
29+
default=False,
30+
),
31+
"_toolchain": attrs.toolchain_dep(
32+
doc="Use system python toolchain for running VUnit",
33+
default="toolchains//:python",
34+
),
35+
"_bins": attrs.exec_dep(
36+
doc="Use vunit_gen toolchain for generating VUnit run.pys",
37+
default="root//tools/vunit_gen:vunit_gen",
38+
),
39+
},
40+
)`
41+
42+
`srcs` is a list of source files for this module, and glob can be used if it makes sense,
43+
`srcs = glob(["*.vhd"])` as an example with the paths being relative to the BUCK file.
44+
45+
`deps` expects a list of BUCK target patterns that point to other targets that this module
46+
depends on, typically RDL targets (see below) or other VHDL module targets. See
47+
[vunit_example](hdl/projects/vunit_example/BUCK) for some examples.
48+
49+
The remaining attributes should generally use the defaults and can be ignored.
50+
51+
52+
== System RDL
53+
Another simple rule here, but each RDL file gets its own rule entry.
54+
55+
The rdl rule in buck is defined [here](tools/rdl.bzl) as
56+
`rdl_file = rule(
57+
impl=_rdl_file_impl,
58+
attrs={
59+
"src": attrs.source(),
60+
"deps": attrs.list(attrs.dep(), default=[]),
61+
"outputs": attrs.list(attrs.string(), default=[]),
62+
"_rdl_gen": attrs.exec_dep(default="root//tools/site_cobble/rdl_pkg:rdl_cli"),
63+
},
64+
)`
65+
66+
The user provides the `src` file path and optionally any other RDL target patterns upon which
67+
this definition depends, and provides a list of expected `outputs`. Output type is determined
68+
by output extension, known possible output extensions are: `.bsv`, `.json`, `.vhd`, `.html`, `.adoc`
69+
70+
The `vhdl_unit` rule knows how to take the RDL targets as a dependency so long as a `.vhd` output is
71+
generated for the target that will be a dep to a VHDL block.

README.md

+62-20
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
# Quartz
22

3-
Quartz is a collection of soft-logic designs and hardware abstraction libraries (HALs) for various
4-
subsystems found in Oxide hardware. This includes components such as Ignition, power sequencing for
5-
system boards and QSFP interface management.
6-
7-
Quartz leans heavily on [Cobalt](https://github.com/oxidecomputer/cobalt) and unless a component is
8-
experimental or specific to an Oxide system, our posture should be to push as much into that project
9-
as possible. Having said that, it is acceptable to prototype in private under the Quartz project and
10-
move something to Cobalt once deemed ready.
3+
Quartz is a collection of soft-logic designs and hardware abstraction libraries
4+
(HALs) for various subsystems found in Oxide hardware. This includes components
5+
such as Ignition, power sequencing for system boards and QSFP interface
6+
management.
117

128
# Cloning instructions
139
Note that cobble is a submodule of cobalt which is used as a submodule here.
@@ -23,18 +19,64 @@ or if already checked out:
2319
```
2420

2521
# Build system help
26-
At the root of the Quartz directory, the BUILD.vars file controls machine-specific paths.
27-
It is recommended that you copy the BUILD.vars.example and adapt for your system paths.
28-
Typically this involves adjusting the [bluespec] [yosys] [nextpnr] sections to point to the tooling in your environment.
22+
In the long-term, we're migrating to buck2 as out build system but until we have
23+
reached parity, we are supporting designs that started using cobble still with
24+
cobble and new design flows using buck2.
25+
26+
## Cobble-based builds
27+
Currently the cobble build chain supports BSV designs and RDL generate
28+
targetting the yosys toolchain.
29+
30+
If you're looking for getting started with a cobble-based build see
31+
[instructions](COBALT_README.md) as well as some further tips
32+
[here](hdl/projects/gimlet/sequencer/README.md) At the root of the Quartz
33+
directory, the BUILD.vars file controls machine-specific paths. It is
34+
recommended that you copy the BUILD.vars.example and adapt for your system
35+
paths. Typically this involves adjusting the [bluespec] [yosys] [nextpnr]
36+
sections to point to the tooling in your environment.
37+
38+
### Adding new source files
39+
In each folder that is scanned, there is a BUILD file that includes the
40+
information for cobble to determine build targets and a complete dependency
41+
tree. In general, bluespec files get added as individual bluespec libraries,
42+
bluespec simulation targets get added as a bluespec_sim target, and
43+
bluesim_binary target.
44+
45+
For top-level designs that would synthesize to an FPGA, a bluespec_verilog
46+
target, a yosys_design target and a nextpnr target are needed to properly
47+
generate bitstreams.
48+
49+
### Adding new hardware targets
50+
To add support for a totally new chip design, a new "environment" in cobble
51+
parlance has to be created. This is done up at the root of the quartz repo in
52+
the BUILD.conf file.
53+
54+
## buck2 builds
55+
This area is under active development, currently supporting VHDL and RDL flows
56+
into VUnit simulations. FPGA toolchain support, and BSV support needs to be
57+
fleshed out.
58+
59+
The docker image does not currently contain buck2 executables.
60+
61+
For information on building `BUCK` files see [here](BUCK_RULES.md)
62+
63+
### Prerequisites
64+
- You need a copy of buck2 built locally. [Instructions](https://buck2.build/docs/getting_started/)
65+
- You'll need python3/pip installed and accessible on your path. We have python 3.10
66+
working in linux, and python 3.12 working in windows. Python 3.9 did not work in
67+
windows at least, we have no other data points on other python versions.
68+
- You'll need to install required python packages `pip install -r tools/requirements.txt`
69+
- You'll need to have GHDL installed and on your path (in linux this comes with
70+
the oss-cad-suite, but oss-cad-suite windows builds don't build GHDL). As of
71+
Jan '24, the ghdl-MINGW32 bit nightly version was working in windows.
2972

30-
## Adding new source files
31-
In each folder that is scanned, there is a BUILD file that includes the information for cobble to determine build targets
32-
and a complete dependency tree. In general, bluespec files get added as individual bluespec libraries, bluespec simulation targets get added
33-
as a bluespec_sim target, and bluesim_binary target.
73+
:warning: **Windows Users**: You need to be in Developer Mode for buck2 to be
74+
able to use symlinks, and should consider setting `LongPathsEnabled` in regedit at
75+
`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem` to 1 and rebooting.
3476

35-
For top-level designs that would synthesize to an FPGA, a bluespec_verilog target, a yosys_design target and a nextpnr target are needed to
36-
properly generate bitstreams.
77+
### buck2 run
78+
Comprehensive buck2 command line guidance is out of the scope of this document
79+
but if you want to see a list of all available buck2 targets you can do: `buck2 ctargets /...`
3780

38-
## Adding new hardware targets
39-
To add support for a totally new chip design, a new "environment" in cobble parlance has to be created. This is done up at the root of the
40-
quartz repo in the BUILD.conf file.
81+
To run a simulation, pick one of the testbench targets and `buck2 run <target>` you may do
82+
`-- <vunit args>` if you need to pass arguments into VUnit.

demo.rdl

-74
This file was deleted.

demo_top.rdl

-6
This file was deleted.

hdl/projects/vunit_example/BUCK

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
load("//tools:hdl.bzl", "vhdl_unit")
2+
load("//tools:rdl.bzl", "rdl_file")
3+
4+
rdl_file(
5+
name = "gimlet_seq_fpga_regs",
6+
src = "gimlet_seq_fpga_regs.rdl",
7+
deps = [],
8+
outputs = ["gimlet.vhd", "gimlet.html", "gimlet.json", "gimlet.bsv"]
9+
)
10+
11+
vhdl_unit(
12+
name = "uart_rx",
13+
srcs = ["uart_rx.vhd",],
14+
)
15+
16+
vhdl_unit(
17+
name = "uart_tx",
18+
srcs = ["uart_tx.vhd"],
19+
)
20+
21+
vhdl_unit(
22+
name = "tb_uart_rx",
23+
srcs = ["tb_uart_rx.vhd"],
24+
deps = [":uart_rx", ":gimlet_seq_fpga_regs"],
25+
is_tb = True
26+
)
27+
28+
vhdl_unit(
29+
name = "tb_uart_tx",
30+
srcs = ["tb_uart_tx.vhd"],
31+
deps = [":uart_tx", ":gimlet_seq_fpga_regs"],
32+
is_tb = True
33+
)

0 commit comments

Comments
 (0)