Commit f202b3a6 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

testbench for DMA

parent 5e84804a
`include "simdrv_defs.svh"
`include "eth_packet.svh"
`include "minic_regs.vh"
`define MAX_PACKET_SIZE 1536
class CSimDrv_Minic;
const uint32_t TX_DESC_VALID = (1<<31);
const uint32_t TX_DESC_WITH_OOB = (1<<30);
const uint32_t TX_DESC_HAS_OWN_MAC = (1<<28);
`define RX_DESC_VALID(d) ((d) & (1<<31) ? 1 : 0)
`define RX_DESC_ERROR(d) ((d) & (1<<30) ? 1 : 0)
`define RX_DESC_HAS_OOB(d) ((d) & (1<<29) ? 1 : 0)
`define RX_DESC_SIZE(d) (((d) & (1<<0) ? -1 : 0) + (d & 'hffe))
protected CBusAccessor acc_regs, acc_pmem;
protected uint32_t base_regs, base_pmem;
protected int pmem_size;
protected bit little_endian;
protected uint32_t tx_head, tx_base, tx_avail, tx_size, tx_count, tx_oob_val;
protected uint32_t rx_head, rx_base, rx_avail, rx_size, rx_count;
protected EthPacket rx_queue[$];
protected EthPacket tx_queue[$];
const int MINIC_MTU = 1536;
function new(int pmem_size_, CBusAccessor regs_, uint32_t base_regs_, CBusAccessor pmem_, uint32_t base_pmem_);
base_pmem = base_pmem_;
base_regs = base_regs_;
acc_regs = regs_;
acc_pmem = pmem_;
pmem_size = pmem_size_;
little_endian = 1;
endfunction // new
task minic_writel(uint32_t addr, uint32_t val);
acc_regs.write(base_regs + addr, val, 4);
endtask // minic_writel
task minic_readl(uint32_t addr, output uint32_t val);
uint64_t tmp;
acc_regs.read(base_regs + addr, tmp, 4);
val = tmp;
endtask // minic_writel
task new_tx_buffer();
tx_head = tx_base;
tx_avail = (tx_size - MINIC_MTU) >> 2;
minic_writel(`ADDR_MINIC_TX_ADDR, tx_base);
endtask // new_tx_buffers
task new_rx_buffer();
rx_head = rx_base;
minic_writel(`ADDR_MINIC_MCR, 0);
minic_writel(`ADDR_MINIC_RX_ADDR, rx_base);
minic_writel(`ADDR_MINIC_RX_SIZE, rx_size >> 2);
minic_writel(`ADDR_MINIC_EIC_ISR, `MINIC_EIC_ISR_RX);
minic_writel(`ADDR_MINIC_MCR, `MINIC_MCR_RX_EN);
endtask // new_rx_buffer
task init();
uint32_t lo, hi;
minic_writel(`ADDR_MINIC_EIC_IDR, `MINIC_EIC_IDR_RX);
minic_writel(`ADDR_MINIC_EIC_ISR, `MINIC_EIC_ISR_RX);
rx_base = base_pmem;
rx_size = pmem_size / 4;
tx_base = base_pmem + pmem_size / 2;
tx_size = pmem_size / 4;
tx_oob_val = 12345;
lo = rx_base >> 2;
hi = (rx_base >> 2) + (rx_size >> 2) - 1;
minic_writel(`ADDR_MINIC_MPROT, (lo << `MINIC_MPROT_LO_OFFSET) | (hi << `MINIC_MPROT_HI_OFFSET));
tx_count = 0;
rx_count = 0;
new_rx_buffer();
minic_writel(`ADDR_MINIC_EIC_IER, `MINIC_EIC_IER_RX);
endtask // init
task tx_frame(byte payload[], uint32_t size, bit with_oob, int ts_id, output uint32_t ts, output int port_id);
int i;
uint32_t d_hdr, mcr, nwords;
u64_array_t buff;
byte tmp[];
byte oob[2];
new_tx_buffer();
if(size < 60) size = 60;
if(size & 1) size = size + 1;
tmp = new[size](payload);
buff = SimUtils.pack({0,0,0,0, tmp, 0,0,0,0}, 4, 1);
size = size / 2;
for(i=0;i<buff.size(); i++)
acc_pmem.write(tx_head + i*4, buff[i], 4);
acc_pmem.write(tx_head, TX_DESC_HAS_OWN_MAC | TX_DESC_VALID | (with_oob ? TX_DESC_WITH_OOB :0 )| size | (ts_id << 12), 4);
minic_readl(`ADDR_MINIC_MCR, mcr);
minic_writel(`ADDR_MINIC_MCR, mcr | `MINIC_MCR_TX_START);
endtask // tx_frame
task rx_frame(ref byte payload[], output uint32_t size, output bit with_ts, output uint32_t ts);
uint32_t payload_size, num_words;
uint64_t desc_hdr;
uint32_t raw_ts;
uint32_t rx_addr_cur, mcr, cur_avail;
u64_array_t pbuff;
int i;
int n_recvd;
uint32_t isr;
minic_readl(`ADDR_MINIC_EIC_ISR, isr);
if(! (isr & `MINIC_EIC_ISR_RX))
return;
acc_pmem.read(rx_head, desc_hdr);
if(!`RX_DESC_VALID(desc_hdr))
begin
$error("SimDRV_Minic::rx_frame: weird, invalid RX desc header");
$stop;
end
payload_size = `RX_DESC_SIZE(desc_hdr);
num_words = (payload_size + 3) >> 2;
pbuff = new [num_words];
// $display("NWords %d hdr %x", num_words, desc_hdr);
if(`RX_DESC_HAS_OOB(desc_hdr))
payload_size = payload_size - 6;
if(!`RX_DESC_ERROR(desc_hdr))
begin
for(i=0; i<num_words;i++)
acc_pmem.read((rx_head + 4 + i * 4) % rx_size, pbuff[i]);
payload = SimUtils.unpack(pbuff, 4, payload_size);
end
size = payload_size;
rx_head = (rx_head + 4 + num_words * 4) % rx_size;
minic_writel(`ADDR_MINIC_RX_AVAIL, (num_words + 1));
minic_readl(`ADDR_MINIC_RX_AVAIL, cur_avail);
acc_pmem.read(rx_head, desc_hdr);
if( cur_avail == (rx_size>>2) || !(`RX_DESC_VALID(desc_hdr)))
begin
minic_readl(`ADDR_MINIC_MCR, mcr);
if(mcr & `MINIC_MCR_RX_FULL)
new_rx_buffer();
minic_writel(`ADDR_MINIC_EIC_ISR, `MINIC_EIC_ISR_RX);
end
endtask // rx_frame
task do_rx();
byte payload[];
uint32_t size, ts;
bit with_ts;
rx_frame(payload, size, with_ts, ts);
if(payload.size() > 0)
begin
EthPacket pkt;
pkt = new;
pkt.deserialize(payload);
rx_queue.push_back(pkt);
end
endtask // do_rx
task run();
uint32_t mcr;
if(tx_queue.size() > 0)
begin
minic_readl(`ADDR_MINIC_MCR, mcr);
// $display("mcr %x, Minic::q_not_empty %d", mcr, tx_queue.size());
if(mcr & `MINIC_MCR_TX_IDLE) begin
byte b[];
uint32_t ts;
int pid;
EthPacket pkt;
pkt = tx_queue.pop_front();
pkt.serialize(b);
tx_frame(b, b.size(), pkt.oob_type == TX_FID ? 1 : 0, pkt.ts.frame_id,ts, pid);
end
end // if (tx_queue.size() > 0)
do_rx();
endtask // run
task send(EthPacket pkt);
tx_queue.push_back(pkt);
endtask // send
function poll();
return rx_queue.size() > 0;
endfunction // poll
task recv(ref EthPacket pkt);
pkt = rx_queue.pop_front();
endtask // recv
endclass // CSimDrv_Minic
`define ADDR_MDIO_MCR 7'h0
`define MDIO_MCR_RESV_OFFSET 0
`define MDIO_MCR_RESV 32'h0000001f
`define MDIO_MCR_UNI_EN_OFFSET 5
`define MDIO_MCR_UNI_EN 32'h00000020
`define MDIO_MCR_SPEED1000_OFFSET 6
`define MDIO_MCR_SPEED1000 32'h00000040
`define MDIO_MCR_CTST_OFFSET 7
`define MDIO_MCR_CTST 32'h00000080
`define MDIO_MCR_FULLDPLX_OFFSET 8
`define MDIO_MCR_FULLDPLX 32'h00000100
`define MDIO_MCR_ANRESTART_OFFSET 9
`define MDIO_MCR_ANRESTART 32'h00000200
`define MDIO_MCR_ISOLATE_OFFSET 10
`define MDIO_MCR_ISOLATE 32'h00000400
`define MDIO_MCR_PDOWN_OFFSET 11
`define MDIO_MCR_PDOWN 32'h00000800
`define MDIO_MCR_ANENABLE_OFFSET 12
`define MDIO_MCR_ANENABLE 32'h00001000
`define MDIO_MCR_SPEED100_OFFSET 13
`define MDIO_MCR_SPEED100 32'h00002000
`define MDIO_MCR_LOOPBACK_OFFSET 14
`define MDIO_MCR_LOOPBACK 32'h00004000
`define MDIO_MCR_RESET_OFFSET 15
`define MDIO_MCR_RESET 32'h00008000
`define ADDR_MDIO_MSR 7'h4
`define MDIO_MSR_ERCAP_OFFSET 0
`define MDIO_MSR_ERCAP 32'h00000001
`define MDIO_MSR_JCD_OFFSET 1
`define MDIO_MSR_JCD 32'h00000002
`define MDIO_MSR_LSTATUS_OFFSET 2
`define MDIO_MSR_LSTATUS 32'h00000004
`define MDIO_MSR_ANEGCAPABLE_OFFSET 3
`define MDIO_MSR_ANEGCAPABLE 32'h00000008
`define MDIO_MSR_RFAULT_OFFSET 4
`define MDIO_MSR_RFAULT 32'h00000010
`define MDIO_MSR_ANEGCOMPLETE_OFFSET 5
`define MDIO_MSR_ANEGCOMPLETE 32'h00000020
`define MDIO_MSR_MFSUPPRESS_OFFSET 6
`define MDIO_MSR_MFSUPPRESS 32'h00000040
`define MDIO_MSR_UNIDIRABLE_OFFSET 7
`define MDIO_MSR_UNIDIRABLE 32'h00000080
`define MDIO_MSR_ESTATEN_OFFSET 8
`define MDIO_MSR_ESTATEN 32'h00000100
`define MDIO_MSR_100HALF2_OFFSET 9
`define MDIO_MSR_100HALF2 32'h00000200
`define MDIO_MSR_100FULL2_OFFSET 10
`define MDIO_MSR_100FULL2 32'h00000400
`define MDIO_MSR_10HALF_OFFSET 11
`define MDIO_MSR_10HALF 32'h00000800
`define MDIO_MSR_10FULL_OFFSET 12
`define MDIO_MSR_10FULL 32'h00001000
`define MDIO_MSR_100HALF_OFFSET 13
`define MDIO_MSR_100HALF 32'h00002000
`define MDIO_MSR_100FULL_OFFSET 14
`define MDIO_MSR_100FULL 32'h00004000
`define MDIO_MSR_100BASE4_OFFSET 15
`define MDIO_MSR_100BASE4 32'h00008000
`define ADDR_MDIO_PHYSID1 7'h8
`define MDIO_PHYSID1_OUI_OFFSET 0
`define MDIO_PHYSID1_OUI 32'h0000ffff
`define ADDR_MDIO_PHYSID2 7'hc
`define MDIO_PHYSID2_REV_NUM_OFFSET 0
`define MDIO_PHYSID2_REV_NUM 32'h0000000f
`define MDIO_PHYSID2_MMNUM_OFFSET 4
`define MDIO_PHYSID2_MMNUM 32'h000003f0
`define MDIO_PHYSID2_OUI_OFFSET 10
`define MDIO_PHYSID2_OUI 32'h0000fc00
`define ADDR_MDIO_ADVERTISE 7'h10
`define MDIO_ADVERTISE_RSVD3_OFFSET 0
`define MDIO_ADVERTISE_RSVD3 32'h0000001f
`define MDIO_ADVERTISE_FULL_OFFSET 5
`define MDIO_ADVERTISE_FULL 32'h00000020
`define MDIO_ADVERTISE_HALF_OFFSET 6
`define MDIO_ADVERTISE_HALF 32'h00000040
`define MDIO_ADVERTISE_PAUSE_OFFSET 7
`define MDIO_ADVERTISE_PAUSE 32'h00000180
`define MDIO_ADVERTISE_RSVD2_OFFSET 9
`define MDIO_ADVERTISE_RSVD2 32'h00000e00
`define MDIO_ADVERTISE_RFAULT_OFFSET 12
`define MDIO_ADVERTISE_RFAULT 32'h00003000
`define MDIO_ADVERTISE_RSVD1_OFFSET 14
`define MDIO_ADVERTISE_RSVD1 32'h00004000
`define MDIO_ADVERTISE_NPAGE_OFFSET 15
`define MDIO_ADVERTISE_NPAGE 32'h00008000
`define ADDR_MDIO_LPA 7'h14
`define MDIO_LPA_RSVD3_OFFSET 0
`define MDIO_LPA_RSVD3 32'h0000001f
`define MDIO_LPA_FULL_OFFSET 5
`define MDIO_LPA_FULL 32'h00000020
`define MDIO_LPA_HALF_OFFSET 6
`define MDIO_LPA_HALF 32'h00000040
`define MDIO_LPA_PAUSE_OFFSET 7
`define MDIO_LPA_PAUSE 32'h00000180
`define MDIO_LPA_RSVD2_OFFSET 9
`define MDIO_LPA_RSVD2 32'h00000e00
`define MDIO_LPA_RFAULT_OFFSET 12
`define MDIO_LPA_RFAULT 32'h00003000
`define MDIO_LPA_LPACK_OFFSET 14
`define MDIO_LPA_LPACK 32'h00004000
`define MDIO_LPA_NPAGE_OFFSET 15
`define MDIO_LPA_NPAGE 32'h00008000
`define ADDR_MDIO_EXPANSION 7'h18
`define MDIO_EXPANSION_RSVD1_OFFSET 0
`define MDIO_EXPANSION_RSVD1 32'h00000001
`define MDIO_EXPANSION_LWCP_OFFSET 1
`define MDIO_EXPANSION_LWCP 32'h00000002
`define MDIO_EXPANSION_ENABLENPAGE_OFFSET 2
`define MDIO_EXPANSION_ENABLENPAGE 32'h00000004
`define MDIO_EXPANSION_RSVD2_OFFSET 3
`define MDIO_EXPANSION_RSVD2 32'h0000fff8
`define ADDR_MDIO_ESTATUS 7'h3c
`define MDIO_ESTATUS_RSVD1_OFFSET 0
`define MDIO_ESTATUS_RSVD1 32'h00000fff
`define MDIO_ESTATUS_1000_THALF_OFFSET 12
`define MDIO_ESTATUS_1000_THALF 32'h00001000
`define MDIO_ESTATUS_1000_TFULL_OFFSET 13
`define MDIO_ESTATUS_1000_TFULL 32'h00002000
`define MDIO_ESTATUS_1000_XHALF_OFFSET 14
`define MDIO_ESTATUS_1000_XHALF 32'h00004000
`define MDIO_ESTATUS_1000_XFULL_OFFSET 15
`define MDIO_ESTATUS_1000_XFULL 32'h00008000
`define ADDR_MDIO_WR_SPEC 7'h40
`define MDIO_WR_SPEC_TX_CAL_OFFSET 0
`define MDIO_WR_SPEC_TX_CAL 32'h00000001
`define MDIO_WR_SPEC_RX_CAL_STAT_OFFSET 1
`define MDIO_WR_SPEC_RX_CAL_STAT 32'h00000002
`define MDIO_WR_SPEC_CAL_CRST_OFFSET 2
`define MDIO_WR_SPEC_CAL_CRST 32'h00000004
`define MDIO_WR_SPEC_BSLIDE_OFFSET 4
`define MDIO_WR_SPEC_BSLIDE 32'h000001f0
`define ADDR_EP_ECR 7'h0
`define EP_ECR_PORTID_OFFSET 0
`define EP_ECR_PORTID 32'h0000001f
`define EP_ECR_RST_CNT_OFFSET 5
`define EP_ECR_RST_CNT 32'h00000020
`define EP_ECR_TX_EN_OFFSET 6
`define EP_ECR_TX_EN 32'h00000040
`define EP_ECR_RX_EN_OFFSET 7
`define EP_ECR_RX_EN 32'h00000080
`define EP_ECR_FEAT_VLAN_OFFSET 24
`define EP_ECR_FEAT_VLAN 32'h01000000
`define EP_ECR_FEAT_DMTD_OFFSET 25
`define EP_ECR_FEAT_DMTD 32'h02000000
`define EP_ECR_FEAT_PTP_OFFSET 26
`define EP_ECR_FEAT_PTP 32'h04000000
`define EP_ECR_FEAT_DPI_OFFSET 27
`define EP_ECR_FEAT_DPI 32'h08000000
`define ADDR_EP_TSCR 7'h4
`define EP_TSCR_EN_TXTS_OFFSET 0
`define EP_TSCR_EN_TXTS 32'h00000001
`define EP_TSCR_EN_RXTS_OFFSET 1
`define EP_TSCR_EN_RXTS 32'h00000002
`define EP_TSCR_CS_START_OFFSET 2
`define EP_TSCR_CS_START 32'h00000004
`define EP_TSCR_CS_DONE_OFFSET 3
`define EP_TSCR_CS_DONE 32'h00000008
`define EP_TSCR_RX_CAL_START_OFFSET 4
`define EP_TSCR_RX_CAL_START 32'h00000010
`define EP_TSCR_RX_CAL_RESULT_OFFSET 5
`define EP_TSCR_RX_CAL_RESULT 32'h00000020
`define ADDR_EP_RFCR 7'h8
`define EP_RFCR_A_RUNT_OFFSET 0
`define EP_RFCR_A_RUNT 32'h00000001
`define EP_RFCR_A_GIANT_OFFSET 1
`define EP_RFCR_A_GIANT 32'h00000002
`define EP_RFCR_A_HP_OFFSET 2
`define EP_RFCR_A_HP 32'h00000004
`define EP_RFCR_KEEP_CRC_OFFSET 3
`define EP_RFCR_KEEP_CRC 32'h00000008
`define EP_RFCR_HPAP_OFFSET 4
`define EP_RFCR_HPAP 32'h00000ff0
`define EP_RFCR_MRU_OFFSET 12
`define EP_RFCR_MRU 32'h03fff000
`define ADDR_EP_VCR0 7'hc
`define EP_VCR0_QMODE_OFFSET 0
`define EP_VCR0_QMODE 32'h00000003
`define EP_VCR0_FIX_PRIO_OFFSET 2
`define EP_VCR0_FIX_PRIO 32'h00000004
`define EP_VCR0_PRIO_VAL_OFFSET 4
`define EP_VCR0_PRIO_VAL 32'h00000070
`define EP_VCR0_PVID_OFFSET 16
`define EP_VCR0_PVID 32'h0fff0000
`define ADDR_EP_VCR1 7'h10
`define EP_VCR1_OFFSET_OFFSET 0
`define EP_VCR1_OFFSET 32'h000003ff
`define EP_VCR1_DATA_OFFSET 10
`define EP_VCR1_DATA 32'h0ffffc00
`define ADDR_EP_PFCR0 7'h14
`define EP_PFCR0_MM_ADDR_OFFSET 0
`define EP_PFCR0_MM_ADDR 32'h0000003f
`define EP_PFCR0_MM_WRITE_OFFSET 6
`define EP_PFCR0_MM_WRITE 32'h00000040
`define EP_PFCR0_ENABLE_OFFSET 7
`define EP_PFCR0_ENABLE 32'h00000080
`define EP_PFCR0_MM_DATA_MSB_OFFSET 8
`define EP_PFCR0_MM_DATA_MSB 32'hffffff00
`define ADDR_EP_PFCR1 7'h18
`define EP_PFCR1_MM_DATA_LSB_OFFSET 0
`define EP_PFCR1_MM_DATA_LSB 32'h00000fff
`define ADDR_EP_TCAR 7'h1c
`define EP_TCAR_PCP_MAP_OFFSET 0
`define EP_TCAR_PCP_MAP 32'h00ffffff
`define ADDR_EP_FCR 7'h20
`define EP_FCR_RXPAUSE_OFFSET 0
`define EP_FCR_RXPAUSE 32'h00000001
`define EP_FCR_TXPAUSE_OFFSET 1
`define EP_FCR_TXPAUSE 32'h00000002
`define EP_FCR_RXPAUSE_802_1Q_OFFSET 2
`define EP_FCR_RXPAUSE_802_1Q 32'h00000004
`define EP_FCR_TXPAUSE_802_1Q_OFFSET 3
`define EP_FCR_TXPAUSE_802_1Q 32'h00000008
`define EP_FCR_TX_THR_OFFSET 8
`define EP_FCR_TX_THR 32'h0000ff00
`define EP_FCR_TX_QUANTA_OFFSET 16
`define EP_FCR_TX_QUANTA 32'hffff0000
`define ADDR_EP_MACH 7'h24
`define ADDR_EP_MACL 7'h28
`define ADDR_EP_MDIO_CR 7'h2c
`define EP_MDIO_CR_DATA_OFFSET 0
`define EP_MDIO_CR_DATA 32'h0000ffff
`define EP_MDIO_CR_ADDR_OFFSET 16
`define EP_MDIO_CR_ADDR 32'h00ff0000
`define EP_MDIO_CR_RW_OFFSET 31
`define EP_MDIO_CR_RW 32'h80000000
`define ADDR_EP_MDIO_ASR 7'h30
`define EP_MDIO_ASR_RDATA_OFFSET 0
`define EP_MDIO_ASR_RDATA 32'h0000ffff
`define EP_MDIO_ASR_PHYAD_OFFSET 16
`define EP_MDIO_ASR_PHYAD 32'h00ff0000
`define EP_MDIO_ASR_READY_OFFSET 31
`define EP_MDIO_ASR_READY 32'h80000000
`define ADDR_EP_IDCODE 7'h34
`define ADDR_EP_DSR 7'h38
`define EP_DSR_LSTATUS_OFFSET 0
`define EP_DSR_LSTATUS 32'h00000001
`define EP_DSR_LACT_OFFSET 1
`define EP_DSR_LACT 32'h00000002
`define ADDR_EP_DMCR 7'h3c
`define EP_DMCR_EN_OFFSET 0
`define EP_DMCR_EN 32'h00000001
`define EP_DMCR_N_AVG_OFFSET 16
`define EP_DMCR_N_AVG 32'h0fff0000
`define ADDR_EP_DMSR 7'h40
`define EP_DMSR_PS_VAL_OFFSET 0
`define EP_DMSR_PS_VAL 32'h00ffffff
`define EP_DMSR_PS_RDY_OFFSET 24
`define EP_DMSR_PS_RDY 32'h01000000
`define ADDR_EP_INJ_CTRL 7'h44
`define EP_INJ_CTRL_PIC_CONF_IFG_OFFSET 0
`define EP_INJ_CTRL_PIC_CONF_IFG 32'h0000ffff
`define EP_INJ_CTRL_PIC_CONF_SEL_OFFSET 16
`define EP_INJ_CTRL_PIC_CONF_SEL 32'h00070000
`define EP_INJ_CTRL_PIC_CONF_VALID_OFFSET 19
`define EP_INJ_CTRL_PIC_CONF_VALID 32'h00080000
`define EP_INJ_CTRL_PIC_MODE_ID_OFFSET 20
`define EP_INJ_CTRL_PIC_MODE_ID 32'h00700000
`define EP_INJ_CTRL_PIC_MODE_VALID_OFFSET 23
`define EP_INJ_CTRL_PIC_MODE_VALID 32'h00800000
`define EP_INJ_CTRL_PIC_ENA_OFFSET 24
`define EP_INJ_CTRL_PIC_ENA 32'h01000000
`ifndef __ETH_PACKET_SVH
`define __ETH_PACKET_SVH
`include "simdrv_defs.svh"
typedef byte mac_addr_t[6];
typedef bit[11:0] vid_t;
typedef bit[2:0] pcp_t;
typedef enum
{
NONE = 0,
TX_FID,
RX_TIMESTAMP
} oob_type_t;
typedef struct {
bit [27:0] ts_r;
bit [3:0] ts_f;
bit [5:0] port_id;
bit [15:0] frame_id;
} wr_timestamp_t;
class EthPacket;
static const mac_addr_t dummy_mac = '{0,0,0,0,0,0} ;
static int _zero = 0;
static const int CMP_OOB = 1;
static const int CMP_STATUS = 2;
byte payload[];
int size;
mac_addr_t src, dst;
oob_type_t oob_type;
bit is_q;
bit is_hp;
bit has_smac;
bit has_crc;
bit error;
bit [15:0] ethertype;
bit [7:0] pclass;
vid_t vid;
pcp_t pcp;
oob_type_t oob;
wr_timestamp_t ts;
task set_size(int size);
payload = new[size](payload);
endtask
function new(int size = _zero);
// size = 0;
src = dummy_mac;
dst = dummy_mac;
is_q = 0;
is_hp = 0;
has_crc = 0;
oob_type = NONE;
payload = new[size](payload);
endfunction // new
task deserialize(byte data[]);
int i, hsize, psize;
if(data.size < 14)
begin
error = 1;
return;
end
for(i=0; i<6;i++)
begin
dst[i] = data[i];
src[i] = data [i+6];
end
has_crc = 0;
if(data[12] == 'h81 && data[13] == 'h00)
begin
is_q = 1;
hsize = 18;
ethertype = {data[16], data[17]};
vid = ((int'(data[14]) << 8) | data[15]) & 12'hfff;
pcp = data[14] >> 5;
end else begin
is_q = 0;
hsize = 14;
ethertype = {data[12], data[13]};
end
psize = data.size() - hsize;
if(psize <= 0)
begin
error = 1;
return;
end
payload = new[psize];
for(i=0;i<data.size() - hsize;i++)
payload[i] = data[hsize + i];
// error = 0;
endtask
task automatic serialize(ref byte data[]);
int i, hsize;
hsize = is_q ? 18 : 14;
data = new[payload.size() + hsize](data);
for(i=0; i<6;i++)
begin
data[i] = dst[i];
data[i + 6] = src[i];
end
if(is_q)
begin
data [12] = 8'h81;
data [13] = 8'h00;
data [14] = {pcp, 1'b0, vid[11:8]};
data [15] = vid[7:0];
data [16] = ethertype[15:8];
data [17] = ethertype[7:0];
end else begin
data[12] = ethertype [15:8];
data[13] = ethertype [7:0];
end
for (i=0; i<payload.size(); i++)
data[i + hsize] = payload[i];
endtask // serialize
function bit equal(ref EthPacket b, input int flags = 0);
if(src != b.src || dst != b.dst || ethertype != b.ethertype)
begin
$display("notequal: hdr");
return 0;
end
if(is_q ^ b.is_q)
begin
$display("notequal: q");
return 0;
end
if(is_q && (vid != b.vid || pcp != b.pcp))
return 0;
if(payload != b.payload)
begin
$display("notequal: payload");
return 0;
end
// return 0;
if(flags & CMP_STATUS)
if(error ^ b.error)
return 0;
if(flags & CMP_OOB) begin
if (b.oob_type != oob_type)
return 0;
if(oob_type == TX_FID && (b.ts.frame_id != ts.frame_id))
return 0;