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.
Files changed (99) hide show
  1. _switchboard.cpython-314-darwin.so +0 -0
  2. switchboard/__init__.py +24 -0
  3. switchboard/ams.py +668 -0
  4. switchboard/apb.py +278 -0
  5. switchboard/autowrap.py +1000 -0
  6. switchboard/axi.py +571 -0
  7. switchboard/axil.py +348 -0
  8. switchboard/bitvector.py +112 -0
  9. switchboard/cmdline.py +142 -0
  10. switchboard/cpp/Makefile +13 -0
  11. switchboard/cpp/bitutil.h +39 -0
  12. switchboard/cpp/pagemap.h +91 -0
  13. switchboard/cpp/pciedev.h +86 -0
  14. switchboard/cpp/router.cc +89 -0
  15. switchboard/cpp/spsc_queue.h +267 -0
  16. switchboard/cpp/switchboard.hpp +257 -0
  17. switchboard/cpp/switchboard_pcie.hpp +234 -0
  18. switchboard/cpp/switchboard_tlm.hpp +98 -0
  19. switchboard/cpp/umilib.h +144 -0
  20. switchboard/cpp/umilib.hpp +113 -0
  21. switchboard/cpp/umisb.hpp +364 -0
  22. switchboard/cpp/xyce.hpp +90 -0
  23. switchboard/deps/__init__.py +0 -0
  24. switchboard/deps/verilog_axi.py +23 -0
  25. switchboard/dpi/__init__.py +0 -0
  26. switchboard/dpi/switchboard_dpi.cc +119 -0
  27. switchboard/dpi/switchboard_dpi.py +13 -0
  28. switchboard/dpi/xyce_dpi.cc +43 -0
  29. switchboard/gpio.py +108 -0
  30. switchboard/icarus.py +85 -0
  31. switchboard/loopback.py +157 -0
  32. switchboard/network.py +714 -0
  33. switchboard/pytest_plugin.py +11 -0
  34. switchboard/sbdesign.py +55 -0
  35. switchboard/sbdut.py +744 -0
  36. switchboard/sbtcp.py +345 -0
  37. switchboard/sc/__init__.py +0 -0
  38. switchboard/sc/morty/__init__.py +0 -0
  39. switchboard/sc/morty/uniquify.py +67 -0
  40. switchboard/sc/sed/__init__.py +0 -0
  41. switchboard/sc/sed/sed_remove.py +47 -0
  42. switchboard/sc/standalone_netlist_flow.py +25 -0
  43. switchboard/switchboard.py +53 -0
  44. switchboard/test_util.py +46 -0
  45. switchboard/uart_xactor.py +66 -0
  46. switchboard/umi.py +793 -0
  47. switchboard/util.py +131 -0
  48. switchboard/verilator/__init__.py +0 -0
  49. switchboard/verilator/config.vlt +13 -0
  50. switchboard/verilator/testbench.cc +143 -0
  51. switchboard/verilator/verilator.py +13 -0
  52. switchboard/verilator_run.py +31 -0
  53. switchboard/verilog/__init__.py +0 -0
  54. switchboard/verilog/common/__init__.py +0 -0
  55. switchboard/verilog/common/common.py +26 -0
  56. switchboard/verilog/common/switchboard.vh +429 -0
  57. switchboard/verilog/common/uart_xactor.sv +247 -0
  58. switchboard/verilog/common/umi_gpio.v +236 -0
  59. switchboard/verilog/fpga/__init__.py +0 -0
  60. switchboard/verilog/fpga/axi_reader.sv +82 -0
  61. switchboard/verilog/fpga/axi_writer.sv +111 -0
  62. switchboard/verilog/fpga/config_registers.sv +249 -0
  63. switchboard/verilog/fpga/fpga.py +21 -0
  64. switchboard/verilog/fpga/include/sb_queue_regmap.vh +21 -0
  65. switchboard/verilog/fpga/include/spsc_queue.vh +7 -0
  66. switchboard/verilog/fpga/memory_fault.sv +40 -0
  67. switchboard/verilog/fpga/sb_fpga_queues.sv +416 -0
  68. switchboard/verilog/fpga/sb_rx_fpga.sv +303 -0
  69. switchboard/verilog/fpga/sb_tx_fpga.sv +294 -0
  70. switchboard/verilog/fpga/umi_fpga_queues.sv +146 -0
  71. switchboard/verilog/sim/__init__.py +0 -0
  72. switchboard/verilog/sim/auto_stop_sim.sv +25 -0
  73. switchboard/verilog/sim/perf_meas_sim.sv +97 -0
  74. switchboard/verilog/sim/queue_to_sb_sim.sv +176 -0
  75. switchboard/verilog/sim/queue_to_umi_sim.sv +66 -0
  76. switchboard/verilog/sim/sb_apb_m.sv +146 -0
  77. switchboard/verilog/sim/sb_axi_m.sv +199 -0
  78. switchboard/verilog/sim/sb_axil_m.sv +180 -0
  79. switchboard/verilog/sim/sb_axil_s.sv +180 -0
  80. switchboard/verilog/sim/sb_clk_gen.sv +89 -0
  81. switchboard/verilog/sim/sb_jtag_rbb_sim.sv +148 -0
  82. switchboard/verilog/sim/sb_rx_sim.sv +55 -0
  83. switchboard/verilog/sim/sb_to_queue_sim.sv +196 -0
  84. switchboard/verilog/sim/sb_tx_sim.sv +55 -0
  85. switchboard/verilog/sim/switchboard_sim.py +49 -0
  86. switchboard/verilog/sim/umi_rx_sim.sv +61 -0
  87. switchboard/verilog/sim/umi_to_queue_sim.sv +66 -0
  88. switchboard/verilog/sim/umi_tx_sim.sv +61 -0
  89. switchboard/verilog/sim/xyce_intf.sv +67 -0
  90. switchboard/vpi/switchboard_vpi.cc +431 -0
  91. switchboard/vpi/xyce_vpi.cc +200 -0
  92. switchboard/warn.py +14 -0
  93. switchboard/xyce.py +27 -0
  94. switchboard_hw-0.3.0.dist-info/METADATA +303 -0
  95. switchboard_hw-0.3.0.dist-info/RECORD +99 -0
  96. switchboard_hw-0.3.0.dist-info/WHEEL +6 -0
  97. switchboard_hw-0.3.0.dist-info/entry_points.txt +6 -0
  98. switchboard_hw-0.3.0.dist-info/licenses/LICENSE +190 -0
  99. 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