Corundum
is very interesting project because somehow it managed to include implementations of Ethernet, PCIe and AXI-S. This is my attempt to deconstruct the source code and understand the the engineering miracle that Corundum is.
Installation Link to heading
Let’s start by installing some dependencies
sudo apt install -y \
git make gcc g++ clang \
python3 python3-pip python3-venv \
verilator \
iverilog \
gtkwave \
libpcap-dev \
libelf-dev
Then in a .venv
, We need to install cocotb
and some other libraries
pip install cocotb cocotb-test cocotbext-axi cocotbext-eth scapy
Running cocotb tests Link to heading
Running mqnic_core
proved to bit tricky, because for some reason running mqnic_core_axi
fails out-of-box with the iverilog compilation errors. So, I have to move some parameters in 2 files.
diff --git a/fpga/common/rtl/mqnic_interface_rx.v b/fpga/common/rtl/mqnic_interface_rx.v
index d993b2bd..37f71f9a 100644
--- a/fpga/common/rtl/mqnic_interface_rx.v
+++ b/fpga/common/rtl/mqnic_interface_rx.v
@@ -79,7 +79,9 @@ module mqnic_interface_rx #
parameter AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH/8,
parameter AXIS_RX_ID_WIDTH = PORTS > 1 ? $clog2(PORTS) : 1,
parameter AXIS_RX_DEST_WIDTH = RX_QUEUE_INDEX_WIDTH+1,
- parameter AXIS_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
+ parameter AXIS_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1,
+ parameter DMA_CLIENT_TAG_WIDTH = $clog2(RX_DESC_TABLE_SIZE),
+ parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH
)
(
input wire clk,
@@ -215,8 +217,7 @@ module mqnic_interface_rx #
input wire [DMA_CLIENT_LEN_WIDTH-1:0] mtu
);
-parameter DMA_CLIENT_TAG_WIDTH = $clog2(RX_DESC_TABLE_SIZE);
-parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH;
+
parameter REQ_TAG_WIDTH = $clog2(RX_DESC_TABLE_SIZE);
diff --git a/fpga/common/rtl/mqnic_interface_tx.v b/fpga/common/rtl/mqnic_interface_tx.v
index 5251bd7b..78edf7a6 100644
--- a/fpga/common/rtl/mqnic_interface_tx.v
+++ b/fpga/common/rtl/mqnic_interface_tx.v
@@ -66,7 +66,9 @@ module mqnic_interface_tx #
parameter AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH/8,
parameter AXIS_TX_ID_WIDTH = TX_QUEUE_INDEX_WIDTH,
parameter AXIS_TX_DEST_WIDTH = $clog2(PORTS)+4,
- parameter AXIS_TX_USER_WIDTH = TX_TAG_WIDTH + 1
+ parameter AXIS_TX_USER_WIDTH = TX_TAG_WIDTH + 1,
+ parameter DMA_CLIENT_TAG_WIDTH = $clog2(TX_DESC_TABLE_SIZE),
+ parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH
)
(
input wire clk,
@@ -188,8 +190,7 @@ module mqnic_interface_tx #
input wire [DMA_CLIENT_LEN_WIDTH-1:0] mtu
);
-parameter DMA_CLIENT_TAG_WIDTH = $clog2(TX_DESC_TABLE_SIZE);
-parameter DMA_CLIENT_LEN_WIDTH = DMA_LEN_WIDTH;
Running top mqnic core Link to heading
To run the simulation, from core AXI cocotb tests
cd fpga/common/tb/mqnic_core_axi/
make
885364.00ns INFO cocotb.mqnic_core_axi.s_axil_ctrl Read complete addr: 0x000101f0 prot: 2 resp: 0 data: 00 00 00 00
885364.00ns INFO cocotb.mqnic_core_axi.s_axil_ctrl Read start addr: 0x000101f8 prot: 2 length: 4
885432.00ns INFO cocotb.mqnic_core_axi.s_axil_ctrl Read complete addr: 0x000101f8 prot: 2 resp: 0 data: 00 00 00 00
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5336, 954442, 167423, 0, 8056, 232373, 0, 0, 0, 0, 44967, 0, 0, 0, 0, 0, 4641, 890538, 134033, 0, 7233, 189328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
885440.00ns INFO cocotb.regression run_test_nic passed
885440.00ns INFO cocotb.regression ******************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
******************************************************************************************
** test_mqnic_core_axi.run_test_nic PASS 885440.00 273.98 3231.76 **
******************************************************************************************
** TESTS=1 PASS=1 FAIL=0 SKIP=0 885440.00 274.35 3227.43 **
******************************************************************************************
Block level test cmac_pad Link to heading
Going deeper in hierarchy, running one of block tests,cmac_pad
in this example
cd fpga/common/tb/cmac_pad
make
5152.00ns INFO cocotb.regression ****************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
****************************************************************************************
** test_cmac_pad.run_test_001 PASS 800.00 0.16 5094.65 **
** test_cmac_pad.run_test_002 PASS 3104.00 0.21 14532.15 **
** test_cmac_pad.run_test_pad_001 PASS 272.00 0.05 4982.60 **
** test_cmac_pad.run_test_pad_002 PASS 976.00 0.07 13656.54 **
****************************************************************************************
** TESTS=4 PASS=4 FAIL=0 SKIP=0 5152.00 0.57 9023.16 **
****************************************************************************************
Generating block diagram of mqnic_core Link to heading
I thought it would be useful to have block diagram of mqnic_core
. Using run.ys
, we can run yosys
to generate json and pass it to netlistsvg
.
prep -top mqnic_core_pcie;
write_json elaborated.json;
write_verilog elaborated.v;
cd fpga/common/rtl
sed -i 's?$finish?//$finish?' *.v
sed -i 's?$error?//$error?' *.v
yosys -s run.ys
netlistsvg elaborated.json -o elaborated.svg
convert elaborated.svg elaborated.png