Start work on parser

This commit is contained in:
2026-08-13 08:35:49 -07:00
parent 82c05ac4dc
commit 2f2727777b
541 changed files with 184695 additions and 10058 deletions

View File

@@ -0,0 +1,127 @@
import cocotb
import logging
from cocotb.clock import Clock
from cocotb.triggers import Timer, RisingEdge, FallingEdge
from cocotb.handle import Immediate
from cocotb.queue import Queue
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink
import socket
from scapy.volatile import RandMAC, RandIP, RandShort, RandInt, RandLong
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP, TCP
from scapy.contrib.wireguard import Wireguard, WireguardTransport
from scapy.utils import str2mac
from scapy.packet import Packet
CLK_PERIOD = 20
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.INFO)
self.input_queue = Queue()
self.expected_queue = Queue()
self.output_queue = Queue()
self.s_axis = AxiStreamSource(AxiStreamBus.from_entity(dut.s_axis), dut.i_clk, dut.i_rst)
self.m_axis = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis), dut.i_clk, dut.i_rst)
cocotb.start_soon(Clock(self.dut.i_clk, CLK_PERIOD, unit="ns").start())
async def cycle_reset(self):
await self._cycle_reset(self.dut.i_rst, self.dut.i_clk)
async def _cycle_reset(self, rst, clk):
rst.value = Immediate(0)
await RisingEdge(clk)
await RisingEdge(clk)
rst.value = 1
await RisingEdge(clk)
await RisingEdge(clk)
rst.value = 0
await RisingEdge(clk)
await RisingEdge(clk)
def assertEqual(self, a, b, name):
if a != b:
self.log.error(f"{name}: {a} != {b}!")
def check_header(self, real_packet: Packet):
for f, v in zip(["src", "dst"], ["ether_source", "ether_dest"]):
actual = real_packet[Ether].getfieldval(f)
parsed = str2mac(self.dut[v].value.to_unsigned().to_bytes(6))
self.assertEqual(actual, parsed, v)
actual_ethertype = real_packet[Ether].getfieldval("type")
parsed_ethertype = self.dut.ether_type.value.to_unsigned()
self.assertEqual(actual_ethertype, parsed_ethertype, "ether_type")
for f, v in zip(["src", "dst"], ["ip_source", "ip_dest"]):
actual = real_packet[IP].getfieldval(f)
parsed = socket.inet_ntoa(self.dut[v].value.to_unsigned().to_bytes(4))
self.assertEqual(actual, parsed, v)
actual_ip_len = real_packet[IP].getfieldval("len")
parsed_ip_len = self.dut.ip_length.value.to_unsigned()
self.assertEqual(actual_ip_len, parsed_ip_len, "ip_length")
actual_ip_proto = real_packet[IP].getfieldval("proto")
parsed_ip_proto = self.dut.ip_proto.value.to_unsigned()
self.assertEqual(actual_ip_proto, parsed_ip_proto, "ip_proto")
for f, v in zip(["sport", "dport"], ["udp_source_port", "udp_dest_port"]):
actual = real_packet[IP].getfieldval(f)
parsed = self.dut[v].value.to_unsigned()
self.assertEqual(actual, parsed, v)
actual_udp_len = real_packet[UDP].getfieldval("len")
parsed_udp_len = self.dut.udp_length.value.to_unsigned()
self.assertEqual(actual_udp_len, parsed_udp_len, "udp_length")
actual_wg_type = real_packet[Wireguard].getfieldval("message_type")
parsed_wg_type = self.dut.wg_type.value.to_unsigned()
self.assertEqual(actual_wg_type, parsed_wg_type, "wg_type")
actual_wg_receiver_index = real_packet[Wireguard].getfieldval("receiver_index")
parsed_wg_receiver_index = self.dut.wg_receiver_index.value.to_unsigned()
self.assertEqual(actual_wg_receiver_index, parsed_wg_receiver_index, "wg_receiver_index")
actual_wg_counter = real_packet[Wireguard].getfieldval("counter")
parsed_wg_counter = self.dut.wg_counter.value.to_unsigned()
self.assertEqual(actual_wg_counter, parsed_wg_counter, "wg_counter")
@cocotb.test
async def test_sanity(dut):
tb = TB(dut)
await tb.cycle_reset()
for _ in range(16):
packet: Packet = Ether(src=RandMAC(), dst=RandMAC()) / IP(src=RandIP(), dst=RandIP()) / UDP(sport=RandShort(), dport=51820) / Wireguard() / WireguardTransport(receiver_index=RandInt(), counter=RandLong()) / b"Random encrypted data here, who knows what"
packet_bytes = packet.build()
real_packet = Ether(packet_bytes)
await tb.s_axis.send(packet_bytes)
await RisingEdge(tb.dut.o_parser_data_valid)
tb.check_header(real_packet)
await Timer(10, "us")

View File

@@ -0,0 +1,59 @@
import net_core_pkg::*;
module parser_wrapper();
logic i_clk;
logic i_rst;
taxi_axis_if #(.DATA_W(32)) s_axis();
taxi_axis_if #(.DATA_W(32)) m_axis();
taxi_axis_if #(.DATA_W(32)) s_axis_be();
taxi_axis_if #(.DATA_W(32)) m_axis_be();
taxi_axis_endian_swap u_s_axis_swap(.s_axis(s_axis), .m_axis(s_axis_be), .swap('1));
taxi_axis_endian_swap u_m_axis_swap(.s_axis(m_axis_be), .m_axis(m_axis), .swap('1));
parser_data_t o_parser_data;
logic o_parser_data_valid;
logic [47:0] ether_dest;
logic [47:0] ether_source;
logic [15:0] ether_type;
logic [15:0] ip_length;
logic [31:0] ip_source;
logic [31:0] ip_dest;
logic [7:0] ip_proto;
logic [15:0] udp_source_port;
logic [15:0] udp_dest_port;
logic [15:0] udp_length;
logic [7:0] wg_type;
logic [31:0] wg_receiver_index;
logic [63:0] wg_counter;
assign ether_dest = o_parser_data.ether_dest;
assign ether_source = o_parser_data.ether_source;
assign ether_type = o_parser_data.ether_type;
assign ip_length = o_parser_data.ip_length;
assign ip_source = o_parser_data.ip_source;
assign ip_dest = o_parser_data.ip_dest;
assign ip_proto = o_parser_data.ip_proto;
assign udp_source_port = o_parser_data.udp_source_port;
assign udp_dest_port = o_parser_data.udp_dest_port;
assign udp_length = o_parser_data.udp_length;
assign wg_type = o_parser_data.wg_type;
assign wg_receiver_index = o_parser_data.wg_receiver_index;
assign wg_counter = o_parser_data.wg_counter;
parser u_dut (
.i_clk (i_clk),
.i_rst (i_rst),
.s_axis (s_axis_be),
.m_axis (m_axis_be),
.o_parser_data (o_parser_data),
.o_parser_data_valid (o_parser_data_valid)
);
endmodule

View File

@@ -0,0 +1,7 @@
tests:
- name: "parser_sanity"
toplevel: "parser_wrapper"
modules:
- "parser_sanity"
sources: "sources.list"
waves: True

View File

@@ -0,0 +1,6 @@
../../verilator.vlt
../../../src/net_core/sources.list
../../../src/common/taxi_sources.list
parser_wrapper.sv

2
sim/net_core/sim.yaml Normal file
View File

@@ -0,0 +1,2 @@
yaml:
- "parser/sim.yaml"

2
sim/sim.yaml Normal file
View File

@@ -0,0 +1,2 @@
yaml:
- "net_core/sim.yaml"

3
sim/verilator.vlt Normal file
View File

@@ -0,0 +1,3 @@
`verilator_config
lint_off -rule TIMESCALEMOD