Commit 3ff6bad1 authored by Hejing Li's avatar Hejing Li
Browse files

Merge branch 'master' into experiments

parents 68f7d33f 8073a95e
...@@ -888,26 +888,29 @@ int main(int argc, char *argv[]) ...@@ -888,26 +888,29 @@ int main(int argc, char *argv[])
{ {
char *vargs[2] = { argv[0], NULL }; char *vargs[2] = { argv[0], NULL };
Verilated::commandArgs(1, vargs); Verilated::commandArgs(1, vargs);
int sync_mode = SYNC_MODES;
#ifdef TRACE_ENABLED #ifdef TRACE_ENABLED
Verilated::traceEverOn(true); Verilated::traceEverOn(true);
#endif #endif
if (argc < 4 && argc > 9) { if (argc < 4 && argc > 10) {
fprintf(stderr, "Usage: corundum_verilator PCI-SOCKET ETH-SOCKET " fprintf(stderr, "Usage: corundum_verilator PCI-SOCKET ETH-SOCKET "
"SHM [START-TICK] [SYNC-PERIOD] [PCI-LATENCY] [ETH-LATENCY] " "SHM [SYNC-MODE] [START-TICK] [SYNC-PERIOD] [PCI-LATENCY] [ETH-LATENCY] "
"[CLOCK-FREQ-MHZ]\n"); "[CLOCK-FREQ-MHZ]\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (argc >= 5) if (argc >= 5)
main_time = strtoull(argv[4], NULL, 0); sync_mode = strtol(argv[4], NULL, 0);
if (argc >= 6) if (argc >= 6)
sync_period = strtoull(argv[5], NULL, 0) * 1000ULL; main_time = strtoull(argv[5], NULL, 0);
if (argc >= 7) if (argc >= 7)
pci_latency = strtoull(argv[6], NULL, 0) * 1000ULL; sync_period = strtoull(argv[6], NULL, 0) * 1000ULL;
if (argc >= 8) if (argc >= 8)
eth_latency = strtoull(argv[7], NULL, 0) * 1000ULL; pci_latency = strtoull(argv[7], NULL, 0) * 1000ULL;
if (argc >= 9) if (argc >= 9)
clock_period = 1000000ULL / strtoull(argv[8], NULL, 0); eth_latency = strtoull(argv[8], NULL, 0) * 1000ULL;
if (argc >= 10)
clock_period = 1000000ULL / strtoull(argv[9], NULL, 0);
struct cosim_pcie_proto_dev_intro di; struct cosim_pcie_proto_dev_intro di;
memset(&di, 0, sizeof(di)); memset(&di, 0, sizeof(di));
...@@ -930,6 +933,9 @@ int main(int argc, char *argv[]) ...@@ -930,6 +933,9 @@ int main(int argc, char *argv[])
nsparams.pci_latency = pci_latency; nsparams.pci_latency = pci_latency;
nsparams.eth_latency = eth_latency; nsparams.eth_latency = eth_latency;
nsparams.sync_delay = sync_period; nsparams.sync_delay = sync_period;
assert(sync_mode == SYNC_MODES || sync_mode == SYNC_BARRIER);
nsparams.sync_mode = sync_mode;
if (nicsim_init(&nsparams, &di)) { if (nicsim_init(&nsparams, &di)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
...@@ -1056,12 +1062,13 @@ int main(int argc, char *argv[]) ...@@ -1056,12 +1062,13 @@ int main(int argc, char *argv[])
std::cerr << "warn: nicsim_sync failed (t=" << main_time << ")" << std::cerr << "warn: nicsim_sync failed (t=" << main_time << ")" <<
std::endl; std::endl;
} }
nicsim_advance_epoch(&nsparams, main_time);
do { do {
poll_h2d(mmio); poll_h2d(mmio);
poll_n2d(rx); poll_n2d(rx);
} while ((nsparams.sync_pci || nsparams.sync_eth) && } while ((nsparams.sync_pci || nsparams.sync_eth) &&
netsim_next_timestamp(&nsparams) <= main_time && !exiting); nicsim_next_timestamp(&nsparams) <= main_time && !exiting);
/* falling edge */ /* falling edge */
top->clk = !top->clk; top->clk = !top->clk;
......
...@@ -22,6 +22,7 @@ class HostSim(Simulator): ...@@ -22,6 +22,7 @@ class HostSim(Simulator):
sleep = 0 sleep = 0
cpu_freq = '3GHz' cpu_freq = '3GHz'
sync_mode = 0
sync_period = 500 sync_period = 500
pci_latency = 500 pci_latency = 500
...@@ -42,6 +43,7 @@ class NICSim(Simulator): ...@@ -42,6 +43,7 @@ class NICSim(Simulator):
network = None network = None
name = '' name = ''
sync_mode = 0
sync_period = 500 sync_period = 500
pci_latency = 500 pci_latency = 500
eth_latency = 500 eth_latency = 500
...@@ -51,10 +53,10 @@ class NICSim(Simulator): ...@@ -51,10 +53,10 @@ class NICSim(Simulator):
net.nics.append(self) net.nics.append(self)
def basic_run_cmd(self, env, name, extra=None): def basic_run_cmd(self, env, name, extra=None):
cmd = '%s/%s %s %s %s 0 %d %d %d' % \ cmd = '%s/%s %s %s %s %d 0 %d %d %d' % \
(env.repodir, name, env.nic_pci_path(self), env.nic_eth_path(self), (env.repodir, name, env.nic_pci_path(self), env.nic_eth_path(self),
env.nic_shm_path(self), self.sync_period, self.pci_latency, env.nic_shm_path(self), self.sync_mode, self.sync_period,
self.eth_latency) self.pci_latency, self.eth_latency)
if extra is not None: if extra is not None:
cmd += ' ' + extra cmd += ' ' + extra
...@@ -66,6 +68,7 @@ class NICSim(Simulator): ...@@ -66,6 +68,7 @@ class NICSim(Simulator):
class NetSim(Simulator): class NetSim(Simulator):
name = '' name = ''
opt = '' opt = ''
sync_mode = 0
sync_period = 500 sync_period = 500
eth_latency = 500 eth_latency = 500
...@@ -126,6 +129,7 @@ class QemuHost(HostSim): ...@@ -126,6 +129,7 @@ class QemuHost(HostSim):
cmd += f'-device cosim-pci,chardev=cosimcd' cmd += f'-device cosim-pci,chardev=cosimcd'
if self.sync: if self.sync:
cmd += ',sync=on' cmd += ',sync=on'
cmd += f',sync-mode={self.sync_mode}'
cmd += f',pci-latency={self.pci_latency}' cmd += f',pci-latency={self.pci_latency}'
cmd += f',sync-period={self.sync_period}' cmd += f',sync-period={self.sync_period}'
else: else:
...@@ -179,6 +183,7 @@ class Gem5Host(HostSim): ...@@ -179,6 +183,7 @@ class Gem5Host(HostSim):
cmd += f'--cosim-shm={env.nic_shm_path(nic)} ' cmd += f'--cosim-shm={env.nic_shm_path(nic)} '
if cpu_type == 'TimingSimpleCPU': if cpu_type == 'TimingSimpleCPU':
cmd += '--cosim-sync ' cmd += '--cosim-sync '
cmd += f'--cosim-sync_mode={self.sync_mode} '
cmd += f'--cosim-pci-lat={self.pci_latency} ' cmd += f'--cosim-pci-lat={self.pci_latency} '
cmd += f'--cosim-sync-int={self.sync_period} ' cmd += f'--cosim-sync-int={self.sync_period} '
if isinstance(nic, I40eNIC): if isinstance(nic, I40eNIC):
...@@ -211,15 +216,15 @@ class I40eNIC(NICSim): ...@@ -211,15 +216,15 @@ class I40eNIC(NICSim):
class WireNet(NetSim): class WireNet(NetSim):
def run_cmd(self, env): def run_cmd(self, env):
assert len(self.nics) == 2 assert len(self.nics) == 2
return '%s/net_wire/net_wire %s %s %d %d' % \ return '%s/net_wire/net_wire %s %s %d %d %d' % \
(env.repodir, env.nic_eth_path(self.nics[0]), (env.repodir, env.nic_eth_path(self.nics[0]),
env.nic_eth_path(self.nics[1]), env.nic_eth_path(self.nics[1]),
self.sync_period, self.eth_latency) self.sync_mode, self.sync_period, self.eth_latency)
class SwitchNet(NetSim): class SwitchNet(NetSim):
def run_cmd(self, env): def run_cmd(self, env):
cmd = env.repodir + '/net_switch/net_switch' cmd = env.repodir + '/net_switch/net_switch'
cmd += f' -S {self.sync_period} -E {self.eth_latency}' cmd += f' -m {self.sync_mode} -S {self.sync_period} -E {self.eth_latency}'
for n in self.nics: for n in self.nics:
cmd += ' -s ' + env.nic_eth_path(n) cmd += ' -s ' + env.nic_eth_path(n)
return cmd return cmd
...@@ -315,4 +320,4 @@ def create_dctcp_hosts(e, num, name_prefix, net, nic_class, host_class, ...@@ -315,4 +320,4 @@ def create_dctcp_hosts(e, num, name_prefix, net, nic_class, host_class,
hosts.append(host) hosts.append(host)
return hosts return hosts
\ No newline at end of file
...@@ -391,21 +391,23 @@ int Runner::runMain(int argc, char *argv[]) ...@@ -391,21 +391,23 @@ int Runner::runMain(int argc, char *argv[])
uint64_t sync_period = 100 * 1000ULL; uint64_t sync_period = 100 * 1000ULL;
uint64_t pci_latency = 500 * 1000ULL; uint64_t pci_latency = 500 * 1000ULL;
uint64_t eth_latency = 500 * 1000ULL; uint64_t eth_latency = 500 * 1000ULL;
int sync_mode = SYNC_MODES;
if (argc < 4 && argc > 8) { if (argc < 4 && argc > 9) {
fprintf(stderr, "Usage: corundum_bm PCI-SOCKET ETH-SOCKET " fprintf(stderr, "Usage: corundum_bm PCI-SOCKET ETH-SOCKET "
"SHM [START-TICK] [SYNC-PERIOD] [PCI-LATENCY] [ETH-LATENCY]\n"); "SHM [SYNC-MODE] [START-TICK] [SYNC-PERIOD] [PCI-LATENCY] [ETH-LATENCY]\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (argc >= 5) if (argc >= 5)
main_time = strtoull(argv[4], NULL, 0); sync_mode = strtol(argv[4], NULL, 0);
if (argc >= 6) if (argc >= 6)
sync_period = strtoull(argv[5], NULL, 0) * 1000ULL; main_time = strtoull(argv[5], NULL, 0);
if (argc >= 7) if (argc >= 7)
pci_latency = strtoull(argv[6], NULL, 0) * 1000ULL; sync_period = strtoull(argv[6], NULL, 0) * 1000ULL;
if (argc >= 8) if (argc >= 8)
eth_latency = strtoull(argv[7], NULL, 0) * 1000ULL; pci_latency = strtoull(argv[7], NULL, 0) * 1000ULL;
if (argc >= 9)
eth_latency = strtoull(argv[8], NULL, 0) * 1000ULL;
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
signal(SIGUSR1, sigusr1_handler); signal(SIGUSR1, sigusr1_handler);
...@@ -421,6 +423,9 @@ int Runner::runMain(int argc, char *argv[]) ...@@ -421,6 +423,9 @@ int Runner::runMain(int argc, char *argv[])
nsparams.pci_latency = pci_latency; nsparams.pci_latency = pci_latency;
nsparams.eth_latency = eth_latency; nsparams.eth_latency = eth_latency;
nsparams.sync_delay = sync_period; nsparams.sync_delay = sync_period;
assert(sync_mode == SYNC_MODES || sync_mode == SYNC_BARRIER);
nsparams.sync_mode = sync_mode;
if (nicsim_init(&nsparams, &dintro)) { if (nicsim_init(&nsparams, &dintro)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
...@@ -433,6 +438,7 @@ int Runner::runMain(int argc, char *argv[]) ...@@ -433,6 +438,7 @@ int Runner::runMain(int argc, char *argv[])
while (nicsim_sync(&nsparams, main_time)) { while (nicsim_sync(&nsparams, main_time)) {
fprintf(stderr, "warn: nicsim_sync failed (t=%lu)\n", main_time); fprintf(stderr, "warn: nicsim_sync failed (t=%lu)\n", main_time);
} }
nicsim_advance_epoch(&nsparams, main_time);
do { do {
poll_h2d(); poll_h2d();
...@@ -440,7 +446,7 @@ int Runner::runMain(int argc, char *argv[]) ...@@ -440,7 +446,7 @@ int Runner::runMain(int argc, char *argv[])
event_trigger(); event_trigger();
if (is_sync) { if (is_sync) {
next_ts = netsim_next_timestamp(&nsparams); next_ts = nicsim_next_timestamp(&nsparams);
if (next_ts > main_time + max_step) if (next_ts > main_time + max_step)
next_ts = main_time + max_step; next_ts = main_time + max_step;
} else { } else {
...@@ -452,7 +458,7 @@ int Runner::runMain(int argc, char *argv[]) ...@@ -452,7 +458,7 @@ int Runner::runMain(int argc, char *argv[])
next_ts = ev_ts; next_ts = ev_ts;
} while (next_ts <= main_time && !exiting); } while (next_ts <= main_time && !exiting);
main_time = next_ts; main_time = nicsim_advance_time(&nsparams, next_ts);
} }
fprintf(stderr, "exit main_time: %lu\n", main_time); fprintf(stderr, "exit main_time: %lu\n", main_time);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <cassert>
extern "C" { extern "C" {
#include <netsim.h> #include <netsim.h>
...@@ -118,9 +119,10 @@ int main(int argc, char *argv[]) ...@@ -118,9 +119,10 @@ int main(int argc, char *argv[])
{ {
int c; int c;
int bad_option = 0; int bad_option = 0;
int sync_mode = SYNC_MODES;
// Parse command line argument // Parse command line argument
while ((c = getopt(argc, argv, "s:S:E:")) != -1 && !bad_option) { while ((c = getopt(argc, argv, "s:S:E:m:")) != -1 && !bad_option) {
switch (c) { switch (c) {
case 's': { case 's': {
struct netsim_interface nsif; struct netsim_interface nsif;
...@@ -141,6 +143,11 @@ int main(int argc, char *argv[]) ...@@ -141,6 +143,11 @@ int main(int argc, char *argv[])
eth_latency = strtoull(optarg, NULL, 0) * 1000ULL; eth_latency = strtoull(optarg, NULL, 0) * 1000ULL;
break; break;
case 'm':
sync_mode = strtol(optarg, NULL, 0);
assert(sync_mode == SYNC_MODES || sync_mode == SYNC_BARRIER);
break;
default: default:
fprintf(stderr, "unknown option %c\n", c); fprintf(stderr, "unknown option %c\n", c);
bad_option = 1; bad_option = 1;
...@@ -161,11 +168,14 @@ int main(int argc, char *argv[]) ...@@ -161,11 +168,14 @@ int main(int argc, char *argv[])
while (!exiting) { while (!exiting) {
// Sync all interfaces // Sync all interfaces
for (auto &nsif : nsifs) { for (auto &nsif : nsifs) {
if (netsim_n2d_sync(&nsif, cur_ts, eth_latency, sync_period) != 0) { if (netsim_n2d_sync(&nsif, cur_ts, eth_latency,
sync_period, sync_mode) != 0) {
fprintf(stderr, "netsim_n2d_sync failed\n"); fprintf(stderr, "netsim_n2d_sync failed\n");
abort(); abort();
} }
} }
netsim_advance_epoch(cur_ts, sync_period, sync_mode);
// Switch packets // Switch packets
uint64_t min_ts; uint64_t min_ts;
do { do {
...@@ -182,7 +192,7 @@ int main(int argc, char *argv[]) ...@@ -182,7 +192,7 @@ int main(int argc, char *argv[])
// Update cur_ts // Update cur_ts
if (min_ts < ULLONG_MAX) { if (min_ts < ULLONG_MAX) {
cur_ts = min_ts; cur_ts = netsim_advance_time(min_ts, sync_period, sync_mode);
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <pcap/pcap.h> #include <pcap/pcap.h>
#include <assert.h>
#include <netsim.h> #include <netsim.h>
...@@ -107,9 +108,10 @@ int main(int argc, char *argv[]) ...@@ -107,9 +108,10 @@ int main(int argc, char *argv[])
uint64_t ts_a, ts_b; uint64_t ts_a, ts_b;
int sync_a, sync_b; int sync_a, sync_b;
pcap_t *pc = NULL; pcap_t *pc = NULL;
int sync_mode = SYNC_MODES;
if (argc < 3 && argc > 6) { if (argc < 3 && argc > 7) {
fprintf(stderr, "Usage: net_wire SOCKET-A SOCKET-B [SYNC-PERIOD] " fprintf(stderr, "Usage: net_wire SOCKET-A SOCKET-B [SYNC-MODE] [SYNC-PERIOD] "
"[ETH-LATENCY] [PCAP-FILE]\n"); "[ETH-LATENCY] [PCAP-FILE]\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
...@@ -119,12 +121,15 @@ int main(int argc, char *argv[]) ...@@ -119,12 +121,15 @@ int main(int argc, char *argv[])
signal(SIGUSR1, sigusr1_handler); signal(SIGUSR1, sigusr1_handler);
if (argc >= 4) if (argc >= 4)
sync_period = strtoull(argv[3], NULL, 0) * 1000ULL; sync_mode = strtol(argv[3], NULL, 0);
if (argc >= 5) if (argc >= 5)
eth_latency = strtoull(argv[4], NULL, 0) * 1000ULL; sync_period = strtoull(argv[4], NULL, 0) * 1000ULL;
if (argc >= 6) { if (argc >= 6)
eth_latency = strtoull(argv[5], NULL, 0) * 1000ULL;
if (argc >= 7) {
pc = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, 65535, pc = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, 65535,
PCAP_TSTAMP_PRECISION_NANO); PCAP_TSTAMP_PRECISION_NANO);
if (pc == NULL) { if (pc == NULL) {
...@@ -132,9 +137,11 @@ int main(int argc, char *argv[]) ...@@ -132,9 +137,11 @@ int main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
dumpfile = pcap_dump_open(pc, argv[5]); dumpfile = pcap_dump_open(pc, argv[6]);
} }
assert(sync_mode == SYNC_MODES || sync_mode == SYNC_BARRIER);
sync_a = sync_b = 1; sync_a = sync_b = 1;
if (netsim_init(&nsif_a, argv[1], &sync_a) != 0) { if (netsim_init(&nsif_a, argv[1], &sync_a) != 0) {
return -1; return -1;
...@@ -145,14 +152,15 @@ int main(int argc, char *argv[]) ...@@ -145,14 +152,15 @@ int main(int argc, char *argv[])
printf("start polling\n"); printf("start polling\n");
while (!exiting) { while (!exiting) {
if (netsim_n2d_sync(&nsif_a, cur_ts, eth_latency, sync_period) != 0) { if (netsim_n2d_sync(&nsif_a, cur_ts, eth_latency, sync_period, sync_mode) != 0) {
fprintf(stderr, "netsim_n2d_sync(nsif_a) failed\n"); fprintf(stderr, "netsim_n2d_sync(nsif_a) failed\n");
abort(); abort();
} }
if (netsim_n2d_sync(&nsif_b, cur_ts, eth_latency, sync_period) != 0) { if (netsim_n2d_sync(&nsif_b, cur_ts, eth_latency, sync_period, sync_mode) != 0) {
fprintf(stderr, "netsim_n2d_sync(nsif_a) failed\n"); fprintf(stderr, "netsim_n2d_sync(nsif_a) failed\n");
abort(); abort();
} }
netsim_advance_epoch(cur_ts, sync_period, sync_mode);
do { do {
move_pkt(&nsif_a, &nsif_b); move_pkt(&nsif_a, &nsif_b);
...@@ -164,11 +172,12 @@ int main(int argc, char *argv[]) ...@@ -164,11 +172,12 @@ int main(int argc, char *argv[])
(sync_b && ts_b <= cur_ts))); (sync_b && ts_b <= cur_ts)));
if (sync_a && sync_b) if (sync_a && sync_b)
cur_ts = (ts_a <= ts_b ? ts_a : ts_b); cur_ts = netsim_advance_time(ts_a <= ts_b ? ts_a : ts_b,
sync_period, sync_mode);
else if (sync_a) else if (sync_a)
cur_ts = ts_a; cur_ts = netsim_advance_time(ts_a, sync_period, sync_mode);
else if (sync_b) else if (sync_b)
cur_ts = ts_b; cur_ts = netsim_advance_time(ts_b, sync_period, sync_mode);
} }
if (dumpfile) if (dumpfile)
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#include <stdint.h> #include <stdint.h>
#include <cosim_eth_proto.h> #include <cosim_eth_proto.h>
#define SYNC_MODES 0
#define SYNC_BARRIER 1
struct netsim_interface { struct netsim_interface {
uint8_t *d2n_queue; uint8_t *d2n_queue;
size_t d2n_pos; size_t d2n_pos;
...@@ -61,6 +64,8 @@ volatile union cosim_eth_proto_n2d *netsim_n2d_alloc( ...@@ -61,6 +64,8 @@ volatile union cosim_eth_proto_n2d *netsim_n2d_alloc(
struct netsim_interface *nsif, uint64_t timestamp, struct netsim_interface *nsif, uint64_t timestamp,
uint64_t latency); uint64_t latency);
int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp, int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp,
uint64_t latency, uint64_t sync_delay); uint64_t latency, uint64_t sync_delay, int sync_mode);
void netsim_advance_epoch(uint64_t timestamp, uint64_t sync_delay, int sync_mode);
uint64_t netsim_advance_time(uint64_t timestamp, uint64_t sync_delay, int sync_mode);
#endif /* ndef COSIM_NETSIM_H_ */ #endif /* ndef COSIM_NETSIM_H_ */
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <netsim.h> #include <netsim.h>
#include "internal.h" #include "internal.h"
static uint64_t current_epoch = 0;
int netsim_init(struct netsim_interface *nsif, int netsim_init(struct netsim_interface *nsif,
const char *eth_socket_path, int *sync_eth) const char *eth_socket_path, int *sync_eth)
{ {
...@@ -137,17 +139,32 @@ volatile union cosim_eth_proto_n2d *netsim_n2d_alloc( ...@@ -137,17 +139,32 @@ volatile union cosim_eth_proto_n2d *netsim_n2d_alloc(
} }
int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp, int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp,
uint64_t latency, uint64_t sync_delay) uint64_t latency, uint64_t sync_delay, int sync_mode)
{ {
volatile union cosim_eth_proto_n2d *msg; volatile union cosim_eth_proto_n2d *msg;
volatile struct cosim_eth_proto_n2d_sync *sync; volatile struct cosim_eth_proto_n2d_sync *sync;
int do_sync;
if (!nsif->sync) if (!nsif->sync)
return 0; return 0;
if (nsif->n2d_timestamp != 0 && switch (sync_mode) {
timestamp - nsif->n2d_timestamp < sync_delay) case SYNC_MODES:
do_sync = nsif->n2d_timestamp == 0 ||
timestamp - nsif->n2d_timestamp >= sync_delay;
break;
case SYNC_BARRIER:
do_sync = current_epoch == 0 ||
timestamp - current_epoch >= sync_delay;
break;
default:
fprintf(stderr, "unsupported sync mode=%u\n", sync_mode);
return 0; return 0;
}
if (!do_sync) {
return 0;
}
msg = netsim_n2d_alloc(nsif, timestamp, latency); msg = netsim_n2d_alloc(nsif, timestamp, latency);
if (msg == NULL) if (msg == NULL)
...@@ -159,3 +176,26 @@ int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp, ...@@ -159,3 +176,26 @@ int netsim_n2d_sync(struct netsim_interface *nsif, uint64_t timestamp,
return 0; return 0;
} }
void netsim_advance_epoch(uint64_t timestamp, uint64_t sync_delay, int sync_mode)
{
if (sync_mode == SYNC_BARRIER) {
if (timestamp - current_epoch >= sync_delay) {
current_epoch = timestamp;
}
}
}
uint64_t netsim_advance_time(uint64_t timestamp, uint64_t sync_delay, int sync_mode)
{
switch (sync_mode) {
case SYNC_MODES:
return timestamp;
case SYNC_BARRIER:
return timestamp < current_epoch + sync_delay ?
timestamp : current_epoch + sync_delay;
default:
fprintf(stderr, "unsupported sync mode=%u\n", sync_mode);
return timestamp;
}
}
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include <cosim_pcie_proto.h> #include <cosim_pcie_proto.h>
#include <cosim_eth_proto.h> #include <cosim_eth_proto.h>
#define SYNC_MODES 0 // ModES style synchronization
#define SYNC_BARRIER 1 // Global barrier style synchronization
struct nicsim_params { struct nicsim_params {
const char *pci_socket_path; const char *pci_socket_path;
const char *eth_socket_path; const char *eth_socket_path;
...@@ -38,6 +41,7 @@ struct nicsim_params { ...@@ -38,6 +41,7 @@ struct nicsim_params {
int sync_pci; int sync_pci;
int sync_eth; int sync_eth;
int sync_mode;
}; };
int nicsim_init(struct nicsim_params *params, int nicsim_init(struct nicsim_params *params,
...@@ -45,7 +49,9 @@ int nicsim_init(struct nicsim_params *params, ...@@ -45,7 +49,9 @@ int nicsim_init(struct nicsim_params *params,
void nicsim_cleanup(void); void nicsim_cleanup(void);
int nicsim_sync(struct nicsim_params *params, uint64_t timestamp); int nicsim_sync(struct nicsim_params *params, uint64_t timestamp);
uint64_t netsim_next_timestamp(struct nicsim_params *params); void nicsim_advance_epoch(struct nicsim_params *params, uint64_t timestamp);
uint64_t nicsim_advance_time(struct nicsim_params *params, uint64_t timestamp);
uint64_t nicsim_next_timestamp(struct nicsim_params *params);
volatile union cosim_pcie_proto_h2d *nicif_h2d_poll( volatile union cosim_pcie_proto_h2d *nicif_h2d_poll(
struct nicsim_params *params, uint64_t timestamp); struct nicsim_params *params, uint64_t timestamp);
......
...@@ -66,6 +66,8 @@ static uint64_t pci_last_tx_time = 0; ...@@ -66,6 +66,8 @@ static uint64_t pci_last_tx_time = 0;
static uint64_t eth_last_rx_time = 0; static uint64_t eth_last_rx_time = 0;
static uint64_t eth_last_tx_time = 0; static uint64_t eth_last_tx_time = 0;
static uint64_t current_epoch = 0;
static int shm_fd = -1; static int shm_fd = -1;
static int pci_cfd = -1; static int pci_cfd = -1;
static int eth_cfd = -1; static int eth_cfd = -1;
...@@ -266,35 +268,91 @@ int nicsim_sync(struct nicsim_params *params, uint64_t timestamp) ...@@ -266,35 +268,91 @@ int nicsim_sync(struct nicsim_params *params, uint64_t timestamp)
volatile union cosim_eth_proto_d2n *d2n; volatile union cosim_eth_proto_d2n *d2n;
/* sync PCI if necessary */ /* sync PCI if necessary */
if (params->sync_pci && (pci_last_tx_time == 0 || if (params->sync_pci) {
timestamp - pci_last_tx_time >= params->sync_delay)) int sync;
{ switch (params->sync_mode) {
d2h = nicsim_d2h_alloc(params, timestamp); case SYNC_MODES:
if (d2h == NULL) { sync = pci_last_tx_time == 0 ||
ret = -1; timestamp - pci_last_tx_time >= params->sync_delay;
} else { break;
d2h->sync.own_type = COSIM_PCIE_PROTO_D2H_MSG_SYNC | case SYNC_BARRIER:
COSIM_PCIE_PROTO_D2H_OWN_HOST; sync = current_epoch == 0 ||
timestamp - current_epoch >= params->sync_delay;
break;
default:
fprintf(stderr, "unsupported sync mode=%u\n", params->sync_mode);
return ret;
}
if (sync)
{
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 */ /* sync Ethernet if necessary */
if (params->sync_eth && (eth_last_tx_time == 0 || if (params->sync_eth) {
timestamp - eth_last_tx_time >= params->sync_delay)) int sync;
{ switch (params->sync_mode) {
d2n = nicsim_d2n_alloc(params, timestamp); case SYNC_MODES:
if (d2n == NULL) { sync = eth_last_tx_time == 0 ||
ret = -1; timestamp - eth_last_tx_time >= params->sync_delay;
} else { break;
d2n->sync.own_type = COSIM_ETH_PROTO_D2N_MSG_SYNC | case SYNC_BARRIER:
COSIM_ETH_PROTO_D2N_OWN_NET; sync = current_epoch == 0 ||
timestamp - current_epoch >= params->sync_delay;
break;
default:
fprintf(stderr, "unsupported sync mode=%u\n", params->sync_mode);
return ret;
}
if (sync)
{
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; return ret;
} }
uint64_t netsim_next_timestamp(struct nicsim_params *params) void nicsim_advance_epoch(struct nicsim_params *params, uint64_t timestamp)
{
if (params->sync_mode == SYNC_BARRIER) {
if ((params->sync_pci || params->sync_eth) &&
timestamp - current_epoch >= params->sync_delay) {
current_epoch = timestamp;
}
}
}
uint64_t nicsim_advance_time(struct nicsim_params *params, uint64_t timestamp)
{
switch (params->sync_mode) {
case SYNC_MODES:
return timestamp;
case SYNC_BARRIER:
return timestamp < current_epoch + params->sync_delay ?
timestamp : current_epoch + params->sync_delay;
default:
fprintf(stderr, "unsupported sync mode=%u\n", params->sync_mode);
return timestamp;
}
}
uint64_t nicsim_next_timestamp(struct nicsim_params *params)
{ {
if (params->sync_pci && params->sync_eth) { if (params->sync_pci && params->sync_eth) {
return (pci_last_rx_time <= eth_last_rx_time ? pci_last_rx_time : return (pci_last_rx_time <= eth_last_rx_time ? pci_last_rx_time :
......
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