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,257 @@
1
+ // Copyright (c) 2024 Zero ASIC Corporation
2
+ // This code is licensed under Apache License 2.0 (see LICENSE for details)
3
+
4
+ #ifndef __SWITCHBOARD_HPP__
5
+ #define __SWITCHBOARD_HPP__
6
+
7
+ #include <array>
8
+ #include <chrono>
9
+ #include <cstdio>
10
+ #include <stdexcept>
11
+ #include <string>
12
+ #include <thread>
13
+ #include <vector>
14
+
15
+ #include "spsc_queue.h"
16
+
17
+ // packet type
18
+ // TODO: make size runtime programmable
19
+ #define SB_DATA_SIZE 52
20
+ struct sb_packet {
21
+ uint32_t destination;
22
+ union {
23
+ struct {
24
+ unsigned int last : 1;
25
+ };
26
+ uint32_t flags;
27
+ };
28
+ uint8_t data[SB_DATA_SIZE];
29
+ } __attribute__((packed));
30
+
31
+ static inline long max_rate_timestamp_us() {
32
+ return std::chrono::duration_cast<std::chrono::microseconds>(
33
+ std::chrono::high_resolution_clock::now().time_since_epoch())
34
+ .count();
35
+ }
36
+
37
+ static inline void max_rate_tick(long& last_us, long min_period_us) {
38
+ if (min_period_us > 0) {
39
+ // measure the time now
40
+
41
+ long now_us = max_rate_timestamp_us();
42
+
43
+ // sleep if needed
44
+
45
+ if (last_us != -1) {
46
+ long dt_us = now_us - last_us;
47
+
48
+ if (dt_us < min_period_us) {
49
+ long sleep_us = min_period_us - dt_us;
50
+ std::this_thread::sleep_for(std::chrono::microseconds(sleep_us));
51
+ }
52
+ }
53
+
54
+ // update the time stamp. it is not enough to set last_us = now_us,
55
+ // due to the sleep_for invocation
56
+
57
+ last_us = max_rate_timestamp_us();
58
+ }
59
+ }
60
+
61
+ static inline void start_delay(double value) {
62
+ if (value > 0) {
63
+ int value_us = (value * 1.0e6) + 0.5;
64
+ std::this_thread::sleep_for(std::chrono::microseconds(value_us));
65
+ }
66
+ }
67
+
68
+ class SB_base {
69
+ public:
70
+ SB_base() : m_active(false), m_q(NULL) {}
71
+
72
+ virtual ~SB_base() {
73
+ deinit();
74
+ }
75
+
76
+ void init(std::string uri, size_t capacity = 0, bool fresh = false, double max_rate = -1) {
77
+ init(uri.c_str(), capacity, fresh, max_rate);
78
+ }
79
+
80
+ void init(const char* uri, size_t capacity = 0, bool fresh = false, double max_rate = -1) {
81
+ // Default to one page of capacity
82
+ if (capacity == 0) {
83
+ capacity = spsc_capacity(getpagesize());
84
+ }
85
+
86
+ // delete old queue if "fresh" is set
87
+ if (fresh) {
88
+ spsc_remove_shmfile(uri);
89
+ }
90
+
91
+ m_q = spsc_open(uri, capacity);
92
+ m_active = true;
93
+ m_timestamp_us = -1;
94
+
95
+ set_max_rate(max_rate);
96
+ }
97
+
98
+ void deinit(void) {
99
+ spsc_close(m_q);
100
+ m_active = false;
101
+ }
102
+
103
+ bool is_active() {
104
+ return m_active;
105
+ }
106
+
107
+ int mlock(void) {
108
+ check_active();
109
+ assert(m_q);
110
+ return spsc_mlock(m_q);
111
+ }
112
+
113
+ int get_capacity(void) {
114
+ check_active();
115
+ return m_q->capacity;
116
+ }
117
+
118
+ void* get_shm_handle(void) {
119
+ check_active();
120
+ return m_q->shm;
121
+ }
122
+
123
+ void set_max_rate(double max_rate) {
124
+ if (max_rate > 0) {
125
+ m_min_period_us = (1.0e6 / max_rate) + 0.5;
126
+ } else {
127
+ m_min_period_us = -1;
128
+ }
129
+ }
130
+
131
+ protected:
132
+ void check_active(void) {
133
+ if (!m_active) {
134
+ throw std::runtime_error("Using an uninitialized SB queue!");
135
+ }
136
+ }
137
+
138
+ bool m_auto_deinit;
139
+ bool m_active;
140
+ long m_min_period_us;
141
+ long m_timestamp_us;
142
+ spsc_queue* m_q;
143
+ };
144
+
145
+ class SBTX : public SB_base {
146
+ public:
147
+ SBTX() {}
148
+
149
+ bool send(sb_packet& p) {
150
+ check_active();
151
+ max_rate_tick(m_timestamp_us, m_min_period_us);
152
+ return spsc_send(m_q, &p, sizeof p);
153
+ }
154
+
155
+ void send_blocking(sb_packet& p) {
156
+ bool success = false;
157
+
158
+ while (!success) {
159
+ success = send(p);
160
+
161
+ if ((!success) && (m_min_period_us == -1)) {
162
+ // maintain old behavior if max_rate isn't specified,
163
+ // i.e. yield on every iteration that the send isn't
164
+ // successful
165
+ std::this_thread::yield();
166
+ }
167
+ }
168
+ }
169
+
170
+ bool all_read() {
171
+ check_active();
172
+ return spsc_size(m_q) == 0;
173
+ }
174
+ };
175
+
176
+ class SBRX : public SB_base {
177
+ public:
178
+ SBRX() {}
179
+
180
+ bool recv(sb_packet& p) {
181
+ check_active();
182
+ max_rate_tick(m_timestamp_us, m_min_period_us);
183
+ return spsc_recv(m_q, &p, sizeof p);
184
+ }
185
+
186
+ bool recv() {
187
+ check_active();
188
+ sb_packet dummy_p;
189
+ max_rate_tick(m_timestamp_us, m_min_period_us);
190
+ return spsc_recv(m_q, &dummy_p, sizeof dummy_p);
191
+ }
192
+
193
+ void recv_blocking(sb_packet& p) {
194
+ bool success = false;
195
+
196
+ while (!success) {
197
+ success = recv(p);
198
+
199
+ if ((!success) && (m_min_period_us == -1)) {
200
+ // maintain old behavior if max_rate isn't specified,
201
+ // i.e. yield on every iteration that the send isn't
202
+ // successful
203
+ std::this_thread::yield();
204
+ }
205
+ }
206
+ }
207
+
208
+ bool recv_peek(sb_packet& p) {
209
+ check_active();
210
+ max_rate_tick(m_timestamp_us, m_min_period_us);
211
+ return spsc_recv_peek(m_q, &p, sizeof p);
212
+ }
213
+ };
214
+
215
+ static inline void delete_shared_queue(const char* name) {
216
+ spsc_remove_shmfile(name);
217
+ }
218
+
219
+ static inline void delete_shared_queue(std::string name) {
220
+ delete_shared_queue(name.c_str());
221
+ }
222
+
223
+ static inline std::string sb_packet_to_str(sb_packet p, ssize_t nbytes = -1) {
224
+ // determine how many bytes to print
225
+ size_t max_idx;
226
+ if (nbytes < 0) {
227
+ max_idx = sizeof(p.data);
228
+ } else {
229
+ max_idx = nbytes;
230
+ }
231
+
232
+ // used for convenient formatting with sprintf
233
+ char buf[128];
234
+
235
+ // build up return value
236
+ std::string retval;
237
+ retval = "";
238
+
239
+ // format control information
240
+ sprintf(buf, "dest: %08x, last: %d, data: {", p.destination, p.last);
241
+ retval += buf;
242
+
243
+ // format data
244
+ for (size_t i = 0; i < max_idx; i++) {
245
+ sprintf(buf, "%02x", p.data[i]);
246
+ retval += buf;
247
+ if (i != (max_idx - 1)) {
248
+ retval += ", ";
249
+ }
250
+ }
251
+
252
+ retval += "}";
253
+
254
+ return retval;
255
+ }
256
+
257
+ #endif // __SWITCHBOARD_HPP__
@@ -0,0 +1,234 @@
1
+ // Switchboard FPGA/PCIe transactor driver
2
+
3
+ // Copyright (c) 2024 Zero ASIC Corporation
4
+ // This code is licensed under Apache License 2.0 (see LICENSE for details)
5
+
6
+ #ifndef __SWITCHBOARD_PCIE_HPP__
7
+ #define __SWITCHBOARD_PCIE_HPP__
8
+
9
+ #include <array>
10
+ #include <cstdio>
11
+ #include <string>
12
+ #include <thread>
13
+ #include <vector>
14
+
15
+ #include "pagemap.h"
16
+ #include "pciedev.h"
17
+ #include "spsc_queue.h"
18
+ #include "switchboard.hpp"
19
+
20
+ #undef D
21
+ #define D(x)
22
+
23
+ #define REG_ID 0x000
24
+ #define REG_ID_FPGA 0x1234
25
+
26
+ #define REG_CAP 0x004
27
+
28
+ #define REG_ENABLE 0x100
29
+ #define REG_RESET 0x104
30
+ #define REG_STATUS 0x108
31
+ #define REG_QUEUE_ADDRESS_LO 0x10c
32
+ #define REG_QUEUE_ADDRESS_HI 0x110
33
+ #define REG_QUEUE_CAPACITY 0x114
34
+
35
+ #define REG_QUEUE_ADDR_SIZE 0x100 // size of addr space dedicated to each queue
36
+
37
+ // Map enough space to configure 256 queues + global config.
38
+ #define PCIE_BAR_MAP_SIZE (REG_QUEUE_ADDR_SIZE * 256 + REG_ENABLE)
39
+
40
+ // Max nr of retries when resetting or disabling queue's.
41
+ #define MAX_RETRY 3
42
+
43
+ template <typename T> static inline void sb_pcie_deinit(T* s) {
44
+
45
+ // Needs to be done in reverse order.
46
+ s->deinit_dev();
47
+ s->deinit_host();
48
+ }
49
+
50
+ class SB_pcie {
51
+ public:
52
+ SB_pcie(int queue_id) : m_queue_id(queue_id), m_map(NULL), m_addr(0) {}
53
+
54
+ ~SB_pcie() {
55
+ sb_pcie_deinit(this);
56
+ }
57
+
58
+ virtual bool init_host(const char* uri, const char* bdf, int bar_num, void* handle) {
59
+ m_addr = pagemap_virt_to_phys(handle);
60
+ m_map = (char*)pcie_bar_map(bdf, bar_num, 0, PCIE_BAR_MAP_SIZE);
61
+ if (m_map == MAP_FAILED) {
62
+ m_map = NULL;
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+
68
+ virtual void deinit_host(void) {
69
+ if (m_map) {
70
+ pcie_bar_unmap(m_map, PCIE_BAR_MAP_SIZE);
71
+ m_map = NULL;
72
+ }
73
+ }
74
+
75
+ bool init_dev(int capacity) {
76
+ int qoffset = m_queue_id * REG_QUEUE_ADDR_SIZE;
77
+ int reset_retry = 0;
78
+ uint32_t r;
79
+
80
+ r = dev_read32(REG_ID);
81
+ D(printf("SB pcie ID=%x\n", r));
82
+ if (r >> 16 != REG_ID_FPGA) {
83
+ printf("%s: Incompatible REG_ID=%x\n", __func__, r);
84
+ return false;
85
+ }
86
+
87
+ r = dev_read32(REG_CAP);
88
+ D(printf("SB pcie CAP=%x\n", r));
89
+
90
+ // Reset the device.
91
+ dev_write32(qoffset + REG_RESET, 0x1);
92
+ D(printf("Read reset state\n"));
93
+ while (dev_read32(qoffset + REG_STATUS) != 0x1) {
94
+ if (reset_retry++ >= MAX_RETRY) {
95
+ return false;
96
+ }
97
+ usleep(100 * 1000);
98
+ }
99
+
100
+ dev_write32(qoffset + REG_QUEUE_ADDRESS_LO, m_addr);
101
+ dev_write32(qoffset + REG_QUEUE_ADDRESS_HI, m_addr >> 32);
102
+ D(printf("SB QUEUE_ADDR=%lx\n", m_addr));
103
+
104
+ dev_write32(qoffset + REG_QUEUE_CAPACITY, capacity);
105
+ D(printf("SB CAPACITY=%d\n", capacity));
106
+
107
+ dev_write32_strong(qoffset + REG_ENABLE, 0x1);
108
+ return true;
109
+ }
110
+
111
+ void deinit_dev() {
112
+ int disable_retry = 0;
113
+
114
+ if (!m_map) {
115
+ return;
116
+ }
117
+ int qoffset = m_queue_id * REG_QUEUE_ADDR_SIZE;
118
+
119
+ // Must disable queue and wait for it to quiesce before unmapping
120
+ // queue shared memory, otherwise FPGA may read from/write to memory
121
+ // that gets reallocated to another process.
122
+ dev_write32_strong(qoffset + REG_ENABLE, 0x0);
123
+ while (dev_read32(qoffset + REG_STATUS) != 0x1) {
124
+ if (disable_retry++ >= MAX_RETRY) {
125
+ return;
126
+ }
127
+ usleep(100 * 1000);
128
+ }
129
+ }
130
+
131
+ virtual uint32_t dev_read32(uint64_t offset) {
132
+ assert(m_map);
133
+ assert(offset <= PCIE_BAR_MAP_SIZE - 4);
134
+ return pcie_read32(m_map + offset);
135
+ }
136
+
137
+ virtual void dev_write32(uint64_t offset, uint32_t v) {
138
+ assert(m_map);
139
+ assert(offset <= PCIE_BAR_MAP_SIZE - 4);
140
+ pcie_write32(m_map + offset, v);
141
+ }
142
+
143
+ virtual void dev_write32_strong(uint64_t offset, uint32_t v) {
144
+ assert(m_map);
145
+ assert(offset <= PCIE_BAR_MAP_SIZE - 4);
146
+ pcie_write32_strong(m_map + offset, v);
147
+ }
148
+
149
+ protected:
150
+ // Queue index.
151
+ int m_queue_id;
152
+
153
+ // m_map holds a pointer to a mapped memory area that can be
154
+ // used for register accesses. Not all implementations will use it.
155
+ char* m_map;
156
+
157
+ // m_addr holds an address to the SPSC queue's SHM area. For some
158
+ // implementations this will simply be a user-space virtual address
159
+ // and for others it may be a physical address for HW DMA implementations
160
+ // to access.
161
+ uint64_t m_addr;
162
+ };
163
+
164
+ static inline bool sb_init_queue(SB_base* s, const char* uri) {
165
+ int capacity;
166
+
167
+ // Create queue's that fit into a single page.
168
+ capacity = spsc_capacity(getpagesize());
169
+ s->init(uri, capacity);
170
+
171
+ // Lock pages into RAM (avoid ondemand allocation or swapping).
172
+ if (s->mlock()) {
173
+ perror("mlock");
174
+ s->deinit();
175
+ return false;
176
+ }
177
+ return true;
178
+ }
179
+
180
+ template <typename T>
181
+ static inline bool sb_pcie_init(T* s, const char* uri, const char* bdf, int bar_num) {
182
+ sb_init_queue(s, uri);
183
+
184
+ if (!s->init_host(uri, bdf, bar_num, s->get_shm_handle())) {
185
+ s->deinit();
186
+ return false;
187
+ }
188
+
189
+ if (!s->init_dev(s->get_capacity())) {
190
+ s->deinit();
191
+ return false;
192
+ }
193
+ return true;
194
+ }
195
+
196
+ class SBTX_pcie : public SBTX, public SB_pcie {
197
+ public:
198
+ SBTX_pcie(int queue_id) : SB_pcie(queue_id) {}
199
+
200
+ bool init(std::string uri, std::string bdf, int bar_num) {
201
+ return init(uri.c_str(), bdf.c_str(), bar_num);
202
+ }
203
+
204
+ bool init(const char* uri, const char* bdf, int bar_num) {
205
+ return sb_pcie_init(this, uri, bdf, bar_num);
206
+ }
207
+
208
+ void deinit(void) {
209
+ sb_pcie_deinit(this);
210
+ }
211
+
212
+ private:
213
+ };
214
+
215
+ class SBRX_pcie : public SBRX, public SB_pcie {
216
+ public:
217
+ SBRX_pcie(int queue_id) : SB_pcie(queue_id) {}
218
+
219
+ bool init(std::string uri, std::string bdf, int bar_num) {
220
+ return init(uri.c_str(), bdf.c_str(), bar_num);
221
+ }
222
+
223
+ bool init(const char* uri, const char* bdf, int bar_num) {
224
+ return sb_pcie_init(this, uri, bdf, bar_num);
225
+ }
226
+
227
+ void deinit(void) {
228
+ sb_pcie_deinit(this);
229
+ }
230
+
231
+ private:
232
+ };
233
+
234
+ #endif // __SWITCHBOARD_PCIE_HPP__
@@ -0,0 +1,98 @@
1
+ // Switchboard TLM transactor driver
2
+
3
+ // Copyright (c) 2024 Zero ASIC Corporation
4
+ // This code is licensed under Apache License 2.0 (see LICENSE for details)
5
+
6
+ #ifndef __SWITCHBOARD_TLM_HPP__
7
+ #define __SWITCHBOARD_TLM_HPP__
8
+
9
+ #include <array>
10
+ #include <cstdio>
11
+ #include <string>
12
+ #include <thread>
13
+ #include <vector>
14
+
15
+ #include "spsc_queue.h"
16
+ #include "switchboard.hpp"
17
+ #include "switchboard_pcie.hpp"
18
+
19
+ #define SC_INCLUDE_DYNAMIC_PROCESSES
20
+
21
+ #include "systemc"
22
+ using namespace sc_core;
23
+ using namespace sc_dt;
24
+ using namespace std;
25
+
26
+ #include "tlm.h"
27
+ #include "tlm_utils/simple_initiator_socket.h"
28
+ #include "tlm_utils/simple_target_socket.h"
29
+
30
+ class SB_tlm : public SB_pcie {
31
+ public:
32
+ tlm_utils::simple_initiator_socket<SB_tlm> socket;
33
+
34
+ SB_tlm(int queue_id) : SB_pcie(queue_id) {}
35
+
36
+ bool init_host(const char* uri, const char* bdf, int bar_num, void* handle) {
37
+ assert(handle);
38
+ m_addr = (uintptr_t)handle;
39
+ return true;
40
+ }
41
+
42
+ void dev_access(tlm::tlm_command cmd, uint64_t offset, void* buf, unsigned int len) {
43
+ unsigned char* buf8 = (unsigned char*)buf;
44
+ sc_time delay = SC_ZERO_TIME;
45
+ tlm::tlm_generic_payload tr;
46
+
47
+ tr.set_command(cmd);
48
+ tr.set_address(offset);
49
+ tr.set_data_ptr(buf8);
50
+ tr.set_data_length(len);
51
+ tr.set_streaming_width(len);
52
+ tr.set_dmi_allowed(false);
53
+ tr.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
54
+
55
+ socket->b_transport(tr, delay);
56
+ assert(tr.get_response_status() == tlm::TLM_OK_RESPONSE);
57
+ }
58
+
59
+ uint32_t dev_read32(uint64_t offset) {
60
+ uint32_t r;
61
+ assert((offset & 3) == 0);
62
+ dev_access(tlm::TLM_READ_COMMAND, offset, &r, sizeof(r));
63
+ return r;
64
+ }
65
+
66
+ void dev_write32(uint64_t offset, uint32_t v) {
67
+ assert((offset & 3) == 0);
68
+ dev_access(tlm::TLM_WRITE_COMMAND, offset, &v, sizeof(v));
69
+ }
70
+
71
+ void dev_write32_strong(uint64_t offset, uint32_t v) {
72
+ uint32_t dummy;
73
+
74
+ dev_write32(offset, v);
75
+ // Enforce PCIe ordering.
76
+ dummy = dev_read32(offset);
77
+ dummy = dummy;
78
+ }
79
+ };
80
+
81
+ class SBTX_tlm : public SBTX, public SB_tlm {
82
+ public:
83
+ SBTX_tlm(int queue_id) : SB_tlm(queue_id) {}
84
+
85
+ bool init(const char* uri) {
86
+ return sb_pcie_init(this, uri, NULL, -1);
87
+ }
88
+ };
89
+
90
+ class SBRX_tlm : public SBRX, public SB_tlm {
91
+ public:
92
+ SBRX_tlm(int queue_id) : SB_tlm(queue_id) {}
93
+
94
+ bool init(const char* uri) {
95
+ return sb_pcie_init(this, uri, NULL, -1);
96
+ }
97
+ };
98
+ #endif