switchboard-hw 0.3.0__cp314-cp314-macosx_10_15_x86_64.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,247 @@
|
|
|
1
|
+
// UMI/UART Transactor
|
|
2
|
+
|
|
3
|
+
// Copyright (c) 2024 Zero ASIC Corporation
|
|
4
|
+
// This code is licensed under Apache License 2.0 (see LICENSE for details)
|
|
5
|
+
|
|
6
|
+
// Written by Edgar E. Iglesias
|
|
7
|
+
|
|
8
|
+
`default_nettype none
|
|
9
|
+
|
|
10
|
+
module uart_xactor
|
|
11
|
+
#(parameter BAUDRATE=115200,
|
|
12
|
+
parameter CLK_FREQ=100 * 1000 * 1000,
|
|
13
|
+
parameter DW=256,
|
|
14
|
+
parameter AW=64,
|
|
15
|
+
parameter CW=32
|
|
16
|
+
)
|
|
17
|
+
(
|
|
18
|
+
input clk,
|
|
19
|
+
input nreset,
|
|
20
|
+
output umi_req_ready,
|
|
21
|
+
input [CW-1:0] umi_req_cmd,
|
|
22
|
+
input [DW-1:0] umi_req_data,
|
|
23
|
+
input [AW-1:0] umi_req_dstaddr,
|
|
24
|
+
input [AW-1:0] umi_req_srcaddr,
|
|
25
|
+
input umi_req_valid,
|
|
26
|
+
|
|
27
|
+
input umi_resp_ready,
|
|
28
|
+
output [CW-1:0] umi_resp_cmd,
|
|
29
|
+
output [DW-1:0] umi_resp_data,
|
|
30
|
+
output [AW-1:0] umi_resp_dstaddr,
|
|
31
|
+
output [AW-1:0] umi_resp_srcaddr,
|
|
32
|
+
output umi_resp_valid,
|
|
33
|
+
|
|
34
|
+
output tx_pad,
|
|
35
|
+
input rx_pad
|
|
36
|
+
);
|
|
37
|
+
localparam UART_DEBUG = 0;
|
|
38
|
+
localparam UART_CLKDIV = (CLK_FREQ / (16 * BAUDRATE) * 16 - 1);
|
|
39
|
+
|
|
40
|
+
localparam REG_TX = 0;
|
|
41
|
+
localparam REG_RX = 4;
|
|
42
|
+
localparam REG_SR = 8;
|
|
43
|
+
|
|
44
|
+
wire [AW-1:0] loc_addr; // memory address
|
|
45
|
+
wire loc_write; // write enable
|
|
46
|
+
wire loc_read; // read request
|
|
47
|
+
wire loc_atomic; // atomic request
|
|
48
|
+
wire [7:0] loc_opcode; // opcode
|
|
49
|
+
wire [2:0] loc_size; // size
|
|
50
|
+
wire [7:0] loc_len; // len
|
|
51
|
+
wire [7:0] loc_atype; // atomic type
|
|
52
|
+
wire [DW-1:0] loc_wrdata; // data to write
|
|
53
|
+
reg [DW-1:0] loc_rddata; // data response
|
|
54
|
+
wire loc_ready; // device is ready
|
|
55
|
+
|
|
56
|
+
umi_endpoint #(.DW(DW))
|
|
57
|
+
ep(.*,
|
|
58
|
+
.udev_req_ready(umi_req_ready),
|
|
59
|
+
.udev_req_cmd(umi_req_cmd),
|
|
60
|
+
.udev_req_data(umi_req_data),
|
|
61
|
+
.udev_req_dstaddr(umi_req_dstaddr),
|
|
62
|
+
.udev_req_srcaddr(umi_req_srcaddr),
|
|
63
|
+
.udev_req_valid(umi_req_valid),
|
|
64
|
+
|
|
65
|
+
.udev_resp_ready(umi_resp_ready),
|
|
66
|
+
.udev_resp_cmd(umi_resp_cmd),
|
|
67
|
+
.udev_resp_data(umi_resp_data),
|
|
68
|
+
.udev_resp_dstaddr(umi_resp_dstaddr),
|
|
69
|
+
.udev_resp_srcaddr(umi_resp_srcaddr),
|
|
70
|
+
.udev_resp_valid(umi_resp_valid));
|
|
71
|
+
|
|
72
|
+
assign loc_ready = 1;
|
|
73
|
+
|
|
74
|
+
wire rxfifo_full;
|
|
75
|
+
wire rxfifo_empty;
|
|
76
|
+
wire [7:0] rxfifo_dout;
|
|
77
|
+
|
|
78
|
+
wire txfifo_full;
|
|
79
|
+
wire txfifo_empty;
|
|
80
|
+
|
|
81
|
+
wire [31:0] reg_sr = {16'b0,
|
|
82
|
+
6'b0, txfifo_full, txfifo_empty,
|
|
83
|
+
6'b0, rxfifo_full, rxfifo_empty};
|
|
84
|
+
wire rxfifo_read = loc_read && loc_addr == REG_RX;
|
|
85
|
+
wire txfifo_write = loc_write && loc_addr == REG_TX;
|
|
86
|
+
|
|
87
|
+
// Reg access logic.
|
|
88
|
+
always @(posedge clk or negedge nreset) begin
|
|
89
|
+
if (~nreset) begin
|
|
90
|
+
loc_rddata <= 0;
|
|
91
|
+
end else begin
|
|
92
|
+
if (loc_read) begin
|
|
93
|
+
case (loc_addr)
|
|
94
|
+
REG_RX: loc_rddata <= {24'b0, rxfifo_dout};
|
|
95
|
+
REG_SR: loc_rddata <= reg_sr;
|
|
96
|
+
default: loc_rddata <= 'hdeadbeef;
|
|
97
|
+
endcase
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
// UART
|
|
103
|
+
localparam STATE_START = 0;
|
|
104
|
+
localparam STATE_STOP = 8;
|
|
105
|
+
localparam STATE_STOP2 = 9;
|
|
106
|
+
|
|
107
|
+
reg [$clog2(UART_CLKDIV):0] clk_i;
|
|
108
|
+
reg [$clog2(STATE_STOP):0] rx_state;
|
|
109
|
+
reg [8-1:0] rx_data;
|
|
110
|
+
reg reset_sync;
|
|
111
|
+
|
|
112
|
+
wire clk_en = (clk_i == 0);
|
|
113
|
+
wire [8-1:0] rx_next_data = {rx_pad, rx_data[7:1]};
|
|
114
|
+
wire rx_next_data_en = clk_en && rx_state == STATE_STOP;
|
|
115
|
+
|
|
116
|
+
reg tx_xmit;
|
|
117
|
+
wire txfifo_read = ~tx_xmit && ~txfifo_empty;
|
|
118
|
+
wire [7:0] txfifo_dout;
|
|
119
|
+
|
|
120
|
+
la_syncfifo #(.DW(8),
|
|
121
|
+
.DEPTH(80), // FIFO Depth, can hold an 80 chars line?
|
|
122
|
+
.NS(1), // Number of power supplies
|
|
123
|
+
.CHAOS(0), // generates random full logic when set
|
|
124
|
+
.CTRLW(1), // width of asic ctrl interface
|
|
125
|
+
.TESTW(1)) // width of asic test interface
|
|
126
|
+
rx_fifo(
|
|
127
|
+
.wr_full (rxfifo_full),
|
|
128
|
+
.rd_dout (rxfifo_dout),
|
|
129
|
+
.rd_empty (rxfifo_empty),
|
|
130
|
+
.clk (clk),
|
|
131
|
+
.nreset (nreset),
|
|
132
|
+
.clear (1'b0),
|
|
133
|
+
.vss (1'b0),
|
|
134
|
+
.vdd (1'b1),
|
|
135
|
+
.chaosmode (1'b0),
|
|
136
|
+
.ctrl (1'b0),
|
|
137
|
+
.test (1'b0),
|
|
138
|
+
.wr_en (rx_next_data_en),
|
|
139
|
+
.wr_din (rx_next_data),
|
|
140
|
+
.rd_en (rxfifo_read));
|
|
141
|
+
|
|
142
|
+
la_syncfifo #(.DW(8),
|
|
143
|
+
.DEPTH(80), // FIFO Depth, can hold an 80 chars line?
|
|
144
|
+
.NS(1), // Number of power supplies
|
|
145
|
+
.CHAOS(0), // generates random full logic when set
|
|
146
|
+
.CTRLW(1), // width of asic ctrl interface
|
|
147
|
+
.TESTW(1)) // width of asic test interface
|
|
148
|
+
tx_fifo(
|
|
149
|
+
.wr_full (txfifo_full),
|
|
150
|
+
.rd_dout (txfifo_dout),
|
|
151
|
+
.rd_empty (txfifo_empty),
|
|
152
|
+
.clk (clk),
|
|
153
|
+
.nreset (nreset),
|
|
154
|
+
.clear (1'b0),
|
|
155
|
+
.vss (1'b0),
|
|
156
|
+
.vdd (1'b1),
|
|
157
|
+
.chaosmode (1'b0),
|
|
158
|
+
.ctrl (1'b0),
|
|
159
|
+
.test (1'b0),
|
|
160
|
+
.wr_en (txfifo_write),
|
|
161
|
+
.wr_din (loc_wrdata[7:0]),
|
|
162
|
+
.rd_en (txfifo_read));
|
|
163
|
+
|
|
164
|
+
// UART CLK
|
|
165
|
+
always @(posedge clk or negedge nreset) begin
|
|
166
|
+
if (~nreset) begin
|
|
167
|
+
clk_i <= 0;
|
|
168
|
+
end else begin
|
|
169
|
+
clk_i <= clk_i + 1;
|
|
170
|
+
if (clk_i == UART_CLKDIV[$clog2(UART_CLKDIV):0]) begin
|
|
171
|
+
clk_i <= 0;
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
// RX logic
|
|
177
|
+
always @(posedge clk or negedge nreset) begin
|
|
178
|
+
if (~nreset) begin
|
|
179
|
+
//$display("clkdiv old=%d new=%d", UART_CLKDIV_OLD, UART_CLKDIV);
|
|
180
|
+
rx_state <= 0;
|
|
181
|
+
rx_data <= 0;
|
|
182
|
+
reset_sync <= 1;
|
|
183
|
+
end else begin
|
|
184
|
+
if (rx_pad == 1) begin
|
|
185
|
+
reset_sync <= 0;
|
|
186
|
+
end
|
|
187
|
+
if (clk_en) begin
|
|
188
|
+
if (rx_state == STATE_START) begin
|
|
189
|
+
/* Wait for start bit. */
|
|
190
|
+
if (rx_pad == 0 && !reset_sync) begin
|
|
191
|
+
rx_state <= rx_state + 1;
|
|
192
|
+
end
|
|
193
|
+
end else if (rx_state <= 8) begin
|
|
194
|
+
rx_state <= rx_state + 1;
|
|
195
|
+
rx_data <= rx_next_data;
|
|
196
|
+
if (rx_state == STATE_STOP) begin
|
|
197
|
+
/* STOP. */
|
|
198
|
+
rx_state <= 0;
|
|
199
|
+
rx_data <= 0;
|
|
200
|
+
if (UART_DEBUG) begin
|
|
201
|
+
$write("%c", rx_next_data); $fflush();
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
if (UART_DEBUG) begin
|
|
207
|
+
$display("state=%d rx=%d data=%x.%x", rx_state, rx_pad, rx_data, rx_next_data);
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
// TX logic
|
|
214
|
+
reg [$clog2(STATE_STOP2):0] tx_state;
|
|
215
|
+
reg [8-1:0] tx_data;
|
|
216
|
+
|
|
217
|
+
reg tx;
|
|
218
|
+
assign tx_pad = tx;
|
|
219
|
+
always @(posedge clk or negedge nreset) begin
|
|
220
|
+
if (~nreset) begin
|
|
221
|
+
tx_state <= 0;
|
|
222
|
+
tx_xmit <= 0;
|
|
223
|
+
tx <= 1;
|
|
224
|
+
end else begin
|
|
225
|
+
if (txfifo_read) begin
|
|
226
|
+
tx_xmit <= 1;
|
|
227
|
+
tx_data <= txfifo_dout;
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
if (clk_en && tx_xmit) begin
|
|
231
|
+
tx_state <= tx_state + 1;
|
|
232
|
+
|
|
233
|
+
if (tx_state == STATE_START) begin
|
|
234
|
+
tx <= 0;
|
|
235
|
+
end else if (tx_state == STATE_STOP2) begin
|
|
236
|
+
tx_xmit <= 0;
|
|
237
|
+
tx_state <= STATE_START;
|
|
238
|
+
tx <= 1;
|
|
239
|
+
end else begin
|
|
240
|
+
tx <= tx_data[tx_state - 1];
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
endmodule
|
|
246
|
+
|
|
247
|
+
`default_nettype wire
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// Universal Memory Interface (UMI) GPIO
|
|
2
|
+
|
|
3
|
+
// The output gpio_out is "updated" by any write to this module, and the
|
|
4
|
+
// input "gpio_in" is read out by any read from this module.
|
|
5
|
+
|
|
6
|
+
// Copyright (c) 2024 Zero ASIC Corporation
|
|
7
|
+
// This code is licensed under Apache License 2.0 (see LICENSE for details)
|
|
8
|
+
|
|
9
|
+
module umi_gpio #(
|
|
10
|
+
parameter integer DW=256,
|
|
11
|
+
parameter integer AW=64,
|
|
12
|
+
parameter integer CW=32,
|
|
13
|
+
parameter integer IWIDTH=32,
|
|
14
|
+
parameter integer OWIDTH=32,
|
|
15
|
+
parameter [OWIDTH-1:0] INITVAL=0
|
|
16
|
+
) (
|
|
17
|
+
input clk,
|
|
18
|
+
input nreset,
|
|
19
|
+
|
|
20
|
+
// GPIO interface
|
|
21
|
+
input [IWIDTH-1:0] gpio_in,
|
|
22
|
+
output [OWIDTH-1:0] gpio_out,
|
|
23
|
+
|
|
24
|
+
// UMI inbound interface
|
|
25
|
+
input udev_req_valid,
|
|
26
|
+
input [CW-1:0] udev_req_cmd,
|
|
27
|
+
input [AW-1:0] udev_req_dstaddr,
|
|
28
|
+
input [AW-1:0] udev_req_srcaddr,
|
|
29
|
+
input [DW-1:0] udev_req_data,
|
|
30
|
+
output udev_req_ready,
|
|
31
|
+
|
|
32
|
+
// UMI outbound interface
|
|
33
|
+
output udev_resp_valid,
|
|
34
|
+
output [CW-1:0] udev_resp_cmd,
|
|
35
|
+
output [AW-1:0] udev_resp_dstaddr,
|
|
36
|
+
output [AW-1:0] udev_resp_srcaddr,
|
|
37
|
+
output [DW-1:0] udev_resp_data,
|
|
38
|
+
input udev_resp_ready
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
`include "umi_messages.vh"
|
|
42
|
+
|
|
43
|
+
// interpret incoming packet
|
|
44
|
+
|
|
45
|
+
wire [4:0] req_opcode;
|
|
46
|
+
wire [2:0] req_size;
|
|
47
|
+
wire [7:0] req_len;
|
|
48
|
+
wire [7:0] req_atype;
|
|
49
|
+
wire [3:0] req_qos;
|
|
50
|
+
wire [1:0] req_prot;
|
|
51
|
+
wire req_eom;
|
|
52
|
+
wire req_eof;
|
|
53
|
+
wire req_ex;
|
|
54
|
+
wire [1:0] req_user;
|
|
55
|
+
wire [23:0] req_user_extended;
|
|
56
|
+
wire [1:0] req_err;
|
|
57
|
+
wire [4:0] req_hostid;
|
|
58
|
+
|
|
59
|
+
/* verilator lint_off PINMISSING */
|
|
60
|
+
umi_unpack #(
|
|
61
|
+
.CW(CW)
|
|
62
|
+
) umi_unpack_i (
|
|
63
|
+
.packet_cmd(udev_req_cmd),
|
|
64
|
+
.cmd_opcode(req_opcode),
|
|
65
|
+
.cmd_size(req_size),
|
|
66
|
+
.cmd_len(req_len),
|
|
67
|
+
.cmd_atype(req_atype),
|
|
68
|
+
.cmd_qos(req_qos),
|
|
69
|
+
.cmd_prot(req_prot),
|
|
70
|
+
.cmd_eom(req_eom),
|
|
71
|
+
.cmd_eof(req_eof),
|
|
72
|
+
.cmd_ex(req_ex),
|
|
73
|
+
.cmd_user(req_user),
|
|
74
|
+
.cmd_user_extended(req_user_extended),
|
|
75
|
+
.cmd_err(req_err),
|
|
76
|
+
.cmd_hostid(req_hostid)
|
|
77
|
+
);
|
|
78
|
+
/* verilator lint_on PINMISSING */
|
|
79
|
+
|
|
80
|
+
wire req_cmd_read;
|
|
81
|
+
assign req_cmd_read = (req_opcode == UMI_REQ_READ) ? 1'b1 : 1'b0;
|
|
82
|
+
|
|
83
|
+
wire req_cmd_write;
|
|
84
|
+
assign req_cmd_write = (req_opcode == UMI_REQ_WRITE) ? 1'b1 : 1'b0;
|
|
85
|
+
|
|
86
|
+
wire req_cmd_posted;
|
|
87
|
+
assign req_cmd_posted = (req_opcode == UMI_REQ_POSTED) ? 1'b1 : 1'b0;
|
|
88
|
+
|
|
89
|
+
// form outgoing packet (which can only be a read response)
|
|
90
|
+
|
|
91
|
+
reg [4:0] resp_opcode;
|
|
92
|
+
reg [2:0] resp_size;
|
|
93
|
+
reg [7:0] resp_len;
|
|
94
|
+
reg [7:0] resp_atype;
|
|
95
|
+
reg [3:0] resp_qos;
|
|
96
|
+
reg [1:0] resp_prot;
|
|
97
|
+
reg resp_eom;
|
|
98
|
+
reg resp_eof;
|
|
99
|
+
reg resp_ex;
|
|
100
|
+
reg [1:0] resp_user;
|
|
101
|
+
reg [23:0] resp_user_extended;
|
|
102
|
+
reg [1:0] resp_err;
|
|
103
|
+
reg [4:0] resp_hostid;
|
|
104
|
+
|
|
105
|
+
umi_pack #(
|
|
106
|
+
.CW(CW)
|
|
107
|
+
) umi_pack_i (
|
|
108
|
+
.cmd_opcode(resp_opcode),
|
|
109
|
+
.cmd_size(resp_size),
|
|
110
|
+
.cmd_len(resp_len),
|
|
111
|
+
.cmd_atype(resp_atype),
|
|
112
|
+
.cmd_prot(resp_prot),
|
|
113
|
+
.cmd_qos(resp_qos),
|
|
114
|
+
.cmd_eom(resp_eom),
|
|
115
|
+
.cmd_eof(resp_eof),
|
|
116
|
+
.cmd_user(resp_user),
|
|
117
|
+
.cmd_err(resp_err),
|
|
118
|
+
.cmd_ex(resp_ex),
|
|
119
|
+
.cmd_hostid(resp_hostid),
|
|
120
|
+
.cmd_user_extended(resp_user_extended),
|
|
121
|
+
.packet_cmd(udev_resp_cmd)
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// main logic
|
|
125
|
+
|
|
126
|
+
reg [OWIDTH-1:0] gpio_out_r;
|
|
127
|
+
assign gpio_out = gpio_out_r;
|
|
128
|
+
|
|
129
|
+
reg [31:0] read_bytes_remaining;
|
|
130
|
+
reg resp_in_progress;
|
|
131
|
+
reg [AW-1:0] read_dstaddr;
|
|
132
|
+
|
|
133
|
+
wire [31:0] nbytes;
|
|
134
|
+
assign nbytes = (resp_in_progress ? read_bytes_remaining :
|
|
135
|
+
({24'd0, req_len} + 32'd1)*(32'd1<<{29'd0, req_size}));
|
|
136
|
+
|
|
137
|
+
wire [31:0] flit_bytes;
|
|
138
|
+
assign flit_bytes = (nbytes <= (DW/8)) ? nbytes : (DW/8);
|
|
139
|
+
|
|
140
|
+
wire [31:0] resp_len_req_next32 = {((flit_bytes >> req_size) - 32'd1)};
|
|
141
|
+
wire [7:0] resp_len_req_next = resp_len_req_next32[7:0];
|
|
142
|
+
|
|
143
|
+
wire [31:0] resp_len_next32 = {((flit_bytes >> resp_size) - 32'd1)};
|
|
144
|
+
wire [7:0] resp_len_next = resp_len_next32[7:0];
|
|
145
|
+
|
|
146
|
+
reg active;
|
|
147
|
+
assign udev_req_ready = (active
|
|
148
|
+
&& (!((udev_resp_valid && (!udev_resp_ready)) || resp_in_progress)));
|
|
149
|
+
|
|
150
|
+
reg udev_resp_valid_r;
|
|
151
|
+
assign udev_resp_valid = udev_resp_valid_r;
|
|
152
|
+
|
|
153
|
+
reg [DW-1:0] udev_resp_data_r;
|
|
154
|
+
assign udev_resp_data = udev_resp_data_r;
|
|
155
|
+
|
|
156
|
+
reg [AW-1:0] udev_resp_dstaddr_r;
|
|
157
|
+
assign udev_resp_dstaddr = udev_resp_dstaddr_r;
|
|
158
|
+
|
|
159
|
+
integer i;
|
|
160
|
+
|
|
161
|
+
always @(posedge clk or negedge nreset) begin
|
|
162
|
+
if (!nreset) begin
|
|
163
|
+
active <= 1'b0;
|
|
164
|
+
end else begin
|
|
165
|
+
active <= 1'b1;
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
always @(posedge clk or negedge nreset) begin
|
|
170
|
+
if (!nreset) begin
|
|
171
|
+
gpio_out_r <= INITVAL;
|
|
172
|
+
read_bytes_remaining <= 'd0;
|
|
173
|
+
resp_in_progress <= 1'b0;
|
|
174
|
+
read_dstaddr <= 'd0;
|
|
175
|
+
udev_resp_valid_r <= 1'b0;
|
|
176
|
+
end else if (udev_req_valid && udev_req_ready) begin
|
|
177
|
+
if (req_cmd_posted || req_cmd_write) begin
|
|
178
|
+
for (i=0; i<flit_bytes; i=i+1) begin
|
|
179
|
+
gpio_out_r[(i[$clog2(OWIDTH)-1:0]+udev_req_dstaddr[$clog2(OWIDTH)-1:0])*8 +: 8]
|
|
180
|
+
<= udev_req_data[i*8 +: 8];
|
|
181
|
+
end
|
|
182
|
+
if (req_cmd_write) begin
|
|
183
|
+
resp_opcode <= UMI_RESP_WRITE;
|
|
184
|
+
udev_resp_valid_r <= 1'b1;
|
|
185
|
+
end
|
|
186
|
+
end else if (req_cmd_read) begin
|
|
187
|
+
for (i=0; i<flit_bytes; i=i+1) begin
|
|
188
|
+
udev_resp_data_r[i*8 +: 8] <=
|
|
189
|
+
gpio_in[(i[$clog2(IWIDTH)-1:0]+udev_req_dstaddr[$clog2(IWIDTH)-1:0])*8 +: 8];
|
|
190
|
+
end
|
|
191
|
+
resp_opcode <= UMI_RESP_READ;
|
|
192
|
+
udev_resp_valid_r <= 1'b1;
|
|
193
|
+
if (nbytes > (DW/8)) begin
|
|
194
|
+
resp_in_progress <= 1'b1;
|
|
195
|
+
read_bytes_remaining <= nbytes - flit_bytes;
|
|
196
|
+
read_dstaddr <= udev_req_dstaddr + {{(AW-32){1'b0}}, flit_bytes};
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
// pass through data
|
|
201
|
+
resp_size <= req_size;
|
|
202
|
+
resp_len <= resp_len_req_next;
|
|
203
|
+
resp_atype <= req_atype;
|
|
204
|
+
resp_prot <= req_prot;
|
|
205
|
+
resp_qos <= req_qos;
|
|
206
|
+
resp_eom <= (nbytes <= (DW/8)) ? 1'b1 : 1'b0;
|
|
207
|
+
resp_eof <= req_eof;
|
|
208
|
+
resp_user <= req_user;
|
|
209
|
+
resp_err <= req_err;
|
|
210
|
+
resp_ex <= req_ex;
|
|
211
|
+
resp_hostid <= req_hostid;
|
|
212
|
+
resp_user_extended <= req_user_extended;
|
|
213
|
+
udev_resp_dstaddr_r <= udev_req_srcaddr;
|
|
214
|
+
end else if (udev_resp_valid && udev_resp_ready) begin
|
|
215
|
+
if (resp_in_progress) begin
|
|
216
|
+
if (read_bytes_remaining == 'd0) begin
|
|
217
|
+
udev_resp_valid_r <= 1'b0;
|
|
218
|
+
resp_in_progress <= 1'b0;
|
|
219
|
+
end else begin
|
|
220
|
+
read_bytes_remaining <= read_bytes_remaining - flit_bytes;
|
|
221
|
+
resp_len <= resp_len_next;
|
|
222
|
+
udev_resp_dstaddr_r <= udev_resp_dstaddr + {{(AW-32){1'b0}}, flit_bytes};
|
|
223
|
+
read_dstaddr <= read_dstaddr + {{(AW-32){1'b0}}, flit_bytes};
|
|
224
|
+
resp_eom <= (read_bytes_remaining <= (DW/8)) ? 1'b1 : 1'b0;
|
|
225
|
+
for (i=0; i<flit_bytes; i=i+1) begin
|
|
226
|
+
udev_resp_data_r[i*8 +: 8] <=
|
|
227
|
+
gpio_in[(i[$clog2(IWIDTH)-1:0]+read_dstaddr[$clog2(IWIDTH)-1:0])*8 +: 8];
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end else begin
|
|
231
|
+
udev_resp_valid_r <= 1'b0;
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
endmodule
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
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 axi_reader #(
|
|
7
|
+
parameter ID_WIDTH = 16
|
|
8
|
+
) (
|
|
9
|
+
input wire clk,
|
|
10
|
+
|
|
11
|
+
input wire rvalid,
|
|
12
|
+
input wire [63:0] raddr,
|
|
13
|
+
output wire [511:0] rdata,
|
|
14
|
+
output wire rready,
|
|
15
|
+
|
|
16
|
+
output wire [ID_WIDTH-1:0] m_axi_arid,
|
|
17
|
+
output wire [63:0] m_axi_araddr,
|
|
18
|
+
output wire [7:0] m_axi_arlen,
|
|
19
|
+
output wire [2:0] m_axi_arsize,
|
|
20
|
+
output wire m_axi_arvalid,
|
|
21
|
+
input wire m_axi_arready,
|
|
22
|
+
|
|
23
|
+
input wire [ID_WIDTH-1:0] m_axi_rid,
|
|
24
|
+
input wire [511:0] m_axi_rdata,
|
|
25
|
+
input wire [1:0] m_axi_rresp,
|
|
26
|
+
input wire m_axi_rlast,
|
|
27
|
+
input wire m_axi_rvalid,
|
|
28
|
+
output wire m_axi_rready
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
localparam [1:0] STATE_IDLE = 2'd0;
|
|
32
|
+
localparam [1:0] STATE_READ = 2'd1;
|
|
33
|
+
localparam [1:0] STATE_WAIT_RESP = 2'd2;
|
|
34
|
+
|
|
35
|
+
reg [1:0] state = STATE_IDLE;
|
|
36
|
+
reg [1:0] state_next;
|
|
37
|
+
|
|
38
|
+
always @(*) begin
|
|
39
|
+
state_next = state;
|
|
40
|
+
case (state)
|
|
41
|
+
STATE_IDLE: begin
|
|
42
|
+
if (rvalid) begin
|
|
43
|
+
state_next = STATE_READ;
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
STATE_READ: begin
|
|
48
|
+
if (m_axi_arready) begin
|
|
49
|
+
state_next = STATE_WAIT_RESP;
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
STATE_WAIT_RESP: begin
|
|
54
|
+
if (m_axi_rvalid) begin
|
|
55
|
+
state_next = STATE_IDLE;
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
// Shouldn't reach here
|
|
60
|
+
default: state_next = 2'bXX;
|
|
61
|
+
endcase
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
always @(posedge clk) begin
|
|
65
|
+
state <= state_next;
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
// Pulse rready after we get response
|
|
69
|
+
assign rready = (state == STATE_WAIT_RESP) && (state_next == STATE_IDLE);
|
|
70
|
+
assign rdata = m_axi_rdata;
|
|
71
|
+
|
|
72
|
+
assign m_axi_arid = {ID_WIDTH{1'b0}};
|
|
73
|
+
assign m_axi_araddr = raddr;
|
|
74
|
+
assign m_axi_arlen = 8'b0;
|
|
75
|
+
assign m_axi_arsize = 3'd6;
|
|
76
|
+
assign m_axi_arvalid = (state == STATE_READ);
|
|
77
|
+
|
|
78
|
+
assign m_axi_rready = (state == STATE_WAIT_RESP);
|
|
79
|
+
|
|
80
|
+
endmodule
|
|
81
|
+
|
|
82
|
+
`default_nettype wire
|
|
@@ -0,0 +1,111 @@
|
|
|
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 axi_writer #(
|
|
7
|
+
parameter ID_WIDTH = 16
|
|
8
|
+
) (
|
|
9
|
+
input wire clk,
|
|
10
|
+
|
|
11
|
+
input wire wvalid,
|
|
12
|
+
input wire [63:0] waddr,
|
|
13
|
+
input wire [63:0] wstrb,
|
|
14
|
+
input wire [511:0] wdata,
|
|
15
|
+
output wire wready,
|
|
16
|
+
|
|
17
|
+
output wire [ID_WIDTH-1:0] m_axi_awid,
|
|
18
|
+
output wire [63:0] m_axi_awaddr,
|
|
19
|
+
output wire [7:0] m_axi_awlen,
|
|
20
|
+
output wire [2:0] m_axi_awsize,
|
|
21
|
+
output wire m_axi_awvalid,
|
|
22
|
+
input wire m_axi_awready,
|
|
23
|
+
|
|
24
|
+
output wire [511:0] m_axi_wdata,
|
|
25
|
+
output wire [63:0] m_axi_wstrb,
|
|
26
|
+
output wire m_axi_wlast,
|
|
27
|
+
output wire m_axi_wvalid,
|
|
28
|
+
input wire m_axi_wready,
|
|
29
|
+
|
|
30
|
+
input wire [ID_WIDTH-1:0] m_axi_bid,
|
|
31
|
+
input wire [1:0] m_axi_bresp,
|
|
32
|
+
input wire m_axi_bvalid,
|
|
33
|
+
output wire m_axi_bready
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
localparam [1:0] STATE_IDLE = 2'd0;
|
|
37
|
+
localparam [1:0] STATE_WR_ADDR_DATA = 2'd1;
|
|
38
|
+
localparam [1:0] STATE_WAIT_RESP = 2'd2;
|
|
39
|
+
|
|
40
|
+
reg [1:0] state = STATE_IDLE;
|
|
41
|
+
reg [1:0] state_next;
|
|
42
|
+
|
|
43
|
+
reg awready_seen = 1'b0;
|
|
44
|
+
reg wready_seen = 1'b0;
|
|
45
|
+
|
|
46
|
+
always @(*) begin
|
|
47
|
+
state_next = state;
|
|
48
|
+
case (state)
|
|
49
|
+
STATE_IDLE: begin
|
|
50
|
+
if (wvalid) begin
|
|
51
|
+
state_next = STATE_WR_ADDR_DATA;
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
// m_axi_awready and m_axi_wready may wait for both m_axi_awvalid
|
|
56
|
+
// and m_axi_wvalid to assert before asserting, so we raise both
|
|
57
|
+
// valid signals and wait for both ready signals.
|
|
58
|
+
STATE_WR_ADDR_DATA: begin
|
|
59
|
+
if ((m_axi_awready || awready_seen) && (m_axi_wready || wready_seen)) begin
|
|
60
|
+
state_next = STATE_WAIT_RESP;
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
STATE_WAIT_RESP: begin
|
|
65
|
+
if (m_axi_bvalid) begin
|
|
66
|
+
state_next = STATE_IDLE;
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
default: begin
|
|
71
|
+
// would only get here if state contains "X"
|
|
72
|
+
// or "Z" bits. this might be a bit more
|
|
73
|
+
// conservative than necessary...
|
|
74
|
+
state_next = 2'bxx;
|
|
75
|
+
end
|
|
76
|
+
endcase
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
always @(posedge clk) begin
|
|
80
|
+
state <= state_next;
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
always @(posedge clk) begin
|
|
84
|
+
if (state == STATE_IDLE) begin
|
|
85
|
+
awready_seen <= 1'b0;
|
|
86
|
+
wready_seen <= 1'b0;
|
|
87
|
+
end else begin
|
|
88
|
+
awready_seen <= m_axi_awready || awready_seen;
|
|
89
|
+
wready_seen <= m_axi_wready || wready_seen;
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
// Pulse wready after we get response
|
|
94
|
+
assign wready = (state == STATE_WAIT_RESP) && (state_next == STATE_IDLE);
|
|
95
|
+
|
|
96
|
+
assign m_axi_awid = {ID_WIDTH{1'b0}};
|
|
97
|
+
assign m_axi_awaddr = waddr;
|
|
98
|
+
assign m_axi_awlen = 8'b0;
|
|
99
|
+
assign m_axi_awsize = 3'd6;
|
|
100
|
+
assign m_axi_awvalid = (state == STATE_WR_ADDR_DATA) && (!awready_seen);
|
|
101
|
+
|
|
102
|
+
assign m_axi_wdata = wdata;
|
|
103
|
+
assign m_axi_wstrb = wstrb;
|
|
104
|
+
assign m_axi_wlast = 1'b1;
|
|
105
|
+
assign m_axi_wvalid = (state == STATE_WR_ADDR_DATA) && (!wready_seen);
|
|
106
|
+
|
|
107
|
+
assign m_axi_bready = (state == STATE_WAIT_RESP);
|
|
108
|
+
|
|
109
|
+
endmodule
|
|
110
|
+
|
|
111
|
+
`default_nettype wire
|