Commit ba6d5d70 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

remove simulation files duplication, use general-cores instead

parent 26d99562
files = [ "logger.svh", "masterfip-common.svh", "mock_turtle_driver.svh", files = [ "logger.svh", "masterfip-common.svh", "mock_turtle_driver.svh",
"mt_cpu_csr_driver.svh", "mt_mqueue_host_driver.svh", "mt_cpu_csr_driver.svh", "mt_mqueue_host_driver.svh",
"serializable.svh", "vhd_wishbone_master.svh", "wrn_cpu_csr_regs.vh" ] "serializable.svh", "vhd_wishbone_master.svh", "wrn_cpu_csr_regs.vh" ]
include_dirs = [ "wb" ]
files = [ "simdrv_defs.svh" ]
`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_MDIO_ECTRL 7'h44
`define MDIO_ECTRL_LPBCK_VEC_OFFSET 0
`define MDIO_ECTRL_LPBCK_VEC 32'h00000007
`define MDIO_ECTRL_SFP_TX_FAULT_OFFSET 3
`define MDIO_ECTRL_SFP_TX_FAULT 32'h00000008
`define MDIO_ECTRL_SFP_LOSS_OFFSET 4
`define MDIO_ECTRL_SFP_LOSS 32'h00000010
`define MDIO_ECTRL_SFP_TX_DISABLE_OFFSET 5
`define MDIO_ECTRL_SFP_TX_DISABLE 32'h00000020
`define MDIO_ECTRL_TX_PRBS_SEL_OFFSET 8
`define MDIO_ECTRL_TX_PRBS_SEL 32'h00000700
`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];
size = data.size;
// 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;
end
return 1;
endfunction // equal
task copy(ref EthPacket b);
endtask // copy
task hexdump(byte buffer []);
string str;
int size ;
int i;
int offset = 0;
const int per_row = 16;
size = buffer.size();
while(size > 0)
begin
int n;
n = (size > per_row ? per_row : size);
$sformat(str,"+%03x: ", offset);
for(i=0;i<n;i++) $sformat(str,"%s%s%02x", str, (i==(per_row/2)?"-":" "), buffer[offset + i]);
$display(str);
offset = offset + n;
size = size - n;
end
endtask // hexdump
task dump(int full = _zero);
string str, tmp;
int t;
if(is_q)
$sformat(str, "802.1q [VID %5d/PCP %d] ", vid, pcp);
else
str = "802.1 ";
$sformat(str, "%s DST [%02x:%02x:%02x:%02x:%02x:%02x] SRC: [%02x:%02x:%02x:%02x:%02x:%02x] Type = 0x%04x size = %d F:(%s%s)", str, dst[0],dst[1],dst[2],dst[3],dst[4],dst[5], src[0],src[1],src[2],src[3],src[4], src[5], ethertype, (is_q ? 18 : 14) + payload.size(),
is_hp ? "H" : " ", has_crc ? "C" : " ");
if(oob_type == TX_FID)
begin
$sformat(tmp, "TxOOB: %x", ts.frame_id);
str = {str, tmp};
end
$display(str);
hexdump(payload);
endtask // dump
endclass // EthPacket
class EthPacketGenerator;
protected EthPacket template;
protected int min_size, max_size;
protected int seed;
static const int SMAC = (1<<0);
static const int DMAC = (1<<1);
static const int ETHERTYPE = (1<<2);
static const int VID = (1<<3);
static const int PCP = (1<<4);
static const int PAYLOAD = (1<<5);
static const int SEQ_PAYLOAD = (1<<7);
static const int SEQ_ID = (1<<10);
static const int TX_OOB = (1<<6);
static const int EVEN_LENGTH = (1<<8);
static const int RX_OOB = (1<<9);
static const int ALL = SMAC | DMAC | VID | ETHERTYPE | PCP | PAYLOAD ;
protected int r_flags;
protected int m_current_frame_id;
protected int cur_seq_id;
function new();
r_flags =ALL;
min_size = 64;
max_size = 128;
m_current_frame_id = 0;
template = new;
cur_seq_id = 0;
endfunction // new
task set_randomization(int flags);
r_flags = flags;
endtask // randomize
typedef byte dyn_array[];
protected function dyn_array random_bvec(int size);
byte v[];
int i;
// $display("RandomBVEC %d", size);
v = new[size](v);
for(i=0;i<size;i++)
v[i] = $dist_uniform(seed, 0, 256);
return v;
endfunction // random_bvec
task set_seed(int seed_);
seed = seed_;
endtask // set_seed
function int get_seed();
return seed;
endfunction // get_seed
protected function dyn_array seq_payload(int size);
byte v[];
int i;
v = new[size](v);
for(i=0;i<size;i++)
v[i] = i;
return v;
endfunction // random_bvec
function automatic EthPacket gen(int set_len = 0);
EthPacket pkt;
int len;
pkt = new;
if (r_flags & SMAC) pkt.src = random_bvec(6); else pkt.src = template.src;
if (r_flags & DMAC) pkt.dst = random_bvec(6); else pkt.dst = template.dst;
pkt.ethertype = (r_flags & ETHERTYPE ? $dist_uniform(seed, 0, 1<<16) : template.ethertype);
pkt.is_q = template.is_q;
pkt.vid = template.vid;
pkt.pcp = template.pcp;
pkt.has_smac = template.has_smac;
if(set_len > 0) len = set_len;
else len = $dist_uniform(seed, min_size, max_size);
if((len & 1) && (r_flags & EVEN_LENGTH))
len++;
if(r_flags & PAYLOAD) pkt.payload = random_bvec(len);
else if(r_flags & SEQ_PAYLOAD) pkt.payload = seq_payload(len);
else pkt.payload = template.payload;
if(r_flags & SEQ_ID)
begin
pkt.payload[0] = cur_seq_id & 'hff;
pkt.payload[1] = (cur_seq_id>>8) & 'hff;
pkt.payload[2] = (cur_seq_id>>16) & 'hff;
pkt.payload[3] = (cur_seq_id>>24) & 'hff;
cur_seq_id++;
end
if(r_flags & TX_OOB)
begin
pkt.ts.frame_id = m_current_frame_id++;
pkt.oob_type = TX_FID;
end
pkt.size = len + 14; //payload + header
return pkt;
endfunction
task set_template(EthPacket pkt);
template = pkt;
endtask // set_template
task set_size(int smin, int smax);
min_size = smin;
max_size = smax;
endtask // set_size
endclass // EthPacketGenerator
virtual class EthPacketSink;
static int _null = 0;
pure virtual function int poll();
virtual function int permanent_stall_enable(); endfunction
virtual function int permanent_stall_disable(); endfunction
pure virtual task recv(ref EthPacket pkt, ref int result = _null);
endclass // EthPacketSink
virtual class EthPacketSource;
static int _null = 0;
pure virtual task send(ref EthPacket pkt, ref int result = _null);
endclass // PacketSource
`endif
//
// Title : Software Wishbone master unit for testbenches
//
// File : if_wishbone.sv
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : SystemVerilog
//
// Default values of certain WB parameters.
`include "simdrv_defs.sv"
interface IWishboneClassicMaster
(
input clk_i,
input rst_n_i
);
parameter g_data_width = 32;
parameter g_addr_width = 32;
/* Interface signals */
logic [g_addr_width - 1 : 0] adr;
logic [g_data_width - 1 : 0] dat_o;
logic [3 : 0] sel; // FIXME: 32-bit only
wire [g_data_width - 1 : 0] dat_i;
wire ack;
logic cyc;
logic stb;
logic we;
wire stall;
initial begin
adr = 0;
dat_o = 0;
sel = 0;
cyc = 0;
stb = 0;
we = 0;
end
time last_access_t = 0;
reg [g_data_width-1:0] dummy;
// enables/disables displaying information about each read/write operation.
int tb_verbose = 0;
task verbose(int onoff);
tb_verbose = onoff;
endtask // wb_verbose
task classic_single_rw_generic;
input [g_addr_width - 1 : 0] trans_addr;
input [g_data_width - 1 : 0] trans_wdata;
output [g_data_width - 1 : 0] trans_rdata;
input rw;
input [3:0] size;
begin : rw_generic_main
if(tb_verbose && rw)
$display("WB write %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
trans_addr, trans_wdata);
if($time != last_access_t) begin
@(posedge clk_i);
end
stb<=1;
cyc<=1;
adr <= {2'b00, trans_addr[31:2]};
we <= rw;
if(rw) begin
case(size)
4: begin dat_o<=trans_wdata; sel <= 4'b1111; end
2: begin
if(adr[1]) begin
dat_o[31:16] <= trans_wdata[15:0];
sel <= 4'b1100;
end else begin
dat_o[15:0] <= trans_wdata[15:0];
sel <= 4'b0011;
end
end
1: begin
case(adr[1:0])
0: begin dat_o[31:24] <= trans_wdata[7:0]; sel <= 4'b1000; end
1: begin dat_o[23:16] <= trans_wdata[7:0]; sel <= 4'b0100; end
2: begin dat_o[15:8] <= trans_wdata[7:0]; sel <= 4'b0010; end
3: begin dat_o[7:0] <= trans_wdata[7:0]; sel <= 4'b0001; end
endcase // case(addr[1:0])
end
endcase // case(size)
end // if (rw)
@(posedge clk_i);
if(ack == 0) begin
while(ack == 0) begin @(posedge clk_i); end
end
trans_rdata = dat_i;
cyc <= 0;
we<=0;
stb<=0;
if(tb_verbose && !rw)
$display("WB read %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
trans_addr, trans_rdata);
last_access_t = $time;
end
endtask // rw_generic
task write32;
input [g_addr_width - 1 : 0] addr;
input [31 : 0] data_i;
begin
classic_single_rw_generic(addr, data_i, dummy, 1, 4);
end
endtask // write32
task read32;
input [g_addr_width - 1 : 0] addr;
output [31 : 0] data_o;
begin : read32_body
reg [g_data_width - 1 : 0] rval;
classic_single_rw_generic(addr, 0, rval, 0, 4);
data_o = rval[31:0];
end
endtask // write32
modport master
(
output adr,
output dat_o,
output sel,
output cyc,
output stb,
output we,
input ack,
input dat_i,
input stall);
endinterface // IWishbone
interface IWishboneLink;
parameter g_data_width = 32;
parameter g_addr_width = 32;
wire [g_addr_width - 1 : 0] adr;
wire [g_data_width - 1 : 0] dat_o;
wire [g_data_width - 1 : 0] dat_i;
wire [(g_data_width/8)-1 : 0] sel;
wire ack;
wire stall;
wire err;
wire rty;
wire cyc;
wire stb;
wire we;
modport slave
(
output adr,
output dat_o,
input dat_i,
output sel,
output cyc,
output stb,
output we,
input ack,
input stall,
input err,
input rty
);
modport master
(
input adr,
input dat_o,
output dat_i,
input sel,
input cyc,
input stb,
input we,
output ack,
output stall,
output err,
output rty
);
endinterface // IWishboneLink
This diff is collapsed.
`ifndef __IF_WISHBONE_SLAVE_SVH
`define __IF_WISHBONE_SLAVE_SVH
`timescale 1ns/1ps
`include "if_wishbone_types.svh"
interface IWishboneSlave
(
input clk_i,
input rst_n_i
);
parameter g_addr_width = 32;
parameter g_data_width = 32;
wire [g_addr_width - 1: 0] adr;
wire [g_data_width - 1: 0] dat_i;
wire [(g_data_width/8)-1 : 0] sel;
logic [g_data_width - 1 : 0] dat_o;
logic ack;
logic stall;
logic err;
logic rty;
wire cyc;
wire stb;
wire we;
time last_access_t = 0;
modport slave
(
input adr,
input dat_o,
input sel,
input cyc,
input stb,
input we,
output ack,
output dat_i,
output stall,
output err,
output rty
);
wb_cycle_t c_queue[$];
wb_cycle_t current_cycle;
reg cyc_prev;
int trans_index;
int first_transaction;
struct {
wb_cycle_type_t mode;
int gen_random_stalls;
int gen_random_errors;
int stall_min_duration;
int stall_max_duration;
real stall_prob;
real error_prob;
} settings;
int permanent_stall = 0;
function automatic int _poll(); return poll(); endfunction
function automatic int _permanent_stall_enable(); return permanent_stall_enable(); endfunction
function automatic int _permanent_stall_disable(); return permanent_stall_disable(); endfunction
task automatic _get(ref wb_cycle_t xfer); get(xfer); endtask
class CIWBSlaveAccessor extends CWishboneAccessor;
function automatic int poll();
return _poll();
endfunction
function automatic int permanent_stall_enable();
return _permanent_stall_enable();
endfunction
function automatic int permanent_stall_disable();
return _permanent_stall_disable();
endfunction
task get(ref wb_cycle_t xfer);
_get(xfer);
endtask
task clear();
endtask // clear
endclass // CIWBSlaveAccessor
function CIWBSlaveAccessor get_accessor();
CIWBSlaveAccessor tmp;
tmp = new;
return tmp;
endfunction // get_accessor
function automatic int permanent_stall_enable();
permanent_stall = 1;
$display("permanent stall ON");
return permanent_stall;
endfunction
function automatic int permanent_stall_disable();
permanent_stall = 0;
$display("permanent stall OFF");
return permanent_stall;
endfunction
function automatic int poll();
return c_queue.size() != 0;
endfunction // poll
task automatic get(ref wb_cycle_t xfer);
while(c_queue.size() <= 0)
@(posedge clk_i);
xfer = c_queue.pop_front();
endtask // pop_cycle
always@(posedge clk_i) cyc_prev <= cyc;
wire cyc_start = !cyc_prev && cyc;
wire cyc_end = cyc_prev && !cyc;
task gen_random_stalls();
static int stall_remaining = 0;
static int seed = 0;
// $display("stallr: %d\n", stall_remaining);
if(settings.gen_random_stalls && (probability_hit(settings.stall_prob) || stall_remaining > 0))
begin
if(stall_remaining == 0)
stall_remaining = $dist_uniform(seed,
settings.stall_min_duration,
settings.stall_max_duration);
if(stall_remaining)
stall_remaining--;
stall <= 1;
end else
stall <= 0;
endtask // gen_random_stalls
function automatic int count_ones(int x, int n_bits);
int i, cnt;
cnt = 0;
for(i=0;i<n_bits;i++) if(x & (1<<i)) cnt ++;
return cnt;
endfunction
function automatic int count_leading_zeroes(int x, int n_bits);
int i;
for(i=0;i<n_bits && !(x & (1<<i)); i++);
return i;
endfunction // count_leading_zeroes
function automatic int count_trailing_zeroes(int x, int n_bits);
int i;
for(i=n_bits-1;i>=0 && !(x & (1<<i)); i--);
return (n_bits-1-i);
endfunction
task pipelined_fsm();
// ML
if(permanent_stall)
stall <= 1;
else if(settings.gen_random_stalls)
gen_random_stalls();
else
stall <= 0;
/* -----\/----- EXCLUDED -----\/-----
if(cyc) begin
end else
stall <= 0;
-----/\----- EXCLUDED -----/\----- */
if(cyc_start) begin
current_cycle.data = {};
trans_index <= 0;
first_transaction = 1;
end
if(cyc_end) begin
c_queue.push_back(current_cycle);
end
if(cyc && settings.gen_random_errors && probability_hit(settings.error_prob))
err <= 1;
else
err <= 0;
if(stb && we && !stall && cyc) begin
int oc, lzc, tzc;
wb_xfer_t d;
oc = count_ones(sel, g_data_width/8);
lzc = count_leading_zeroes(sel, g_data_width/8);
tzc = count_trailing_zeroes(sel, g_data_width/8);
d.a = adr * (g_data_width / 8);
d.size = oc;
d.d = (dat_i>>(8*lzc)) & ((1<<(oc*8)) -1);
if(lzc + tzc + oc != g_data_width/8)
$error("IWishboneSlave [write a %x d %x sel %x]: non-contiguous sel", adr, dat_i, sel);
d.sel [g_data_width/8-1:0] = sel;
current_cycle.data.push_back(d);
// $display("ifWb:[%d] write a %x d %x sel %x",current_cycle.data.size(), adr, dat_i, sel);
ack <= 1;
end else if(stb && !we && !stall) begin
// $error("Sorry, no pipelined read for slave yet implemented");
ack <= 0;
end else
ack <= 0;
endtask // pipelined_fsm
always@(posedge clk_i)
begin
if(!rst_n_i)
begin
c_queue = {};
current_cycle.data = {};
trans_index = 0;
ack <= 0;
rty <= 0;
err <= 0;
dat_o <= 0;
stall <= 0;
end else begin
if(settings.mode == PIPELINED)
pipelined_fsm();
end
end
initial begin
settings.mode = PIPELINED;
settings.gen_random_stalls = 1;
settings.stall_prob = 0.1;
settings.stall_min_duration = 1;
settings.stall_max_duration = 2;
end
endinterface // IWishboneSlave
`endif
\ No newline at end of file
`ifndef IF_WISHBONE_ACCESSOR_SV
`define IF_WISHBONE_ACCESSOR_SV
`include "if_wishbone_types.svh"
virtual class CWishboneAccessor extends CBusAccessor;
static int _null = 0;
protected wb_cycle_type_t m_cycle_type;
function new();
m_cycle_type = CLASSIC;
m_default_xfer_size = 4;
endfunction // new
virtual task set_mode(wb_cycle_type_t mode);
m_cycle_type = mode;
endtask // set_mode
// [slave only] checks if there are any transactions in the queue
virtual function automatic int poll();
return 0;
endfunction // poll
// ML stuff [slave only]
virtual function automatic int permanent_stall_enable();
$display("CWisboneAccessor: permanent_stall: ON");
endfunction;
// ML stuff [slave only]
virtual function automatic int permanent_stall_disable();
$display("CWisboneAccessor: permanent_stall: OFF");
endfunction;
// [slave only] adds a simulation event (e.g. a forced STALL, RETRY, ERROR)
// evt = event type (STALL, ERROR, RETRY)
// behv = event behavior: DELAYED - event occurs after a predefined delay (dly_start)
// RANDOM - event occurs randomly with probability (prob)
// These two can be combined (random events occuring after a certain initial delay)
// DELAYED events can be repeated (rep_rate parameter)
virtual task add_event(wba_sim_event_t evt, wba_sim_behavior_t behv, int dly_start, real prob, int rep_rate);
endtask // add_event
// [slave only] gets a cycle from the queue
virtual task get(ref wb_cycle_t xfer);
endtask // get
// [master only] executes a cycle and returns its result
virtual task put(ref wb_cycle_t xfer);
endtask // put
virtual function int idle();
return 1;
endfunction // idle
// [master only] generic write(s), blocking
virtual task writem(uint64_t addr[], uint64_t data[], int size = 4, ref int result = _null);
wb_cycle_t cycle;
int i;
cycle.ctype = m_cycle_type;
cycle.rw = 1'b1;
for(i=0;i < addr.size(); i++)
begin
wb_xfer_t xfer;
xfer.a = addr[i];
xfer.d = data[i];
xfer.size = size;
cycle.data.push_back(xfer);
end
// $display("DS: %d", cycle.data.size());
put(cycle);
get(cycle);
result = cycle.result;
endtask // write
// [master only] generic read(s), blocking
virtual task readm(uint64_t addr[], ref uint64_t data[],input int size = 4, ref int result = _null);
wb_cycle_t cycle;
int i;
cycle.ctype = m_cycle_type;
cycle.rw = 1'b0;
for(i=0;i < addr.size(); i++)
begin
wb_xfer_t xfer;
xfer.a = addr[i];
xfer.size = size;
cycle.data.push_back(xfer);
end
put(cycle);
get(cycle);
for(i=0;i < addr.size(); i++)
data[i] = cycle.data[i].d;
result = cycle.result;
endtask // readm
virtual task read(uint64_t addr, ref uint64_t data, input int size = 4, ref int result = _null);
uint64_t aa[], da[];
aa = new[1];
da = new[1];
aa[0] = addr;
readm(aa, da, size, result);
data = da[0];
endtask
virtual task write(uint64_t addr, uint64_t data, int size = 4, ref int result = _null);
uint64_t aa[], da[];
aa = new[1];
da = new[1];
aa[0] = addr;
da[0] = data;
writem(aa, da, size, result);
endtask
endclass // CWishboneAccessor
static int seed = 0;
function automatic int probability_hit(real prob);
real rand_val;
rand_val = real'($dist_uniform(seed, 0, 1000)) / 1000.0;
if(rand_val < prob)
return 1;
else
return 0;
endfunction // probability_hit
`endif // `ifndef IF_WISHBONE_ACCESSOR_SV
//
// Title : Software Wishbone master unit for testbenches
//
// File : wishbone_master_tb.v
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : Verilog 2001
//
`ifndef __IF_WB_DEFS_SV
`define __IF_WB_DEFS_SV
`include "simdrv_defs.sv"
typedef enum
{
R_OK = 0,
R_ERROR,
R_RETRY
} wb_cycle_result_t;
typedef enum
{
CLASSIC = 0,
PIPELINED = 1
} wb_cycle_type_t;
typedef struct {
uint64_t a;
uint64_t d;
bit[7:0] sel;
int size;
} wb_xfer_t;
typedef struct {
int rw;
wb_cycle_type_t ctype;
wb_xfer_t data[$];
wb_cycle_result_t result;
} wb_cycle_t;
virtual class CWishboneAccessor;
virtual function automatic int poll();
return 0;
endfunction // poll
virtual task get(output wb_cycle_t xfer);
endtask // get
virtual task put(input wb_cycle_t xfer);
endtask // put
virtual function int idle();
return 0;
endfunction // idle
virtual task clear(); endtask
endclass // CWishboneAccessor
int seed = 0;
function automatic int probability_hit(real prob);
real rand_val;
rand_val = real'($dist_uniform(seed, 0, 1000)) / 1000.0;
if(rand_val < prob)
return 1;
else
return 0;
endfunction // probability_hit
`endif // `ifndef __IF_WB_DEFS_SV
//
// Title : Pipelined Wishbone BFM - type definitions
//
// File : if_wishbone_types.sv
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : Verilog 2001
//
`ifndef __IF_WB_TYPES_SVH
`define __IF_WB_TYPES_SVH
`include "simdrv_defs.svh"
typedef enum
{
R_OK = 0,
R_ERROR,
R_RETRY
} wb_cycle_result_t;
typedef enum
{
CLASSIC = 0,
PIPELINED = 1
} wb_cycle_type_t;
typedef enum {
WORD = 0,
BYTE = 1
} wb_address_granularity_t;
typedef struct {
uint64_t a;
uint64_t d;
int size;
bit [7:0] sel;
} wb_xfer_t;
typedef struct {
int rw;
wb_cycle_type_t ctype;
wb_xfer_t data[$];
wb_cycle_result_t result;
} wb_cycle_t;
typedef enum
{
RETRY = 0,
STALL,
ERROR
} wba_sim_event_t;
typedef enum
{
RANDOM = (1<<0),
DELAYED = (1<<1)
} wba_sim_behavior_t;
`endif // `ifndef __IF_WB_TYPES_SVH
`define ADDR_LBK_MCR 5'h0
`define LBK_MCR_ENA_OFFSET 0
`define LBK_MCR_ENA 32'h00000001
`define LBK_MCR_CLR_OFFSET 1
`define LBK_MCR_CLR 32'h00000002
`define LBK_MCR_FDMAC_OFFSET 2
`define LBK_MCR_FDMAC 32'h00000004
`define ADDR_LBK_DMAC_L 5'h4
`define ADDR_LBK_DMAC_H 5'h8
`define ADDR_LBK_RCV_CNT 5'hc
`define ADDR_LBK_DRP_CNT 5'h10
`define ADDR_LBK_FWD_CNT 5'h14
`define ADDR_MINIC_MCR 7'h0
`define MINIC_MCR_TX_START_OFFSET 0
`define MINIC_MCR_TX_START 32'h00000001
`define MINIC_MCR_TX_IDLE_OFFSET 1
`define MINIC_MCR_TX_IDLE 32'h00000002
`define MINIC_MCR_TX_ERROR_OFFSET 2
`define MINIC_MCR_TX_ERROR 32'h00000004
`define MINIC_MCR_RX_READY_OFFSET 8
`define MINIC_MCR_RX_READY 32'h00000100
`define MINIC_MCR_RX_FULL_OFFSET 9
`define MINIC_MCR_RX_FULL 32'h00000200
`define MINIC_MCR_RX_EN_OFFSET 10
`define MINIC_MCR_RX_EN 32'h00000400
`define MINIC_MCR_TX_TS_READY_OFFSET 11
`define MINIC_MCR_TX_TS_READY 32'h00000800
`define MINIC_MCR_RX_CLASS_OFFSET 16
`define MINIC_MCR_RX_CLASS 32'h00ff0000
`define ADDR_MINIC_TX_ADDR 7'h4
`define ADDR_MINIC_RX_ADDR 7'h8
`define ADDR_MINIC_RX_SIZE 7'hc
`define ADDR_MINIC_RX_AVAIL 7'h10
`define ADDR_MINIC_TSR0 7'h14
`define MINIC_TSR0_VALID_OFFSET 0
`define MINIC_TSR0_VALID 32'h00000001
`define MINIC_TSR0_PID_OFFSET 1
`define MINIC_TSR0_PID 32'h0000003e
`define MINIC_TSR0_FID_OFFSET 6
`define MINIC_TSR0_FID 32'h003fffc0
`define ADDR_MINIC_TSR1 7'h18
`define MINIC_TSR1_TSVAL_OFFSET 0
`define MINIC_TSR1_TSVAL 32'hffffffff
`define ADDR_MINIC_DBGR 7'h1c
`define MINIC_DBGR_IRQ_CNT_OFFSET 0
`define MINIC_DBGR_IRQ_CNT 32'h00ffffff
`define MINIC_DBGR_WB_IRQ_VAL_OFFSET 24
`define MINIC_DBGR_WB_IRQ_VAL 32'h01000000
`define ADDR_MINIC_MPROT 7'h20
`define MINIC_MPROT_LO_OFFSET 0
`define MINIC_MPROT_LO 32'h0000ffff
`define MINIC_MPROT_HI_OFFSET 16
`define MINIC_MPROT_HI 32'hffff0000
`define ADDR_MINIC_EIC_IDR 7'h40
`define MINIC_EIC_IDR_TX_OFFSET 0
`define MINIC_EIC_IDR_TX 32'h00000001
`define MINIC_EIC_IDR_RX_OFFSET 1
`define MINIC_EIC_IDR_RX 32'h00000002
`define MINIC_EIC_IDR_TXTS_OFFSET 2
`define MINIC_EIC_IDR_TXTS 32'h00000004
`define ADDR_MINIC_EIC_IER 7'h44
`define MINIC_EIC_IER_TX_OFFSET 0
`define MINIC_EIC_IER_TX 32'h00000001
`define MINIC_EIC_IER_RX_OFFSET 1
`define MINIC_EIC_IER_RX 32'h00000002
`define MINIC_EIC_IER_TXTS_OFFSET 2
`define MINIC_EIC_IER_TXTS 32'h00000004
`define ADDR_MINIC_EIC_IMR 7'h48
`define MINIC_EIC_IMR_TX_OFFSET 0
`define MINIC_EIC_IMR_TX 32'h00000001
`define MINIC_EIC_IMR_RX_OFFSET 1
`define MINIC_EIC_IMR_RX 32'h00000002
`define MINIC_EIC_IMR_TXTS_OFFSET 2
`define MINIC_EIC_IMR_TXTS 32'h00000004
`define ADDR_MINIC_EIC_ISR 7'h4c
`define MINIC_EIC_ISR_TX_OFFSET 0
`define MINIC_EIC_ISR_TX 32'h00000001
`define MINIC_EIC_ISR_RX_OFFSET 1
`define MINIC_EIC_ISR_RX 32'h00000002
`define MINIC_EIC_ISR_TXTS_OFFSET 2
`define MINIC_EIC_ISR_TXTS 32'h00000004
`define OLD_ADDR_EP_ECR 8'h0
`define OLD_EP_ECR_PORTID_OFFSET 0
`define OLD_EP_ECR_PORTID 32'h0000001f
`define OLD_EP_ECR_RST_CNT_OFFSET 5
`define OLD_EP_ECR_RST_CNT 32'h00000020
`define OLD_EP_ECR_TX_EN_FRA_OFFSET 6
`define OLD_EP_ECR_TX_EN_FRA 32'h00000040
`define OLD_EP_ECR_RX_EN_FRA_OFFSET 7
`define OLD_EP_ECR_RX_EN_FRA 32'h00000080
`define OLD_ADDR_EP_TSCR 8'h4
`define OLD_EP_TSCR_EN_TXTS_OFFSET 0
`define OLD_EP_TSCR_EN_TXTS 32'h00000001
`define OLD_EP_TSCR_EN_RXTS_OFFSET 1
`define OLD_EP_TSCR_EN_RXTS 32'h00000002
`define OLD_EP_TSCR_CS_START_OFFSET 2
`define OLD_EP_TSCR_CS_START 32'h00000004
`define OLD_EP_TSCR_CS_DONE_OFFSET 3
`define OLD_EP_TSCR_CS_DONE 32'h00000008
`define OLD_ADDR_EP_RFCR 8'h8
`define OLD_EP_RFCR_A_RUNT_OFFSET 0
`define OLD_EP_RFCR_A_RUNT 32'h00000001
`define OLD_EP_RFCR_A_GIANT_OFFSET 1
`define OLD_EP_RFCR_A_GIANT 32'h00000002
`define OLD_EP_RFCR_A_HP_OFFSET 2
`define OLD_EP_RFCR_A_HP 32'h00000004
`define OLD_EP_RFCR_A_FRAG_OFFSET 3
`define OLD_EP_RFCR_A_FRAG 32'h00000008
`define OLD_EP_RFCR_QMODE_OFFSET 4
`define OLD_EP_RFCR_QMODE 32'h00000030
`define OLD_EP_RFCR_FIX_PRIO_OFFSET 6
`define OLD_EP_RFCR_FIX_PRIO 32'h00000040
`define OLD_EP_RFCR_PRIO_VAL_OFFSET 8
`define OLD_EP_RFCR_PRIO_VAL 32'h00000700
`define OLD_EP_RFCR_VID_VAL_OFFSET 16
`define OLD_EP_RFCR_VID_VAL 32'h0fff0000
`define OLD_ADDR_EP_FCR 8'hc
`define OLD_EP_FCR_RXPAUSE_OFFSET 0
`define OLD_EP_FCR_RXPAUSE 32'h00000001
`define OLD_EP_FCR_TXPAUSE_OFFSET 1
`define OLD_EP_FCR_TXPAUSE 32'h00000002
`define OLD_EP_FCR_TX_THR_OFFSET 8
`define OLD_EP_FCR_TX_THR 32'h0000ff00
`define OLD_EP_FCR_TX_QUANTA_OFFSET 16
`define OLD_EP_FCR_TX_QUANTA 32'hffff0000
`define OLD_ADDR_EP_MACH 8'h10
`define OLD_ADDR_EP_MACL 8'h14
`define OLD_ADDR_EP_DMCR 8'h18
`define OLD_EP_DMCR_EN_OFFSET 0
`define OLD_EP_DMCR_EN 32'h00000001
`define OLD_EP_DMCR_N_AVG_OFFSET 16
`define OLD_EP_DMCR_N_AVG 32'h0fff0000
`define OLD_ADDR_EP_DMSR 8'h1c
`define OLD_EP_DMSR_PS_VAL_OFFSET 0
`define OLD_EP_DMSR_PS_VAL 32'h00ffffff
`define OLD_EP_DMSR_PS_RDY_OFFSET 24
`define OLD_EP_DMSR_PS_RDY 32'h01000000
`define OLD_ADDR_EP_MDIO_CR 8'h20
`define OLD_EP_MDIO_CR_DATA_OFFSET 0
`define OLD_EP_MDIO_CR_DATA 32'h0000ffff
`define OLD_EP_MDIO_CR_ADDR_OFFSET 16
`define OLD_EP_MDIO_CR_ADDR 32'h00ff0000
`define OLD_EP_MDIO_CR_RW_OFFSET 31
`define OLD_EP_MDIO_CR_RW 32'h80000000
`define OLD_ADDR_EP_MDIO_SR 8'h24
`define OLD_EP_MDIO_SR_RDATA_OFFSET 0
`define OLD_EP_MDIO_SR_RDATA 32'h0000ffff
`define OLD_EP_MDIO_SR_READY_OFFSET 31
`define OLD_EP_MDIO_SR_READY 32'h80000000
`define OLD_ADDR_EP_IDCODE 8'h28
`define OLD_ADDR_EP_DSR 8'h2c
`define OLD_EP_DSR_LSTATUS_OFFSET 0
`define OLD_EP_DSR_LSTATUS 32'h00000001
`define OLD_EP_DSR_LACT_OFFSET 1
`define OLD_EP_DSR_LACT 32'h00000002
`define OLD_ADDR_EP_AFCR 8'h30
`define OLD_EP_AFCR_ENABLE_OFFSET 0
`define OLD_EP_AFCR_ENABLE 32'h00000001
`define OLD_EP_AFCR_RULE_SEL_OFFSET 1
`define OLD_EP_AFCR_RULE_SEL 32'h0000000e
`define OLD_EP_AFCR_MATRIX_ADDR_OFFSET 4
`define OLD_EP_AFCR_MATRIX_ADDR 32'h00000ff0
`define OLD_EP_AFCR_MATRIX_DATA_OFFSET 12
`define OLD_EP_AFCR_MATRIX_DATA 32'h000ff000
`define OLD_EP_AFCR_MATRIX_WRITE_P_OFFSET 20
`define OLD_EP_AFCR_MATRIX_WRITE_P 32'h00100000
`define OLD_ADDR_EP_AFR0 8'h34
`define OLD_EP_AFR0_DMAC_EN_OFFSET 0
`define OLD_EP_AFR0_DMAC_EN 32'h00000001
`define OLD_EP_AFR0_VID_EN_OFFSET 1
`define OLD_EP_AFR0_VID_EN 32'h00000002
`define OLD_EP_AFR0_ETYPE_EN_OFFSET 2
`define OLD_EP_AFR0_ETYPE_EN 32'h00000004
`define OLD_EP_AFR0_VID_OFFSET 3
`define OLD_EP_AFR0_VID 32'h00007ff8
`define OLD_ADDR_EP_AFR1 8'h38
`define OLD_EP_AFR1_DMAC_LO_OFFSET 0
`define OLD_EP_AFR1_DMAC_LO 32'hffffffff
`define OLD_ADDR_EP_AFR2 8'h3c
`define OLD_EP_AFR2_DMAC_HI_OFFSET 0
`define OLD_EP_AFR2_DMAC_HI 32'h0000ffff
`define OLD_EP_AFR2_ETYPE_OFFSET 16
`define OLD_EP_AFR2_ETYPE 32'hffff0000
`define OLD_BASE_EP_RMON_RAM 8'h80
`define OLD_SIZE_EP_RMON_RAM 32'h20
/* Packet Filter microcode definitions */
class PFilterMicrocode;
typedef enum
{
AND = 0,
NAND = 4,
OR = 1,
NOR = 5,
XOR = 2,
XNOR = 6,
MOV = 3,
NOT = 7
} pfilter_op_t;
const uint64_t PF_MODE_LOGIC = (1<<34);
const uint64_t PF_MODE_CMP = 0;
const int max_size = 64;
protected int code_pos;
protected uint64_t code_buf[];
function new();
code_pos = 0;
code_buf = new[max_size];
endfunction // new
task check_size();
if(code_pos == max_size - 1)
$error("microcode: code too big (max size: %d)", max_size);
endtask // check_size
task check_reg_range(int val, int minval, int maxval, string name);
if(val < minval || val > maxval)
$error("microcode: %s register out of range (%d to %d)", name, minval,maxval);
endtask // check_reg_range
// rd = (packet[offset] & mask == value) op rd
task cmp(int offset, int value, int mask, pfilter_op_t op, int rd);
uint64_t ir;
check_size();
if(offset > code_pos-1)
$error("microcode: comparison offset is bigger than current PC. Insert some nops before comparing");
check_reg_range(rd, 1, 15, "ra/rd");
ir = (PF_MODE_CMP | (offset << 7)
| ((mask & 'h1) ? (1<<29) : 0)
| ((mask & 'h10) ? (1<<30) : 0)
| ((mask & 'h100) ? (1<<31) : 0)
| ((mask & 'h1000) ? (1<<32) : 0))
| op | (rd << 3);
ir = ir | (value & 'hffff) << 13;
code_buf[code_pos++] = ir;
endtask // cmp
// rd = (packet[offset] & (1<<bit_index)) op rd
task btst(int offset, int bit_index, pfilter_op_t op, int rd);
uint64_t ir;
check_size();
if(offset > code_pos-1)
$error("microcode: comparison offset is bigger than current PC. Insert some nops before comparing");
check_reg_range(rd, 1, 15, "ra/rd");
check_reg_range(bit_index, 0, 15, "bit index");
ir = ((1<<33) | PF_MODE_CMP | (offset << 7) | (bit_index << 29) | op | (rd << 3));
code_buf[code_pos++] = ir;
endtask // cmp
task nop();
uint64_t ir;
check_size();
ir = PF_MODE_LOGIC;
code_buf[code_pos++] = ir;
endtask // nop
// rd = ra op rb
task logic2(int rd, int ra, pfilter_op_t op, int rb);
uint64_t ir;
check_size();
check_reg_range(ra, 0, 31, "ra");
check_reg_range(rb, 0, 31, "rb");
check_reg_range(rd, 1, 31, "rd");
ir = (ra << 8) | (rb << 13) | ((rd & 'hf) << 3) | ((rd & 'h10) ? (1<<7) : 0) | op;
ir = ir | PF_MODE_LOGIC | (3<<23);
code_buf[code_pos++] = ir;
endtask // logic2
// rd = (ra op rb) op2 rc
task logic3(int rd, int ra, pfilter_op_t op, int rb, pfilter_op_t op2, int rc);
uint64_t ir;
check_size();
check_reg_range(ra, 0, 31, "ra");
check_reg_range(rb, 0, 31, "rb");
check_reg_range(rc, 0, 31, "rb");
check_reg_range(rd, 1, 31, "rd");
ir = (ra << 8) | (rb << 13) | (rc << 18) | ((rd & 'hf) << 3) | ((rd & 'h10) ? (1<<7) : 0) | op;
ir = ir | PF_MODE_LOGIC | (op2<<23);
code_buf[code_pos++] = ir;
endtask // logic3
typedef uint64_t u64_array[];
function u64_array assemble();
u64_array tmp;
// code_buf[code_pos++] = (1<<35); // insert FIN instruction
// tmp = new [code_pos](code_buf);
code_buf[code_pos] = (1<<35); // insert FIN instruction
tmp = new [code_pos+1](code_buf);
return tmp;
endfunction // assemble
endclass // PFilterMicrocode
`define ADDR_PPSG_CR 5'h0
`define PPSG_CR_CNT_RST_OFFSET 0
`define PPSG_CR_CNT_RST 32'h00000001
`define PPSG_CR_CNT_EN_OFFSET 1
`define PPSG_CR_CNT_EN 32'h00000002
`define PPSG_CR_CNT_ADJ_OFFSET 2
`define PPSG_CR_CNT_ADJ 32'h00000004
`define PPSG_CR_CNT_SET_OFFSET 3
`define PPSG_CR_CNT_SET 32'h00000008
`define PPSG_CR_PWIDTH_OFFSET 4
`define PPSG_CR_PWIDTH 32'hfffffff0
`define ADDR_PPSG_CNTR_NSEC 5'h4
`define ADDR_PPSG_CNTR_UTCLO 5'h8
`define ADDR_PPSG_CNTR_UTCHI 5'hc
`define ADDR_PPSG_ADJ_NSEC 5'h10
`define ADDR_PPSG_ADJ_UTCLO 5'h14
`define ADDR_PPSG_ADJ_UTCHI 5'h18
`define ADDR_PPSG_ESCR 5'h1c
`define PPSG_ESCR_SYNC_OFFSET 0
`define PPSG_ESCR_SYNC 32'h00000001
`define PPSG_ESCR_PPS_VALID_OFFSET 1
`define PPSG_ESCR_PPS_VALID 32'h00000002
`define PPSG_ESCR_TM_VALID_OFFSET 2
`define PPSG_ESCR_TM_VALID 32'h00000004
`define PPSG_ESCR_SEC_SET_OFFSET 3
`define PPSG_ESCR_SEC_SET 32'h00000008
`define PPSG_ESCR_NSEC_SET_OFFSET 4
`define PPSG_ESCR_NSEC_SET 32'h00000010
`define ADDR_SI570_RFREQL 4'h0
`define ADDR_SI570_RFREQH 4'h4
`define ADDR_SI570_GPSR 4'h8
`define SI570_GPSR_SCL_OFFSET 0
`define SI570_GPSR_SCL 32'h00000001
`define SI570_GPSR_SDA_OFFSET 1
`define SI570_GPSR_SDA 32'h00000002
`define ADDR_SI570_GPCR 4'hc
`define SI570_GPCR_SCL_OFFSET 0
`define SI570_GPCR_SCL 32'h00000001
`define SI570_GPCR_SDA_OFFSET 1
`define SI570_GPCR_SDA 32'h00000002
`ifndef SIMDRV_DEFS_SV
`define SIMDRV_DEFS_SV 1
typedef longint unsigned uint64_t;
typedef int unsigned uint32_t;
typedef shortint unsigned uint16_t;
typedef uint64_t u64_array_t[];
typedef byte byte_array_t[];
virtual class CBusAccessor;
static int _null = 0;
int m_default_xfer_size;
task set_default_xfer_size(int default_size);
m_default_xfer_size = default_size;
endtask // set_default_xfer_size
pure virtual task writem(uint64_t addr[], uint64_t data[], input int size, ref int result);
pure virtual task readm(uint64_t addr[], ref uint64_t data[], input int size, ref int result);
virtual task read(uint64_t addr, ref uint64_t data, input int size = m_default_xfer_size, ref int result = _null);
int res;
uint64_t aa[1], da[];
da= new[1];
aa[0] = addr;
readm(aa, da, size, res);
data = da[0];
endtask
virtual task write(uint64_t addr, uint64_t data, input int size = m_default_xfer_size, ref int result = _null);
uint64_t aa[1], da[1];
aa[0] = addr;
da[0] = data;
writem(aa, da, size, result);
endtask
endclass // CBusAccessor
class CSimUtils;
static function automatic u64_array_t pack(byte x[], int size, int big_endian = 1);
u64_array_t tmp;
int i, j;
int nwords, nbytes;
nwords = (x.size() + size - 1) / size;
tmp = new [nwords];
for(i=0;i<nwords;i++)
begin
uint64_t d;
d =0;
nbytes = (x.size() - i * nbytes > size ? size : x.size() - i*nbytes);
for(j=0;j<nbytes;j++)
begin
if(big_endian)
d = d | ((x[i*size+j] << (8*(size-1-j))));
else
d = d | ((x[i*size+j] << (8*j)));
end
tmp[i] = d;
end
return tmp;
endfunction // pack
static function automatic byte_array_t unpack(u64_array_t x, int entry_size, int size, int big_endian = 1);
byte_array_t tmp;
int i, n;
tmp = new[size];
n = 0;
i = 0;
while(n < size)
begin
tmp[n] = x[i] >> (8*(entry_size-1 - (n % entry_size)));
n++;
if(n % entry_size == 0)
i++;
end
return tmp;
endfunction // unpack
endclass // CSimUtils
static CSimUtils SimUtils;
`endif
\ No newline at end of file
`define ADDR_SPLL_CSR 6'h0
`define SPLL_CSR_N_REF_OFFSET 0
`define SPLL_CSR_N_REF 32'h0000003f
`define SPLL_CSR_N_OUT_OFFSET 8
`define SPLL_CSR_N_OUT 32'h00000700
`define ADDR_SPLL_OCCR 6'h4
`define SPLL_OCCR_OUT_EN_OFFSET 0
`define SPLL_OCCR_OUT_EN 32'h000000ff
`define SPLL_OCCR_AUX_LOCK_OFFSET 8
`define SPLL_OCCR_AUX_LOCK 32'h0000ff00
`define ADDR_SPLL_RCER 6'h8
`define ADDR_SPLL_PER_HPLL 6'hc
`define ADDR_SPLL_DAC_HPLL 6'h10
`define ADDR_SPLL_DAC_MAIN 6'h14
`define SPLL_DAC_MAIN_VALUE_OFFSET 0
`define SPLL_DAC_MAIN_VALUE 32'h0000ffff
`define SPLL_DAC_MAIN_DAC_SEL_OFFSET 16
`define SPLL_DAC_MAIN_DAC_SEL 32'h000f0000
`define ADDR_SPLL_DEGLITCH_THR 6'h18
`define ADDR_SPLL_EIC_IDR 6'h20
`define SPLL_EIC_IDR_TAG_OFFSET 0
`define SPLL_EIC_IDR_TAG 32'h00000001
`define ADDR_SPLL_EIC_IER 6'h24
`define SPLL_EIC_IER_TAG_OFFSET 0
`define SPLL_EIC_IER_TAG 32'h00000001
`define ADDR_SPLL_EIC_IMR 6'h28
`define SPLL_EIC_IMR_TAG_OFFSET 0
`define SPLL_EIC_IMR_TAG 32'h00000001
`define ADDR_SPLL_EIC_ISR 6'h2c
`define SPLL_EIC_ISR_TAG_OFFSET 0
`define SPLL_EIC_ISR_TAG 32'h00000001
`define ADDR_SPLL_TRR_R0 6'h30
`define SPLL_TRR_R0_VALUE_OFFSET 0
`define SPLL_TRR_R0_VALUE 32'h00ffffff
`define SPLL_TRR_R0_CHAN_ID_OFFSET 24
`define SPLL_TRR_R0_CHAN_ID 32'h7f000000
`define SPLL_TRR_R0_DISC_OFFSET 31
`define SPLL_TRR_R0_DISC 32'h80000000
`define ADDR_SPLL_TRR_CSR 6'h34
`define SPLL_TRR_CSR_EMPTY_OFFSET 17
`define SPLL_TRR_CSR_EMPTY 32'h00020000
`define ADDR_SPLL_CSR 8'h0
`define SPLL_CSR_UNUSED0_OFFSET 8
`define SPLL_CSR_UNUSED0 32'h00003f00
`define SPLL_CSR_N_REF_OFFSET 16
`define SPLL_CSR_N_REF 32'h003f0000
`define SPLL_CSR_N_OUT_OFFSET 24
`define SPLL_CSR_N_OUT 32'h07000000
`define SPLL_CSR_DBG_SUPPORTED_OFFSET 27
`define SPLL_CSR_DBG_SUPPORTED 32'h08000000
`define ADDR_SPLL_ECCR 8'h4
`define SPLL_ECCR_EXT_EN_OFFSET 0
`define SPLL_ECCR_EXT_EN 32'h00000001
`define SPLL_ECCR_EXT_SUPPORTED_OFFSET 1
`define SPLL_ECCR_EXT_SUPPORTED 32'h00000002
`define SPLL_ECCR_EXT_REF_LOCKED_OFFSET 2
`define SPLL_ECCR_EXT_REF_LOCKED 32'h00000004
`define SPLL_ECCR_EXT_REF_STOPPED_OFFSET 3
`define SPLL_ECCR_EXT_REF_STOPPED 32'h00000008
`define SPLL_ECCR_EXT_REF_PLLRST_OFFSET 31
`define SPLL_ECCR_EXT_REF_PLLRST 32'h80000000
`define ADDR_SPLL_AL_CR 8'h8
`define SPLL_AL_CR_VALID_OFFSET 0
`define SPLL_AL_CR_VALID 32'h000001ff
`define SPLL_AL_CR_REQUIRED_OFFSET 9
`define SPLL_AL_CR_REQUIRED 32'h0003fe00
`define ADDR_SPLL_AL_CREF 8'hc
`define ADDR_SPLL_AL_CIN 8'h10
`define ADDR_SPLL_FREQ_CSR 8'h14
`define SPLL_FREQ_CSR_FREQ_OFFSET 0
`define SPLL_FREQ_CSR_FREQ 32'h03ffffff
`define SPLL_FREQ_CSR_VALID_OFFSET 26
`define SPLL_FREQ_CSR_VALID 32'h04000000
`define SPLL_FREQ_CSR_CHAN_SEL_OFFSET 27
`define SPLL_FREQ_CSR_CHAN_SEL 32'hf8000000
`define ADDR_SPLL_F_REF 8'h18
`define SPLL_F_REF_FREQ_OFFSET 0
`define SPLL_F_REF_FREQ 32'h0fffffff
`define SPLL_F_REF_VALID_OFFSET 28
`define SPLL_F_REF_VALID 32'h10000000
`define ADDR_SPLL_F_EXT 8'h1c
`define SPLL_F_EXT_FREQ_OFFSET 0
`define SPLL_F_EXT_FREQ 32'h0fffffff
`define SPLL_F_EXT_VALID_OFFSET 28
`define SPLL_F_EXT_VALID 32'h10000000
`define ADDR_SPLL_OCCR 8'h20
`define SPLL_OCCR_OUT_EN_OFFSET 8
`define SPLL_OCCR_OUT_EN 32'h0000ff00
`define SPLL_OCCR_OUT_LOCK_OFFSET 16
`define SPLL_OCCR_OUT_LOCK 32'h00ff0000
`define ADDR_SPLL_RCER 8'h24
`define ADDR_SPLL_OCER 8'h28
`define ADDR_SPLL_DAC_HPLL 8'h40
`define ADDR_SPLL_DAC_MAIN 8'h44
`define SPLL_DAC_MAIN_VALUE_OFFSET 0
`define SPLL_DAC_MAIN_VALUE 32'h0000ffff
`define SPLL_DAC_MAIN_DAC_SEL_OFFSET 16
`define SPLL_DAC_MAIN_DAC_SEL 32'h000f0000
`define ADDR_SPLL_DEGLITCH_THR 8'h48
`define ADDR_SPLL_DFR_SPLL 8'h4c
`define SPLL_DFR_SPLL_VALUE_OFFSET 0
`define SPLL_DFR_SPLL_VALUE 32'h7fffffff
`define SPLL_DFR_SPLL_EOS_OFFSET 31
`define SPLL_DFR_SPLL_EOS 32'h80000000
`define ADDR_SPLL_EIC_IDR 8'h60
`define SPLL_EIC_IDR_TAG_OFFSET 0
`define SPLL_EIC_IDR_TAG 32'h00000001
`define ADDR_SPLL_EIC_IER 8'h64
`define SPLL_EIC_IER_TAG_OFFSET 0
`define SPLL_EIC_IER_TAG 32'h00000001
`define ADDR_SPLL_EIC_IMR 8'h68
`define SPLL_EIC_IMR_TAG_OFFSET 0
`define SPLL_EIC_IMR_TAG 32'h00000001
`define ADDR_SPLL_EIC_ISR 8'h6c
`define SPLL_EIC_ISR_TAG_OFFSET 0
`define SPLL_EIC_ISR_TAG 32'h00000001
`define ADDR_SPLL_DFR_HOST_R0 8'h70
`define SPLL_DFR_HOST_R0_VALUE_OFFSET 0
`define SPLL_DFR_HOST_R0_VALUE 32'hffffffff
`define ADDR_SPLL_DFR_HOST_R1 8'h74
`define SPLL_DFR_HOST_R1_SEQ_ID_OFFSET 0
`define SPLL_DFR_HOST_R1_SEQ_ID 32'h0000ffff
`define ADDR_SPLL_DFR_HOST_CSR 8'h78
`define SPLL_DFR_HOST_CSR_FULL_OFFSET 16
`define SPLL_DFR_HOST_CSR_FULL 32'h00010000
`define SPLL_DFR_HOST_CSR_EMPTY_OFFSET 17
`define SPLL_DFR_HOST_CSR_EMPTY 32'h00020000
`define SPLL_DFR_HOST_CSR_USEDW_OFFSET 0
`define SPLL_DFR_HOST_CSR_USEDW 32'h00001fff
`define ADDR_SPLL_TRR_R0 8'h7c
`define SPLL_TRR_R0_VALUE_OFFSET 0
`define SPLL_TRR_R0_VALUE 32'h00ffffff
`define SPLL_TRR_R0_CHAN_ID_OFFSET 24
`define SPLL_TRR_R0_CHAN_ID 32'h7f000000
`define SPLL_TRR_R0_DISC_OFFSET 31
`define SPLL_TRR_R0_DISC 32'h80000000
`define ADDR_SPLL_TRR_CSR 8'h80
`define SPLL_TRR_CSR_EMPTY_OFFSET 17
`define SPLL_TRR_CSR_EMPTY 32'h00020000
`timescale 1ps/1ps
// Clock/reset generator module for the TBI interface.
module tbi_clock_rst_gen
(
output clk_ref_o,
output clk_sys_o,
output phy_rbclk_o,
output rst_n_o);
parameter g_rbclk_period = 8010;
parameter g_refclk_period = 8000;
parameter g_sysclk_period = 15900;
reg refclk = 0, refclk2 = 0, rbclk = 0, rst_n = 0;
always #(g_rbclk_period/2) rbclk <= ~rbclk;
always #(g_refclk_period/2) refclk <= ~refclk;
always #(g_sysclk_period/2) refclk2 <= ~refclk2;
// always@(posedge refclk) refclk2 <= ~refclk2;
initial begin repeat(10) @(posedge refclk2); rst_n = 1; end
assign clk_ref_o = refclk;
assign clk_sys_o = refclk2;
assign phy_rbclk_o = rbclk;
assign rst_n_o = rst_n;
endmodule // tbi_clock_gen
`timescale 1ns/1ps
// Clock alignment FIFO for looping back the endpoint TX/RX path
module tbi_loopback_fifo
(
input tx_clk_i,
input rx_clk_i,
input [9:0] tx_data_i,
output reg [9:0] rx_data_o
);
parameter g_buf_size = 20000;
parameter g_error_prob = 0;
function automatic int probability_hit(int prob, int max_prob);
int rand_val;
rand_val = $random % (max_prob+1);
if(rand_val < 0) rand_val = -rand_val;
if(rand_val < prob)
return 1;
else
return 0;
endfunction // probability_hit
reg[9:0] buffer[100000];
int write_ptr, read_ptr, count;
initial begin
write_ptr = 0;
read_ptr = 0;
count = 0;
end
always@(posedge tx_clk_i) begin
buffer[write_ptr] <= tx_data_i;
count++;
write_ptr++;
end
always@(posedge rx_clk_i) begin
if(count == 0) begin
$display("loopback FIFO underrun!");
rx_data_o <= 0;
end else begin
if(probability_hit(g_error_prob, 1000))
rx_data_o <= 'hfff;
else
rx_data_o <= buffer[read_ptr];
read_ptr++;
count--;
end
end
endmodule
`ifndef __WB_FABRIC_DEFS_SVH
`define __WB_FABRIC_DEFS_SVH
const bit [2:0] WRF_STATUS = 3'b100;
const bit [2:0] WRF_DATA = 3'b000;
const bit [2:0] WRF_OOB = 3'b010;
const bit [2:0] WRF_USER = 3'b110;
const bit [3:0] WRF_OOB_TX_FID = 4'b0001;
const bit [3:0] WRF_OOB_RX_TIMESTAMP = 4'b0000;
`endif // `ifndef __WB_FABRIC_DEFS_SVH
`ifndef __WB_PACKET_SINK_SVH
`define __WB_PACKET_SINK_SVH
`include "simdrv_defs.svh"
`include "eth_packet.svh"
`include "if_wishbone_accessor.svh"
`include "wb_fabric_defs.svh"
class WBPacketSink extends EthPacketSink;
protected CWishboneAccessor m_acc;
function new(CWishboneAccessor acc);
m_acc = acc;
endfunction // new
function int poll();
return m_acc.poll();
endfunction // poll
function int permanent_stall_enable();
return m_acc.permanent_stall_enable();
endfunction
function int permanent_stall_disable();
return m_acc.permanent_stall_disable();
endfunction
protected task decode_status(uint64_t stat, ref EthPacket pkt);
if(stat & 'h2)
pkt.error = 1'b1;
else begin
pkt.has_smac = (stat & 'h4 ? 1'b1 : 1'b0);
pkt.has_crc = (stat & 'h8 ? 1'b1 : 1'b0);
pkt.pclass = (stat>>8) & 'hff;
end
endtask // decode_status
protected task decode_oob(uint64_t oob, int size, ref EthPacket pkt);
if(!size)
return;
else if(size == 2 && (oob >> 28) == WRF_OOB_TX_FID)
begin
// $display("GotTxOOB");
pkt.oob_type = TX_FID;
pkt.ts.frame_id = oob & 'hffff;
end
else if (size == 3 && (oob >> 46) == WRF_OOB_RX_TIMESTAMP)
begin
// $display("GotRXOOB");
end else begin
$error("Invalid OOB!");
$stop;
end
endtask // decode_oob
task recv(ref EthPacket pkt, ref int result = _null);
uint64_t oob = 0;
byte tmp[];
wb_cycle_t cyc;
int i, size = 0, n = 0, n_oob = 0;
int oob_size = 0;
pkt = new;
m_acc.get(cyc);
for(i=0;i<cyc.data.size(); i++)
if (cyc.data[i].a == WRF_DATA)
size = size + cyc.data[i].size;
tmp = new[size];
// $display("CDS %d size: %d\n", cyc.data.size(), size);
pkt.size = size;
for(i=0;i<cyc.data.size(); i++)
begin
wb_xfer_t xf = cyc.data[i];
case(xf.a)
WRF_STATUS:
begin
decode_status(xf.d, pkt);
if(pkt.error)
break;
end
WRF_DATA:
begin
if(xf.size == 1)
tmp[n++] = (xf.d & 'hff);
else if(xf.size == 2)begin
tmp[n++] = ((xf.d >> 8) & 'hff);
tmp[n++] = (xf.d & 'hff);
end
end
WRF_OOB:
begin
oob = (oob << 16) | xf.d;
oob_size ++;
end
endcase // case (xf.a)
end
pkt.deserialize(tmp);
if(pkt.error == 1'b0)
decode_oob(oob, oob_size, pkt);
endtask // recv
endclass // WBPacketSink
`endif
`ifndef __WB_PACKET_SOURCE_SVH
`define __WB_PACKET_SOURCE_SVH
`include "simdrv_defs.svh"
`include "eth_packet.svh"
`include "if_wishbone_accessor.svh"
`include "wb_fabric_defs.svh"
class WBPacketSource extends EthPacketSource;
protected CWishboneAccessor m_acc;
function new(CWishboneAccessor acc);
m_acc = acc;
endfunction // new
function bit[15:0] pack_status(ref EthPacket pkt, input bit error = 0);
bit [15:0] st;
st[0] = (pkt.is_hp ? 1'b1: 1'b0);
st[1] = 1'b0;
st[2] = (pkt.has_smac ? 1'b1: 1'b0);
st[3] = error;
st[15:8] = pkt.pclass; // FIXME: add packet classes
st[7:4]= 0;
return st;
endfunction // pack_status
task unpack_status(bit[15:0] status, ref EthPacket pkt);
endtask // unpack_status
typedef bit[15:0] oob_array16[];
function u64_array_t pack_oob(ref EthPacket pkt);
u64_array_t oob;
case(pkt.oob_type)
TX_FID: begin
oob = new[2];
oob[0] = {WRF_OOB_TX_FID, 12'b0};
oob[1] = pkt.ts.frame_id;
end
endcase // case (pkt.oob_type)
return oob;
endfunction // pack_oob
task send(ref EthPacket pkt, ref int result = _null);
byte pdata[]; // FIXME: dynamic allocation would be better...
u64_array_t pdata_p;
u64_array_t oob_p;
int i, len;
wb_cycle_t cyc;
wb_xfer_t xf;
cyc.ctype = PIPELINED;
cyc.rw = 1;
/* First, the status register */
xf.a = WRF_STATUS;
xf.d = pack_status(pkt);
xf.size = 2;
cyc.data.push_back(xf);
pkt.serialize(pdata);
pdata_p = SimUtils.pack(pdata, 2, 1);
len = pdata_p.size();
for(i=0; i < len; i++)
begin
xf.a = WRF_DATA;
if(i==len-1 && (pdata.size()&1))
begin
xf.size = 1;
xf.d = pdata_p[i] >> 8;
end else begin
xf.size = 2;
xf.d = pdata_p[i];
end
cyc.data.push_back(xf);
end
if(pkt.error)
begin
xf.a = WRF_STATUS;
xf.d = pack_status(pkt, 1);
xf.size = 2;
cyc.data.push_back(xf);
end else begin
// $display("WBPacketSource::send(): DataSize: %d\n", cyc.data.size());
oob_p = pack_oob(pkt);
for (i=0;i<oob_p.size(); i++)
begin
xf.a = WRF_OOB;
xf.d = oob_p[i] & 'hffff;
xf.size = 2;
cyc.data.push_back(xf);
end
end // else: !if(pkt.error)
m_acc.put(cyc);
m_acc.get(cyc);
result = cyc.result;
endtask // send
endclass // WBPacketSource
`endif
//
// Title : Software Wishbone master unit for testbenches
//
// File : wishbone_master_tb.v
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : Verilog 2001
//
// Default values of certain WB parameters.
`timescale 1ns/1ps
// Bus clock period
`ifndef WB_CLOCK_PERIOD
`define WB_CLOCK_PERIOD 16
`define WB_RESET_DELAY (3*`WB_CLOCK_PERIOD)
`endif
// Widths of wishbone address/data/byte select
`ifndef WB_DATA_BUS_WIDTH
`define WB_DATA_BUS_WIDTH 32
`endif
`ifndef WB_ADDRESS_BUS_WIDTH
`define WB_ADDRESS_BUS_WIDTH 32
`endif
`define WB_BWSEL_WIDTH ((`WB_DATA_BUS_WIDTH + 7) / 8)
module WB_TEST_MASTER (
`ifdef WB_USE_EXTERNAL_CLOCK
input clk_i,
input rst_n_i
`endif
);
// these signals make the WB bus, which can be accessed from outside the module
reg [`WB_ADDRESS_BUS_WIDTH - 1 : 0] wb_addr = 0;
reg [`WB_DATA_BUS_WIDTH - 1 : 0] wb_data_o = 0;
reg [`WB_BWSEL_WIDTH - 1 : 0] wb_bwsel = 0;
wire [`WB_DATA_BUS_WIDTH -1 : 0] wb_data_i;
wire wb_ack;
reg wb_cyc = 0;
reg wb_stb = 0;
reg wb_we = 0;
reg rst_reg = 0;
reg clk_reg = 1;
wire wb_clk, wb_rst;
reg wb_tb_verbose = 1;
reg wb_monitor_bus = 1;
time last_access_t = 0;
reg [`WB_DATA_BUS_WIDTH -1 : 0] dummy;
// ready signal. 1 indicates that WB_TEST unit is initialized and ready for commands
reg ready = 0;
`ifndef WB_USE_EXTERNAL_CLOCK
// generate the WB bus clock
always #(`WB_CLOCK_PERIOD/2) clk_reg <= ~clk_reg;
// generate the reset and ready signals
initial begin
#(`WB_RESET_DELAY) rst_reg <= 1;
#(`WB_CLOCK_PERIOD*2) ready <= 1;
end
assign wb_clk = clk_reg;
assign wb_rst = rst_reg;
`else // !`ifdef WB_USE_OWN_CLOCK
assign wb_clk = clk_i;
assign wb_rst = rst_n_i;
initial begin repeat(3) @(posedge wb_clk); ready = 1; end
`endif // !`ifdef WB_USE_OWN_CLOCK
// enables/disables displaying information about each read/write operation.
task verbose;
input onoff;
begin
wb_tb_verbose = onoff;
end
endtask // wb_verbose
task monitor_bus;
input onoff;
begin
wb_monitor_bus = onoff;
end
endtask // monitor_bus
task rw_generic;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [`WB_DATA_BUS_WIDTH - 1 : 0] data_i;
output [`WB_DATA_BUS_WIDTH - 1 : 0] data_o;
input rw;
input [3:0] size;
begin : rw_generic_main
if(wb_tb_verbose && rw)
$display("WB write %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
addr, data_i);
if($time != last_access_t) begin
@(posedge wb_clk);
end
wb_stb<=1;
wb_cyc<=1;
wb_addr <= {2'b00, addr[31:2]};
wb_we <= rw;
if(rw) begin
case(size)
4: begin wb_data_o<=data_i; wb_bwsel <= 4'b1111; end
2: begin
if(addr[1]) begin
wb_data_o[31:16] <= data_i[15:0];
wb_bwsel <= 4'b1100;
end else begin
wb_data_o[15:0] <= data_i[15:0];
wb_bwsel <= 4'b0011;
end
end
1: begin
case(addr[1:0])
0: begin wb_data_o[31:24] <= data_i[7:0]; wb_bwsel <= 4'b1000; end
1: begin wb_data_o[23:16] <= data_i[7:0]; wb_bwsel <= 4'b0100; end
2: begin wb_data_o[15:8] <= data_i[7:0]; wb_bwsel <= 4'b0010; end
3: begin wb_data_o[7:0] <= data_i[7:0]; wb_bwsel <= 4'b0001; end
endcase // case(addr[1:0])
end
endcase // case(size)
end // if (rw)
@(posedge wb_clk);
if(wb_ack == 0) begin
while(wb_ack == 0) begin @(posedge wb_clk); end
end
data_o = wb_data_i;
wb_cyc <= 0;
wb_we<=0;
wb_stb<=0;
if(wb_tb_verbose && !rw)
$display("WB read %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
addr, wb_data_i);
last_access_t = $time;
end
endtask // rw_generic
task write8;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [7 : 0] data_i;
begin
rw_generic(addr, data_i, dummy, 1, 1);
end
endtask // write8
task read8;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
output [7 : 0] data_o;
begin : read8_body
reg [`WB_DATA_BUS_WIDTH - 1 : 0] rval;
rw_generic(addr, 0, rval, 0, 1);
data_o = rval[7:0];
end
endtask // write8
task write32;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [31 : 0] data_i;
begin
rw_generic(addr, data_i, dummy, 1, 4);
end
endtask // write32
task read32;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
output [31 : 0] data_o;
begin : read32_body
reg [`WB_DATA_BUS_WIDTH - 1 : 0] rval;
rw_generic(addr, 0, rval, 0, 4);
data_o = rval[31:0];
end
endtask // write32
// bus monitor
always@(posedge wb_clk) begin
if(wb_monitor_bus && wb_cyc && wb_stb && wb_ack)begin
if(wb_we) $display("ACK-Write: addr %x wdata %x bwsel %b", wb_addr, wb_data_o, wb_bwsel);
else $display("ACK-Read: addr %x rdata %x", wb_addr, wb_data_i);
end
end
endmodule
\ No newline at end of file
`define ADDR_SYSC_RSTR 5'h0
`define SYSC_RSTR_TRIG_OFFSET 0
`define SYSC_RSTR_TRIG 32'h0fffffff
`define SYSC_RSTR_RST_OFFSET 28
`define SYSC_RSTR_RST 32'h10000000
`define ADDR_SYSC_GPSR 5'h4
`define SYSC_GPSR_LED_STAT_OFFSET 0
`define SYSC_GPSR_LED_STAT 32'h00000001
`define SYSC_GPSR_LED_LINK_OFFSET 1
`define SYSC_GPSR_LED_LINK 32'h00000002
`define SYSC_GPSR_FMC_SCL_OFFSET 2
`define SYSC_GPSR_FMC_SCL 32'h00000004
`define SYSC_GPSR_FMC_SDA_OFFSET 3
`define SYSC_GPSR_FMC_SDA 32'h00000008
`define SYSC_GPSR_NET_RST_OFFSET 4
`define SYSC_GPSR_NET_RST 32'h00000010
`define SYSC_GPSR_BTN1_OFFSET 5
`define SYSC_GPSR_BTN1 32'h00000020
`define SYSC_GPSR_BTN2_OFFSET 6
`define SYSC_GPSR_BTN2 32'h00000040
`define SYSC_GPSR_SFP_DET_OFFSET 7
`define SYSC_GPSR_SFP_DET 32'h00000080
`define SYSC_GPSR_SFP_SCL_OFFSET 8
`define SYSC_GPSR_SFP_SCL 32'h00000100
`define SYSC_GPSR_SFP_SDA_OFFSET 9
`define SYSC_GPSR_SFP_SDA 32'h00000200
`define SYSC_GPSR_SPI_SCLK_OFFSET 10
`define SYSC_GPSR_SPI_SCLK 32'h00000400
`define SYSC_GPSR_SPI_NCS_OFFSET 11
`define SYSC_GPSR_SPI_NCS 32'h00000800
`define SYSC_GPSR_SPI_MOSI_OFFSET 12
`define SYSC_GPSR_SPI_MOSI 32'h00001000
`define SYSC_GPSR_SPI_MISO_OFFSET 13
`define SYSC_GPSR_SPI_MISO 32'h00002000
`define ADDR_SYSC_GPCR 5'h8
`define SYSC_GPCR_LED_STAT_OFFSET 0
`define SYSC_GPCR_LED_STAT 32'h00000001
`define SYSC_GPCR_LED_LINK_OFFSET 1
`define SYSC_GPCR_LED_LINK 32'h00000002
`define SYSC_GPCR_FMC_SCL_OFFSET 2
`define SYSC_GPCR_FMC_SCL 32'h00000004
`define SYSC_GPCR_FMC_SDA_OFFSET 3
`define SYSC_GPCR_FMC_SDA 32'h00000008
`define SYSC_GPCR_SFP_SCL_OFFSET 8
`define SYSC_GPCR_SFP_SCL 32'h00000100
`define SYSC_GPCR_SFP_SDA_OFFSET 9
`define SYSC_GPCR_SFP_SDA 32'h00000200
`define SYSC_GPCR_SPI_SCLK_OFFSET 10
`define SYSC_GPCR_SPI_SCLK 32'h00000400
`define SYSC_GPCR_SPI_CS_OFFSET 11
`define SYSC_GPCR_SPI_CS 32'h00000800
`define SYSC_GPCR_SPI_MOSI_OFFSET 12
`define SYSC_GPCR_SPI_MOSI 32'h00001000
`define ADDR_SYSC_HWFR 5'hc
`define SYSC_HWFR_MEMSIZE_OFFSET 0
`define SYSC_HWFR_MEMSIZE 32'h0000000f
`define ADDR_SYSC_TCR 5'h10
`define SYSC_TCR_TDIV_OFFSET 0
`define SYSC_TCR_TDIV 32'h00000fff
`define SYSC_TCR_ENABLE_OFFSET 31
`define SYSC_TCR_ENABLE 32'h80000000
`define ADDR_SYSC_TVR 5'h14
action = "simulation" action = "simulation"
sim_tool = "modelsim" sim_tool = "modelsim"
top_module = "main" top_module = "main"
target = "xilinx"
syn_device = "xc6slx45t"
vcom_opt = "-2008 -mixedsvvh l" vcom_opt = "-2008 -mixedsvvh l"
vlog_opt = "+incdir+../../ip_cores/masterfip-gw/testbench/top_mt +incdir+../../sim" vlog_opt = "+incdir+../../ip_cores/masterfip-gw/testbench/top_mt +incdir+../../sim"
...@@ -10,7 +12,8 @@ sim_pre_cmd = "vlib ../fake_proasic3; vmap proasic3 ../fake_proasic3" ...@@ -10,7 +12,8 @@ sim_pre_cmd = "vlib ../fake_proasic3; vmap proasic3 ../fake_proasic3"
files = ["sim_main.sv", "ram4k9.v" ] files = ["sim_main.sv", "ram4k9.v" ]
include_dirs = [ "../../sim", "../../sim/include", "../../sim/include/wb" ] include_dirs = [ "../../sim", "../../sim/include",
"../../ip_cores/general-cores/sim" ]
modules = { modules = {
"local" : ["../../sim/fcm2", "../../rtl", "../../top/spec_test", "local" : ["../../sim/fcm2", "../../rtl", "../../top/spec_test",
......
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