switchboard-hw 0.3.0__cp314-cp314-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _switchboard.cpython-314-darwin.so +0 -0
- switchboard/__init__.py +24 -0
- switchboard/ams.py +668 -0
- switchboard/apb.py +278 -0
- switchboard/autowrap.py +1000 -0
- switchboard/axi.py +571 -0
- switchboard/axil.py +348 -0
- switchboard/bitvector.py +112 -0
- switchboard/cmdline.py +142 -0
- switchboard/cpp/Makefile +13 -0
- switchboard/cpp/bitutil.h +39 -0
- switchboard/cpp/pagemap.h +91 -0
- switchboard/cpp/pciedev.h +86 -0
- switchboard/cpp/router.cc +89 -0
- switchboard/cpp/spsc_queue.h +267 -0
- switchboard/cpp/switchboard.hpp +257 -0
- switchboard/cpp/switchboard_pcie.hpp +234 -0
- switchboard/cpp/switchboard_tlm.hpp +98 -0
- switchboard/cpp/umilib.h +144 -0
- switchboard/cpp/umilib.hpp +113 -0
- switchboard/cpp/umisb.hpp +364 -0
- switchboard/cpp/xyce.hpp +90 -0
- switchboard/deps/__init__.py +0 -0
- switchboard/deps/verilog_axi.py +23 -0
- switchboard/dpi/__init__.py +0 -0
- switchboard/dpi/switchboard_dpi.cc +119 -0
- switchboard/dpi/switchboard_dpi.py +13 -0
- switchboard/dpi/xyce_dpi.cc +43 -0
- switchboard/gpio.py +108 -0
- switchboard/icarus.py +85 -0
- switchboard/loopback.py +157 -0
- switchboard/network.py +714 -0
- switchboard/pytest_plugin.py +11 -0
- switchboard/sbdesign.py +55 -0
- switchboard/sbdut.py +744 -0
- switchboard/sbtcp.py +345 -0
- switchboard/sc/__init__.py +0 -0
- switchboard/sc/morty/__init__.py +0 -0
- switchboard/sc/morty/uniquify.py +67 -0
- switchboard/sc/sed/__init__.py +0 -0
- switchboard/sc/sed/sed_remove.py +47 -0
- switchboard/sc/standalone_netlist_flow.py +25 -0
- switchboard/switchboard.py +53 -0
- switchboard/test_util.py +46 -0
- switchboard/uart_xactor.py +66 -0
- switchboard/umi.py +793 -0
- switchboard/util.py +131 -0
- switchboard/verilator/__init__.py +0 -0
- switchboard/verilator/config.vlt +13 -0
- switchboard/verilator/testbench.cc +143 -0
- switchboard/verilator/verilator.py +13 -0
- switchboard/verilator_run.py +31 -0
- switchboard/verilog/__init__.py +0 -0
- switchboard/verilog/common/__init__.py +0 -0
- switchboard/verilog/common/common.py +26 -0
- switchboard/verilog/common/switchboard.vh +429 -0
- switchboard/verilog/common/uart_xactor.sv +247 -0
- switchboard/verilog/common/umi_gpio.v +236 -0
- switchboard/verilog/fpga/__init__.py +0 -0
- switchboard/verilog/fpga/axi_reader.sv +82 -0
- switchboard/verilog/fpga/axi_writer.sv +111 -0
- switchboard/verilog/fpga/config_registers.sv +249 -0
- switchboard/verilog/fpga/fpga.py +21 -0
- switchboard/verilog/fpga/include/sb_queue_regmap.vh +21 -0
- switchboard/verilog/fpga/include/spsc_queue.vh +7 -0
- switchboard/verilog/fpga/memory_fault.sv +40 -0
- switchboard/verilog/fpga/sb_fpga_queues.sv +416 -0
- switchboard/verilog/fpga/sb_rx_fpga.sv +303 -0
- switchboard/verilog/fpga/sb_tx_fpga.sv +294 -0
- switchboard/verilog/fpga/umi_fpga_queues.sv +146 -0
- switchboard/verilog/sim/__init__.py +0 -0
- switchboard/verilog/sim/auto_stop_sim.sv +25 -0
- switchboard/verilog/sim/perf_meas_sim.sv +97 -0
- switchboard/verilog/sim/queue_to_sb_sim.sv +176 -0
- switchboard/verilog/sim/queue_to_umi_sim.sv +66 -0
- switchboard/verilog/sim/sb_apb_m.sv +146 -0
- switchboard/verilog/sim/sb_axi_m.sv +199 -0
- switchboard/verilog/sim/sb_axil_m.sv +180 -0
- switchboard/verilog/sim/sb_axil_s.sv +180 -0
- switchboard/verilog/sim/sb_clk_gen.sv +89 -0
- switchboard/verilog/sim/sb_jtag_rbb_sim.sv +148 -0
- switchboard/verilog/sim/sb_rx_sim.sv +55 -0
- switchboard/verilog/sim/sb_to_queue_sim.sv +196 -0
- switchboard/verilog/sim/sb_tx_sim.sv +55 -0
- switchboard/verilog/sim/switchboard_sim.py +49 -0
- switchboard/verilog/sim/umi_rx_sim.sv +61 -0
- switchboard/verilog/sim/umi_to_queue_sim.sv +66 -0
- switchboard/verilog/sim/umi_tx_sim.sv +61 -0
- switchboard/verilog/sim/xyce_intf.sv +67 -0
- switchboard/vpi/switchboard_vpi.cc +431 -0
- switchboard/vpi/xyce_vpi.cc +200 -0
- switchboard/warn.py +14 -0
- switchboard/xyce.py +27 -0
- switchboard_hw-0.3.0.dist-info/METADATA +303 -0
- switchboard_hw-0.3.0.dist-info/RECORD +99 -0
- switchboard_hw-0.3.0.dist-info/WHEEL +6 -0
- switchboard_hw-0.3.0.dist-info/entry_points.txt +6 -0
- switchboard_hw-0.3.0.dist-info/licenses/LICENSE +190 -0
- switchboard_hw-0.3.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
// Copyright (c) 2024 Zero ASIC Corporation
|
|
2
|
+
// This code is licensed under Apache License 2.0 (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
`default_nettype none
|
|
5
|
+
|
|
6
|
+
module sb_fpga_queues #(
|
|
7
|
+
parameter NUM_RX_QUEUES = 1,
|
|
8
|
+
parameter NUM_TX_QUEUES = 1,
|
|
9
|
+
parameter NUM_USER_REGS = 0,
|
|
10
|
+
|
|
11
|
+
parameter integer DW=416
|
|
12
|
+
) (
|
|
13
|
+
input wire clk,
|
|
14
|
+
input wire nreset,
|
|
15
|
+
|
|
16
|
+
// Switchboard interfaces
|
|
17
|
+
output wire [NUM_RX_QUEUES*DW-1:0] rx_data,
|
|
18
|
+
output wire [NUM_RX_QUEUES*32-1:0] rx_dest,
|
|
19
|
+
output wire [NUM_RX_QUEUES-1:0] rx_last,
|
|
20
|
+
input wire [NUM_RX_QUEUES-1:0] rx_ready,
|
|
21
|
+
output wire [NUM_RX_QUEUES-1:0] rx_valid,
|
|
22
|
+
|
|
23
|
+
input wire [NUM_TX_QUEUES*DW-1:0] tx_data,
|
|
24
|
+
input wire [NUM_TX_QUEUES*32-1:0] tx_dest,
|
|
25
|
+
input wire [NUM_TX_QUEUES-1:0] tx_last,
|
|
26
|
+
output wire [NUM_TX_QUEUES-1:0] tx_ready,
|
|
27
|
+
input wire [NUM_TX_QUEUES-1:0] tx_valid,
|
|
28
|
+
|
|
29
|
+
output wire [(NUM_USER_REGS > 0 ? NUM_USER_REGS : 1)*32-1:0] cfg_user,
|
|
30
|
+
|
|
31
|
+
// AXI manager interface for memory access
|
|
32
|
+
output wire [15:0] m_axi_awid,
|
|
33
|
+
output wire [63:0] m_axi_awaddr,
|
|
34
|
+
output wire [7:0] m_axi_awlen,
|
|
35
|
+
output wire [2:0] m_axi_awsize,
|
|
36
|
+
output wire [18:0] m_axi_awuser,
|
|
37
|
+
output wire m_axi_awvalid,
|
|
38
|
+
input wire m_axi_awready,
|
|
39
|
+
|
|
40
|
+
output wire [511:0] m_axi_wdata,
|
|
41
|
+
output wire [63:0] m_axi_wstrb,
|
|
42
|
+
output wire m_axi_wlast,
|
|
43
|
+
output wire m_axi_wvalid,
|
|
44
|
+
input wire m_axi_wready,
|
|
45
|
+
|
|
46
|
+
input wire [15:0] m_axi_bid,
|
|
47
|
+
input wire [1:0] m_axi_bresp,
|
|
48
|
+
input wire m_axi_bvalid,
|
|
49
|
+
output wire m_axi_bready,
|
|
50
|
+
|
|
51
|
+
output wire [15:0] m_axi_arid,
|
|
52
|
+
output wire [63:0] m_axi_araddr,
|
|
53
|
+
output wire [7:0] m_axi_arlen,
|
|
54
|
+
output wire [2:0] m_axi_arsize,
|
|
55
|
+
output wire [18:0] m_axi_aruser,
|
|
56
|
+
output wire m_axi_arvalid,
|
|
57
|
+
input wire m_axi_arready,
|
|
58
|
+
|
|
59
|
+
input wire [15:0] m_axi_rid,
|
|
60
|
+
input wire [511:0] m_axi_rdata,
|
|
61
|
+
input wire [1:0] m_axi_rresp,
|
|
62
|
+
input wire m_axi_rlast,
|
|
63
|
+
input wire m_axi_rvalid,
|
|
64
|
+
output wire m_axi_rready,
|
|
65
|
+
|
|
66
|
+
// AXIL subordinate interface for config registers
|
|
67
|
+
input wire s_axil_awvalid,
|
|
68
|
+
input wire [31:0] s_axil_awaddr,
|
|
69
|
+
output wire s_axil_awready,
|
|
70
|
+
|
|
71
|
+
input wire s_axil_wvalid,
|
|
72
|
+
input wire [31:0] s_axil_wdata,
|
|
73
|
+
input wire [3:0] s_axil_wstrb,
|
|
74
|
+
output wire s_axil_wready,
|
|
75
|
+
|
|
76
|
+
output wire s_axil_bvalid,
|
|
77
|
+
output wire [1:0] s_axil_bresp,
|
|
78
|
+
input wire s_axil_bready,
|
|
79
|
+
|
|
80
|
+
input wire s_axil_arvalid,
|
|
81
|
+
input wire [31:0] s_axil_araddr,
|
|
82
|
+
output wire s_axil_arready,
|
|
83
|
+
|
|
84
|
+
output wire s_axil_rvalid,
|
|
85
|
+
output wire [31:0] s_axil_rdata,
|
|
86
|
+
output wire [1:0] s_axil_rresp,
|
|
87
|
+
input wire s_axil_rready
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
localparam NUM_QUEUES = NUM_RX_QUEUES + NUM_TX_QUEUES;
|
|
91
|
+
// We have a fixed number of ID bits out, and we need to reserve a few for
|
|
92
|
+
// response routing in the arbiter.
|
|
93
|
+
localparam ID_WIDTH = 16 - $clog2(NUM_QUEUES);
|
|
94
|
+
|
|
95
|
+
wire [NUM_QUEUES-1:0] cfg_enable;
|
|
96
|
+
wire [NUM_QUEUES-1:0] cfg_reset;
|
|
97
|
+
wire [NUM_QUEUES*64-1:0] cfg_base_addr;
|
|
98
|
+
wire [NUM_QUEUES*32-1:0] cfg_capacity;
|
|
99
|
+
|
|
100
|
+
wire [NUM_QUEUES-1:0] status_idle;
|
|
101
|
+
|
|
102
|
+
wire [NUM_QUEUES*ID_WIDTH-1:0] axi_awid;
|
|
103
|
+
wire [NUM_QUEUES*64-1:0] axi_awaddr;
|
|
104
|
+
wire [NUM_QUEUES*8-1:0] axi_awlen;
|
|
105
|
+
wire [NUM_QUEUES*3-1:0] axi_awsize;
|
|
106
|
+
wire [NUM_QUEUES-1:0] axi_awvalid;
|
|
107
|
+
wire [NUM_QUEUES-1:0] axi_awready;
|
|
108
|
+
|
|
109
|
+
wire [NUM_QUEUES*512-1:0] axi_wdata;
|
|
110
|
+
wire [NUM_QUEUES*64-1:0] axi_wstrb;
|
|
111
|
+
wire [NUM_QUEUES-1:0] axi_wlast;
|
|
112
|
+
wire [NUM_QUEUES-1:0] axi_wvalid;
|
|
113
|
+
wire [NUM_QUEUES-1:0] axi_wready;
|
|
114
|
+
|
|
115
|
+
wire [NUM_QUEUES*ID_WIDTH-1:0] axi_bid;
|
|
116
|
+
wire [NUM_QUEUES*2-1:0] axi_bresp;
|
|
117
|
+
wire [NUM_QUEUES-1:0] axi_bvalid;
|
|
118
|
+
wire [NUM_QUEUES-1:0] axi_bready;
|
|
119
|
+
|
|
120
|
+
wire [NUM_QUEUES*ID_WIDTH-1:0] axi_arid;
|
|
121
|
+
wire [NUM_QUEUES*64-1:0] axi_araddr;
|
|
122
|
+
wire [NUM_QUEUES*8-1:0] axi_arlen;
|
|
123
|
+
wire [NUM_QUEUES*3-1:0] axi_arsize;
|
|
124
|
+
wire [NUM_QUEUES-1:0] axi_arvalid;
|
|
125
|
+
wire [NUM_QUEUES-1:0] axi_arready;
|
|
126
|
+
|
|
127
|
+
wire [NUM_QUEUES*ID_WIDTH-1:0] axi_rid;
|
|
128
|
+
wire [NUM_QUEUES*512-1:0] axi_rdata;
|
|
129
|
+
wire [NUM_QUEUES*2-1:0] axi_rresp;
|
|
130
|
+
wire [NUM_QUEUES-1:0] axi_rlast;
|
|
131
|
+
wire [NUM_QUEUES-1:0] axi_rvalid;
|
|
132
|
+
wire [NUM_QUEUES-1:0] axi_rready;
|
|
133
|
+
|
|
134
|
+
genvar i;
|
|
135
|
+
generate
|
|
136
|
+
for (i = 0; i < NUM_RX_QUEUES; i = i + 1) begin
|
|
137
|
+
sb_rx_fpga #(
|
|
138
|
+
.ID_WIDTH(ID_WIDTH),
|
|
139
|
+
.DW(DW)
|
|
140
|
+
) rx (
|
|
141
|
+
.clk(clk),
|
|
142
|
+
.en(cfg_enable[2*i]),
|
|
143
|
+
.reset(cfg_reset[2*i]),
|
|
144
|
+
|
|
145
|
+
.cfg_base_addr(cfg_base_addr[64*(2*i)+:64]),
|
|
146
|
+
.cfg_capacity(cfg_capacity[32*(2*i)+:32]),
|
|
147
|
+
|
|
148
|
+
.status_idle(status_idle[2*i]),
|
|
149
|
+
|
|
150
|
+
.data(rx_data[DW*i+:DW]),
|
|
151
|
+
.dest(rx_dest[32*i+:32]),
|
|
152
|
+
.last(rx_last[i]),
|
|
153
|
+
.ready(rx_ready[i]),
|
|
154
|
+
.valid(rx_valid[i]),
|
|
155
|
+
|
|
156
|
+
.m_axi_awid(axi_awid[ID_WIDTH*i+:ID_WIDTH]),
|
|
157
|
+
.m_axi_awaddr(axi_awaddr[64*i+:64]),
|
|
158
|
+
.m_axi_awlen(axi_awlen[8*i+:8]),
|
|
159
|
+
.m_axi_awsize(axi_awsize[3*i+:3]),
|
|
160
|
+
.m_axi_awvalid(axi_awvalid[i]),
|
|
161
|
+
.m_axi_awready(axi_awready[i]),
|
|
162
|
+
|
|
163
|
+
.m_axi_wdata(axi_wdata[512*i+:512]),
|
|
164
|
+
.m_axi_wstrb(axi_wstrb[64*i+:64]),
|
|
165
|
+
.m_axi_wlast(axi_wlast[i]),
|
|
166
|
+
.m_axi_wvalid(axi_wvalid[i]),
|
|
167
|
+
.m_axi_wready(axi_wready[i]),
|
|
168
|
+
|
|
169
|
+
.m_axi_bid(axi_bid[ID_WIDTH*i+:ID_WIDTH]),
|
|
170
|
+
.m_axi_bresp(axi_bresp[2*i+:2]),
|
|
171
|
+
.m_axi_bvalid(axi_bvalid[i]),
|
|
172
|
+
.m_axi_bready(axi_bready[i]),
|
|
173
|
+
|
|
174
|
+
.m_axi_arid(axi_arid[ID_WIDTH*i+:ID_WIDTH]),
|
|
175
|
+
.m_axi_araddr(axi_araddr[64*i+:64]),
|
|
176
|
+
.m_axi_arlen(axi_arlen[8*i+:8]),
|
|
177
|
+
.m_axi_arsize(axi_arsize[3*i+:3]),
|
|
178
|
+
.m_axi_arvalid(axi_arvalid[i]),
|
|
179
|
+
.m_axi_arready(axi_arready[i]),
|
|
180
|
+
|
|
181
|
+
.m_axi_rid(axi_rid[ID_WIDTH*i+:ID_WIDTH]),
|
|
182
|
+
.m_axi_rdata(axi_rdata[512*i+:512]),
|
|
183
|
+
.m_axi_rresp(axi_rresp[2*i+:2]),
|
|
184
|
+
.m_axi_rlast(axi_rlast[i]),
|
|
185
|
+
.m_axi_rvalid(axi_rvalid[i]),
|
|
186
|
+
.m_axi_rready(axi_rready[i])
|
|
187
|
+
);
|
|
188
|
+
end
|
|
189
|
+
endgenerate
|
|
190
|
+
|
|
191
|
+
generate
|
|
192
|
+
for (i = NUM_RX_QUEUES; i < NUM_QUEUES; i = i + 1) begin
|
|
193
|
+
sb_tx_fpga #(
|
|
194
|
+
.ID_WIDTH(ID_WIDTH),
|
|
195
|
+
.DW(DW)
|
|
196
|
+
) tx (
|
|
197
|
+
.clk(clk),
|
|
198
|
+
.en(cfg_enable[2*(i-NUM_RX_QUEUES)+1]),
|
|
199
|
+
.reset(cfg_reset[2*(i-NUM_RX_QUEUES)+1]),
|
|
200
|
+
|
|
201
|
+
.cfg_base_addr(cfg_base_addr[64*(2*(i-NUM_RX_QUEUES)+1)+:64]),
|
|
202
|
+
.cfg_capacity(cfg_capacity[32*(2*(i-NUM_RX_QUEUES)+1)+:32]),
|
|
203
|
+
|
|
204
|
+
.status_idle(status_idle[2*(i-NUM_RX_QUEUES)+1]),
|
|
205
|
+
|
|
206
|
+
.data(tx_data[DW*(i-NUM_RX_QUEUES)+:DW]),
|
|
207
|
+
.dest(tx_dest[32*(i-NUM_RX_QUEUES)+:32]),
|
|
208
|
+
.last(tx_last[i-NUM_RX_QUEUES]),
|
|
209
|
+
.ready(tx_ready[i-NUM_RX_QUEUES]),
|
|
210
|
+
.valid(tx_valid[i-NUM_RX_QUEUES]),
|
|
211
|
+
|
|
212
|
+
.m_axi_awid(axi_awid[ID_WIDTH*i+:ID_WIDTH]),
|
|
213
|
+
.m_axi_awaddr(axi_awaddr[64*i+:64]),
|
|
214
|
+
.m_axi_awlen(axi_awlen[8*i+:8]),
|
|
215
|
+
.m_axi_awsize(axi_awsize[3*i+:3]),
|
|
216
|
+
.m_axi_awvalid(axi_awvalid[i]),
|
|
217
|
+
.m_axi_awready(axi_awready[i]),
|
|
218
|
+
|
|
219
|
+
.m_axi_wdata(axi_wdata[512*i+:512]),
|
|
220
|
+
.m_axi_wstrb(axi_wstrb[64*i+:64]),
|
|
221
|
+
.m_axi_wlast(axi_wlast[i]),
|
|
222
|
+
.m_axi_wvalid(axi_wvalid[i]),
|
|
223
|
+
.m_axi_wready(axi_wready[i]),
|
|
224
|
+
|
|
225
|
+
.m_axi_bid(axi_bid[ID_WIDTH*i+:ID_WIDTH]),
|
|
226
|
+
.m_axi_bresp(axi_bresp[2*i+:2]),
|
|
227
|
+
.m_axi_bvalid(axi_bvalid[i]),
|
|
228
|
+
.m_axi_bready(axi_bready[i]),
|
|
229
|
+
|
|
230
|
+
.m_axi_arid(axi_arid[ID_WIDTH*i+:ID_WIDTH]),
|
|
231
|
+
.m_axi_araddr(axi_araddr[64*i+:64]),
|
|
232
|
+
.m_axi_arlen(axi_arlen[8*i+:8]),
|
|
233
|
+
.m_axi_arsize(axi_arsize[3*i+:3]),
|
|
234
|
+
.m_axi_arvalid(axi_arvalid[i]),
|
|
235
|
+
.m_axi_arready(axi_arready[i]),
|
|
236
|
+
|
|
237
|
+
.m_axi_rid(axi_rid[ID_WIDTH*i+:ID_WIDTH]),
|
|
238
|
+
.m_axi_rdata(axi_rdata[512*i+:512]),
|
|
239
|
+
.m_axi_rresp(axi_rresp[2*i+:2]),
|
|
240
|
+
.m_axi_rlast(axi_rlast[i]),
|
|
241
|
+
.m_axi_rvalid(axi_rvalid[i]),
|
|
242
|
+
.m_axi_rready(axi_rready[i])
|
|
243
|
+
);
|
|
244
|
+
end
|
|
245
|
+
endgenerate
|
|
246
|
+
|
|
247
|
+
config_registers #(
|
|
248
|
+
.NUM_QUEUES(NUM_QUEUES),
|
|
249
|
+
.NUM_USER_REGS(NUM_USER_REGS)
|
|
250
|
+
) config_regs (
|
|
251
|
+
.clk(clk),
|
|
252
|
+
.nreset(nreset),
|
|
253
|
+
|
|
254
|
+
.status_idle(status_idle),
|
|
255
|
+
.cfg_enable(cfg_enable),
|
|
256
|
+
.cfg_reset(cfg_reset),
|
|
257
|
+
.cfg_base_addr(cfg_base_addr),
|
|
258
|
+
.cfg_capacity(cfg_capacity),
|
|
259
|
+
.cfg_user(cfg_user),
|
|
260
|
+
|
|
261
|
+
.s_axil_awaddr(s_axil_awaddr),
|
|
262
|
+
.s_axil_awvalid(s_axil_awvalid),
|
|
263
|
+
.s_axil_awready(s_axil_awready),
|
|
264
|
+
.s_axil_wdata(s_axil_wdata),
|
|
265
|
+
.s_axil_wstrb(s_axil_wstrb),
|
|
266
|
+
.s_axil_wvalid(s_axil_wvalid),
|
|
267
|
+
.s_axil_wready(s_axil_wready),
|
|
268
|
+
.s_axil_bresp(s_axil_bresp),
|
|
269
|
+
.s_axil_bvalid(s_axil_bvalid),
|
|
270
|
+
.s_axil_bready(s_axil_bready),
|
|
271
|
+
.s_axil_araddr(s_axil_araddr),
|
|
272
|
+
.s_axil_arvalid(s_axil_arvalid),
|
|
273
|
+
.s_axil_arready(s_axil_arready),
|
|
274
|
+
.s_axil_rdata(s_axil_rdata),
|
|
275
|
+
.s_axil_rresp(s_axil_rresp),
|
|
276
|
+
.s_axil_rvalid(s_axil_rvalid),
|
|
277
|
+
.s_axil_rready(s_axil_rready)
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// Handles arbitration between AXI interfaces on queues, as well as
|
|
281
|
+
// registering outputs.
|
|
282
|
+
axi_crossbar #(
|
|
283
|
+
.S_COUNT(NUM_QUEUES),
|
|
284
|
+
.M_COUNT(1),
|
|
285
|
+
.DATA_WIDTH(512),
|
|
286
|
+
.ADDR_WIDTH(64),
|
|
287
|
+
.S_ID_WIDTH(ID_WIDTH),
|
|
288
|
+
.M_ADDR_WIDTH(32'd64),
|
|
289
|
+
.S_AW_REG_TYPE({NUM_QUEUES{2'd0}}),
|
|
290
|
+
.S_W_REG_TYPE({NUM_QUEUES{2'd0}}),
|
|
291
|
+
.S_B_REG_TYPE({NUM_QUEUES{2'd0}}),
|
|
292
|
+
.S_AR_REG_TYPE({NUM_QUEUES{2'd0}}),
|
|
293
|
+
.S_R_REG_TYPE({NUM_QUEUES{2'd0}}),
|
|
294
|
+
.M_AW_REG_TYPE(2'd2),
|
|
295
|
+
.M_W_REG_TYPE(2'd2),
|
|
296
|
+
.M_B_REG_TYPE(2'd2),
|
|
297
|
+
.M_AR_REG_TYPE(2'd2),
|
|
298
|
+
.M_R_REG_TYPE(2'd2)
|
|
299
|
+
) crossbar (
|
|
300
|
+
.clk(clk),
|
|
301
|
+
.rst(~nreset),
|
|
302
|
+
|
|
303
|
+
.s_axi_awid(axi_awid),
|
|
304
|
+
.s_axi_awaddr(axi_awaddr),
|
|
305
|
+
.s_axi_awlen(axi_awlen),
|
|
306
|
+
.s_axi_awsize(axi_awsize),
|
|
307
|
+
.s_axi_awburst(),
|
|
308
|
+
.s_axi_awlock(),
|
|
309
|
+
.s_axi_awcache(),
|
|
310
|
+
.s_axi_awprot(),
|
|
311
|
+
.s_axi_awqos(),
|
|
312
|
+
.s_axi_awuser(),
|
|
313
|
+
.s_axi_awvalid(axi_awvalid),
|
|
314
|
+
.s_axi_awready(axi_awready),
|
|
315
|
+
.s_axi_wdata(axi_wdata),
|
|
316
|
+
.s_axi_wstrb(axi_wstrb),
|
|
317
|
+
.s_axi_wlast(axi_wlast),
|
|
318
|
+
.s_axi_wuser(),
|
|
319
|
+
.s_axi_wvalid(axi_wvalid),
|
|
320
|
+
.s_axi_wready(axi_wready),
|
|
321
|
+
.s_axi_bid(axi_bid),
|
|
322
|
+
.s_axi_bresp(axi_bresp),
|
|
323
|
+
.s_axi_buser(),
|
|
324
|
+
.s_axi_bvalid(axi_bvalid),
|
|
325
|
+
.s_axi_bready(axi_bready),
|
|
326
|
+
.s_axi_arid(axi_arid),
|
|
327
|
+
.s_axi_araddr(axi_araddr),
|
|
328
|
+
.s_axi_arlen(axi_arlen),
|
|
329
|
+
.s_axi_arsize(axi_arsize),
|
|
330
|
+
.s_axi_arburst(),
|
|
331
|
+
.s_axi_arlock(),
|
|
332
|
+
.s_axi_arcache(),
|
|
333
|
+
.s_axi_arprot(),
|
|
334
|
+
.s_axi_arqos(),
|
|
335
|
+
.s_axi_aruser(),
|
|
336
|
+
.s_axi_arvalid(axi_arvalid),
|
|
337
|
+
.s_axi_arready(axi_arready),
|
|
338
|
+
.s_axi_rid(axi_rid),
|
|
339
|
+
.s_axi_rdata(axi_rdata),
|
|
340
|
+
.s_axi_rresp(axi_rresp),
|
|
341
|
+
.s_axi_rlast(axi_rlast),
|
|
342
|
+
.s_axi_ruser(),
|
|
343
|
+
.s_axi_rvalid(axi_rvalid),
|
|
344
|
+
.s_axi_rready(axi_rready),
|
|
345
|
+
|
|
346
|
+
.m_axi_awid (m_axi_awid),
|
|
347
|
+
.m_axi_awaddr (m_axi_awaddr),
|
|
348
|
+
.m_axi_awlen (m_axi_awlen),
|
|
349
|
+
.m_axi_awsize (m_axi_awsize),
|
|
350
|
+
.m_axi_awburst (),
|
|
351
|
+
.m_axi_awlock (),
|
|
352
|
+
.m_axi_awcache (),
|
|
353
|
+
.m_axi_awprot (),
|
|
354
|
+
.m_axi_awqos (),
|
|
355
|
+
.m_axi_awregion (),
|
|
356
|
+
.m_axi_awuser (),
|
|
357
|
+
.m_axi_awvalid (m_axi_awvalid),
|
|
358
|
+
.m_axi_awready (m_axi_awready),
|
|
359
|
+
.m_axi_wdata (m_axi_wdata),
|
|
360
|
+
.m_axi_wstrb (m_axi_wstrb),
|
|
361
|
+
.m_axi_wlast (m_axi_wlast),
|
|
362
|
+
.m_axi_wuser (),
|
|
363
|
+
.m_axi_wvalid (m_axi_wvalid),
|
|
364
|
+
.m_axi_wready (m_axi_wready),
|
|
365
|
+
.m_axi_bid (m_axi_bid),
|
|
366
|
+
.m_axi_bresp (m_axi_bresp),
|
|
367
|
+
.m_axi_buser (),
|
|
368
|
+
.m_axi_bvalid (m_axi_bvalid),
|
|
369
|
+
.m_axi_bready (m_axi_bready),
|
|
370
|
+
.m_axi_arid (m_axi_arid),
|
|
371
|
+
.m_axi_araddr (m_axi_araddr),
|
|
372
|
+
.m_axi_arlen (m_axi_arlen),
|
|
373
|
+
.m_axi_arsize (m_axi_arsize),
|
|
374
|
+
.m_axi_arburst (),
|
|
375
|
+
.m_axi_arlock (),
|
|
376
|
+
.m_axi_arcache (),
|
|
377
|
+
.m_axi_arprot (),
|
|
378
|
+
.m_axi_arqos (),
|
|
379
|
+
.m_axi_arregion (),
|
|
380
|
+
.m_axi_aruser (),
|
|
381
|
+
.m_axi_arvalid (m_axi_arvalid),
|
|
382
|
+
.m_axi_arready (m_axi_arready),
|
|
383
|
+
.m_axi_rid (m_axi_rid),
|
|
384
|
+
.m_axi_rdata (m_axi_rdata),
|
|
385
|
+
.m_axi_rresp (m_axi_rresp),
|
|
386
|
+
.m_axi_rlast (m_axi_rlast),
|
|
387
|
+
.m_axi_ruser (),
|
|
388
|
+
.m_axi_rvalid (m_axi_rvalid),
|
|
389
|
+
.m_axi_rready (m_axi_rready)
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
`ifdef DEBUG
|
|
393
|
+
ila_0 ILA_PCIM_RD (
|
|
394
|
+
.clk (clk),
|
|
395
|
+
.probe0 (m_axi_arvalid),
|
|
396
|
+
.probe1 (m_axi_araddr),
|
|
397
|
+
.probe2 (m_axi_arready),
|
|
398
|
+
.probe3 (m_axi_rvalid),
|
|
399
|
+
.probe4 (m_axi_rdata[63:0]),
|
|
400
|
+
.probe5 (m_axi_rready)
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
ila_0 ILA_PCIM_WR (
|
|
404
|
+
.clk (clk),
|
|
405
|
+
.probe0 (m_axi_awvalid),
|
|
406
|
+
.probe1 (m_axi_awaddr),
|
|
407
|
+
.probe2 (m_axi_awready),
|
|
408
|
+
.probe3 (m_axi_wvalid),
|
|
409
|
+
.probe4 (m_axi_wdata[63:0]),
|
|
410
|
+
.probe5 (m_axi_wready)
|
|
411
|
+
);
|
|
412
|
+
`endif
|
|
413
|
+
|
|
414
|
+
endmodule
|
|
415
|
+
|
|
416
|
+
`default_nettype wire
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// Copyright (c) 2024 Zero ASIC Corporation
|
|
2
|
+
// This code is licensed under Apache License 2.0 (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
`default_nettype none
|
|
5
|
+
|
|
6
|
+
module sb_rx_fpga #(
|
|
7
|
+
parameter ID_WIDTH = 16,
|
|
8
|
+
// must be <= 448 (512-64)
|
|
9
|
+
parameter DW = 416
|
|
10
|
+
) (
|
|
11
|
+
input wire clk,
|
|
12
|
+
input wire en,
|
|
13
|
+
input wire reset,
|
|
14
|
+
|
|
15
|
+
output reg [DW-1:0] data={DW{1'b0}},
|
|
16
|
+
output reg [31:0] dest=32'b0,
|
|
17
|
+
output reg last=1'b0,
|
|
18
|
+
input wire ready,
|
|
19
|
+
output reg valid=1'b0,
|
|
20
|
+
|
|
21
|
+
input wire [63:0] cfg_base_addr,
|
|
22
|
+
input wire [31:0] cfg_capacity,
|
|
23
|
+
|
|
24
|
+
output wire status_idle,
|
|
25
|
+
|
|
26
|
+
output wire [ID_WIDTH-1:0] m_axi_awid,
|
|
27
|
+
output wire [63:0] m_axi_awaddr,
|
|
28
|
+
output wire [7:0] m_axi_awlen,
|
|
29
|
+
output wire [2:0] m_axi_awsize,
|
|
30
|
+
output wire m_axi_awvalid,
|
|
31
|
+
input wire m_axi_awready,
|
|
32
|
+
|
|
33
|
+
output wire [511:0] m_axi_wdata,
|
|
34
|
+
output wire [63:0] m_axi_wstrb,
|
|
35
|
+
output wire m_axi_wlast,
|
|
36
|
+
output wire m_axi_wvalid,
|
|
37
|
+
input wire m_axi_wready,
|
|
38
|
+
|
|
39
|
+
input wire [ID_WIDTH-1:0] m_axi_bid,
|
|
40
|
+
input wire [1:0] m_axi_bresp,
|
|
41
|
+
input wire m_axi_bvalid,
|
|
42
|
+
output wire m_axi_bready,
|
|
43
|
+
|
|
44
|
+
output wire [ID_WIDTH-1:0] m_axi_arid,
|
|
45
|
+
output wire [63:0] m_axi_araddr,
|
|
46
|
+
output wire [7:0] m_axi_arlen,
|
|
47
|
+
output wire [2:0] m_axi_arsize,
|
|
48
|
+
output wire m_axi_arvalid,
|
|
49
|
+
input wire m_axi_arready,
|
|
50
|
+
|
|
51
|
+
input wire [ID_WIDTH-1:0] m_axi_rid,
|
|
52
|
+
input wire [511:0] m_axi_rdata,
|
|
53
|
+
input wire [1:0] m_axi_rresp,
|
|
54
|
+
input wire m_axi_rlast,
|
|
55
|
+
input wire m_axi_rvalid,
|
|
56
|
+
output wire m_axi_rready
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
`include "spsc_queue.vh"
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* Main state machine
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
localparam [2:0] STATE_IDLE = 3'd0;
|
|
66
|
+
localparam [2:0] STATE_RD_HEAD = 3'd1;
|
|
67
|
+
localparam [2:0] STATE_RD_PACKET = 3'd2;
|
|
68
|
+
localparam [2:0] STATE_WR_TAIL = 3'd3;
|
|
69
|
+
localparam [2:0] STATE_FAULT = 3'd4;
|
|
70
|
+
|
|
71
|
+
wire wvalid;
|
|
72
|
+
reg [63:0] waddr;
|
|
73
|
+
reg [63:0] wstrb;
|
|
74
|
+
reg [511:0] wdata;
|
|
75
|
+
wire wready;
|
|
76
|
+
|
|
77
|
+
wire rvalid;
|
|
78
|
+
reg [63:0] raddr;
|
|
79
|
+
wire rready;
|
|
80
|
+
wire [511:0] rdata;
|
|
81
|
+
|
|
82
|
+
wire empty;
|
|
83
|
+
wire fault;
|
|
84
|
+
|
|
85
|
+
reg [2:0] state = STATE_IDLE;
|
|
86
|
+
reg [2:0] state_next;
|
|
87
|
+
|
|
88
|
+
always @(*) begin
|
|
89
|
+
state_next = state;
|
|
90
|
+
case (state)
|
|
91
|
+
STATE_IDLE: begin
|
|
92
|
+
if (!valid && en) begin
|
|
93
|
+
if (!empty) begin
|
|
94
|
+
state_next = STATE_RD_PACKET;
|
|
95
|
+
end else begin
|
|
96
|
+
state_next = STATE_RD_HEAD;
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
STATE_RD_HEAD: begin
|
|
102
|
+
if (rready && !en) begin
|
|
103
|
+
state_next = STATE_IDLE;
|
|
104
|
+
end else if (!empty) begin
|
|
105
|
+
state_next = STATE_RD_PACKET;
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
STATE_RD_PACKET: begin
|
|
110
|
+
// This state doesn't force a transition to IDLE on !en, since
|
|
111
|
+
// we always need to write the tail after reading the packet.
|
|
112
|
+
if (rready) begin
|
|
113
|
+
state_next = STATE_WR_TAIL;
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
STATE_WR_TAIL: begin
|
|
118
|
+
if (wready) begin
|
|
119
|
+
state_next = STATE_IDLE;
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
STATE_FAULT: begin
|
|
124
|
+
state_next = STATE_FAULT;
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
// Shouldn't reach here
|
|
128
|
+
default: state_next = 3'bXXX;
|
|
129
|
+
endcase
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
always @(posedge clk) begin
|
|
133
|
+
if (reset) begin
|
|
134
|
+
state <= STATE_IDLE;
|
|
135
|
+
end else if (fault) begin
|
|
136
|
+
state <= STATE_FAULT;
|
|
137
|
+
end else begin
|
|
138
|
+
state <= state_next;
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* Queue state logic
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
reg [31:0] head = 32'd0;
|
|
147
|
+
reg [31:0] tail = 32'd0;
|
|
148
|
+
wire [31:0] head_next;
|
|
149
|
+
wire [31:0] tail_next;
|
|
150
|
+
wire [31:0] tail_incr;
|
|
151
|
+
|
|
152
|
+
assign head_next = (state == STATE_RD_HEAD && rready) ? rdata[31:0] : head;
|
|
153
|
+
|
|
154
|
+
assign tail_incr = (tail + 32'd1 == cfg_capacity) ? 32'd0 : (tail + 32'd1);
|
|
155
|
+
assign tail_next = (state == STATE_RD_PACKET && rready) ? tail_incr : tail;
|
|
156
|
+
|
|
157
|
+
always @(posedge clk) begin
|
|
158
|
+
if (reset) begin
|
|
159
|
+
head <= 32'd0;
|
|
160
|
+
tail <= 32'd0;
|
|
161
|
+
end else begin
|
|
162
|
+
head <= head_next;
|
|
163
|
+
tail <= tail_next;
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
// Use *_next signals here to speed up state machine transitions.
|
|
168
|
+
assign empty = (head_next == tail_next);
|
|
169
|
+
|
|
170
|
+
// Addresses within queue
|
|
171
|
+
wire [63:0] head_addr;
|
|
172
|
+
wire [63:0] tail_addr;
|
|
173
|
+
assign head_addr = cfg_base_addr + HEAD_OFFSET;
|
|
174
|
+
assign tail_addr = cfg_base_addr + TAIL_OFFSET;
|
|
175
|
+
|
|
176
|
+
/*
|
|
177
|
+
* Checker for out-of-bounds writes
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
wire wvalid_checked;
|
|
181
|
+
wire [63:0] fault_addr;
|
|
182
|
+
memory_fault write_checker(
|
|
183
|
+
.clk(clk),
|
|
184
|
+
.reset(reset),
|
|
185
|
+
|
|
186
|
+
.access_valid_in(wvalid),
|
|
187
|
+
.access_addr(waddr),
|
|
188
|
+
.access_valid_out(wvalid_checked),
|
|
189
|
+
|
|
190
|
+
.base_legal_addr(cfg_base_addr),
|
|
191
|
+
.legal_length(cfg_capacity * PACKET_SIZE + PACKET_OFFSET),
|
|
192
|
+
|
|
193
|
+
.fault(fault),
|
|
194
|
+
.fault_addr(fault_addr)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
/*
|
|
198
|
+
* Simple W/R interface to AXI bus
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
axi_writer #(
|
|
202
|
+
.ID_WIDTH(ID_WIDTH)
|
|
203
|
+
) writer (
|
|
204
|
+
.wvalid(wvalid_checked),
|
|
205
|
+
.*
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
axi_reader #(
|
|
209
|
+
.ID_WIDTH(ID_WIDTH)
|
|
210
|
+
) reader (
|
|
211
|
+
.*
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
assign wvalid = (state == STATE_WR_TAIL);
|
|
215
|
+
always @(*) begin
|
|
216
|
+
waddr = 64'd0;
|
|
217
|
+
wstrb = 64'd0;
|
|
218
|
+
wdata = 512'd0;
|
|
219
|
+
if (state == STATE_WR_TAIL) begin
|
|
220
|
+
waddr = tail_addr;
|
|
221
|
+
wstrb = 64'hff;
|
|
222
|
+
wdata = {480'd0, tail};
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
assign rvalid = ((state == STATE_RD_HEAD) || (state == STATE_RD_PACKET));
|
|
226
|
+
always @(*) begin
|
|
227
|
+
raddr = 64'd0;
|
|
228
|
+
if (state == STATE_RD_HEAD) begin
|
|
229
|
+
raddr = head_addr;
|
|
230
|
+
end else if (state == STATE_RD_PACKET) begin
|
|
231
|
+
raddr = cfg_base_addr + PACKET_OFFSET + (tail * PACKET_SIZE);
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* SB handshaking
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
// This logic relies on maintaining invariant that valid != 1 when state ==
|
|
240
|
+
// STATE_RD_PACKET
|
|
241
|
+
always @(posedge clk) begin
|
|
242
|
+
if (reset) begin
|
|
243
|
+
valid <= 1'b0;
|
|
244
|
+
dest <= 32'd0;
|
|
245
|
+
last <= 1'b0;
|
|
246
|
+
data <= 'd0;
|
|
247
|
+
end else if (state == STATE_RD_PACKET && rready) begin
|
|
248
|
+
valid <= 1'b1;
|
|
249
|
+
dest <= rdata[31:0];
|
|
250
|
+
last <= rdata[32];
|
|
251
|
+
data <= rdata[DW+64-1:64];
|
|
252
|
+
end else if (valid && ready) begin
|
|
253
|
+
valid <= 1'b0;
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
assign status_idle = state == STATE_IDLE;
|
|
258
|
+
|
|
259
|
+
`ifdef DEBUG
|
|
260
|
+
ila_0 ILA_RD (
|
|
261
|
+
.clk (clk),
|
|
262
|
+
.probe0 (m_axi_arvalid),
|
|
263
|
+
.probe1 (m_axi_araddr),
|
|
264
|
+
.probe2 (m_axi_arready),
|
|
265
|
+
.probe3 (m_axi_rvalid),
|
|
266
|
+
.probe4 (m_axi_rdata[63:0]),
|
|
267
|
+
.probe5 (m_axi_rready)
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
ila_0 ILA_WR (
|
|
271
|
+
.clk (clk),
|
|
272
|
+
.probe0 (m_axi_awvalid),
|
|
273
|
+
.probe1 (m_axi_awaddr),
|
|
274
|
+
.probe2 (m_axi_awready),
|
|
275
|
+
.probe3 (m_axi_wvalid),
|
|
276
|
+
.probe4 (m_axi_wdata[63:0]),
|
|
277
|
+
.probe5 (m_axi_wready)
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
ila_0 ILA_STATE (
|
|
281
|
+
.clk (clk),
|
|
282
|
+
.probe0 (en),
|
|
283
|
+
.probe1 ({head, tail}),
|
|
284
|
+
.probe2 (valid),
|
|
285
|
+
.probe3 (ready),
|
|
286
|
+
.probe4 ({state, tail_incr}),
|
|
287
|
+
.probe5 (empty)
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
ila_0 ILA_FAULT (
|
|
291
|
+
.clk (clk),
|
|
292
|
+
.probe0 (fault),
|
|
293
|
+
.probe1 (fault_addr),
|
|
294
|
+
.probe2 (),
|
|
295
|
+
.probe3 (),
|
|
296
|
+
.probe4 (),
|
|
297
|
+
.probe5 ()
|
|
298
|
+
);
|
|
299
|
+
`endif
|
|
300
|
+
|
|
301
|
+
endmodule
|
|
302
|
+
|
|
303
|
+
`default_nettype wire
|