mirror of https://github.com/llvm/circt.git
[ESI] Cosimulation integration tests (#259)
* [ESI] Cosimulation integration tests * Fixes * Set an integration test timeout.
This commit is contained in:
parent
ac8ea5d10c
commit
113ee95719
|
@ -10,6 +10,7 @@ if (TARGET EsiCosimDpiServer)
|
|||
set(ESI_COSIM_PATH ${ESI_COSIM_LIB_DIR}/libEsiCosimDpiServer.so)
|
||||
endif()
|
||||
|
||||
set(CIRCT_INTEGRATION_TIMEOUT 60) # Set a 60s timeout on individual tests.
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import binascii
|
||||
import capnp
|
||||
import random
|
||||
import time
|
||||
|
||||
|
||||
class LoopbackTester:
|
||||
"""Provides methods to test the untyped loopback simulation."""
|
||||
|
||||
# Some of these are generalizable and should be hoisted into a base class
|
||||
# when other cosim tests get written.
|
||||
|
||||
def __init__(self, schemaPath, hostPort):
|
||||
self.dpi = capnp.load(schemaPath)
|
||||
self.rpc_client = capnp.TwoPartyClient(hostPort)
|
||||
self.cosim = self.rpc_client.bootstrap().cast_as(self.dpi.CosimDpiServer)
|
||||
|
||||
def test_list(self):
|
||||
ifaces = self.cosim.list().wait().ifaces
|
||||
assert len(ifaces) > 0
|
||||
|
||||
def test_open_close(self):
|
||||
ifaces = self.cosim.list().wait().ifaces
|
||||
openResp = self.cosim.open(ifaces[0]).wait()
|
||||
assert openResp.iface is not None
|
||||
ep = openResp.iface
|
||||
ep.close().wait()
|
||||
|
||||
def openEP(self):
|
||||
ifaces = self.cosim.list().wait().ifaces
|
||||
openResp = self.cosim.open(ifaces[0]).wait()
|
||||
assert openResp.iface is not None
|
||||
return openResp.iface
|
||||
|
||||
def write(self, ep):
|
||||
r = random.randrange(0, 2**24)
|
||||
data = r.to_bytes(3, 'big')
|
||||
print(f'Sending: {binascii.hexlify(data)}')
|
||||
ep.send(self.dpi.UntypedData.new_message(data=data)).wait()
|
||||
return data
|
||||
|
||||
def read(self, ep):
|
||||
while True:
|
||||
recvResp = ep.recv(False).wait()
|
||||
if recvResp.hasData:
|
||||
break
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
assert recvResp.resp is not None
|
||||
dataMsg = recvResp.resp.as_struct(self.dpi.UntypedData)
|
||||
data = dataMsg.data
|
||||
print(binascii.hexlify(data))
|
||||
return data
|
||||
|
||||
def write_read(self):
|
||||
ep = self.openEP()
|
||||
print("Testing writes")
|
||||
dataSent = self.write(ep)
|
||||
print()
|
||||
print("Testing reads")
|
||||
dataRecv = self.read(ep)
|
||||
ep.close().wait()
|
||||
assert dataSent == dataRecv
|
||||
|
||||
def write_read_many(self, num_msgs=50):
|
||||
ep = self.openEP()
|
||||
print("Testing writes")
|
||||
dataSent = list()
|
||||
for _ in range(num_msgs):
|
||||
dataSent.append(self.write(ep))
|
||||
print()
|
||||
print("Testing reads")
|
||||
dataRecv = list()
|
||||
for _ in range(num_msgs):
|
||||
dataRecv.append(self.read(ep))
|
||||
ep.close().wait()
|
||||
assert dataSent == dataRecv
|
|
@ -0,0 +1,85 @@
|
|||
// PY: import loopback as test
|
||||
// PY: rpc = test.LoopbackTester(rpcschemapath, simhostport)
|
||||
// PY: rpc.test_list()
|
||||
// PY: rpc.test_open_close()
|
||||
// PY: rpc.write_read_many(5)
|
||||
|
||||
import Cosim_DpiPkg::*;
|
||||
|
||||
module main(
|
||||
`ifdef VERILATOR
|
||||
input logic clk,
|
||||
input logic rstn
|
||||
`endif
|
||||
);
|
||||
localparam int TYPE_SIZE_BITS =
|
||||
(1 * 64) + // root message
|
||||
(1 * 64) + // list header
|
||||
(1 * 64); // list of length 3 bytes, rounded up to multiples of 8 bytes
|
||||
`ifndef VERILATOR
|
||||
logic clk;
|
||||
logic rstn;
|
||||
`endif
|
||||
|
||||
wire DataOutValid;
|
||||
wire DataOutReady = 1;
|
||||
wire [TYPE_SIZE_BITS-1:0] DataOut;
|
||||
|
||||
logic DataInValid;
|
||||
logic DataInReady;
|
||||
logic [TYPE_SIZE_BITS-1:0] DataIn;
|
||||
|
||||
Cosim_Endpoint #(
|
||||
.ENDPOINT_ID(1),
|
||||
.RECV_TYPE_ID(1),
|
||||
.RECV_TYPE_SIZE_BITS(TYPE_SIZE_BITS),
|
||||
.SEND_TYPE_ID(1),
|
||||
.SEND_TYPE_SIZE_BITS(TYPE_SIZE_BITS)
|
||||
) ep (
|
||||
.*
|
||||
);
|
||||
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if (rstn)
|
||||
begin
|
||||
if (DataOutValid && DataOutReady)
|
||||
begin
|
||||
$display("[%d] Recv'd: %h", $time(), DataOut);
|
||||
DataIn <= DataOut;
|
||||
end
|
||||
DataInValid <= DataOutValid && DataOutReady;
|
||||
|
||||
if (DataInValid && DataInReady)
|
||||
begin
|
||||
$display("[%d] Sent: %h", $time(), DataIn);
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
DataInValid <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
`ifndef VERILATOR
|
||||
// Clock
|
||||
initial
|
||||
begin
|
||||
clk = 1'b0;
|
||||
while (1)
|
||||
begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
end
|
||||
|
||||
initial
|
||||
begin
|
||||
rstn = 0;
|
||||
#17
|
||||
// Run!
|
||||
rstn = 1;
|
||||
end
|
||||
`endif
|
||||
|
||||
endmodule
|
|
@ -40,6 +40,10 @@ llvm_config.with_system_environment(
|
|||
|
||||
llvm_config.use_default_substitutions()
|
||||
|
||||
# Set the timeout, if requested.
|
||||
if config.timeout is not None and config.timeout != "":
|
||||
lit_config.maxIndividualTestTime = int(config.timeout)
|
||||
|
||||
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
|
||||
# subdirectories contain auxiliary inputs for various tests in their parent
|
||||
# directories.
|
||||
|
|
|
@ -38,6 +38,7 @@ config.circt_include_dir = "@CIRCT_MAIN_SRC_DIR@"
|
|||
config.circt_shlib_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
|
||||
config.verilator_path = "@VERILATOR_PATH@"
|
||||
config.esi_cosim_path = "@ESI_COSIM_PATH@"
|
||||
config.timeout = "@CIRCT_INTEGRATION_TIMEOUT@"
|
||||
|
||||
# Support substitution of the tools_dir with user parameters. This is
|
||||
# used when we can't determine the tool dir at configuration time.
|
||||
|
|
|
@ -45,7 +45,7 @@ bool EndpointRegistry::registerEndpoint(int epId, uint64_t sendTypeId,
|
|||
// Endpoint constructor args.
|
||||
std::forward_as_tuple(sendTypeId, sendTypeMaxSize,
|
||||
recvTypeId, recvTypeMaxSize));
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EndpointRegistry::iterateEndpoints(
|
||||
|
|
Loading…
Reference in New Issue