Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autowrap and network construction features #212

Merged
merged 30 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8cde8dd
work in progress
sgherbst Apr 24, 2024
2ac6a13
automatically set up interfaces
sgherbst Apr 25, 2024
4bcbdc3
get autowrap working for axi and axil
sgherbst Apr 25, 2024
763f341
further simplification of examples using autowrap
sgherbst Apr 25, 2024
875430d
new mechanism for accessing interfaces
sgherbst Apr 26, 2024
b6d7252
work in progress
sgherbst Apr 27, 2024
60f7c3c
umi_fifo network example works
sgherbst Apr 30, 2024
f388f89
fix bug in example
sgherbst Apr 30, 2024
be40b9d
update network example to use two rtl modules
sgherbst Apr 30, 2024
44c3ac9
automatically clean up queues created during a network simulation
sgherbst Apr 30, 2024
613366d
clean up diff
sgherbst Apr 30, 2024
11503b4
more interesting network example
sgherbst Apr 30, 2024
7ebe2ac
add network example to regression testing
sgherbst Apr 30, 2024
85eab26
remove network simulation from tests as an experiment
sgherbst Apr 30, 2024
be9b413
update documentation
sgherbst Apr 30, 2024
a40c8c1
max_rate and start_delay features for verilator and pybind
sgherbst May 2, 2024
d2875b2
fix bug in axi-lite max-rate implementation
sgherbst May 2, 2024
bc8698b
try adding verilator network test
sgherbst May 2, 2024
ee25b1d
implement max_rate and start_delay for non-verilator simulators
sgherbst May 2, 2024
8ffb423
fix bug in max_rate_tick
sgherbst May 3, 2024
4d65701
adjust max_rate behavior (work in progress)
sgherbst May 3, 2024
63ac1df
try disabling minimal test as an experiment
sgherbst May 3, 2024
5b7e567
run only the network test
sgherbst May 3, 2024
33e9e80
fix umi version for regression test
sgherbst May 3, 2024
c63e23e
fix lint
sgherbst May 4, 2024
2876815
fix mismatches in code vs documentation for examples
sgherbst May 4, 2024
ad87041
update documentation
sgherbst May 4, 2024
77eeaf7
Merge branch 'main' into sgh/autowrap
sgherbst May 7, 2024
5d93f65
Merge branch 'main' into sgh/autowrap
sgherbst May 8, 2024
c4f7f0d
fix typo
sgherbst May 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@v4

# note that "sb_loopback.v" is not included in linting. verible doesn't
# seem to be able to take into account the macro definitions in the port
# list, so linting unfortunately needs to be disabled for that file.

- name: Lint with Verible
run: |
find . \( \
Expand All @@ -64,6 +68,7 @@ jobs:
-or -path "./examples/deps/*" \
-or -name "axil_interconnect_wrap_1x2.v" \
-or -name "picorv32.v" \
-or -name "sb_loopback.v" \
\) > files.txt
cat files.txt
verible-verilog-lint \
Expand Down
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ The [python](python) example is similar to the [minimal](minimal) example, excep
We also provide a mechanism for bridging switchboard connections over TCP, which may be useful if you're running a simulation or FPGA-based emulator on one machine, but want to interact with it from another machine. The [tcp example](tcp) shows how to set this up; it's mostly a matter of calling `start_tcp_bridge` on the server and client sides.

Switchboard also supports mixed-signal simulation by using Xyce in conjunction with a digital simulator. The [xyce example](xyce) shows how this can be set up by instantiating a SPICE subcircuit as an ordinary Verilog module and calling `SbDut.input_analog()` to configure analog/digital interfaces.

For a preview of switchboard's new features to automatically generate Verilog wrappers and construct networks of simulations dynamically, have a look at the [network](network) example.
20 changes: 8 additions & 12 deletions examples/axi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,20 @@ PASS!

`make icarus` runs the example using Icarus Verilog as the digital simulator.

In the Verilog implementation, [testbench.sv](testbench.sv) instantiates a switchboard module that acts as an AXI manager.
In the Python script [test.py](test.py), an AXI interface is specified using the `interfaces` argument of `SbDut`. The name of the interface is `s_axi`, corresponding to the AXI port prefix in the `axi_ram` implementation. After simulation starts, the AXI interface object is retrieved from the `SbDut.intfs` dictionary.

```verilog
`include "switchboard.vh"
```python
interfaces = {
's_axi': dict(type='axi', dw=dw, aw=aw, idw=idw, direction='subordinate')
}

...

`SB_AXI_M(axi, DATA_WIDTH, ADDR_WIDTH, ID_WIDTH, "axi");
```

Based on the first argument, `axi`, the module instance is called `axi_sb_inst` and it connects to AXI signals starting with the prefix `axi`. The next three arguments specify the widths of the data, address, and ID buses, respectively. The last argument indicates that the switchboard queues to be used start with the prefix `axi`: `axi-aw.q`, `axi-w.q`, `axi-b.q`, `axi-ar.q`, `axi-r.q`.
dut = SbDut('axi_ram', ..., interfaces=interfaces, ...)

Various optional macro arguments can fine-tune the behavior, for example changing the clock signal name, which defaults to `clk`.

In the Python script [test.py](test.py), a corresponding `AxiTxRx` object is created, using the same shorthand for connecting to all 5 queues.
...

```python
axi = AxiTxRx('axi', data_width=..., addr_width=..., id_width=...)
axi = dut.intfs['s_axi'] # type: AxiTxRx
```

As with `UmiTxRx`, this object may be used to issue read and write transactions involving numpy scalars and arrays. Under the hood, each transaction may be converted to multiple cycles of AXI transactions, with the write strobe automatically calculated in each cycle.
Expand Down
28 changes: 23 additions & 5 deletions examples/axi/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@
import random
import numpy as np

from switchboard import SbDut, AxiTxRx
from switchboard import SbDut


def main():
# build the simulator
dut = build_testbench()

# create the queues
axi = AxiTxRx('axi', data_width=32, addr_width=13, id_width=8, max_beats=dut.args.max_beats)
# wire up max-beats argument
dut.intf_defs['s_axi']['max_beats'] = dut.args.max_beats

# launch the simulation
dut.simulate()

# run the test: write to random addresses and read back in a random order

axi = dut.intfs['s_axi']

addr_bytes = (axi.addr_width + 7) // 8

model = np.zeros((1 << axi.addr_width,), dtype=np.uint8)
Expand Down Expand Up @@ -70,6 +72,22 @@ def main():


def build_testbench():
dw = 32
aw = 13
idw = 8

parameters = dict(
DATA_WIDTH=dw,
ADDR_WIDTH=aw,
ID_WIDTH=idw,
)

interfaces = {
's_axi': dict(type='axi', dw=dw, aw=aw, idw=idw, direction='subordinate')
}

resets = [dict(name='rst', delay=8)]

extra_args = {
'-n': dict(type=int, default=10000, help='Number of'
' words to write as part of the test.'),
Expand All @@ -79,7 +97,8 @@ def build_testbench():
' number of beats to use in AXI transfers.')
}

dut = SbDut(cmdline=True, extra_args=extra_args)
dut = SbDut('axi_ram', autowrap=True, cmdline=True, extra_args=extra_args,
parameters=parameters, interfaces=interfaces, resets=resets)

dut.register_package_source(
'verilog-axi',
Expand All @@ -88,7 +107,6 @@ def build_testbench():
)

dut.input('rtl/axi_ram.v', package='verilog-axi')
dut.input('testbench.sv')

dut.add('tool', 'verilator', 'task', 'compile', 'warningoff',
['WIDTHEXPAND', 'CASEINCOMPLETE', 'WIDTHTRUNC', 'TIMESCALEMOD'])
Expand Down
69 changes: 0 additions & 69 deletions examples/axi/testbench.sv

This file was deleted.

20 changes: 8 additions & 12 deletions examples/axil/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,20 @@ PASS!

`make icarus` runs the example using Icarus Verilog as the digital simulator.

In the Verilog implementation, [testbench.sv](testbench.sv) instantiates a switchboard module that acts as an AXI-Lite manager.
In the Python script [test.py](test.py), an AXI-Lite interface is specified using the `interfaces` argument of `SbDut`. The name of the interface is `s_axil`, corresponding to the AXI-Lite port prefix in the `axil_ram` implementation. After simulation starts, the AXI-Lite interface object is retrieved from the `SbDut.intfs` dictionary.

```verilog
`include "switchboard.vh"
```python
interfaces = {
's_axil': dict(type='axil', dw=dw, aw=aw, direction='subordinate')
}

...

`SB_AXIL_M(axil, DATA_WIDTH, ADDR_WIDTH, "axil");
```

Based on the first argument, `axil`, the module instance is called `axil_sb_inst` and it connects to AXI-Lite signals starting with the prefix `axil`. The next two arguments specify the widths of the data and address buses, respectively. The last argument indicates that the switchboard queues to be used start with the prefix `axil`: `axil-aw.q`, `axil-w.q`, `axil-b.q`, `axil-ar.q`, `axil-r.q`.
dut = SbDut('axill_ram', ..., interfaces=interfaces, ...)

Various optional macro arguments can fine-tune the behavior, for example changing the clock signal name, which defaults to `clk`.

In the Python script [test.py](test.py), a corresponding `AxiLiteTxRx` object is created, using the same shorthand for connecting to all 5 queues.
...

```python
axil = AxiLiteTxRx('axil', data_width=..., addr_width=...)
axi = dut.intfs['s_axil'] # type: AxiLiteTxRx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a typo. Should be axil = dut.intfs['s_axil']

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch - fixed

```

As with `UmiTxRx`, this object may be used to issue read and write transactions involving numpy scalars and arrays. Under the hood, each transaction may be converted to multiple cycles of AXI transactions, with the write strobe automatically calculated in each cycle.
Expand Down
29 changes: 20 additions & 9 deletions examples/axil/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@
import random
import numpy as np

from switchboard import SbDut, AxiLiteTxRx
from switchboard import SbDut


def main():
# build the simulator
dut = build_testbench()

# create the queues
axil = AxiLiteTxRx('axil', data_width=32, addr_width=13)

# launch the simulation
dut.simulate()

# run the test: write to random addresses and read back in a random order

axil = dut.intfs['s_axil']

addr_bytes = (axil.addr_width + 7) // 8

model = np.zeros((1 << axil.addr_width,), dtype=np.uint8)
Expand Down Expand Up @@ -70,16 +69,29 @@ def main():


def build_testbench():
dw = 32
aw = 13

parameters = dict(
DATA_WIDTH=dw,
ADDR_WIDTH=aw
)

interfaces = {
's_axil': dict(type='axil', dw=dw, aw=aw, direction='subordinate')
}

resets = [dict(name='rst', delay=8)]

extra_args = {
'-n': dict(type=int, default=10000, help='Number of'
' words to write as part of the test.'),
'--max-bytes': dict(type=int, default=10, help='Maximum'
' number of bytes in any single read/write.'),
'--max-beats': dict(type=int, default=256, help='Maximum'
' number of beats to use in AXI transfers.')
' number of bytes in any single read/write.')
}

dut = SbDut(cmdline=True, extra_args=extra_args)
dut = SbDut('axil_ram', autowrap=True, cmdline=True, extra_args=extra_args,
parameters=parameters, interfaces=interfaces, resets=resets)

dut.register_package_source(
'verilog-axi',
Expand All @@ -88,7 +100,6 @@ def build_testbench():
)

dut.input('rtl/axil_ram.v', package='verilog-axi')
dut.input('testbench.sv')

dut.add('tool', 'verilator', 'task', 'compile', 'warningoff',
['WIDTHTRUNC', 'TIMESCALEMOD'])
Expand Down
67 changes: 0 additions & 67 deletions examples/axil/testbench.sv

This file was deleted.

34 changes: 34 additions & 0 deletions examples/common/verilog/sb_loopback.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2024 Zero ASIC Corporation
// This code is licensed under Apache License 2.0 (see LICENSE for details)

`default_nettype none

`include "switchboard.vh"

module sb_loopback #(
parameter DW=256,
parameter [7:0] INCREMENT=1
) (
input clk,

`SB_INPUT(in, DW),
`SB_OUTPUT(out, DW)
);

// loopback with increment

genvar i;
generate
for (i=0; i<(DW/8); i=i+1) begin
assign out_data[(i*8) +: 8] = in_data[(i*8) +: 8] + INCREMENT;
end
endgenerate

assign out_dest = in_dest;
assign out_last = in_last;
assign out_valid = in_valid;
assign in_ready = out_ready;

endmodule

`default_nettype wire
Loading