Commit 87f7ac7a authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

nicsim_common,corundum(_bm): move sync support to library

parent c35116cf
...@@ -22,17 +22,13 @@ extern "C" { ...@@ -22,17 +22,13 @@ extern "C" {
#define CLOCK_PERIOD (100 * 1000ULL) // 100ns -> 10MHz #define CLOCK_PERIOD (100 * 1000ULL) // 100ns -> 10MHz
#define SYNC_PERIOD (500 * 1000ULL) // 100ns #define SYNC_PERIOD (500 * 1000ULL) // 100ns
#define PCI_LATENCY (1 * 1000 * 1000ULL) // 1us #define PCI_LATENCY (1 * 1000 * 1000ULL) // 1us
#define ETH_ASYNCHRONY (1 * 1000 * 1000ULL) // 1us #define ETH_LATENCY (1 * 1000 * 1000ULL) // 1us
struct DMAOp; struct DMAOp;
static volatile int exiting = 0; static volatile int exiting = 0;
static int sync_pci_en, sync_eth_en;
static uint64_t main_time = 0; static uint64_t main_time = 0;
static uint64_t pci_last_rx_time = 0; static struct nicsim_params nsparams;
static uint64_t pci_last_tx_time = 0;
static uint64_t eth_last_rx_time = 0;
static uint64_t eth_last_tx_time = 0;
#ifdef TRACE_ENABLED #ifdef TRACE_ENABLED
static VerilatedVcdC* trace; static VerilatedVcdC* trace;
#endif #endif
...@@ -541,18 +537,14 @@ static void h2d_write(MMIOInterface &mmio, ...@@ -541,18 +537,14 @@ static void h2d_write(MMIOInterface &mmio,
static void poll_h2d(MMIOInterface &mmio) static void poll_h2d(MMIOInterface &mmio)
{ {
volatile union cosim_pcie_proto_h2d *msg = nicif_h2d_poll(); volatile union cosim_pcie_proto_h2d *msg =
nicif_h2d_poll(&nsparams, main_time);
uint8_t t; uint8_t t;
if (msg == NULL) if (msg == NULL)
return; return;
t = msg->dummy.own_type & COSIM_PCIE_PROTO_H2D_MSG_MASK; t = msg->dummy.own_type & COSIM_PCIE_PROTO_H2D_MSG_MASK;
pci_last_rx_time = msg->dummy.timestamp;
// we're running synchronized but it's not time for this message yet
if (sync_pci_en && pci_last_rx_time > main_time)
return;
//std::cerr << "poll_h2d: polled type=" << (int) t << std::endl; //std::cerr << "poll_h2d: polled type=" << (int) t << std::endl;
switch (t) { switch (t) {
...@@ -586,10 +578,7 @@ static void poll_h2d(MMIOInterface &mmio) ...@@ -586,10 +578,7 @@ static void poll_h2d(MMIOInterface &mmio)
static volatile union cosim_pcie_proto_d2h *d2h_alloc(void) static volatile union cosim_pcie_proto_d2h *d2h_alloc(void)
{ {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); return nicsim_d2h_alloc(&nsparams, main_time);
msg->dummy.timestamp = main_time + PCI_LATENCY;
pci_last_tx_time = main_time;
return msg;
} }
class EthernetTx { class EthernetTx {
...@@ -606,7 +595,8 @@ class EthernetTx { ...@@ -606,7 +595,8 @@ class EthernetTx {
void packet_done() void packet_done()
{ {
volatile union cosim_eth_proto_d2n *msg = nicsim_d2n_alloc(); volatile union cosim_eth_proto_d2n *msg =
nicsim_d2n_alloc(&nsparams, main_time);
volatile struct cosim_eth_proto_d2n_send *send; volatile struct cosim_eth_proto_d2n_send *send;
if (!msg) if (!msg)
...@@ -615,6 +605,7 @@ class EthernetTx { ...@@ -615,6 +605,7 @@ class EthernetTx {
send = &msg->send; send = &msg->send;
memcpy((void *) send->data, packet_buf, packet_len); memcpy((void *) send->data, packet_buf, packet_len);
send->len = packet_len; send->len = packet_len;
send->timestamp = main_time + ETH_LATENCY;
//WMB(); //WMB();
send->own_type = COSIM_ETH_PROTO_D2N_MSG_SEND | send->own_type = COSIM_ETH_PROTO_D2N_MSG_SEND |
...@@ -749,18 +740,23 @@ static void n2d_recv(EthernetRx &rx, ...@@ -749,18 +740,23 @@ static void n2d_recv(EthernetRx &rx,
static void poll_n2d(EthernetRx &rx) static void poll_n2d(EthernetRx &rx)
{ {
volatile union cosim_eth_proto_n2d *msg = nicif_n2d_poll(); volatile union cosim_eth_proto_n2d *msg =
nicif_n2d_poll(&nsparams, main_time);
uint8_t t; uint8_t t;
if (msg == NULL) if (msg == NULL)
return; return;
t = msg->dummy.own_type & COSIM_ETH_PROTO_N2D_MSG_MASK; t = msg->dummy.own_type & COSIM_ETH_PROTO_N2D_MSG_MASK;
switch (t) { switch (t) {
case COSIM_ETH_PROTO_N2D_MSG_RECV: case COSIM_ETH_PROTO_N2D_MSG_RECV:
n2d_recv(rx, &msg->recv); n2d_recv(rx, &msg->recv);
break; break;
case COSIM_ETH_PROTO_N2D_MSG_SYNC:
break;
default: default:
std::cerr << "poll_n2d: unsupported type=" << t << std::endl; std::cerr << "poll_n2d: unsupported type=" << t << std::endl;
} }
...@@ -878,24 +874,6 @@ static void msi_step(Vinterface &top, PCICoordinator &coord) ...@@ -878,24 +874,6 @@ static void msi_step(Vinterface &top, PCICoordinator &coord)
} }
} }
static void send_sync_pci(MMIOInterface &mmio)
{
volatile union cosim_pcie_proto_d2h *msg;
volatile struct cosim_pcie_proto_d2h_sync *sync;
if (pci_last_tx_time == 0 || main_time - pci_last_tx_time >= SYNC_PERIOD) {
msg = d2h_alloc();
sync = &msg->sync;
// WMB();
sync->own_type = COSIM_PCIE_PROTO_D2H_MSG_SYNC |
COSIM_PCIE_PROTO_D2H_OWN_HOST;
}
}
static void sync_eth(EthernetRx &rx)
{
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *vargs[2] = { argv[0], NULL }; char *vargs[2] = { argv[0], NULL };
...@@ -925,15 +903,19 @@ int main(int argc, char *argv[]) ...@@ -925,15 +903,19 @@ int main(int argc, char *argv[])
di.pci_revision = 0x00; di.pci_revision = 0x00;
di.pci_msi_nvecs = 32; di.pci_msi_nvecs = 32;
sync_pci_en = 1; nsparams.sync_pci = 1;
sync_eth_en = 1; nsparams.sync_eth = 1;
if (nicsim_init(&di, argv[1], &sync_pci_en, argv[2], &sync_eth_en, nsparams.pci_socket_path = argv[1];
argv[3])) nsparams.eth_socket_path = argv[2];
{ nsparams.shm_path = argv[3];
nsparams.pci_latency = PCI_LATENCY;
nsparams.eth_latency = ETH_LATENCY;
nsparams.sync_delay = SYNC_PERIOD;
if (nicsim_init(&nsparams, &di)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
std::cout << "sync_pci=" << sync_pci_en << " sync_eth=" << sync_eth_en << std::cout << "sync_pci=" << nsparams.sync_pci <<
std::endl; " sync_eth=" << nsparams.sync_eth << std::endl;
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
...@@ -1044,15 +1026,16 @@ int main(int argc, char *argv[]) ...@@ -1044,15 +1026,16 @@ int main(int argc, char *argv[])
top->rst = 0; top->rst = 0;
while (!exiting) { while (!exiting) {
if (sync_pci_en) while (nicsim_sync(&nsparams, main_time)) {
send_sync_pci(mmio); std::cerr << "warn: nicsim_sync failed (t=" << main_time << ")" <<
if (sync_eth_en) std::endl;
sync_eth(rx); }
do { do {
poll_h2d(mmio); poll_h2d(mmio);
poll_n2d(rx); poll_n2d(rx);
} while (sync_pci_en && pci_last_rx_time < main_time && !exiting); } while ((nsparams.sync_pci || nsparams.sync_eth) &&
netsim_next_timestamp(&nsparams) <= main_time && !exiting);
/* falling edge */ /* falling edge */
top->clk = !top->clk; top->clk = !top->clk;
......
...@@ -13,10 +13,17 @@ extern "C" { ...@@ -13,10 +13,17 @@ extern "C" {
#include <netsim.h> #include <netsim.h>
} }
#define SYNC_PERIOD (500 * 1000ULL) // 100ns
#define PCI_LATENCY (1 * 1000 * 1000ULL) // 1us
#define ETH_LATENCY (1 * 1000 * 1000ULL) // 1us
static void issue_dma_op(corundum::DMAOp *op); static void issue_dma_op(corundum::DMAOp *op);
static void msi_issue(uint8_t vec); static void msi_issue(uint8_t vec);
static void eth_send(void *data, size_t len); static void eth_send(void *data, size_t len);
static uint64_t main_time = 0;
static struct nicsim_params nsparams;
namespace corundum { namespace corundum {
DescRing::DescRing() DescRing::DescRing()
...@@ -757,7 +764,8 @@ sigint_handler(int dummy) ...@@ -757,7 +764,8 @@ sigint_handler(int dummy)
static volatile union cosim_pcie_proto_d2h * static volatile union cosim_pcie_proto_d2h *
d2h_alloc(void) d2h_alloc(void)
{ {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg =
nicsim_d2h_alloc(&nsparams, main_time);
if (msg == NULL) { if (msg == NULL) {
fprintf(stderr, "d2h_alloc: no entry available\n"); fprintf(stderr, "d2h_alloc: no entry available\n");
abort(); abort();
...@@ -768,7 +776,8 @@ d2h_alloc(void) ...@@ -768,7 +776,8 @@ d2h_alloc(void)
static volatile union cosim_eth_proto_d2n * static volatile union cosim_eth_proto_d2n *
d2n_alloc(void) d2n_alloc(void)
{ {
volatile union cosim_eth_proto_d2n *msg = nicsim_d2n_alloc(); volatile union cosim_eth_proto_d2n *msg =
nicsim_d2n_alloc(&nsparams, main_time);
if (msg == NULL) { if (msg == NULL) {
fprintf(stderr, "d2n_alloc: no entry available\n"); fprintf(stderr, "d2n_alloc: no entry available\n");
abort(); abort();
...@@ -893,7 +902,8 @@ static void eth_send(void *data, size_t len) ...@@ -893,7 +902,8 @@ static void eth_send(void *data, size_t len)
static void poll_h2d(Corundum &nic) static void poll_h2d(Corundum &nic)
{ {
volatile union cosim_pcie_proto_h2d *msg = nicif_h2d_poll(); volatile union cosim_pcie_proto_h2d *msg =
nicif_h2d_poll(&nsparams, main_time);
uint8_t type; uint8_t type;
if (msg == NULL) if (msg == NULL)
...@@ -927,7 +937,8 @@ static void poll_h2d(Corundum &nic) ...@@ -927,7 +937,8 @@ static void poll_h2d(Corundum &nic)
static void poll_n2d(Corundum &nic) static void poll_n2d(Corundum &nic)
{ {
volatile union cosim_eth_proto_n2d *msg = nicif_n2d_poll(); volatile union cosim_eth_proto_n2d *msg =
nicif_n2d_poll(&nsparams, main_time);
uint8_t t; uint8_t t;
if (msg == NULL) if (msg == NULL)
...@@ -949,6 +960,17 @@ static void poll_n2d(Corundum &nic) ...@@ -949,6 +960,17 @@ static void poll_n2d(Corundum &nic)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
uint64_t next_ts;
if (argc != 4 && argc != 5) {
fprintf(stderr, "Usage: corundum_bm PCI-SOCKET ETH-SOCKET "
"SHM [START-TICK]\n");
return EXIT_FAILURE;
}
if (argc == 5)
main_time = strtoull(argv[4], NULL, 0);
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
struct cosim_pcie_proto_dev_intro di; struct cosim_pcie_proto_dev_intro di;
...@@ -962,18 +984,34 @@ int main(int argc, char *argv[]) ...@@ -962,18 +984,34 @@ int main(int argc, char *argv[])
di.pci_revision = 0x00; di.pci_revision = 0x00;
di.pci_msi_nvecs = 32; di.pci_msi_nvecs = 32;
int sync_pci_en = 0, sync_eth_en = 0; nsparams.sync_pci = 1;
if (nicsim_init(&di, "/tmp/cosim-pci", &sync_pci_en, nsparams.sync_eth = 1;
"/tmp/cosim-eth", &sync_eth_en, nsparams.pci_socket_path = argv[1];
"/dev/shm/dummy_nic_shm")) { nsparams.eth_socket_path = argv[2];
nsparams.shm_path = argv[3];
nsparams.pci_latency = PCI_LATENCY;
nsparams.eth_latency = ETH_LATENCY;
nsparams.sync_delay = SYNC_PERIOD;
if (nicsim_init(&nsparams, &di)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fprintf(stderr, "sync_pci=%d sync_eth=%d\n", nsparams.sync_pci,
nsparams.sync_eth);
Corundum nic; Corundum nic;
while (!exiting) { while (!exiting) {
poll_h2d(nic); while (nicsim_sync(&nsparams, main_time)) {
poll_n2d(nic); fprintf(stderr, "warn: nicsim_sync failed (t=%llu)\n", main_time);
}
do {
poll_h2d(nic);
poll_n2d(nic);
next_ts = netsim_next_timestamp(&nsparams);
} while ((nsparams.sync_pci || nsparams.sync_eth) &&
next_ts <= main_time && !exiting);
main_time = next_ts;
} }
nicsim_cleanup(); nicsim_cleanup();
......
...@@ -27,24 +27,41 @@ ...@@ -27,24 +27,41 @@
#include <cosim_pcie_proto.h> #include <cosim_pcie_proto.h>
#include <cosim_eth_proto.h> #include <cosim_eth_proto.h>
int nicsim_init(struct cosim_pcie_proto_dev_intro *di, struct nicsim_params {
const char *pci_socket_path, int *sync_pci, const char *pci_socket_path;
const char *eth_socket_path, int *sync_eth, const char *eth_socket_path;
const char *shm_path); const char *shm_path;
uint64_t pci_latency;
uint64_t eth_latency;
uint64_t sync_delay;
int sync_pci;
int sync_eth;
};
int nicsim_init(struct nicsim_params *params,
struct cosim_pcie_proto_dev_intro *di);
void nicsim_cleanup(void); void nicsim_cleanup(void);
int nicsim_sync(struct nicsim_params *params, uint64_t timestamp);
uint64_t netsim_next_timestamp(struct nicsim_params *params);
volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(void); volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(
struct nicsim_params *params, uint64_t timestamp);
void nicif_h2d_done(volatile union cosim_pcie_proto_h2d *msg); void nicif_h2d_done(volatile union cosim_pcie_proto_h2d *msg);
void nicif_h2d_next(void); void nicif_h2d_next(void);
volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void); volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(
struct nicsim_params *params, uint64_t timestamp);
volatile union cosim_eth_proto_n2d *nicif_n2d_poll(void); volatile union cosim_eth_proto_n2d *nicif_n2d_poll(
struct nicsim_params *params, uint64_t timestamp);
void nicif_n2d_done(volatile union cosim_eth_proto_n2d *msg); void nicif_n2d_done(volatile union cosim_eth_proto_n2d *msg);
void nicif_n2d_next(void); void nicif_n2d_next(void);
volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(void); volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(
struct nicsim_params *params, uint64_t timestamp);
#endif /* ndef COSIM_NICSIM_H_ */ #endif /* ndef COSIM_NICSIM_H_ */
...@@ -61,6 +61,10 @@ static uint8_t *n2d_queue; ...@@ -61,6 +61,10 @@ static uint8_t *n2d_queue;
static size_t n2d_pos; static size_t n2d_pos;
static size_t n2d_off; /* offset in shm region */ static size_t n2d_off; /* offset in shm region */
static uint64_t pci_last_rx_time = 0;
static uint64_t pci_last_tx_time = 0;
static uint64_t eth_last_rx_time = 0;
static uint64_t eth_last_tx_time = 0;
static int shm_fd = -1; static int shm_fd = -1;
static int pci_cfd = -1; static int pci_cfd = -1;
...@@ -173,16 +177,17 @@ static int accept_conns(struct cosim_pcie_proto_dev_intro *di, ...@@ -173,16 +177,17 @@ static int accept_conns(struct cosim_pcie_proto_dev_intro *di,
return 0; return 0;
} }
int nicsim_init(struct cosim_pcie_proto_dev_intro *di, int nicsim_init(struct nicsim_params *params,
const char *pci_socket_path, int *sync_pci, struct cosim_pcie_proto_dev_intro *di)
const char *eth_socket_path, int *sync_eth,
const char *shm_path)
{ {
int pci_lfd = -1, eth_lfd = -1; int pci_lfd = -1, eth_lfd = -1;
void *shmptr; void *shmptr;
/* ready in memory queues */ /* ready in memory queues */
if ((shm_fd = shm_create(shm_path, 32 * 1024 * 1024, &shmptr)) < 0) { if ((shm_fd = shm_create(params->shm_path, 32 * 1024 * 1024, &shmptr))
< 0)
{
return -1; return -1;
} }
...@@ -199,39 +204,41 @@ int nicsim_init(struct cosim_pcie_proto_dev_intro *di, ...@@ -199,39 +204,41 @@ int nicsim_init(struct cosim_pcie_proto_dev_intro *di,
d2h_pos = h2d_pos = d2n_pos = n2d_pos = 0; d2h_pos = h2d_pos = d2n_pos = n2d_pos = 0;
/* get listening sockets ready */ /* get listening sockets ready */
if (pci_socket_path != NULL) { if (params->pci_socket_path != NULL) {
if ((pci_lfd = uxsocket_init(pci_socket_path)) < 0) { if ((pci_lfd = uxsocket_init(params->pci_socket_path)) < 0) {
return -1; return -1;
} }
} }
if (eth_socket_path != NULL) { if (params->eth_socket_path != NULL) {
if ((eth_lfd = uxsocket_init(eth_socket_path)) < 0) { if ((eth_lfd = uxsocket_init(params->eth_socket_path)) < 0) {
return -1; return -1;
} }
} }
/* accept connection fds */ /* accept connection fds */
if (accept_conns(di, pci_lfd, sync_pci, eth_lfd, sync_eth) != 0) { if (accept_conns(di, pci_lfd, &params->sync_pci, eth_lfd,
&params->sync_eth) != 0)
{
return -1; return -1;
} }
/* receive introductions from other end */ /* receive introductions from other end */
if (pci_socket_path != NULL) { if (params->pci_socket_path != NULL) {
struct cosim_pcie_proto_host_intro hi; struct cosim_pcie_proto_host_intro hi;
if (recv(pci_cfd, &hi, sizeof(hi), 0) != sizeof(hi)) { if (recv(pci_cfd, &hi, sizeof(hi), 0) != sizeof(hi)) {
return -1; return -1;
} }
if ((hi.flags & COSIM_PCIE_PROTO_FLAGS_HI_SYNC) == 0) if ((hi.flags & COSIM_PCIE_PROTO_FLAGS_HI_SYNC) == 0)
*sync_pci = 0; params->sync_pci = 0;
printf("pci host info received\n"); printf("pci host info received\n");
} }
if (eth_socket_path != NULL) { if (params->eth_socket_path != NULL) {
struct cosim_eth_proto_net_intro ni; struct cosim_eth_proto_net_intro ni;
if (recv(eth_cfd, &ni, sizeof(ni), 0) != sizeof(ni)) { if (recv(eth_cfd, &ni, sizeof(ni), 0) != sizeof(ni)) {
return -1; return -1;
} }
if ((ni.flags & COSIM_ETH_PROTO_FLAGS_NI_SYNC) == 0) if ((ni.flags & COSIM_ETH_PROTO_FLAGS_NI_SYNC) == 0)
*sync_eth = 0; params->sync_eth = 0;
printf("eth net info received\n"); printf("eth net info received\n");
} }
...@@ -244,10 +251,63 @@ void nicsim_cleanup(void) ...@@ -244,10 +251,63 @@ void nicsim_cleanup(void)
close(eth_cfd); close(eth_cfd);
} }
/******************************************************************************/
/* Sync */
int nicsim_sync(struct nicsim_params *params, uint64_t timestamp)
{
int ret = 0;
volatile union cosim_pcie_proto_d2h *d2h;
volatile union cosim_eth_proto_d2n *d2n;
/* sync PCI if necessary */
if (params->sync_pci &&
timestamp - pci_last_tx_time >= params->sync_delay)
{
d2h = nicsim_d2h_alloc(params, timestamp);
if (d2h == NULL) {
ret = -1;
} else {
d2h->sync.own_type = COSIM_PCIE_PROTO_D2H_MSG_SYNC |
COSIM_PCIE_PROTO_D2H_OWN_HOST;
}
}
/* sync Ethernet if necessary */
if (params->sync_eth &&
timestamp - eth_last_tx_time >= params->sync_delay)
{
d2n = nicsim_d2n_alloc(params, timestamp);
if (d2n == NULL) {
ret = -1;
} else {
d2n->sync.own_type = COSIM_ETH_PROTO_D2N_MSG_SYNC |
COSIM_ETH_PROTO_D2N_OWN_NET;
}
}
return ret;
}
uint64_t netsim_next_timestamp(struct nicsim_params *params)
{
if (params->sync_pci && params->sync_eth) {
return (pci_last_rx_time <= eth_last_rx_time ? pci_last_rx_time :
eth_last_rx_time);
} else if (params->sync_pci) {
return pci_last_rx_time;
} else if (params->sync_eth) {
return eth_last_rx_time;
} else {
return 0;
}
}
/******************************************************************************/ /******************************************************************************/
/* PCI */ /* PCI */
volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(void) volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(
struct nicsim_params *params, uint64_t timestamp)
{ {
volatile union cosim_pcie_proto_h2d *msg = volatile union cosim_pcie_proto_h2d *msg =
(volatile union cosim_pcie_proto_h2d *) (volatile union cosim_pcie_proto_h2d *)
...@@ -258,6 +318,11 @@ volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(void) ...@@ -258,6 +318,11 @@ volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(void)
COSIM_PCIE_PROTO_H2D_OWN_DEV) COSIM_PCIE_PROTO_H2D_OWN_DEV)
return NULL; return NULL;
/* if in sync mode, wait till message is ready */
pci_last_rx_time = msg->dummy.timestamp;
if (params->sync_pci && pci_last_rx_time > timestamp)
return NULL;
return msg; return msg;
} }
...@@ -272,7 +337,8 @@ void nicif_h2d_next(void) ...@@ -272,7 +337,8 @@ void nicif_h2d_next(void)
h2d_pos = (h2d_pos + 1) % H2D_ENUM; h2d_pos = (h2d_pos + 1) % H2D_ENUM;
} }
volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void) volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(
struct nicsim_params *params, uint64_t timestamp)
{ {
volatile union cosim_pcie_proto_d2h *msg = volatile union cosim_pcie_proto_d2h *msg =
(volatile union cosim_pcie_proto_d2h *) (volatile union cosim_pcie_proto_d2h *)
...@@ -284,6 +350,9 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void) ...@@ -284,6 +350,9 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void)
return NULL; return NULL;
} }
msg->dummy.timestamp = timestamp + params->pci_latency;;
pci_last_tx_time = timestamp;
d2h_pos = (d2h_pos + 1) % D2H_ENUM; d2h_pos = (d2h_pos + 1) % D2H_ENUM;
return msg; return msg;
} }
...@@ -291,7 +360,8 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void) ...@@ -291,7 +360,8 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void)
/******************************************************************************/ /******************************************************************************/
/* Ethernet */ /* Ethernet */
volatile union cosim_eth_proto_n2d *nicif_n2d_poll(void) volatile union cosim_eth_proto_n2d *nicif_n2d_poll(
struct nicsim_params *params, uint64_t timestamp)
{ {
volatile union cosim_eth_proto_n2d *msg = volatile union cosim_eth_proto_n2d *msg =
(volatile union cosim_eth_proto_n2d *) (volatile union cosim_eth_proto_n2d *)
...@@ -302,6 +372,11 @@ volatile union cosim_eth_proto_n2d *nicif_n2d_poll(void) ...@@ -302,6 +372,11 @@ volatile union cosim_eth_proto_n2d *nicif_n2d_poll(void)
COSIM_ETH_PROTO_N2D_OWN_DEV) COSIM_ETH_PROTO_N2D_OWN_DEV)
return NULL; return NULL;
/* if in sync mode, wait till message is ready */
eth_last_rx_time = msg->dummy.timestamp;
if (params->sync_eth && eth_last_rx_time > timestamp)
return NULL;
return msg; return msg;
} }
...@@ -316,7 +391,8 @@ void nicif_n2d_next(void) ...@@ -316,7 +391,8 @@ void nicif_n2d_next(void)
n2d_pos = (n2d_pos + 1) % N2D_ENUM; n2d_pos = (n2d_pos + 1) % N2D_ENUM;
} }
volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(void) volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(
struct nicsim_params *params, uint64_t timestamp)
{ {
volatile union cosim_eth_proto_d2n *msg = volatile union cosim_eth_proto_d2n *msg =
(volatile union cosim_eth_proto_d2n *) (volatile union cosim_eth_proto_d2n *)
...@@ -328,6 +404,9 @@ volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(void) ...@@ -328,6 +404,9 @@ volatile union cosim_eth_proto_d2n *nicsim_d2n_alloc(void)
return NULL; return NULL;
} }
msg->dummy.timestamp = timestamp + params->eth_latency;
eth_last_tx_time = timestamp;
d2n_pos = (d2n_pos + 1) % D2N_ENUM; d2n_pos = (d2n_pos + 1) % D2N_ENUM;
return msg; return msg;
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment