Commit 521ce665 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

proto,corundum: update sync protocol

parent 0db2a90d
...@@ -19,20 +19,25 @@ extern "C" { ...@@ -19,20 +19,25 @@ extern "C" {
#include "dma.h" #include "dma.h"
#include "mem.h" #include "mem.h"
#define CLOCK_PERIOD (10 * 1000 * 1000ULL) // 200KHz #define CLOCK_PERIOD (100 * 1000ULL) // 100ns -> 10MHz
#define PCI_ASYNCHRONY (500 * 1000 * 1000ULL) // 200us #define SYNC_PERIOD (500 * 1000ULL) // 100ns
#define ETH_ASYNCHRONY (500 * 1000 * 1000ULL) // 200us #define PCI_LATENCY (1 * 1000 * 1000ULL) // 1us
#define ETH_ASYNCHRONY (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_time = 0; static uint64_t pci_last_rx_time = 0;
static uint64_t eth_last_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;
#ifdef TRACE_ENABLED #ifdef TRACE_ENABLED
static VerilatedVcdC* trace; static VerilatedVcdC* trace;
#endif #endif
static volatile union cosim_pcie_proto_d2h *d2h_alloc(void);
static void sigint_handler(int dummy) static void sigint_handler(int dummy)
...@@ -317,7 +322,7 @@ class MMIOInterface { ...@@ -317,7 +322,7 @@ class MMIOInterface {
void pci_rwcomp_issue(MMIOOp *op) void pci_rwcomp_issue(MMIOOp *op)
{ {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
volatile struct cosim_pcie_proto_d2h_readcomp *rc; volatile struct cosim_pcie_proto_d2h_readcomp *rc;
volatile struct cosim_pcie_proto_d2h_writecomp *wc; volatile struct cosim_pcie_proto_d2h_writecomp *wc;
...@@ -391,7 +396,7 @@ std::set<DMAOp *> pci_dma_pending; ...@@ -391,7 +396,7 @@ std::set<DMAOp *> pci_dma_pending;
void pci_dma_issue(DMAOp *op) void pci_dma_issue(DMAOp *op)
{ {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
uint8_t ty; uint8_t ty;
if (!msg) if (!msg)
...@@ -483,7 +488,7 @@ static void h2d_read(MMIOInterface &mmio, ...@@ -483,7 +488,7 @@ static void h2d_read(MMIOInterface &mmio,
{ {
//std::cout << "got read " << read->offset << std::endl; //std::cout << "got read " << read->offset << std::endl;
if (read->offset < 0x80000) { if (read->offset < 0x80000) {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
volatile struct cosim_pcie_proto_d2h_readcomp *rc; volatile struct cosim_pcie_proto_d2h_readcomp *rc;
if (!msg) if (!msg)
...@@ -515,7 +520,7 @@ static void h2d_write(MMIOInterface &mmio, ...@@ -515,7 +520,7 @@ static void h2d_write(MMIOInterface &mmio,
//std::cout << "got write " << write->offset << " = " << val << std::endl; //std::cout << "got write " << write->offset << " = " << val << std::endl;
if (write->offset < 0x80000) { if (write->offset < 0x80000) {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
volatile struct cosim_pcie_proto_d2h_writecomp *wc; volatile struct cosim_pcie_proto_d2h_writecomp *wc;
if (!msg) if (!msg)
...@@ -534,11 +539,6 @@ static void h2d_write(MMIOInterface &mmio, ...@@ -534,11 +539,6 @@ static void h2d_write(MMIOInterface &mmio,
} }
} }
static void h2d_sync(volatile struct cosim_pcie_proto_h2d_sync *sync)
{
pci_last_time = sync->timestamp;
}
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();
...@@ -548,6 +548,12 @@ static void poll_h2d(MMIOInterface &mmio) ...@@ -548,6 +548,12 @@ static void poll_h2d(MMIOInterface &mmio)
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) {
case COSIM_PCIE_PROTO_H2D_MSG_READ: case COSIM_PCIE_PROTO_H2D_MSG_READ:
...@@ -567,7 +573,6 @@ static void poll_h2d(MMIOInterface &mmio) ...@@ -567,7 +573,6 @@ static void poll_h2d(MMIOInterface &mmio)
break; break;
case COSIM_PCIE_PROTO_H2D_MSG_SYNC: case COSIM_PCIE_PROTO_H2D_MSG_SYNC:
h2d_sync(&msg->sync);
break; break;
default: default:
...@@ -579,6 +584,14 @@ static void poll_h2d(MMIOInterface &mmio) ...@@ -579,6 +584,14 @@ static void poll_h2d(MMIOInterface &mmio)
}; };
static volatile union cosim_pcie_proto_d2h *d2h_alloc(void)
{
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc();
msg->dummy.timestamp = main_time + PCI_LATENCY;
pci_last_tx_time = main_time;
return msg;
}
class EthernetTx { class EthernetTx {
protected: protected:
Vinterface &top; Vinterface &top;
...@@ -833,7 +846,7 @@ class PCICoordinator { ...@@ -833,7 +846,7 @@ class PCICoordinator {
void pci_msi_issue(uint8_t vec) void pci_msi_issue(uint8_t vec)
{ {
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
volatile struct cosim_pcie_proto_d2h_interrupt *intr; volatile struct cosim_pcie_proto_d2h_interrupt *intr;
#ifdef MSI_DEBUG #ifdef MSI_DEBUG
...@@ -865,23 +878,17 @@ static void msi_step(Vinterface &top, PCICoordinator &coord) ...@@ -865,23 +878,17 @@ static void msi_step(Vinterface &top, PCICoordinator &coord)
} }
} }
static void sync_pci(MMIOInterface &mmio) static void send_sync_pci(MMIOInterface &mmio)
{ {
uint64_t cur_ts = (main_time / 2) * CLOCK_PERIOD; volatile union cosim_pcie_proto_d2h *msg;
volatile union cosim_pcie_proto_d2h *msg = nicsim_d2h_alloc();
volatile struct cosim_pcie_proto_d2h_sync *sync; volatile struct cosim_pcie_proto_d2h_sync *sync;
sync = &msg->sync; if (pci_last_tx_time == 0 || main_time - pci_last_tx_time >= SYNC_PERIOD) {
msg = d2h_alloc();
sync->timestamp = cur_ts + PCI_ASYNCHRONY; sync = &msg->sync;
// WMB(); // WMB();
sync->own_type = COSIM_PCIE_PROTO_D2H_MSG_SYNC | sync->own_type = COSIM_PCIE_PROTO_D2H_MSG_SYNC |
COSIM_PCIE_PROTO_D2H_OWN_HOST; COSIM_PCIE_PROTO_D2H_OWN_HOST;
while (pci_last_time < cur_ts && !exiting) {
/*std::cout << "waiting for pci pci_time=" << pci_last_time <<
" cur=" << cur_ts << std::endl;*/
poll_h2d(mmio);
} }
} }
...@@ -897,13 +904,14 @@ int main(int argc, char *argv[]) ...@@ -897,13 +904,14 @@ int main(int argc, char *argv[])
Verilated::traceEverOn(true); Verilated::traceEverOn(true);
#endif #endif
if (argc != 4) { if (argc != 4 && argc != 5) {
fprintf(stderr, "Usage: corundum_verilator PCI-SOCKET ETH-SOCKET " fprintf(stderr, "Usage: corundum_verilator PCI-SOCKET ETH-SOCKET "
"SHM\n"); "SHM [START-TICK]\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (argc == 5)
main_time = strtoull(argv[4], NULL, 0);
int sync_pci_en, sync_eth_en;
struct cosim_pcie_proto_dev_intro di; struct cosim_pcie_proto_dev_intro di;
memset(&di, 0, sizeof(di)); memset(&di, 0, sizeof(di));
...@@ -1037,15 +1045,18 @@ int main(int argc, char *argv[]) ...@@ -1037,15 +1045,18 @@ int main(int argc, char *argv[])
while (!exiting) { while (!exiting) {
if (sync_pci_en) if (sync_pci_en)
sync_pci(mmio); send_sync_pci(mmio);
if (sync_eth_en) if (sync_eth_en)
sync_eth(rx); sync_eth(rx);
poll_h2d(mmio);
poll_n2d(rx); do {
poll_h2d(mmio);
poll_n2d(rx);
} while (sync_pci_en && pci_last_rx_time < main_time && !exiting);
/* falling edge */ /* falling edge */
top->clk = !top->clk; top->clk = !top->clk;
main_time++; main_time += CLOCK_PERIOD / 2;
top->eval(); top->eval();
mmio.step(); mmio.step();
...@@ -1067,7 +1078,7 @@ int main(int argc, char *argv[]) ...@@ -1067,7 +1078,7 @@ int main(int argc, char *argv[])
/* raising edge */ /* raising edge */
top->clk = !top->clk; top->clk = !top->clk;
main_time++; main_time += CLOCK_PERIOD / 2;
//top->s_axis_tx_ptp_ts_96 = main_time; //top->s_axis_tx_ptp_ts_96 = main_time;
top->s_axis_tx_ptp_ts_valid = 1; top->s_axis_tx_ptp_ts_valid = 1;
...@@ -1076,6 +1087,7 @@ int main(int argc, char *argv[]) ...@@ -1076,6 +1087,7 @@ int main(int argc, char *argv[])
top->eval(); top->eval();
} }
report_outputs(top); report_outputs(top);
std::cout << std::endl << std::endl << "main_time:" << main_time << std::endl;
#ifdef TRACE_ENABLED #ifdef TRACE_ENABLED
trace->dump(main_time + 1); trace->dump(main_time + 1);
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
#include <stdint.h> #include <stdint.h>
//#define COSIM_PCI_MSG_SZCHECK(s) static_assert(sizeof(s) == 64)
//#define COSIM_PCI_MSG_SZCHECK(s) _Static_assert(sizeof(s) == 64)
#define COSIM_PCI_MSG_SZCHECK(s)
/******************************************************************************/ /******************************************************************************/
/* Initialization messages on Unix socket */ /* Initialization messages on Unix socket */
...@@ -93,34 +97,43 @@ struct cosim_pcie_proto_host_intro { ...@@ -93,34 +97,43 @@ struct cosim_pcie_proto_host_intro {
#define COSIM_PCIE_PROTO_D2H_MSG_WRITECOMP 0x6 #define COSIM_PCIE_PROTO_D2H_MSG_WRITECOMP 0x6
struct cosim_pcie_proto_d2h_dummy { struct cosim_pcie_proto_d2h_dummy {
uint8_t pad[63]; uint8_t pad[48];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_dummy);
struct cosim_pcie_proto_d2h_sync { struct cosim_pcie_proto_d2h_sync {
uint8_t pad[48];
uint64_t timestamp; uint64_t timestamp;
uint8_t pad[55]; uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_sync);
struct cosim_pcie_proto_d2h_read { struct cosim_pcie_proto_d2h_read {
uint64_t req_id; uint64_t req_id;
uint64_t offset; uint64_t offset;
uint16_t len; uint16_t len;
uint8_t pad[45]; uint8_t pad[30];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_read);
struct cosim_pcie_proto_d2h_write { struct cosim_pcie_proto_d2h_write {
uint64_t req_id; uint64_t req_id;
uint64_t offset; uint64_t offset;
uint16_t len; uint16_t len;
uint8_t pad[45]; uint8_t pad[30];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
uint8_t data[]; uint8_t data[];
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_write);
#define COSIM_PCIE_PROTO_INT_LEGACY_HI 0 #define COSIM_PCIE_PROTO_INT_LEGACY_HI 0
#define COSIM_PCIE_PROTO_INT_LEGACY_LO 1 #define COSIM_PCIE_PROTO_INT_LEGACY_LO 1
...@@ -130,22 +143,31 @@ struct cosim_pcie_proto_d2h_write { ...@@ -130,22 +143,31 @@ struct cosim_pcie_proto_d2h_write {
struct cosim_pcie_proto_d2h_interrupt { struct cosim_pcie_proto_d2h_interrupt {
uint16_t vector; uint16_t vector;
uint8_t inttype; uint8_t inttype;
uint8_t pad[60]; uint8_t pad[45];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_interrupt);
struct cosim_pcie_proto_d2h_readcomp { struct cosim_pcie_proto_d2h_readcomp {
uint64_t req_id; uint64_t req_id;
uint8_t pad[55]; uint8_t pad[40];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
uint8_t data[]; uint8_t data[];
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_readcomp);
struct cosim_pcie_proto_d2h_writecomp { struct cosim_pcie_proto_d2h_writecomp {
uint64_t req_id; uint64_t req_id;
uint8_t pad[55]; uint8_t pad[40];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_d2h_writecomp);
union cosim_pcie_proto_d2h { union cosim_pcie_proto_d2h {
struct cosim_pcie_proto_d2h_dummy dummy; struct cosim_pcie_proto_d2h_dummy dummy;
...@@ -155,7 +177,8 @@ union cosim_pcie_proto_d2h { ...@@ -155,7 +177,8 @@ union cosim_pcie_proto_d2h {
struct cosim_pcie_proto_d2h_interrupt interrupt; struct cosim_pcie_proto_d2h_interrupt interrupt;
struct cosim_pcie_proto_d2h_readcomp readcomp; struct cosim_pcie_proto_d2h_readcomp readcomp;
struct cosim_pcie_proto_d2h_writecomp writecomp; struct cosim_pcie_proto_d2h_writecomp writecomp;
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(union cosim_pcie_proto_d2h);
/******************************************************************************/ /******************************************************************************/
...@@ -175,47 +198,64 @@ union cosim_pcie_proto_d2h { ...@@ -175,47 +198,64 @@ union cosim_pcie_proto_d2h {
#define COSIM_PCIE_PROTO_H2D_MSG_WRITECOMP 0x5 #define COSIM_PCIE_PROTO_H2D_MSG_WRITECOMP 0x5
struct cosim_pcie_proto_h2d_dummy { struct cosim_pcie_proto_h2d_dummy {
uint8_t pad[63]; uint8_t pad[48];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_dummy);
struct cosim_pcie_proto_h2d_sync { struct cosim_pcie_proto_h2d_sync {
uint8_t pad[48];
uint64_t timestamp; uint64_t timestamp;
uint8_t pad[55]; uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_sync);
struct cosim_pcie_proto_h2d_read { struct cosim_pcie_proto_h2d_read {
uint64_t req_id; uint64_t req_id;
uint64_t offset; uint64_t offset;
uint16_t len; uint16_t len;
uint8_t bar; uint8_t bar;
uint8_t pad[44]; uint8_t pad[29];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_read);
struct cosim_pcie_proto_h2d_write { struct cosim_pcie_proto_h2d_write {
uint64_t req_id; uint64_t req_id;
uint64_t offset; uint64_t offset;
uint16_t len; uint16_t len;
uint8_t bar; uint8_t bar;
uint8_t pad[44]; uint8_t pad[29];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
uint8_t data[]; uint8_t data[];
} __attribute__((packed)); } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_write);
struct cosim_pcie_proto_h2d_readcomp { struct cosim_pcie_proto_h2d_readcomp {
uint64_t req_id; uint64_t req_id;
uint8_t pad[55]; uint8_t pad[40];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
uint8_t data[]; uint8_t data[];
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_readcomp);
struct cosim_pcie_proto_h2d_writecomp { struct cosim_pcie_proto_h2d_writecomp {
uint64_t req_id; uint64_t req_id;
uint8_t pad[55]; uint8_t pad[40];
uint64_t timestamp;
uint8_t pad_[7];
uint8_t own_type; uint8_t own_type;
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(struct cosim_pcie_proto_h2d_writecomp);
union cosim_pcie_proto_h2d { union cosim_pcie_proto_h2d {
struct cosim_pcie_proto_h2d_dummy dummy; struct cosim_pcie_proto_h2d_dummy dummy;
...@@ -224,6 +264,7 @@ union cosim_pcie_proto_h2d { ...@@ -224,6 +264,7 @@ union cosim_pcie_proto_h2d {
struct cosim_pcie_proto_h2d_write write; struct cosim_pcie_proto_h2d_write write;
struct cosim_pcie_proto_h2d_readcomp readcomp; struct cosim_pcie_proto_h2d_readcomp readcomp;
struct cosim_pcie_proto_h2d_writecomp writecomp; struct cosim_pcie_proto_h2d_writecomp writecomp;
}; } __attribute__((packed));
COSIM_PCI_MSG_SZCHECK(union cosim_pcie_proto_h2d);
#endif /* ndef COSIM_PCIE_PROTO_H_ */ #endif /* ndef COSIM_PCIE_PROTO_H_ */
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