130 """Check actual transport requests and responses, including zero padding."""
131 lines = Path(
"hostmem_read.log").read_text().splitlines()
133 bytes.fromhex(line.split(
"]", 1)[1])
135 if "__cosim_hostmem_read_req.data" in line
138 bytes.fromhex(line.split(
"]", 1)[1])
140 if "__cosim_hostmem_read_resp.data" in line
142 word_bytes = bus_width // 8
143 cap = max(256, word_bytes)
144 chunks = [(address + offset, data[offset:offset + cap])
145 for address, data
in expected_reads
146 for offset
in range(0, len(data), cap)]
147 assert len(requests) == len(chunks)
148 assert len(responses) == sum(
149 (len(data) + word_bytes - 1) // word_bytes
for _, data
in expected_reads)
151 for request, (address, data)
in zip(requests, chunks):
152 assert len(request) == 13
153 assert int.from_bytes(request[1:5],
"little") == len(data)
154 assert int.from_bytes(request[5:],
"little") == address
155 for offset
in range(0, len(data), word_bytes):
156 response = responses[response_idx]
158 assert len(response) == word_bytes + 2
159 packed = int.from_bytes(response,
"little")
160 assert packed & 1 == int(offset + word_bytes >= len(data))
161 assert packed >> (bus_width + 1) == request[0]
162 assert (packed >> 1) & ((1 << bus_width) - 1) == int.from_bytes(
163 data[offset:offset + word_bytes],
"little")
166def _run(conn: AcceleratorConnection,
167 max_outstanding: int,
168 bus_width: int = 64) ->
None:
169 hostmem = conn.get_service_hostmem()
171 acc = conn.build_accelerator()
173 for width
in ELEMENT_WIDTHS:
174 dut =
_Dut(conn, acc, width)
177 gated_reads = [(0, max(120, 4 * (bus_width // 8) // dut.stride + 1))
183 dut.issue(gated_reads)
184 in_flight = min(len(gated_reads), max_outstanding)
187 assert dut.accepted_count() == in_flight, (
188 f
"width {width}: expected {in_flight} reads in flight with the "
189 f
"response side stalled")
192 dut.check_responses(gated_reads)
193 assert dut.accepted_count() == len(gated_reads)
196 dut.issue(STREAMED_READS)
197 dut.check_responses(STREAMED_READS)
198 assert dut.accepted_count() == len(gated_reads) + len(STREAMED_READS)
199 for offset, count
in gated_reads + STREAMED_READS:
200 start = offset * dut.stride
201 expected_reads.append(
202 (dut.mem.ptr + start, dut.data[start:start + count * dut.stride]))
204 for width
in [13, bus_width, bus_width + 24, 16384]:
205 dut = acc.children[esiaccel.AppID(
"single", width)]
206 req = dut.ports[esiaccel.AppID(
"req")]
207 resp = dut.ports[esiaccel.AppID(
"resp")]
210 size = (width + 7) // 8
211 mem = hostmem.allocate(size + bus_width // 8 + 6)
212 ctypes.memset(mem.ptr, 0xA5, mem.size)
214 ctypes.memmove(mem.ptr + 3, data, size)
215 req.write(mem.ptr + 3)
216 assert resp.read().result(timeout=30) == (int.from_bytes(data,
"little") &
218 expected_reads.append((mem.ptr + 3, data))
222@cosim_test(HW_DIR / "hostmem_read.py", args=("{tmp_dir}", "1"))