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;
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
// Fabric TAP emulator example.
// usage: (as root)
// tunctl -t tap0
// ifconfig tap0 192.168.100.100
// arping -I tap0 192.168.100.101
// you should see some ARP requests coming
`timescale 1ns / 1ps
`include "fabric_emu.sv"
`include "fabric_emu_tap.sv"
module main;
const int c_clock_period = 8;
reg clk = 0;
reg rst_n = 0;
`WRF_WIRES(from_tap); // Data coming from tap0 interface
`WRF_WIRES(to_tap); // Data going to tap0 interface
// generate clock and reset signals
always #(c_clock_period/2) clk <= ~clk;
initial begin
repeat(3) @(posedge clk);
rst_n = 1;
end
// Two fabric emulators talking to each other
fabric_emu_tap U_tap
(
.clk_sys_i(clk),
.rst_n_i(rst_n),
`WRF_CONNECT_SOURCE(rx, from_tap), // connect fabric source/sinks
`WRF_CONNECT_SINK(tx, to_tap)
);
fabric_emu U_emu
(
.clk_i(clk),
.rst_n_i(rst_n),
`WRF_CONNECT_SOURCE(rx, to_tap),
`WRF_CONNECT_SINK(tx, from_tap)
);
// Check if there's anything received by the TAP emulator
always @(posedge clk) if (U_emu.poll())
begin
ether_frame_t frame;
$display("TAP Emulator received a frame!");
U_emu.receive(frame);
dump_frame_header("EmuB RX: ", frame);
frame.hdr.src = 'h010203040506; // modify the MAC address and send the frame back to tap interface
U_emu.send(frame.hdr, frame.payload, frame.size);
end
endmodule // main
/*
White Rabbit endpoint fabric interface BFM/emulator
*/
`include "fabric_emu_defs.sv"
`include "fabric_emu_funcs.sv"
module fabric_emu
(
// fabric clock & reset
input clk_i,
input rst_n_i,
//////////////////////////////////////////////////////////////////////////////
// Fabric output (source)
//////////////////////////////////////////////////////////////////////////////
`WRF_FULL_PORTS_SOURCE(rx),
//////////////////////////////////////////////////////////////////////////////
// Fabric input (sink)
//////////////////////////////////////////////////////////////////////////////
`WRF_FULL_PORTS_SINK(tx),
/////////////////////////////////////////////////////////////////////////
// Endpoint TXTSU emulation. See wrsw_endpoint.vhd for signal details ///
/////////////////////////////////////////////////////////////////////////
input [4:0] txtsu_port_id_i,
input [15:0] txtsu_fid_i,
input [31:0] txtsu_tsval_i,
input txtsu_valid_i,
output txtsu_ack_o
);
// max. number of packet in TX/RX queues
parameter g_QUEUE_SIZE = 2048;
// packet queues holding TXed and RXed packets
CPacketQueue tx_queue, rx_queue;
typedef struct {
bit sim_tx_underrun;
bit sim_tx_abort;
bit sim_rx_abort;
bit sim_tx_error;
bit sim_rx_error;
bit sim_rx_throttle;
bit sim_tx_throttle;
bit sim_random_rx_aborts;
int tx_underrun_delay;
int tx_abort_delay;
int rx_abort_delay;
int tx_error_delay;
int rx_error_delay;
int rx_throttle_prob; // throttle event probability (0 = never, 100 = always - stalled WRF)
int tx_throttle_prob;
int random_rx_abort_prob;
} _settings_t ;
_settings_t SIM;
reg txtsu_ack_int;
int rx_gen_oob = 1;
int ready = 0;
// output regs
reg [15:0] irx_data_o;
reg [4:0] irx_ctrl_o;
reg irx_bytesel_o;
reg irx_sof_p1_o;
reg irx_eof_p1_o;
reg irx_valid_o;
reg irx_rerror_p1_o;
reg irx_idle_o;
reg irx_tabort_p1_o;
reg itx_dreq_o;
reg itx_terror_p1_o;
reg itx_rabort_p1_o;
assign rx_data_o = irx_data_o;
assign rx_ctrl_o = irx_ctrl_o;
assign rx_bytesel_o = irx_bytesel_o;
assign rx_sof_p1_o = irx_sof_p1_o;
assign rx_eof_p1_o = irx_eof_p1_o;
assign rx_valid_o = irx_valid_o;
assign rx_rerror_p1_o = irx_rerror_p1_o;
assign rx_idle_o = irx_idle_o;
assign rx_tabort_p1_o = irx_tabort_p1_o;
assign tx_dreq_o = itx_dreq_o;
assign tx_terror_p1_o = itx_terror_p1_o;
assign tx_rabort_p1_o = itx_rabort_p1_o;
// monitor the reset line and initialize the fabric I/F when reset is active
always@(posedge clk_i)
if(!rst_n_i) begin
ready = 0;
// reset WRF source signals
irx_data_o <= 16'hxxxx;
irx_ctrl_o <= 4'hx;
irx_bytesel_o <= 1'bx;
irx_sof_p1_o <= 0;
irx_eof_p1_o <= 0;
irx_valid_o <= 0;
irx_rerror_p1_o <= 0;
irx_tabort_p1_o <= 0;
// reset WRF sink signals
itx_dreq_o <= 1;
itx_terror_p1_o <= 0;
itx_rabort_p1_o <= 0;
tx_queue = new (g_QUEUE_SIZE);
rx_queue = new (g_QUEUE_SIZE);
txtsu_ack_int <= 0;
wait_clk();
wait_clk();
ready = 1;
end
// waits for 1 fabric clock cycle
task wait_clk;
@(posedge clk_i);
endtask // wait_clk
// returns 1 with probability (prob/max_prob)
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
// enables/disables RX fabric (data source) flow throttling. prob parameter defines the probability (0-100)
// of throttle events
task simulate_rx_throttling(input enable, int prob);
SIM.sim_rx_throttle = enable;
SIM.rx_throttle_prob = prob;
endtask // simulate_tx_throttling
// the same for TX fabric (data sink)
task simulate_tx_throttling(input enable, int prob);
SIM.sim_tx_throttle = enable;
SIM.tx_throttle_prob = prob;
endtask // simulate_tx_throttling
// enables TX fabric source underrun simulation. When enabled, the fabric emulator will stop
// transmitting the data after un_delay transmitted, causing an underrun error in the endopoint.
task simulate_tx_underrun(input enable, input [31:0] un_delay);
SIM.sim_tx_underrun = enable;
SIM.tx_underrun_delay = un_delay;
endtask // simulate_tx_underrun
// Simulates an abort on data source after delay outputted words
task simulate_rx_abort(input enable, input [31:0] delay);
SIM.sim_rx_abort = enable;
SIM.rx_abort_delay = delay;
endtask // simulate_rx_abort
task simulate_random_rx_aborts(input enable, int prob);
SIM.sim_random_rx_aborts = enable;
SIM.random_rx_abort_prob = prob;
endtask
task simulate_tx_abort(input enable, input[31:0] delay);
SIM.sim_tx_abort = enable;
SIM.tx_abort_delay = delay;
endtask
task simulate_rx_error(input enable, input [31:0] delay);
SIM.sim_rx_error = enable;
SIM.rx_error_delay = delay;
endtask
task simulate_tx_error(input enable, input[31:0] delay);
SIM.sim_tx_error = enable;
SIM.tx_error_delay = delay;
endtask
// low-level packet send function: spits out tot_len data_vec[] and ctrl_vec[] values onto the WRF, simulating various error/abort/throttling conditions. Do not call directly.
task send_fabric(input [15:0] data_vec[],
input [3:0] ctrl_vec[],
input int odd_len,
input int tot_len,
input int single_idx,
output int error);
int i;
int rand_val;
i = 0;
error = 0;
// wait untile the remote side wants some data from us
while(!rx_dreq_i) wait_clk();
// generate a single-cycle pulse on SOF_P1
irx_valid_o <= 0;
irx_sof_p1_o <= 1;
wait_clk();
irx_sof_p1_o <= 0;
while(i<tot_len) begin
// simulate TX abort condition
if(SIM.sim_tx_abort && i == SIM.tx_abort_delay) begin
irx_valid_o <= 0;
irx_tabort_p1_o <= 1;
wait_clk();
irx_tabort_p1_o <= 0;
wait_clk();
return;
end
// simulate TX (source-orginating) error
if(SIM.sim_tx_error && i == SIM.tx_error_delay) begin
irx_rerror_p1_o <= 1;
wait_clk();
irx_valid_o <= 0;
irx_rerror_p1_o <= 0;
wait_clk();
return;
end
// packet sink requested transfer abort
if(rx_rabort_p1_i) begin
irx_valid_o <= 0;
irx_sof_p1_o <= 0;
irx_eof_p1_o <= 0;
irx_tabort_p1_o <= 0;
error = 1;
return;
end
// simulate TX buffer underrun
if(!rx_dreq_i || (SIM.sim_tx_underrun && (i >= SIM.tx_underrun_delay))) begin
wait_clk();
continue;
// simulate TX flow throttling
end else if(SIM.sim_tx_throttle && probability_hit(SIM.tx_throttle_prob, 100)) begin
irx_valid_o <= 0;
wait_clk();
continue;
// no errors and nothing to mimick? just send the frame...
end else begin
irx_valid_o <= 1;
irx_data_o <= data_vec[i];
irx_ctrl_o <= ctrl_vec[i];
irx_bytesel_o <= (single_idx == i && odd_len);
if(i == tot_len -1) begin
irx_eof_p1_o <= 1;
wait_clk();
irx_valid_o <= 0;
irx_eof_p1_o <= 0;
end
i++;
end
wait_clk();
irx_valid_o <= 0;
end // while (i<tot_len)
/* -----\/----- EXCLUDED -----\/-----
while(rx_dreq_i) begin
if(irx_rerror_p1_i) begin
error = 1;
$display("fabric_emu::send(): RX error during gap");
irx_valid_o <= 0;
irx_sof_p1_o <= 0;
irx_eof_p1_o <= 0;
irx_tabort_p1_o <= 0;
return;
end
wait_clk();
end
-----/\----- EXCLUDED -----/\----- */
endtask // _send_fabric
// Main send function. inputs a frame with ethernet header hdr and a payload (without FCS)
// of length "length"
task send(input ether_header_t hdr, input int payload[], input int length);
reg [`c_wrsw_ctrl_size - 1 : 0] ctrl_vec[0:2000];
reg [15:0] data_vec[0:2000];
reg [31:0] fcs_val;
int i;
int tot_len;
int odd_len;
int single_idx;
int error;
CCRC32 crc_gen;
ether_frame_t frame;
if(!ready) begin
$error("Attempt to call fabric_emu::send() when the emulator is being reset");
return;
end
// $display("Endpoint::send %s [%d bytes]", format_ether_header(hdr), length);
ctrl_vec[0] = `c_wrsw_ctrl_dst_mac; data_vec [0] = hdr.dst[47:32];
ctrl_vec[1] = `c_wrsw_ctrl_dst_mac; data_vec [1] = hdr.dst[31:16];
ctrl_vec[2] = `c_wrsw_ctrl_dst_mac; data_vec [2] = hdr.dst[15:0];
if(!hdr.no_mac) begin
ctrl_vec[3] = `c_wrsw_ctrl_src_mac; data_vec [3] = hdr.src[47:32];
ctrl_vec[4] = `c_wrsw_ctrl_src_mac; data_vec [4] = hdr.src[31:16];
ctrl_vec[5] = `c_wrsw_ctrl_src_mac; data_vec [5] = hdr.src[15:0];
end else begin
ctrl_vec[3] = `c_wrsw_ctrl_none; data_vec [3] = 0;
ctrl_vec[4] = `c_wrsw_ctrl_none; data_vec [4] = 0;
ctrl_vec[5] = `c_wrsw_ctrl_none; data_vec [5] = 0;
end
if(hdr.is_802_1q) begin
ctrl_vec[6] = `c_wrsw_ctrl_none; data_vec[6] = 'h8100;
ctrl_vec[7] = `c_wrsw_ctrl_ethertype; data_vec[7] = hdr.ethertype;
ctrl_vec[8] = `c_wrsw_ctrl_vid_prio; data_vec[8] = hdr.vid | (hdr.prio << 13);
tot_len = 9;
end else begin
ctrl_vec[6] = `c_wrsw_ctrl_ethertype; data_vec[6] = hdr.ethertype;
tot_len = 7;
end
for(int i = 0; i<(length+1) / 2; i++)
begin
data_vec[tot_len + i] = (payload[i*2] << 8) | payload[i*2+1];
// $display("DV: %d=%x", tot_len+i, data_vec[tot_len+i]);
ctrl_vec[tot_len + i] = `c_wrsw_ctrl_payload;
end
tot_len = tot_len + (length + 1) / 2;
odd_len = (length & 1);
single_idx = tot_len-1;
crc_gen = new;
for(int i = 0; i< tot_len; i++)
crc_gen.update(data_vec[i], (i==single_idx && odd_len ? 1 : 0));
fcs_val = crc_gen.get();
// insert the OOB (if applicable)
if(hdr.oob_type == `OOB_TYPE_TXTS) begin
if(hdr.oob_fid == 0)
hdr.oob_fid = $random;
data_vec[tot_len] = hdr.oob_fid;
ctrl_vec[tot_len] = `c_wrsw_ctrl_tx_oob;
tot_len ++;
end else if (hdr.oob_type == `OOB_TYPE_RXTS) begin
bit[47:0] oob_data;
oob_data = 0;
oob_data[32+4:32] = hdr.port_id;
oob_data[31:28] = hdr.timestamp_f;
oob_data[27:0] = hdr.timestamp_r;
data_vec[tot_len] = oob_data[47:32]; ctrl_vec[tot_len] = `c_wrsw_ctrl_rx_oob; tot_len++;
data_vec[tot_len] = oob_data[31:16]; ctrl_vec[tot_len] = `c_wrsw_ctrl_rx_oob; tot_len++;
data_vec[tot_len] = oob_data[16:0]; ctrl_vec[tot_len] = `c_wrsw_ctrl_rx_oob; tot_len++;
end
frame.error = 0;
frame.hdr = hdr;
frame.hdr.has_timestamp = 0;
frame.fcs = fcs_val;
for(i=0;i<length;i++)
frame.payload[i] = payload[i];
frame.size = length;
// generate the frame on the TX fabric
send_fabric(data_vec, ctrl_vec, odd_len, tot_len, single_idx, error);
frame.error = error;
tx_queue.push(frame);
endtask // send
task automatic send_raw(byte raw_data[]);
reg [`c_wrsw_ctrl_size - 1 : 0] ctrl_vec[0:2000];
reg [15:0] data_vec[0:2000];
int error, i;
for(i=0; i<(raw_data.size()+1) / 2; i++)
begin
ctrl_vec[i] = `c_wrsw_ctrl_payload;
data_vec[i][15:8] = raw_data[2*i];
data_vec[i][7:0] = raw_data[2*i+1];
end
send_fabric(data_vec, ctrl_vec, ( raw_data.size() % 2) ? 1 : 0, i, i-1, error);
endtask // send_raw
// Handles WRF packet sink input
task automatic rx_process();
reg [`c_wrsw_ctrl_size - 1 : 0] ctrl_vec[0:2000];
reg [15:0] data_vec[0:2000];
int bytesel_saved;
ether_frame_t frame;
int error;
int rand_val;
int abort_me;
int abort_offset;
int n;
int i, data_start, tot_len, payload_len;
i = 0;
bytesel_saved = 0;
wait_clk();
abort_me = probability_hit(SIM.random_rx_abort_prob, 100) && SIM.sim_random_rx_aborts;
// $display("RXprocess", $time);
abort_offset = 10;
/* $display("RXThrottle %d prob %d", SIM.sim_rx_throttle , probability_hit(SIM.rx_throttle_prob);*/
while(1) begin
// simulate the flow throttling
if(SIM.sim_rx_throttle && probability_hit(SIM.rx_throttle_prob, 100))
itx_dreq_o <= 0;
else
itx_dreq_o <= 1;
if(abort_me && i>=abort_offset) // simulate the RX abort
begin
$display("simulate random RX abort");
itx_rabort_p1_o <= 1;
wait_clk();
itx_rabort_p1_o <= 0;
return;
end
if(SIM.sim_rx_abort && i >= SIM.rx_abort_delay)
begin
itx_rabort_p1_o <= 1;
wait_clk();
itx_rabort_p1_o <= 0;
return;
end
if(SIM.sim_rx_error && i >= SIM.rx_error_delay)
begin
itx_terror_p1_o <= 1;
wait_clk();
itx_terror_p1_o <= 0;
return;
end
// got a valid data word? Put it in the buffer
if(tx_valid_i) begin
ctrl_vec[i] = tx_ctrl_i;
data_vec[i] = tx_data_i;
if(tx_bytesel_i && tx_ctrl_i == `c_wrsw_ctrl_payload) bytesel_saved = 1;
i++;
end
if(tx_eof_p1_i || tx_rerror_p1_i) break;
wait_clk();
end
error = tx_rerror_p1_i;
tot_len = i;
n =0;
frame.raw_data = new[10000];
for (i=0; i<tot_len && ctrl_vec[i] != `c_wrsw_ctrl_rx_oob; i++)
begin
frame.raw_data[2*i] = data_vec[i] >> 8;
frame.raw_data[2*i + 1] = data_vec[i] & 'hff;
n =n+2;
end
if(bytesel_saved)
n--;
frame.raw_data = new[n](frame.raw_data);
frame.hdr.dst[47:32] = data_vec[0];
frame.hdr.dst[31:16] = data_vec[1];
frame.hdr.dst[15:0] = data_vec[2];
frame.hdr.src[47:32] = data_vec[3];
frame.hdr.src[31:16] = data_vec[4];
frame.hdr.src[15:0] = data_vec[5];
if(data_vec[6] == 16'h8100) begin // 802.1q header
frame.hdr.is_802_1q = 1;
frame.hdr.ethertype = data_vec[7];
frame.hdr.vid = data_vec[8] & 16'h0fff;
frame.hdr.prio = (data_vec[8] >> 13);
data_start = 9;
end else begin
frame.hdr.is_802_1q = 0;
frame.hdr.ethertype = data_vec[6];
data_start = 7;
end
payload_len = 0;
for(i=0; ctrl_vec[data_start + i] == `c_wrsw_ctrl_payload && i < tot_len; i++)
begin
frame.payload[2*i] = data_vec[data_start + i][15:8];
frame.payload[2*i+1] = data_vec[data_start + i][7:0];
payload_len = payload_len + 2;
end
if(bytesel_saved)
payload_len --;
if(tot_len > i && ctrl_vec[data_start + i] == `c_wrsw_ctrl_rx_oob) begin
frame.hdr.has_timestamp = 1;
frame.hdr.port_id = data_vec[data_start+i][15:11];
frame.hdr.timestamp_r = {data_vec[data_start+i+1][11:0],data_vec[data_start+i+2]} ;
frame.hdr.timestamp_f = data_vec[data_start+i+1][15:12];
end
frame.size = payload_len;
frame.error = error;
// dump_frame_header("RX: ", frame);
rx_queue.push(frame);
endtask // rx_process
task emulate_txtsu();
if(txtsu_valid_i && !txtsu_ack_int) begin
if(tx_queue.update_tx_timestamp( txtsu_fid_i, txtsu_port_id_i,txtsu_tsval_i))
// $display("emulate_txtsu(): got TX timestamp for FID: 0x%04x", txtsu_fid_i);
wait_clk();
txtsu_ack_int <= 1;
end else
txtsu_ack_int <= 0;
endtask // sim_txtsu
initial forever begin
itx_dreq_o <= 1;
wait_clk();
if(tx_sof_p1_i) rx_process();
end
initial forever begin
wait_clk();
if(txtsu_valid_i) emulate_txtsu();
end
assign txtsu_ack_o = txtsu_ack_int;
function int poll();
if(!ready) return 0;
return rx_queue.get_count();
endfunction // UNMATCHED !!
task automatic receive(output ether_frame_t fra);
rx_queue.pop(fra);
endtask
endmodule
\ No newline at end of file
`ifndef __FABRIC_EMU_DEFS_SV
`define __FABRIC_EMU_DEFS_SV
/* Ethernet frame header extended with WR-compliant OOB signalling */
typedef struct {
bit no_mac; // when 1, there's no valid source MAC present in the frame header and the SRC MAC field must be filled by the endpoint
bit [47:0] dst; // DST MAC
bit [47:0] src; // SRC MAC
bit [15:0] ethertype;
bit is_802_1q; // when 1, the frame has 802.1q header
bit [11:0] vid; // VLAN ID
bit [2:0] prio; // PCP priority tag
int oob_type; // OOB TYPE: OOB_TYPE_TXTS = TX frame ID (for TX timestamping), OOB_TYPE_RXTS = RX timestamp
bit[15:0] oob_fid; //
bit [27:0] timestamp_r;
bit [3:0] timestamp_f;
bit [4:0] port_id;
bit has_timestamp; // when 1, the TX/RX timestamp is valid
} ether_header_t;
/* Full ethernet frame */
typedef struct {
ether_header_t hdr;
int size;
bit[7:0] payload[$];
bit[31:0] fcs;
bit error;
bit has_payload;
bit has_raw;
byte raw_data[];
} ether_frame_t;
/* WR-compliant TX frame timestamp */
typedef struct {
bit[15:0] fid;
bit [4:0] pid;
bit [27:0] timestamp_r;
bit [3:0] timestamp_f;
} tx_timestamp_t;
`timescale 1ns/1ps
/* Bus widths definition, taken from global_defs.vhd */
`define c_wrsw_ctrl_size 4
`define c_wrsw_oob_frame_id_size 16
`define c_wrsw_timestamp_size_r 28
`define c_wrsw_timestamp_size_f 4
`define c_wrsw_mac_addr_width 48
`define c_wrsw_vid_width 12
`define c_wrsw_prio_width 3
/* ctrl bus codes */
`define c_wrsw_ctrl_none 4'h0
`define c_wrsw_ctrl_dst_mac 4'h1
`define c_wrsw_ctrl_src_mac 4'h2
`define c_wrsw_ctrl_ethertype 4'h3
`define c_wrsw_ctrl_vid_prio 4'h4
`define c_wrsw_ctrl_tx_oob 4'h5
`define c_wrsw_ctrl_rx_oob 4'h6
`define c_wrsw_ctrl_payload 4'h7
/* OOB types */
`define OOB_TYPE_TXTS 1
`define OOB_TYPE_RXTS 2
`define QUEUE_MAX_FRAMES 128
//
// WhiteRabbit Fabric Interface (WRF) Macros
//
// declares basic fabric interface (only the mandatory singals)
// sink port list in a verilog/SV module, prefixed with "prefix":
// for example `WRF_PORTS_SINK(test) will generate the following signals
// test_sof_p1_i, test_eof_p1_i, test_data_i, etc....
`define WRF_PORTS_SINK(prefix) \
input [15:0] prefix``_data_i,\
input [3:0] prefix``_ctrl_i,\
input prefix``_bytesel_i,\
input prefix``_sof_p1_i,\
input prefix``_eof_p1_i,\
output prefix``_dreq_o,\
input prefix``_valid_i,\
input prefix``_rerror_p1_i
// same as above but with all WRF signals
`define WRF_FULL_PORTS_SINK(prefix) \
`WRF_PORTS_SINK(prefix),\
output prefix``_terror_p1_o,\
input prefix``_idle_i,\
input prefix``_tabort_p1_i,\
output prefix``_rabort_p1_o
// like the macro above, but for fabric source, mandatory signals only
`define WRF_PORTS_SOURCE(prefix) \
output [15:0] prefix``_data_o,\
output [3:0] prefix``_ctrl_o,\
output prefix``_bytesel_o,\
output prefix``_sof_p1_o,\
output prefix``_eof_p1_o,\
input prefix``_dreq_i,\
output prefix``_valid_o,\
output prefix``_rerror_p1_o
// same as above, but for full WRF
`define WRF_FULL_PORTS_SOURCE(prefix) \
`WRF_PORTS_SOURCE(prefix), \
input prefix``_terror_p1_i,\
output prefix``_idle_o,\
output prefix``_tabort_p1_o,\
input prefix``_rabort_p1_i
// declares a list of verilog/SV wires for a given fabric name
`define WRF_WIRES(prefix) \
wire [15:0] prefix``_data;\
wire [3 :0] prefix``_ctrl;\
wire prefix``_bytesel;\
wire prefix``_dreq;\
wire prefix``_valid;\
wire prefix``_sof_p1;\
wire prefix``_eof_p1;\
wire prefix``_rerror_p1;
// same as above, but for full WRF
`define WRF_FULL_WIRES(prefix) \
`WRF_WIRES(prefix)\
wire prefix``_terror_p1;\
wire prefix``_idle;\
wire prefix``_tabort_p1;\
wire prefix``_rabort_p1;
// Connects fabric sink ports prefixed with port_pfx to fabric wires prefixed with fab_pfx
`define _WRF_CONNECT_MANDATORY_SINK(port_pfx, fab_pfx) \
.port_pfx``_data_i(fab_pfx``_data),\
.port_pfx``_ctrl_i(fab_pfx``_ctrl),\
.port_pfx``_bytesel_i(fab_pfx``_bytesel),\
.port_pfx``_dreq_o(fab_pfx``_dreq),\
.port_pfx``_valid_i(fab_pfx``_valid),\
.port_pfx``_sof_p1_i(fab_pfx``_sof_p1),\
.port_pfx``_eof_p1_i(fab_pfx``_eof_p1),\
.port_pfx``_rerror_p1_i(fab_pfx``_rerror_p1)
// full fabric I/F version
`define WRF_FULL_CONNECT_SINK(port_pfx, fab_pfx) \
`_WRF_CONNECT_MANDATORY_SINK(port_pfx, fab_pfx), \
.port_pfx``_terror_p1_o(fab_pfx``_terror_p1),\
.port_pfx``_tabort_p1_i(fab_pfx``_tabort_p1),\
.port_pfx``_rabort_p1_o(fab_pfx``_rabort_p1),\
.port_pfx``_idle_i(fab_pfx``_idle)
// Connects fabric sink ports prefixed with port_pfx to fabric wires prefixed with fab_pfx
`define WRF_CONNECT_SINK(port_pfx, fab_pfx) \
`_WRF_CONNECT_MANDATORY_SINK(port_pfx, fab_pfx), \
.port_pfx``_terror_p1_o(),\
.port_pfx``_tabort_p1_i(1'b0),\
.port_pfx``_rabort_p1_o(),\
.port_pfx``_idle_i(1'b0)
`define _WRF_CONNECT_MANDATORY_SOURCE(port_pfx, fab_pfx) \
.port_pfx``_data_o(fab_pfx``_data),\
.port_pfx``_ctrl_o(fab_pfx``_ctrl),\
.port_pfx``_bytesel_o(fab_pfx``_bytesel),\
.port_pfx``_dreq_i(fab_pfx``_dreq),\
.port_pfx``_valid_o(fab_pfx``_valid),\
.port_pfx``_sof_p1_o(fab_pfx``_sof_p1),\
.port_pfx``_eof_p1_o(fab_pfx``_eof_p1),\
.port_pfx``_rerror_p1_o(fab_pfx``_rerror_p1)
// same as above, but for source ports, full WRF version
`define WRF_FULL_CONNECT_SOURCE(port_pfx, fab_pfx) \
`_WRF_CONNECT_MANDATORY_SOURCE(port_pfx, fab_pfx),\
.port_pfx``_terror_p1_i(fab_pfx``_terror_p1),\
.port_pfx``_tabort_p1_o(fab_pfx``_tabort_p1),\
.port_pfx``_rabort_p1_i(fab_pfx``_rabort_p1),\
.port_pfx``_idle_o(fab_pfx``_idle)
// same as above, but for source ports, basic WRF version
`define WRF_CONNECT_SOURCE(port_pfx, fab_pfx) \
`_WRF_CONNECT_MANDATORY_SOURCE(port_pfx, fab_pfx),\
.port_pfx``_terror_p1_i(1'b0),\
.port_pfx``_tabort_p1_o(),\
.port_pfx``_rabort_p1_i(1'b0),\
.port_pfx``_idle_o()
`endif
\ No newline at end of file
// Fabric emulator example, showing 2 fabric emulators connected together and exchanging packets.
`timescale 1ns / 1ps
`include "fabric_emu.sv"
module main;
const int c_clock_period = 8;
reg clk = 0;
reg rst_n = 0;
`WRF_WIRES(ab); // Emu A to B fabric
`WRF_WIRES(ba); // And the other way around
// generate clock and reset signals
always #(c_clock_period/2) clk <= ~clk;
initial begin
repeat(3) @(posedge clk);
rst_n = 1;
end
// Two fabric emulators talking to each other
fabric_emu U_emuA
(
.clk_i(clk),
.rst_n_i(rst_n),
`WRF_CONNECT_SOURCE(rx, ba), // connect fabric source/sinks
`WRF_CONNECT_SINK(tx, ab)
);
fabric_emu U_emuB
(
.clk_i(clk),
.rst_n_i(rst_n),
`WRF_CONNECT_SOURCE(rx, ab),
`WRF_CONNECT_SINK(tx, ba)
);
initial begin
ether_header_t hdr;
int buffer[1024];
int i;
wait(U_emuA.ready); // wait until both emulators are initialized
wait(U_emuB.ready);
hdr.src = 'h123456789abcdef;
hdr.dst = 'hcafeb1badeadbef;
hdr.ethertype = 1234;
hdr.is_802_1q = 0;
hdr.oob_type = `OOB_TYPE_RXTS;
hdr.timestamp_r = 10000;
hdr.timestamp_f = 4;
hdr.port_id = 5;
for(i=0;i<100;i++)
buffer[i] = i;
// simulate some flow throttling
U_emuA.simulate_rx_throttling(1, 50);
U_emuA.send(hdr, buffer, 100);
hdr.src = 'h0f0e0a0b0d00;
U_emuB.send(hdr, buffer, 50);
end
// Check if there's anything received by EMU B
always @(posedge clk) if (U_emuB.poll())
begin
ether_frame_t frame;
$display("Emulator B received a frame!");
U_emuB.receive(frame);
dump_frame_header("EmuB RX: ", frame);
end
// Check if there's anything received by EMU A
always @(posedge clk) if (U_emuA.poll())
begin
ether_frame_t frame;
$display("Emulator A received a frame!");
U_emuA.receive(frame);
dump_frame_header("EmuA RX: ", frame);
end
endmodule // main
`timescale 1ns/1ps
/* Ethernet FCS calculator class */
class CCRC32;
protected bit [31:0] crc;
protected bit [31:0] crc_tab[256];
function new();
reg [31:0] c, poly;
int i, j;
poly = 32'hEDB88320;
for (i = 0; i < 256; i++) begin
c = i;
for (j = 8; j > 0; j--) begin
if (c & 1)
c = (c >> 1) ^ poly;
else
c >>= 1;
end
crc_tab[i] = c;
end
crc = 32'hffffffff;
endfunction // new
function bit[31:0] bitrev(bit[31:0] x, int n);
reg [31:0] y= 0;
int i;
for(i=0;i<n;i++) if(x & (1<<i)) y|= 1<< (n-1-i);
bitrev=y;
endfunction
task update_int(bit[7:0] x);
crc = ((crc >> 8) & 32'h00FFFFFF) ^ crc_tab[(crc ^ bitrev(x,8)) & 32'hFF];
endtask
task update(input [15:0] x, int bytesel);
update_int(x[15:8]);
if(!bytesel)
update_int(x[7:0]);
endtask // update
function bit[31:0] get();
get = bitrev(crc ^ 32'hffffffff, 32);
endfunction // get
endclass
/* Simple packet queue */
class CPacketQueue;
protected int head, tail, count;
protected int size;
protected ether_frame_t d[];
function new (int _size);
size = _size;
head = 0;
tail = 0;
count = 0;
d = new [_size];
endfunction // new
task push(input ether_frame_t frame);
if(count == size) begin
$display("CPacketQueue::push(): queue overflow");
$stop();
end
d[head] = frame;
head++; if(head == size) head = 0;
count++;
endtask // push
task pop (output ether_frame_t frame);
if(count <= 0) begin
$display("CPacketQueue::pop(): queue empty");
$stop();
end
frame = d[tail];
tail++; if(tail == size) tail = 0;
count--;
endtask // pop
function int get_count();
return count;
endfunction // get_count
/* Looks for a packet with matching OOB frame identifier and updates it with the new timestamp value */
function int update_tx_timestamp(input [15:0] oob_fid,
input [4:0] port_id,
input [31:0] ts_value);
int i;
i = tail;
while(i != head)
begin
if(d[i].hdr.oob_type == `OOB_TYPE_TXTS && d[i].hdr.oob_fid == oob_fid) begin
d[i].hdr.timestamp_r = ts_value[27:0];
d[i].hdr.timestamp_f = ts_value[31:28];
d[i].hdr.has_timestamp = 1;
return 1;
end
i++;
if(i == count) i = 0;
end
return 0;
endfunction // update_tx_timestamp
endclass // CPacketQueue
// converts a nbytes-long number (hex) to hexadecimal string
function automatic string hex_2_str(input [47:0] hex, int nbytes);
int i;
string s = "";
string hexchars = "0123456789abcdef";
reg [47:0] t;
t = hex;
for(i=0; i<2*nbytes; i++) begin
s= {hexchars[t&'hf], s};
t=t>>4;
end
return s;
endfunction // hex_2_str
// formats an Ethernet frame header as a nice looking string
function automatic string format_ether_header(input ether_header_t hdr);
string s = {"DST: ", hex_2_str(hdr.dst, 6),
" SRC: ", hex_2_str(hdr.src, 6),
" Type: 0x",hex_2_str(hdr.ethertype, 2) };
if(hdr.is_802_1q) s = {s, " VLAN: 0x", hex_2_str({4'b0,hdr.vid}, 2), " PRIO: ", hex_2_str({5'b0, hdr.prio},1) };
return s;
endfunction // automatic
task dump_frame_header(string s, ether_frame_t frame);
$display("%s %s length = %d %s %s", s, format_ether_header(frame.hdr), frame.size, frame.error?"ERROR":"OK", frame.hdr.has_timestamp?"TS":"NoTS");
endtask // dump_frame_header
\ No newline at end of file
/* Linux TAP driver interface to WR fabric */
`timescale 1ns/1ps
`include "fabric_emu_defs.sv"
// module uses Linux TAP interface as a packet source/sink for the fabric simulator.
// link with VPI tap.sl
/* TODO:
- add CTRL code generation
*/
class CPacketFIFO;
int m_size, m_wrptr, m_rdptr, m_count, m_pktcnt;
bit[8:0] m_buffer[];
function new(int size);
m_size = size;
m_buffer = new [size];
m_rdptr = 0;
m_wrptr = 0;
m_count = 0;
m_pktcnt = 0;
endfunction // new
task _push(bit[8:0] val);
if(m_count >= m_size)
$error("FIFO overflow");
m_buffer[m_wrptr++] = val;
m_count++;
endtask // _push
function bit[8:0] get();
return m_buffer[m_rdptr];
endfunction // _get
function bit[8:0] pop();
bit [8:0] rval;
rval = m_buffer[m_rdptr++];
m_count--;
return rval;
endfunction
function int empty();
return (m_count == 0);
endfunction // _empty
task write(bit [7:0] val, bit eop);
// $display("fwrite: %x %x", val, eop);
_push({eop,val});
endtask // write
function int got_packet();
return (m_pktcnt != 0 );
endfunction // got_packets
function int end_of_packet();
bit[8:0] rval;
rval = get();
return rval[8];
endfunction // end_of_packet
endclass // packet_fifo
module fabric_emu_tap
(
input clk_sys_i,
input rst_n_i,
`WRF_FULL_PORTS_SINK(tx),
`WRF_FULL_PORTS_SOURCE(rx)
);
reg [7:0] tap_rx;
reg tap_dvalid_rx;
reg [7:0] tap_tx = 0;
reg tap_dvalid_tx = 0;
CPacketFIFO rx_fifo;
CPacketFIFO tx_fifo;
const int c_FIFO_SIZE = 32768;
const int c_INTERFRAME_GAP = 32768;
assign tx_drop_o = 0;
initial begin
rx_fifo = new(c_FIFO_SIZE);
tx_fifo = new (c_FIFO_SIZE);
end
reg rx_sof_p_int = 0;
reg rx_eof_p_int = 0;
reg tx_dreq_int = 0;
reg [15:0] rx_data_int = 0;
reg [3:0] rx_ctrl_int = 0;
reg rx_error_p_int = 0;
reg rx_bytesel_int = 0;
reg rx_valid_int = 0;
assign rx_sof_p1_o = rx_sof_p_int;
assign rx_eof_p1_o = rx_eof_p_int;
assign tx_dreq_o = tx_dreq_int;
assign rx_data_o = rx_data_int;
assign rx_ctrl_o = rx_ctrl_int;
assign rx_rerror_p1_o = rx_error_p_int;
assign rx_bytesel_o = rx_bytesel_int;
assign rx_valid_o = rx_valid_int;
assign rx_idle_o = 0;
assign rx_tabort_p1_o = 0;
assign tx_terror_p1_o = 0;
assign tx_rabort_p1_o = 0;
reg tap_dvalid_rx_d0 = 0;
reg [7:0] tap_data_d0;
always@(posedge clk_sys_i or negedge clk_sys_i)
begin
// TAP interface PLI call
$tap_io(tap_tx, tap_dvalid_tx, tap_rx, tap_dvalid_rx);
tap_dvalid_rx_d0 <= tap_dvalid_rx;
// TAP reception
if(tap_dvalid_rx_d0 && !tap_dvalid_rx)
rx_fifo.write(0, 1);
else if (tap_dvalid_rx)
rx_fifo.write(tap_rx, 0);
// TAP transmission
if(!tx_fifo.empty())
begin
bit[7:0] data;
bit eof;
{eof, data} = tx_fifo.pop();
// $display("TX: %x eof %b", data, eof);
tap_data_d0 <= data;
tap_tx <= tap_data_d0;
tap_dvalid_tx = !eof;
end
end
task automatic wait_clks(int howmuch);
while(howmuch--) @(posedge clk_sys_i);
endtask // automatic
const int FRX_NOFRAME = 1;
const int FRX_TX = 2;
const int FRX_EOF = 3;
int fab_rx_state;
int fab_rx_offset;
function bit[3:0] gen_ctrl(int offset);
if(offset >=0 && offset <= 2)
return `c_wrsw_ctrl_dst_mac;
else if(offset >=3 && offset <= 5)
return `c_wrsw_ctrl_src_mac;
else if(offset == 6)
return `c_wrsw_ctrl_ethertype;
else
return `c_wrsw_ctrl_payload;
endfunction // gen_ctrl
task automatic fabric_do_rx();
// $display("FabDoRX");
case (fab_rx_state)
FRX_NOFRAME:begin
rx_eof_p_int <= 0;
if(!rx_fifo.empty()) begin
rx_sof_p_int <= 1;
fab_rx_state = FRX_TX;
fab_rx_offset = 0;
return;
end
end
FRX_TX:begin
bit [8:0] lsb, msb;
rx_sof_p_int <= 0;
if(rx_fifo.end_of_packet()) begin
rx_fifo.pop();
fab_rx_state <= FRX_EOF;
rx_valid_int <= 0;
return;
end
msb = rx_fifo.pop();
if(rx_fifo.end_of_packet()) begin
rx_fifo.pop();
fab_rx_state <= FRX_EOF;
rx_valid_int <= 1;
rx_data_int [15:8] <= msb[7:0];
rx_ctrl_int <= gen_ctrl(fab_rx_offset++);
rx_bytesel_int <= 1;
end else begin
lsb = rx_fifo.pop();
rx_valid_int <= 1;
rx_bytesel_int <= 0;
rx_data_int = {msb[7:0], lsb[7:0] };
rx_ctrl_int <= gen_ctrl(fab_rx_offset++);
end
end
FRX_EOF: begin
rx_eof_p_int <= 1;
wait_clks(1);
rx_eof_p_int <= 0;
fab_rx_state <= FRX_NOFRAME;
wait_clks(c_INTERFRAME_GAP);
end
endcase // case (fab_rx_state)
endtask // automatic
task fabric_do_tx();
bit[7:0] buffer[2048];
int i, len ;
i = 0;
while(1) begin
if(tx_valid_i) begin
// ignore OOB
if(tx_ctrl_i == `c_wrsw_ctrl_tx_oob || tx_ctrl_i == `c_wrsw_ctrl_rx_oob)
continue;
buffer[i++] = tx_data_i[15:8];
if(!tx_bytesel_i)
buffer[i++] = tx_data_i[7:0];
end
if(tx_eof_p1_i)
break;
wait_clks(1);
end
// $display("FabTX: %d bytes", i);
len = i;
for(i=0;i<len;i++)
tx_fifo.write(buffer[i], 0);
tx_fifo.write(0, 1);
endtask // fabric_do_tx
initial fab_rx_state = FRX_NOFRAME;
initial forever begin
wait_clks(1);
if(rx_dreq_i)
fabric_do_rx();
else
rx_valid_int <= 0;
end
initial forever begin
tx_dreq_int <= 1;
wait_clks(1);
if(tx_sof_p1_i)
fabric_do_tx();
end
endmodule // tap_if
\ No newline at end of file
//
// 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
//
// 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
//
/* Todo:
pipelined reads
settings wrapped in the accessor object
*/
`include "simdrv_defs.svh"
`include "if_wishbone_types.svh"
`include "if_wishbone_accessor.svh"
interface IWishboneMaster
(
input clk_i,
input rst_n_i
);
parameter g_addr_width = 32;
parameter g_data_width = 32;
logic [g_addr_width - 1 : 0] adr;
logic [g_data_width - 1 : 0] dat_o;
logic [(g_data_width/8)-1 : 0] sel;
wire [g_data_width - 1 : 0] dat_i;
wire ack;
wire stall;
wire err;
wire rty;
logic cyc;
logic stb;
logic we;
wire clk;
wire rst_n;
time last_access_t = 0;
struct {
int gen_random_throttling;
real throttle_prob;
int little_endian;
int cyc_on_stall;
wb_address_granularity_t addr_gran;
} settings;
modport master
(
output adr,
output dat_o,
output sel,
output cyc,
output stb,
output we,
input ack,
input dat_i,
input stall,
input err,
input rty
);
function automatic logic[g_addr_width-1:0] gen_addr(uint64_t addr, int xfer_size);
if(settings.addr_gran == WORD)
case(g_data_width)
8: return addr;
16: return addr >> 1;
32: return addr >> 2;
64: return addr >> 3;
default: $error("IWishbone: invalid WB data bus width [%d bits\n]", g_data_width);
endcase // case (xfer_size)
else
return addr;
endfunction
function automatic logic[63:0] rev_bits(logic [63:0] x, int nbits);
logic[63:0] tmp;
int i;
for (i=0;i<nbits;i++)
tmp[nbits-1-i] = x[i];
return tmp;
endfunction // rev_bits
//FIXME: little endian
function automatic logic[(g_data_width/8)-1:0] gen_sel(uint64_t addr, int xfer_size, int little_endian);
logic [(g_data_width/8)-1:0] sel;
const int dbytes = (g_data_width/8-1);
sel = ((1<<xfer_size) - 1);
return rev_bits(sel << (addr % xfer_size), g_data_width/8);
endfunction
function automatic logic[g_data_width-1:0] gen_data(uint64_t addr, uint64_t data, int xfer_size, int little_endian);
const int dbytes = (g_data_width/8-1);
logic[g_data_width-1:0] tmp;
tmp = data << (8 * (dbytes - (xfer_size - 1 - (addr % xfer_size))));
// $display("GenData: xs %d dbytes %d %x", tmp, xfer_size, dbytes);
return tmp;
endfunction // gen_data
function automatic uint64_t decode_data(uint64_t addr, logic[g_data_width-1:0] data, int xfer_size);
int rem;
// $display("decode: a %x d %x xs %x", addr, data ,xfer_size);
rem = addr % xfer_size;
return (data >> (8*rem)) & ((1<<(xfer_size*8)) - 1);
endfunction // decode_data
task automatic classic_cycle
(
inout wb_xfer_t xfer[],
input bit rw,
input int n_xfers,
output wb_cycle_result_t result
);
int i;
if($time != last_access_t)
@(posedge clk_i); /* resynchronize, just in case */
for(i=0;i<n_xfers;i++)
begin
stb <= 1'b1;
cyc <= 1'b1;
adr <= gen_addr(xfer[i].a, xfer[i].size);
we <= rw;
sel <= gen_sel(xfer[i].a, xfer[i].size, settings.little_endian);
//gen_sel(xfer[i].a, xfer[i].size);
dat_o <= gen_data(xfer[i].a, xfer[i].d, xfer[i].size, settings.little_endian);
@(posedge clk_i);
if(ack == 0) begin
while(ack == 0) begin @(posedge clk_i); end
end else if(err == 1'b1 || rty == 1'b1)
begin
cyc <= 0;
we <= 0;
stb <= 0;
result = (err ==1'b1 ? R_ERROR: R_RETRY);
break;
end
xfer[i].d = decode_data(xfer[i].a, dat_i, xfer[i].size);
cyc <= 0;
we <= 0;
stb <= 0;
end // if (ack == 0)
@(posedge clk_i);
result = R_OK;
last_access_t = $time;
endtask // automatic
reg xf_idle = 1;
int ack_cnt_int;
always@(posedge clk_i)
begin
if(!cyc)
ack_cnt_int <= 0;
else if(stb && !stall && !ack)
ack_cnt_int++;
else if((!stb || stall) && ack)
ack_cnt_int--;
end
task automatic count_ack(ref int ack_cnt);
// if(stb && !stall && !ack)
// ack_cnt++;
if (ack)
ack_cnt--;
endtask
task automatic handle_readback(ref wb_xfer_t xf [$], input int read, ref int cur_rdbk);
if(ack && read)
begin
xf[cur_rdbk].d = dat_i;
cur_rdbk++;
end
endtask // handle_readback
task automatic pipelined_cycle
(
ref wb_xfer_t xfer[$],
input int write,
input int n_xfers,
output wb_cycle_result_t result
);
int i;
int ack_count ;
int failure ;
int cur_rdbk;
ack_count = 0;
failure = 0;
xf_idle = 0;
cur_rdbk = 0;
if($time != last_access_t)
@(posedge clk_i); /* resynchronize, just in case */
while(stall && !settings.cyc_on_stall)
@(posedge clk_i);
cyc <= 1'b1;
i =0;
ack_count = n_xfers;
while(i<n_xfers)
begin
count_ack(ack_count);
handle_readback(xfer, !write, cur_rdbk);
if(err) begin
result = R_ERROR;
failure = 1;
break;
end
if(rty) begin
result = R_RETRY;
failure = 1;
break;
end
if (!stall && settings.gen_random_throttling && probability_hit(settings.throttle_prob)) begin
stb <= 1'b0;
we <= 1'b0;
@(posedge clk_i);
end else begin
adr <= gen_addr(xfer[i].a, xfer[i].size);
stb <= 1'b1;
if(write)
begin
we <= 1'b1;
sel <= gen_sel(xfer[i].a, xfer[i].size, settings.little_endian);
dat_o <= gen_data(xfer[i].a, xfer[i].d, xfer[i].size, settings.little_endian);
end else begin
we<=1'b0;
sel <= 'hffffffff;
end
@(posedge clk_i);
stb <= 1'b0;
we <= 1'b0;
if(stall)
begin
stb <= 1'b1;
if(write)
we <= 1'b1;
while(stall)
begin
count_ack(ack_count);
@(posedge clk_i);
end
stb <= 1'b0;
we <= 1'b0;
end
i++;
end
end // for (i =0;i<n_xfers;i++)
while((ack_count > 0) && !failure)
begin
// $display("AckCount %d", ack_count);
if(err) begin
result = R_ERROR;
failure = 1;
break;
end
if(rty) begin
result = R_RETRY;
failure = 1;
break;
end
count_ack(ack_count);
handle_readback(xfer, !write, cur_rdbk);
if(stb && !ack)
ack_count++;
else if(!stb && ack)
ack_count--;
@(posedge clk_i);
end
cyc <= 1'b0;
@(posedge clk_i);
if(!failure)
result = R_OK;
xf_idle = 1;
last_access_t = $time;
endtask // automatic
wb_cycle_t request_queue[$];
wb_cycle_t result_queue[$];
class CIWBMasterAccessor extends CWishboneAccessor;
function automatic int poll();
return 0;
endfunction
task get(ref wb_cycle_t xfer);
while(!result_queue.size())
@(posedge clk_i);
xfer = result_queue.pop_front();
endtask
task clear();
endtask // clear
task put(ref wb_cycle_t xfer);
// $display("WBMaster[%d]: PutCycle",g_data_width);
request_queue.push_back(xfer);
endtask // put
function int idle();
return (request_queue.size() == 0) && xf_idle;
endfunction // idle
endclass // CIWBMasterAccessor
function CIWBMasterAccessor get_accessor();
CIWBMasterAccessor tmp;
tmp = new;
return tmp;
endfunction // get_accessoror
always@(posedge clk_i)
if(!rst_n_i)
begin
request_queue = {};
result_queue = {};
xf_idle = 1;
cyc <= 0;
dat_o <= 0;
stb <= 0;
sel <= 0;
adr <= 0;
we <= 0;
end
initial begin
settings.gen_random_throttling = 0;
settings.throttle_prob = 0.1;
settings.cyc_on_stall = 0;
settings.addr_gran = WORD;
end
initial forever
begin
@(posedge clk_i);
if(request_queue.size() > 0)
begin
wb_cycle_t c;
wb_cycle_result_t res;
c = request_queue.pop_front();
case(c.ctype)
PIPELINED:
begin
pipelined_cycle(c.data, c.rw, c.data.size(), res);
c.result =res;
end
CLASSIC:
begin
// $display("WBMaster: got classic cycle [%d, rw %d]", c.data.size(), c.rw);
classic_cycle(c.data, c.rw, c.data.size, res);
c.result =res;
end
endcase // case (c.ctype)
result_queue.push_back(c);
end
end
endinterface // IWishbone
`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_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_PRESENT_OFFSET 2
`define SPLL_ECCR_EXT_REF_PRESENT 32'h00000004
`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_F_DMTD 8'h14
`define SPLL_F_DMTD_FREQ_OFFSET 0
`define SPLL_F_DMTD_FREQ 32'h0fffffff
`define SPLL_F_DMTD_VALID_OFFSET 28
`define SPLL_F_DMTD_VALID 32'h10000000
`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
# vsim -do {run;quit} -c work.main
# ** Note: (vsim-3813) Design is being optimized due to module recompilation...
# // ModelSim SE 6.5e Feb 26 2010 Linux 2.6.38-ARCH
# //
# // Copyright 1991-2010 Mentor Graphics Corporation
# // All Rights Reserved.
# //
# // THIS WORK CONTAINS TRADE SECRET AND
# // PROPRIETARY INFORMATION WHICH IS THE PROPERTY
# // OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
# // AND IS SUBJECT TO LICENSE TERMS.
# //
# Loading sv_std.std
# Loading work.test_epacket_sv_unit(fast)
# Loading work.main(fast)
# run
# 802.1q [VID 555/PCP 0] DST [ff:ff:ff:ff:ff:ff] SRC: [01:02:03:04:05:06] Type = 0x1234 size = 118 F:( )
# +000: 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f
# +010: 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f
# +020: 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f
# +030: 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f
# +040: 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f
# +050: 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f
# +060: 60 61 62 63
# eq: 1
# RandomBVEC 72
# 802.1q [VID 555/PCP 0] DST [ff:ff:ff:ff:ff:ff] SRC: [01:02:03:04:05:06] Type = 0x9215 size = 90 F:( )
# +000: 04 32 87 c7 32 09 81 87-bb 9f f7 c6 fd 63 63 55
# +010: f3 3c 09 c8 fa 67 74 63-af 5e 16 32 32 85 40 90
# +020: d6 4f 4b 09 06 29 b6 6b-01 57 8f 68 92 85 65 1e
# +030: fa c5 a1 6c bc 44 f6 db-e4 d7 5e 95 05 38 c3 a8
# +040: 1d 9d 3f 8b f9 ed b1 a6
# RandomBVEC 89
# 802.1q [VID 555/PCP 0] DST [ff:ff:ff:ff:ff:ff] SRC: [01:02:03:04:05:06] Type = 0xcfa2 size = 107 F:( )
# +000: fd 5c 50 2e 2d c5 24 68-6c 28 cb 86 61 e5 3b 9f
# +010: 89 3f b7 9d 90 6a c3 3c-ae a5 20 95 ac 43 47 4e
# +020: fe 13 ba 51 17 5a 30 a2-fc 66 73 ad 95 76 6d 32
# +030: 5a 70 bd a2 68 95 d6 87-ef 4d 7f 62 ab a8 34 05
# +040: dc 1c bd 5c cb ca 02 2c-ee 27 ed 36 3b e6 db cb
# +050: 23 82 fc b5 5a c4 95 16-64
# ** Note: $finish : test_epacket.sv(53)
# Time: 0 ns Iteration: 0 Instance: /main
`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 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 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
sim_tool="modelsim"
top_module="main"
action = "simulation"
target = "xilinx"
fetchto = "../../ip_cores"
syn_device="xc6slx45t"
include_dirs=["../include","gn4124_bfm", "ddr3"]
files = [ "main.sv","l2p_fifo.vhd","ddr3/ddr3.v" ]
modules = { "local" : [ "../../rtl", "gn4124_bfm", "../../../adc/rtl", "../../../ip_cores/timetag_core/rtl",
"../../../ip_cores/general-cores", "../../../ip_cores/ddr3-sp6-core",
"../../../ip_cores/gn4124-core" ]};
This source diff could not be displayed because it is too large. You can view the blob instead.
/****************************************************************************************
*
* File Name: ddr3_mcp.v
*
* Dependencies: ddr3.v, ddr3_parameters.vh
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3) multi-chip package model
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
`timescale 1ps / 1ps
module ddr3_mcp (
rst_n,
ck,
ck_n,
cke,
cs_n,
ras_n,
cas_n,
we_n,
dm_tdqs,
ba,
addr,
dq,
dqs,
dqs_n,
tdqs_n,
odt
);
`include "ddr3_parameters.vh"
// Declare Ports
input rst_n;
input ck;
input ck_n;
input [CS_BITS-1:0] cke;
input [CS_BITS-1:0] cs_n;
input ras_n;
input cas_n;
input we_n;
inout [DM_BITS-1:0] dm_tdqs;
input [BA_BITS-1:0] ba;
input [ADDR_BITS-1:0] addr;
inout [DQ_BITS-1:0] dq;
inout [DQS_BITS-1:0] dqs;
inout [DQS_BITS-1:0] dqs_n;
output [DQS_BITS-1:0] tdqs_n;
input [CS_BITS-1:0] odt;
wire [RANKS-1:0] cke_mcp = cke;
wire [RANKS-1:0] cs_n_mcp = cs_n;
wire [RANKS-1:0] odt_mcp = odt;
ddr3 rank [RANKS-1:0] (
rst_n,
ck,
ck_n,
cke_mcp,
cs_n_mcp,
ras_n,
cas_n,
we_n,
dm_tdqs,
ba,
addr,
dq,
dqs,
dqs_n,
tdqs_n,
odt_mcp
);
endmodule
/****************************************************************************************
*
* File Name: ddr3_module.v
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3) module model
*
* Limitation: - SPD (Serial Presence-Detect) is not modeled
* - Command/Address parity is not modeled
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
`timescale 1ps / 1ps
module ddr3_module (
reset_n,
ck ,
ck_n ,
cke ,
s_n ,
ras_n ,
cas_n ,
we_n ,
ba ,
addr ,
odt ,
dqs ,
dqs_n ,
dq ,
`ifdef SODIMM
`else
cb ,
`endif
scl ,
sa ,
sda
);
`include "ddr3_parameters.vh"
input reset_n;
input [1:0] cke ;
input ras_n ;
input cas_n ;
input we_n ;
input [2:0] ba ;
input [15:0] addr ;
input [1:0] odt ;
inout [17:0] dqs ;
inout [17:0] dqs_n ;
inout [63:0] dq ;
input scl ; // no connect
inout sda ; // no connect
`ifdef QUAD_RANK
initial if (DEBUG) $display("%m: Quad Rank");
`else `ifdef DUAL_RANK
initial if (DEBUG) $display("%m: Dual Rank");
`else
initial if (DEBUG) $display("%m: Single Rank");
`endif `endif
`ifdef ECC
initial if (DEBUG) $display("%m: ECC");
`ifdef SODIMM
initial begin
$display("%m ERROR: ECC is not available on SODIMM configurations");
if (STOP_ON_ERROR) $stop(0);
end
`endif
`else
initial if (DEBUG) $display("%m: non ECC");
`endif
`ifdef RDIMM
initial if (DEBUG) $display("%m: RDIMM");
input ck ;
input ck_n ;
input [3:0] s_n ;
inout [7:0] cb ;
input [2:0] sa ; // no connect
wire [1:0] rck = {2{ck}};
wire [1:0] rck_n = {2{ck_n}};
reg [3:0] rs_n ;
reg rras_n ;
reg rcas_n ;
reg rwe_n ;
reg [2:0] rba ;
reg [15:0] raddr ;
reg [3:0] rcke ;
reg [3:0] rodt ;
always @(negedge reset_n or posedge ck) begin
if (!reset_n) begin
rs_n <= #(500) 0;
rras_n <= #(500) 0;
rcas_n <= #(500) 0;
rwe_n <= #(500) 0;
rba <= #(500) 0;
raddr <= #(500) 0;
rcke <= #(500) 0;
rodt <= #(500) 0;
end else begin
rs_n <= #(500) s_n ;
rras_n <= #(500) ras_n;
rcas_n <= #(500) cas_n;
rwe_n <= #(500) we_n ;
rba <= #(500) ba ;
raddr <= #(500) addr ;
`ifdef QUAD_RANK
rcke <= #(500) {{2{cke[1]}}, {2{cke[0]}}};
rodt <= #(500) {{2{odt[1]}}, {2{odt[0]}}};
`else
rcke <= #(500) {2'b00, cke};
rodt <= #(500) {2'b00, odt};
`endif
end
end
`else
input [1:0] ck ;
input [1:0] ck_n ;
input [1:0] s_n ;
`ifdef SODIMM
initial if (DEBUG) $display("%m: SODIMM");
input [1:0] sa ; // no connect
wire [7:0] cb;
`else
initial if (DEBUG) $display("%m: UDIMM");
inout [7:0] cb ;
input [2:0] sa ; // no connect
`endif
wire [1:0] rck = ck ;
wire [1:0] rck_n = ck_n ;
wire [2:0] rba = ba ;
wire [15:0] raddr = addr ;
wire rras_n = ras_n;
wire rcas_n = cas_n;
wire rwe_n = we_n ;
`ifdef QUAD_RANK
wire [3:0] rs_n = {{2{s_n[1]}}, {2{s_n[0]}}};
wire [3:0] rcke = {{2{cke[1]}}, {2{cke[0]}}};
wire [3:0] rodt = {{2{odt[1]}}, {2{odt[0]}}};
`else
wire [3:0] rs_n = {2'b00, s_n};
wire [3:0] rcke = {2'b00, cke};
wire [3:0] rodt = {2'b00, odt};
`endif
`endif
wire [15:0] rcb = {8'b0, cb};
wire zero = 1'b0;
wire one = 1'b1;
// all DUAL_RANK UDIMMs have mirrored address
`ifdef QUAD_RANK
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`else `ifdef DUAL_RANK
`ifdef UDIMM
initial if (DEBUG) $display("%m: ADDRESS MIRROR");
wire [15:0] maddr = {raddr[15:9], raddr[7], raddr[8], raddr[5], raddr[6], raddr[3], raddr[4], raddr[2:0]};
wire [2:0] mba = {rba[2], rba[0], rba[1]};
`else
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`endif
`else
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`endif `endif
//ddr3 (rst_n , ck , ck_n , cke , cs_n , ras_n , cas_n , we_n , dm_tdqs , ba , addr , dq , dqs , dqs_n , tdqs_n , odt );
`ifdef x4
initial if (DEBUG) $display("%m: Component Width = x4");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[0]);
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[0]);
ddr3 U6R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[0]);
ddr3 U7R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[0]);
ddr3 U8R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[0]);
ddr3 U9R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[0]);
`ifdef ECC
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[0]);
`endif
ddr3 U18R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[0]);
ddr3 U17R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[0]);
ddr3 U16R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[0]);
ddr3 U15R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[0]);
ddr3 U13R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[0]);
ddr3 U12R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[0]);
ddr3 U11R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[0]);
ddr3 U10R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[0]);
`ifdef ECC
ddr3 U14R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[1]);
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[1]);
ddr3 U6R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[1]);
ddr3 U7R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[1]);
ddr3 U8R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[1]);
ddr3 U9R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[1]);
`ifdef ECC
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[1]);
`endif
ddr3 U18R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[1]);
ddr3 U17R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[1]);
ddr3 U16R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[1]);
ddr3 U15R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[1]);
ddr3 U13R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[1]);
ddr3 U12R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[1]);
ddr3 U11R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[1]);
ddr3 U10R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[1]);
`ifdef ECC
ddr3 U14R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[2]);
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[2]);
ddr3 U6R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[2]);
ddr3 U7R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[2]);
ddr3 U8R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[2]);
ddr3 U9R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[2]);
`ifdef ECC
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[2]);
`endif
ddr3 U18R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[2]);
ddr3 U17R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[2]);
ddr3 U16R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[2]);
ddr3 U15R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[2]);
ddr3 U13R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[2]);
ddr3 U12R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[2]);
ddr3 U11R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[2]);
ddr3 U10R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[2]);
`ifdef ECC
ddr3 U14R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[3]);
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[3]);
ddr3 U6R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[3]);
ddr3 U7R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[3]);
ddr3 U8R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[3]);
ddr3 U9R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[3]);
`ifdef ECC
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[3]);
`endif
ddr3 U18R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[3]);
ddr3 U17R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[3]);
ddr3 U16R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[3]);
ddr3 U15R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[3]);
ddr3 U13R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[3]);
ddr3 U12R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[3]);
ddr3 U11R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[3]);
ddr3 U10R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[3]);
`ifdef ECC
ddr3 U14R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[3]);
`endif
`endif
`else `ifdef x8
initial if (DEBUG) $display("%m: Component Width = x8");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[0]);
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[0]);
ddr3 U6R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[0]);
ddr3 U7R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[0]);
ddr3 U8R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[0]);
ddr3 U9R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[0]);
`ifdef ECC
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[ 9] , mba, maddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10] , mba, maddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[1]);
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[11] , mba, maddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12] , mba, maddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[1]);
ddr3 U6R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[13] , mba, maddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[1]);
ddr3 U7R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14] , mba, maddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[1]);
ddr3 U8R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[15] , mba, maddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[1]);
ddr3 U9R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16] , mba, maddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[1]);
`ifdef ECC
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[17] , mba, maddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[2]);
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[2]);
ddr3 U6R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[2]);
ddr3 U7R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[2]);
ddr3 U8R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[2]);
ddr3 U9R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[2]);
`ifdef ECC
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[3]);
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[3]);
ddr3 U6R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[3]);
ddr3 U7R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[3]);
ddr3 U8R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[3]);
ddr3 U9R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[3]);
`ifdef ECC
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[3]);
`endif
`endif
`else `ifdef x16
initial if (DEBUG) $display("%m: Component Width = x16");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[0]);
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[0]);
`ifdef ECC
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10: 9] , mba, maddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12:11] , mba, maddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14:13] , mba, maddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[1]);
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16:15] , mba, maddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[1]);
`ifdef ECC
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, {one, dqs[17]}, mba, maddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[2]);
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[2]);
`ifdef ECC
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[3]);
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[3]);
`ifdef ECC
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[3]);
`endif
`endif
`endif `endif `endif
endmodule
/****************************************************************************************
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
// Parameters based on DDR3e PreJEDEC Micron specs 09022009.fm RevC 9/2/09 EN
// DDR3-2133 093/E/F
// DDR3-1866 107/E/F
// Parameters based on DDR3 Micron specs 2Gb_DDR3_SDRAM.pdf - Rev. I 7/09 EN
// DDR3-1600 125/E
// DDR3-1333 15/E
// DDR3-1066 187/E
// DDR3-800 25/E
// Timing parameters based on Speed Grade
// SYMBOL UNITS DESCRIPTION
// ------ ----- -----------
`ifdef sg093 // sg093 is equivalent to the JEDEC DDR3-2133 (14-14-14) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 180; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48090; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13090; // tRCD ps Active to Read/Write command time
parameter TRP = 13090; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13090; // TAA ps Internal READ command to first data
parameter CL_TIME = 13090; // CL ps Minimum CAS Latency
`elsif sg093E // sg093E is equivalent to the JEDEC DDR3-2133 (13-13-13) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47155; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12155; // tRCD ps Active to Read/Write command time
parameter TRP = 12155; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12155; // TAA ps Internal READ command to first data
parameter CL_TIME = 12155; // CL ps Minimum CAS Latency
`elsif sg093F // sg093F is equivalent to the JEDEC DDR3-2133 (12-12-12) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 46220; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 11220; // tRCD ps Active to Read/Write command time
parameter TRP = 11220; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 11220; // TAA ps Internal READ command to first data
parameter CL_TIME = 11220; // CL ps Minimum CAS Latency
`elsif sg107 // sg107 is equivalent to the JEDEC DDR3-1866 (13-13-13) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48910; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13910; // tRCD ps Active to Read/Write command time
parameter TRP = 13910; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13910; // TAA ps Internal READ command to first data
parameter CL_TIME = 13910; // CL ps Minimum CAS Latency
`elsif sg107E // sg107E is equivalent to the JEDEC DDR3-1866 (12-12-12) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47840; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12840; // tRCD ps Active to Read/Write command time
parameter TRP = 12840; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12840; // TAA ps Internal READ command to first data
parameter CL_TIME = 12840; // CL ps Minimum CAS Latency
`elsif sg107F // sg107F is equivalent to the JEDEC DDR3-1866 (11-11-11) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 46770; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 11770; // tRCD ps Active to Read/Write command time
parameter TRP = 11770; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 11770; // TAA ps Internal READ command to first data
parameter CL_TIME = 11770; // CL ps Minimum CAS Latency
`elsif sg125E // sg125E is equivalent to the JEDEC DDR3-1600 (10-10-10) speed bin
parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
parameter TIS = 170; // tIS ps Input Setup Time
parameter TIH = 120; // tIH ps Input Hold Time
parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
parameter TRP = 12500; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
`elsif sg125 // sg125 is equivalent to the JEDEC DDR3-1600 (11-11-11) speed bin
parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
parameter TIS = 170; // tIS ps Input Setup Time
parameter TIH = 120; // tIH ps Input Hold Time
parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48750; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13750; // tRCD ps Active to Read/Write command time
parameter TRP = 13750; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13750; // TAA ps Internal READ command to first data
parameter CL_TIME = 13750; // CL ps Minimum CAS Latency
`elsif sg15E // sg15E is equivalent to the JEDEC DDR3-1333H (9-9-9) speed bin
parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
parameter TIS = 190; // tIS ps Input Setup Time
parameter TIH = 140; // tIH ps Input Hold Time
parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 49500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13500; // tRCD ps Active to Read/Write command time
parameter TRP = 13500; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13500; // TAA ps Internal READ command to first data
parameter CL_TIME = 13500; // CL ps Minimum CAS Latency
`elsif sg15 // sg15 is equivalent to the JEDEC DDR3-1333J (10-10-10) speed bin
parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
parameter TIS = 190; // tIS ps Input Setup Time
parameter TIH = 140; // tIH ps Input Hold Time
parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 51000; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`elsif sg187E // sg187E is equivalent to the JEDEC DDR3-1066F (7-7-7) speed bin
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
parameter TIS = 275; // tIS ps Input Setup Time
parameter TIH = 200; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 50625; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
parameter TRP = 13125; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
`elsif sg187 // sg187 is equivalent to the JEDEC DDR3-1066G (8-8-8) speed bin
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
parameter TIS = 275; // tIS ps Input Setup Time
parameter TIH = 200; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`elsif sg25E // sg25E is equivalent to the JEDEC DDR3-800D (5-5-5) speed bin
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
parameter TIS = 350; // tIS ps Input Setup Time
parameter TIH = 275; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 50000; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
parameter TRP = 12500; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
`else `define sg25 // sg25 is equivalent to the JEDEC DDR3-800E (6-6-6) speed bin
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
parameter TIS = 350; // tIS ps Input Setup Time
parameter TIH = 275; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`endif
`ifdef x16
`ifdef sg093
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg093E
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg093F
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107E
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107F
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg125E
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg125
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg15E
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg15
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
`else // sg187E, sg187, sg25, sg25E
parameter TRRD = 10000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 50000; // tFAW ps (2KB page size) Four Bank Activate window
`endif
`else // x4, x8
`ifdef sg093
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg093E
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg093F
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107E
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107F
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg125E
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg125
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg15E
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg15
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg187E
parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg187
parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
`else // sg25, sg25E
parameter TRRD = 10000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (1KB page size) Four Bank Activate window
`endif
`endif
// Timing Parameters
// Mode Register
parameter CL_MIN = 5; // CL tCK Minimum CAS Latency
parameter CL_MAX = 14; // CL tCK Maximum CAS Latency
parameter AL_MIN = 0; // AL tCK Minimum Additive Latency
parameter AL_MAX = 2; // AL tCK Maximum Additive Latency
parameter WR_MIN = 5; // WR tCK Minimum Write Recovery
parameter WR_MAX = 16; // WR tCK Maximum Write Recovery
parameter BL_MIN = 4; // BL tCK Minimum Burst Length
parameter BL_MAX = 8; // BL tCK Minimum Burst Length
parameter CWL_MIN = 5; // CWL tCK Minimum CAS Write Latency
parameter CWL_MAX = 10; // CWL tCK Maximum CAS Write Latency
// Clock
parameter TCK_MAX = 3300; // tCK ps Maximum Clock Cycle Time
parameter TCH_AVG_MIN = 0.47; // tCH tCK Minimum Clock High-Level Pulse Width
parameter TCL_AVG_MIN = 0.47; // tCL tCK Minimum Clock Low-Level Pulse Width
parameter TCH_AVG_MAX = 0.53; // tCH tCK Maximum Clock High-Level Pulse Width
parameter TCL_AVG_MAX = 0.53; // tCL tCK Maximum Clock Low-Level Pulse Width
parameter TCH_ABS_MIN = 0.43; // tCH tCK Minimum Clock High-Level Pulse Width
parameter TCL_ABS_MIN = 0.43; // tCL tCK Maximum Clock Low-Level Pulse Width
parameter TCKE_TCK = 3; // tCKE tCK CKE minimum high or low pulse width
parameter TAA_MAX = 20000; // TAA ps Internal READ command to first data
// Data OUT
parameter TQH = 0.38; // tQH ps DQ output hold time from DQS, DQS#
// Data Strobe OUT
parameter TRPRE = 0.90; // tRPRE tCK DQS Read Preamble
parameter TRPST = 0.30; // tRPST tCK DQS Read Postamble
// Data Strobe IN
parameter TDQSH = 0.45; // tDQSH tCK DQS input High Pulse Width
parameter TDQSL = 0.45; // tDQSL tCK DQS input Low Pulse Width
parameter TWPRE = 0.90; // tWPRE tCK DQS Write Preamble
parameter TWPST = 0.30; // tWPST tCK DQS Write Postamble
// Command and Address
parameter TZQCS = 64; // tZQCS tCK ZQ Cal (Short) time
parameter TZQINIT = 512; // tZQinit tCK ZQ Cal (Long) time
parameter TZQOPER = 256; // tZQoper tCK ZQ Cal (Long) time
parameter TCCD = 4; // tCCD tCK Cas to Cas command delay
parameter TCCD_DG = 2; // tCCD_DG tCK Cas to Cas command delay to different group
parameter TRAS_MAX = 60e9; // tRAS ps Maximum Active to Precharge command time
parameter TWR = 15000; // tWR ps Write recovery time
parameter TMRD = 4; // tMRD tCK Load Mode Register command cycle time
parameter TMOD = 15000; // tMOD ps LOAD MODE to non-LOAD MODE command cycle time
parameter TMOD_TCK = 12; // tMOD tCK LOAD MODE to non-LOAD MODE command cycle time
parameter TRRD_TCK = 4; // tRRD tCK Active bank a to Active bank b command time
parameter TRRD_DG = 3000; // tRRD_DG ps Active bank a to Active bank b command time to different group
parameter TRRD_DG_TCK = 2; // tRRD_DG tCK Active bank a to Active bank b command time to different group
parameter TRTP = 7500; // tRTP ps Read to Precharge command delay
parameter TRTP_TCK = 4; // tRTP tCK Read to Precharge command delay
parameter TWTR = 7500; // tWTR ps Write to Read command delay
parameter TWTR_DG = 3750; // tWTR_DG ps Write to Read command delay to different group
parameter TWTR_TCK = 4; // tWTR tCK Write to Read command delay
parameter TWTR_DG_TCK = 2; // tWTR_DG tCK Write to Read command delay to different group
parameter TDLLK = 512; // tDLLK tCK DLL locking time
// Refresh - 2Gb
parameter TRFC_MIN = 160000; // tRFC ps Refresh to Refresh Command interval minimum value
parameter TRFC_MAX =70312500; // tRFC ps Refresh to Refresh Command Interval maximum value
// Power Down
parameter TXP_TCK = 3; // tXP tCK Exit power down to a valid command
parameter TXPDLL = 24000; // tXPDLL ps Exit precharge power down to READ or WRITE command (DLL-off mode)
parameter TXPDLL_TCK = 10; // tXPDLL tCK Exit precharge power down to READ or WRITE command (DLL-off mode)
parameter TACTPDEN = 1; // tACTPDEN tCK Timing of last ACT command to power down entry
parameter TPRPDEN = 1; // tPREPDEN tCK Timing of last PRE command to power down entry
parameter TREFPDEN = 1; // tARPDEN tCK Timing of last REFRESH command to power down entry
parameter TCPDED = 1; // tCPDED tCK Command pass disable/enable delay
parameter TPD_MAX =TRFC_MAX; // tPD ps Power-down entry-to-exit timing
parameter TXPR = 170000; // tXPR ps Exit Reset from CKE assertion to a valid command
parameter TXPR_TCK = 5; // tXPR tCK Exit Reset from CKE assertion to a valid command
// Self Refresh
parameter TXS = 170000; // tXS ps Exit self refesh to a non-read or write command
parameter TXS_TCK = 5; // tXS tCK Exit self refesh to a non-read or write command
parameter TXSDLL = TDLLK; // tXSRD tCK Exit self refresh to a read or write command
parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit.
parameter TCKSRE = 10000; // tCKSRE ps Valid Clock requirement after self refresh entry (SRE)
parameter TCKSRE_TCK = 5; // tCKSRE tCK Valid Clock requirement after self refresh entry (SRE)
parameter TCKSRX = 10000; // tCKSRX ps Valid Clock requirement prior to self refresh exit (SRX)
parameter TCKSRX_TCK = 5; // tCKSRX tCK Valid Clock requirement prior to self refresh exit (SRX)
parameter TCKESR_TCK = 4; // tCKESR tCK Minimum CKE low width for Self Refresh entry to exit timing
// ODT
parameter TAOF = 0.7; // tAOF tCK RTT turn-off from ODTLoff reference
parameter TAONPD = 8500; // tAONPD ps Asynchronous RTT turn-on delay (Power-Down with DLL frozen)
parameter TAOFPD = 8500; // tAONPD ps Asynchronous RTT turn-off delay (Power-Down with DLL frozen)
parameter ODTH4 = 4; // ODTH4 tCK ODT minimum HIGH time after ODT assertion or write (BL4)
parameter ODTH8 = 6; // ODTH8 tCK ODT minimum HIGH time after write (BL8)
parameter TADC = 0.7; // tADC tCK RTT dynamic change skew
// Write Levelization
parameter TWLMRD = 40; // tWLMRD tCK First DQS pulse rising edge after tDQSS margining mode is programmed
parameter TWLDQSEN = 25; // tWLDQSEN tCK DQS/DQS delay after tDQSS margining mode is programmed
parameter TWLOE = 2000; // tWLOE ps Write levelization output error
// Size Parameters based on Part Width
`ifdef x4
parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 15; // MAX Address Bits
parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 4; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
`elsif x8
parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 15; // MAX Address Bits
parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 8; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
`else `define x16
parameter DM_BITS = 2; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 14; // MAX Address Bits
parameter ROW_BITS = 14; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 2; // Set this parameter to control how many Dqs bits are used
`endif
// Size Parameters
parameter BA_BITS = 3; // Set this parmaeter to control how many Bank Address bits are used
parameter MEM_BITS = 16; // Set this parameter to control how many write data bursts can be stored in memory. The default is 2^10=1024.
parameter AP = 10; // the address bit that controls auto-precharge and precharge-all
parameter BC = 12; // the address bit that controls burst chop
parameter BL_BITS = 3; // the number of bits required to count to BL_MAX
parameter BO_BITS = 2; // the number of Burst Order Bits
`ifdef QUAD_RANK
`define DUAL_RANK // also define DUAL_RANK
parameter CS_BITS = 4; // Number of Chip Select Bits
parameter RANKS = 4; // Number of Chip Selects
`elsif DUAL_RANK
parameter CS_BITS = 2; // Number of Chip Select Bits
parameter RANKS = 2; // Number of Chip Selects
`else
parameter CS_BITS = 2; // Number of Chip Select Bits
parameter RANKS = 1; // Number of Chip Selects
`endif
// Simulation parameters
parameter RZQ = 240; // termination resistance
parameter PRE_DEF_PAT = 8'hAA; // value returned during mpr pre-defined pattern readout
parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors
parameter DEBUG = 0; // Turn on Debug messages
parameter BUS_DELAY = 0; // delay in nanoseconds
parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads
parameter RANDOM_SEED = 711689044; //seed value for random generator.
parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe
parameter RDQSEN_PST = 1; // DQS driving time after last read strobe
parameter RDQS_PRE = 2; // DQS low time prior to first read strobe
parameter RDQS_PST = 1; // DQS low time after last read strobe
parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data
parameter RDQEN_PST = 0; // DQ/DM driving time after last read data
parameter WDQS_PRE = 2; // DQS half clock periods prior to first write strobe
parameter WDQS_PST = 1; // DQS half clock periods after last write strobe
// check for legal cas latency based on the cas write latency
function valid_cl;
input [3:0] cl;
input [3:0] cwl;
case ({cwl, cl})
`ifdef sg093
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg093E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13},
{4'd10, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg093F
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd9 },
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13},
{4'd10, 4'd12},
{4'd10, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg107
{4'd5, 4'd6 },
{4'd6, 4'd8 },
{4'd7, 4'd10},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg107E
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg107F
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg125E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11}: valid_cl = 1;
`elsif sg125
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11}: valid_cl = 1;
`elsif sg15E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10}: valid_cl = 1;
`elsif sg15
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd8 },
{4'd7, 4'd10}: valid_cl = 1;
`elsif sg187E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 }: valid_cl = 1;
`elsif sg187
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd8 }: valid_cl = 1;
`elsif sg25E
{4'd5, 4'd5 },
{4'd5, 4'd6 }: valid_cl = 1;
`elsif sg25
{4'd5, 4'd5 },
{4'd5, 4'd6 }: valid_cl = 1;
`endif
default : valid_cl = 0;
endcase
endfunction
// find the minimum valid cas write latency
function [3:0] min_cwl;
input period;
real period;
min_cwl = (period >= 2500.0) ? 5:
(period >= 1875.0) ? 6:
(period >= 1500.0) ? 7:
(period >= 1250.0) ? 8:
(period >= 1070.0) ? 9:
10; // (period >= 935)
endfunction
// find the minimum valid cas latency
function [3:0] min_cl;
input period;
real period;
reg [3:0] cwl;
reg [3:0] cl;
begin
cwl = min_cwl(period);
for (cl=CL_MAX; cl>=CL_MIN; cl=cl-1) begin
if (valid_cl(cl, cwl)) begin
min_cl = cl;
end
end
end
endfunction
files = ["mem_model.vhd", "textutil.vhd", "gn412x_bfm.vhd", "util.vhd"]
/* Crude wrapper for Gennum-provided GN4124x BFM. Supports only single CSR reads/writes so far. */
`ifndef __GN4124_BFM_SVH
`define __GN4124_BFM_SVH 1
`include "simdrv_defs.svh"
interface IGN4124PCIMaster;
int cmd_str_int[256];
reg cmd_req = 0;
wire cmd_ack;
reg internal_rstn = 0;
wire lclk_p, lclk_n, l2p_clk_p, l2p_clk_n, p2l_clk_p, p2l_clk_n;
wire [15:0] l2p_data, p2l_data;
wire l2p_dframe, l2p_valid, l2p_edb;
wire p2l_dframe, p2l_valid, p2l_rdy;
wire [1:0] l_wr_rdy, p_rd_d_rdy;
wire [1:0] p_wr_req, p_wr_rdy, vc_rdy;
wire l2p_rdy, tx_error, rx_error;
wire [15:0] gpio;
// Local bus to Gennum
modport L2P
(
input l2p_clk_n,
input l2p_clk_p,
input l2p_data,
input l2p_dframe,
input l2p_valid,
input l2p_edb,
output l_wr_rdy,
output p_rd_d_rdy,
output l2p_rdy,
output tx_error
);
// Gennum to local bus
modport P2L
(
output p2l_clk_p,
output p2l_clk_n,
output p2l_dframe,
output p2l_data,
output p2l_valid,
input p2l_rdy,
output p_wr_req,
input p_wr_rdy,
input rx_error,
output vc_rdy
);
wire rst_n;
modport SYS
(
output lclk_p,
output lclk_n,
output rst_n,
inout gpio);
wire [31:0] cmd_rddata;
wire cmd_rddata_valid;
GN412X_BFM
U_BFM (
.CMD_INT (cmd_str_int),
.CMD_REQ (cmd_req),
.CMD_ACK (cmd_ack),
.CMD_CLOCK_EN (1'b1),
.CMD_RD_DATA(cmd_rddata),
.CMD_RD_DATA_VALID(cmd_rddata_valid),
.RSTINn (internal_rstn),
.RSTOUT33n(rst_n),
.LCLK (lclk_p),
.LCLKn (lclk_n),
.L2P_CLKp (l2p_clk_p),
.L2P_CLKn (l2p_clk_n),
.L2P_DATA (l2p_data),
.L2P_DFRAME (l2p_dframe),
.L2P_VALID (l2p_valid),
.L2P_EDB (l2p_edb),
.L_WR_RDY (l_wr_rdy),
.P_RD_D_RDY (p_rd_d_rdy),
.L2P_RDY (l2p_rdy),
.TX_ERROR (tx_error),
.P2L_CLKp (p2l_clk_p),
.P2L_CLKn (p2l_clk_n),
.P2L_DATA (p2l_data),
.P2L_DFRAME (p2l_dframe),
.P2L_VALID (p2l_valid),
.P2L_RDY (p2l_rdy),
.P_WR_REQ (p_wr_req),
.P_WR_RDY (p_wr_rdy),
.RX_ERROR (rx_error),
.VC_RDY (vc_rdy),
.GPIO (gpio)
);
int line_no = 1;
task send_cmd(string cmd);
int i;
string cmd_2;
$sformat(cmd_2, "%-1d %s", line_no++, cmd);
// $display("SendCmd '%s'", cmd_2);
for(i=0;i<cmd_2.len(); i++)
cmd_str_int[i] = int'(cmd_2[i]);
cmd_str_int[i] = 0;
#10ns;
cmd_req = 1;
while(!cmd_ack) #1ns;
cmd_req = 0;
while(cmd_ack) #1ns;
#10ns;
endtask // send_cmd
bit ready = 0;
task init();
#100ns;
internal_rstn <= 1;
#100ns;
send_cmd("init");
send_cmd("reset %d16");
send_cmd("bar 0 FF00000000000000 08000000 0 7 0");
send_cmd("bfm_bar 0 0000000040000000 20000000");
send_cmd("bfm_bar 1 0000000020000000 20000000");
send_cmd("wait %d64");
ready = 1;
// send_cmd("wr FF000000000A0004 F 007C0270");
// send_cmd("rd FF000000000A0004 F");
endtask // init
initial init();
task automatic readback(ref uint64_t value);
@(posedge cmd_rddata_valid);
value = cmd_rddata;
@(negedge cmd_rddata_valid);
endtask // readback
class CBusAccessor_Gennum extends CBusAccessor;
function new();
endfunction // new
task writem(uint64_t addr[], uint64_t data[], input int size, ref int result);
string cmd;
int i;
if(size != 4)
$fatal("CBusAccessor_Gennum: only size=4 supported");
for(i=0;i<addr.size();i++)
begin
$sformat(cmd,"wr FF000000%08X F %08X", addr[i], data[i]);
send_cmd(cmd);
end
endtask // writem
task readm(uint64_t addr[], ref uint64_t data[], input int size, ref int result);
string cmd;
int i;
uint64_t tmp;
if(size != 4)
$fatal("CBusAccessor_Gennum: only size=4 supported");
for(i=0;i<addr.size();i++)
begin
$sformat(cmd,"rd FF000000%08X F", addr[i]);
fork
send_cmd(cmd);
readback(tmp);
join
data[i] = tmp;
end
endtask // readm
endclass // CBusAccessor_Gennum
function CBusAccessor get_accessor();
CBusAccessor_Gennum g = new;
return g;
endfunction
endinterface
/* Helper macro for wiring Gennum-Xilinx ports in spec_top */
`define GENNUM_WIRE_SPEC_PINS(IF_NAME) \
.L_RST_N (IF_NAME.SYS.rst_n),\
.L_CLKp (IF_NAME.SYS.lclk_p),\
.L_CLKn (IF_NAME.SYS.lclk_n),\
.p2l_clkp (IF_NAME.P2L.p2l_clk_p),\
.p2l_clkn (IF_NAME.P2L.p2l_clk_n),\
.p2l_data (IF_NAME.P2L.p2l_data),\
.p2l_dframe (IF_NAME.P2L.p2l_dframe),\
.p2l_valid (IF_NAME.P2L.p2l_valid),\
.p2l_rdy (IF_NAME.P2L.p2l_rdy),\
.p_wr_req (IF_NAME.P2L.p_wr_req),\
.p_wr_rdy (IF_NAME.P2L.p_wr_rdy),\
.rx_error (IF_NAME.P2L.rx_error),\
.l2p_clkp (IF_NAME.L2P.l2p_clk_p),\
.l2p_clkn (IF_NAME.L2P.l2p_clk_n),\
.l2p_data (IF_NAME.L2P.l2p_data),\
.l2p_dframe (IF_NAME.L2P.l2p_dframe),\
.l2p_valid (IF_NAME.L2P.l2p_valid),\
.l2p_edb (IF_NAME.L2P.l2p_edb),\
.l2p_rdy (IF_NAME.L2P.l2p_rdy),\
.l_wr_rdy (IF_NAME.L2P.l_wr_rdy),\
.p_rd_d_rdy (IF_NAME.L2P.p_rd_d_rdy),\
.tx_error (IF_NAME.L2P.tx_error),\
.vc_rdy (IF_NAME.P2L.vc_rdy)
`endif // `ifndef __GN4124_BFM_SVH
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
use work.util.all;
-----------------------------------------------------------------------------
-- *Module : textutil
--
-- *Description : Improved Free-format string and line manipulation
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
-----------------------------------------------------------------------------
package textutil is
procedure read_token(L : inout line; X : out STRING);
procedure sget_token(S : in string; P : inout integer; X : out STRING);
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_int(S : in string; P : inout integer; X : out integer);
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR;
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character;
function is_hex(C : in character) return BOOLEAN;
function hex_char_to_int(C : in character) return integer;
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR);
procedure read_int(L : inout line; I : out integer);
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR);
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING;
function to_str(constant V: in STD_ULOGIC) return STRING;
function to_str(constant val : in INTEGER) return STRING;
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING;
end textutil;
package body textutil is
-----------------------------------------------------------------------------
-- *Module : read_token
--
-- *Description : Skip over spaces then load a token string from a line
-- until either the string is full or the token is finished
-- (i.e. another space). The output string is padded out
-- with blanks at the end if the token length is less then
-- the full string length.
-----------------------------------------------------------------------------
procedure read_token(L : inout line; X : out STRING) is
variable char : character;
begin
if(L'length > 0) then
char := ' ';
while((char = ' ') and (L'length > 0)) loop -- Skip spaces
read(L, char);
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(L'length > 0) then
read(L, char);
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from file"
severity error;
end if;
end read_token;
-----------------------------------------------------------------------------
-- *Module : sget_token
--
-- *Description : Same as read_token except for strings.
-----------------------------------------------------------------------------
procedure sget_token(S : in string; P : inout integer; X : out STRING) is
variable char : character;
begin
if(S'length > P) then
char := ' ';
while((char = ' ') and (S'length >= P)) loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(S'length > P) then
char := S(P);
P := P + 1;
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from a string"
severity error;
end if;
end sget_token;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_vector
--
-- *Description : Convert a hex character to a vector
-----------------------------------------------------------------------------
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR is
variable X : STD_ULOGIC_VECTOR( 3 downto 0);
begin
case C is
when '0' => X := "0000";
when '1' => X := "0001";
when '2' => X := "0010";
when '3' => X := "0011";
when '4' => X := "0100";
when '5' => X := "0101";
when '6' => X := "0110";
when '7' => X := "0111";
when '8' => X := "1000";
when '9' => X := "1001";
when 'A' => X := "1010";
when 'B' => X := "1011";
when 'C' => X := "1100";
when 'D' => X := "1101";
when 'E' => X := "1110";
when 'F' => X := "1111";
when 'a' => X := "1010";
when 'b' => X := "1011";
when 'c' => X := "1100";
when 'd' => X := "1101";
when 'e' => X := "1110";
when 'f' => X := "1111";
when others =>
X := "0000";
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_vector;
-----------------------------------------------------------------------------
-- *Module : vector_to_hex_char
--
-- *Description : Convert a vector to a hex character. Only uses low 4 bits.
-----------------------------------------------------------------------------
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(3 downto 0);
begin
if(V'length < 4) then
VV := To_X01(V(V'low + 3 downto V'low));
else
VV := To_X01(V(V'low + V'length - 1 downto V'low));
end if;
case VV is
when "0000" => C := '0';
when "0001" => C := '1';
when "0010" => C := '2';
when "0011" => C := '3';
when "0100" => C := '4';
when "0101" => C := '5';
when "0110" => C := '6';
when "0111" => C := '7';
when "1000" => C := '8';
when "1001" => C := '9';
when "1010" => C := 'A';
when "1011" => C := 'B';
when "1100" => C := 'C';
when "1101" => C := 'D';
when "1110" => C := 'E';
when "1111" => C := 'F';
when others => C := 'X';
end case;
return(C);
end vector_to_hex_char;
-----------------------------------------------------------------------------
-- *Module : is_hex
--
-- *Description : report if a char is ASCII hex
-----------------------------------------------------------------------------
function is_hex(C : in character) return BOOLEAN is
variable X : boolean;
begin
case C is
when '0' => X := TRUE;
when '1' => X := TRUE;
when '2' => X := TRUE;
when '3' => X := TRUE;
when '4' => X := TRUE;
when '5' => X := TRUE;
when '6' => X := TRUE;
when '7' => X := TRUE;
when '8' => X := TRUE;
when '9' => X := TRUE;
when 'A' => X := TRUE;
when 'B' => X := TRUE;
when 'C' => X := TRUE;
when 'D' => X := TRUE;
when 'E' => X := TRUE;
when 'F' => X := TRUE;
when 'a' => X := TRUE;
when 'b' => X := TRUE;
when 'c' => X := TRUE;
when 'd' => X := TRUE;
when 'e' => X := TRUE;
when 'f' => X := TRUE;
when others =>
X := FALSE;
end case;
return(X);
end is_hex;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_int
--
-- *Description : Convert a hex character to an integer
-----------------------------------------------------------------------------
function hex_char_to_int(C : in character) return integer is
variable X : integer;
begin
case C is
when '0' => X := 0;
when '1' => X := 1;
when '2' => X := 2;
when '3' => X := 3;
when '4' => X := 4;
when '5' => X := 5;
when '6' => X := 6;
when '7' => X := 7;
when '8' => X := 8;
when '9' => X := 9;
when 'A' => X := 10;
when 'B' => X := 11;
when 'C' => X := 12;
when 'D' => X := 13;
when 'E' => X := 14;
when 'F' => X := 15;
when 'a' => X := 10;
when 'b' => X := 11;
when 'c' => X := 12;
when 'd' => X := 13;
when 'e' => X := 14;
when 'f' => X := 15;
when others =>
X := 0;
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_int;
-----------------------------------------------------------------------------
-- *Module : read_vector
--
-- *Description : load a vector from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
else
assert false report "Couldn't read a vector"
severity error;
end if;
end read_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector
--
-- *Description : Same as sget_vector except for strings
-----------------------------------------------------------------------------
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
q := 0;
char := S(P);
if(is_hex(char)) then
while(is_hex(char) and not (S'length = P)) loop
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector_64
--
-- *Description : Same as sget_vector except can handle 64 bit quantities and hex or binary base (no base 10)
-----------------------------------------------------------------------------
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(63 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
char := S(P);
-- P := P + 1;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
v := (others => '0');
char := S(P);
if(base = 2) then
while(((char = '0') or (char = '1')) and not (P > S'length)) loop
if(char = '0') then
v := v(v'high-1 downto 0) & '0';
else
v := v(v'high-1 downto 0) & '1';
end if;
P := P + 1;
char := S(P);
end loop;
else
while(is_hex(char) and not (P > S'length)) loop
if(is_hex(char)) then
v := v(v'high-4 downto 0) & hex_char_to_vector(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector_64;
-----------------------------------------------------------------------------
-- *Module : read_int
--
-- *Description : load an integer from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_int(L : inout line; I : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
I := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end read_int;
-----------------------------------------------------------------------------
-- *Module : sget_int
--
-- *Description : Same as read_int except for strings
-----------------------------------------------------------------------------
procedure sget_int(S : in string; P : inout integer; X : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(S'length > P) then
char := ' ';
while(char = ' ') loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
char := S(P);
P := P + 1;
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (S'length = P)) loop
char := S(P);
P := P + 1;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
X := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end sget_int;
-----------------------------------------------------------------------------
-- *Module : write_hex_vector
--
-- *Description : writes out a vector as hex
-----------------------------------------------------------------------------
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR) is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(((V'length + 3)/4) * 4 - 1 downto 0);
begin
VV := (others => '0');
VV(V'length -1 downto 0) := V;
for i in VV'length/4 - 1 downto 0 loop
C := vector_to_hex_char(VV(i*4+3 downto i*4));
write(L, C);
end loop;
end write_hex_vector;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC_VECTOR to a string of the same length
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING is
variable S : STRING(1 to V'length);
variable sp : integer;
begin
sp := 1;
for i in V'range loop
case V(i) is
when '1' | 'H' =>
S(sp) := '1';
when '0' | 'L' =>
S(sp) := '0';
when others =>
S(sp) := 'X';
end case;
sp := sp + 1;
end loop;
return(S);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC to a string
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC) return STRING is
-- variable S : STRING(1);
begin
case V is
when '1' | 'H' =>
return("1");
when '0' | 'L' =>
return("0");
when others =>
return("X");
end case;
return("X");
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a integer to a string
-----------------------------------------------------------------------------
function to_str(constant val : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result((pos-1) downto 1);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_strn
--
-- *Description : Converts an integer to a string of length N
-----------------------------------------------------------------------------
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
result := (others => ' ');
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result(n downto 1);
end to_strn;
end textutil;
library ieee;
use ieee.std_logic_1164.all;
--library synopsys;
--use synopsys.arithmetic.all;
package UTIL is
type t_cmd_array is array (1 to 256) of integer;
function to_mvl ( b: in boolean ) return STD_ULOGIC;
function to_mvl ( i: in integer ) return STD_ULOGIC;
function to_vector(input,num_bits:integer) return STD_ULOGIC_VECTOR;
-- function to_signed( b: in std_ulogic_vector ) return signed;
-- function to_std_ulogic_vector( b: in signed ) return std_ulogic_vector;
-- function std_logic_to_std_ulogic( b: in std_logic ) return std_ulogic;
-- function std_ulogic_to_std_logic( b: in std_ulogic ) return std_logic;
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC;
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC;
function exp(input: STD_ULOGIC; num_bits: integer) return STD_ULOGIC_VECTOR;
function exp(input: STD_ULOGIC_VECTOR; num_bits: integer) return STD_ULOGIC_VECTOR;
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer;
function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function to_int(l: std_ulogic_vector) return natural;
function to_int(l: std_ulogic) return natural;
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function ge ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function gt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function lt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function eq ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function maximum ( arg1, arg2 : INTEGER) return INTEGER;
function minimum ( arg1, arg2 : INTEGER) return INTEGER;
procedure keep(signal X: inout STD_LOGIC);
function log2(A: in integer) return integer;
-------------------------------------------------------------------
-- Declaration of Synthesis directive attributes
-------------------------------------------------------------------
ATTRIBUTE synthesis_return : string ;
end UTIL;
package body UTIL is
--------------------------------------------------------------------
-- function to_signed ( b: in std_ulogic_vector ) return signed is
-- variable result : signed(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_signed;
--------------------------------------------------------------------
-- function to_std_ulogic_vector ( b: in signed ) return std_ulogic_vector is
-- variable result : std_ulogic_vector(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_std_ulogic_vector;
--------------------------------------------------------------------
function to_mvl ( b: in boolean ) return STD_ULOGIC is
begin
if ( b = TRUE ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function to_mvl ( i: in integer ) return STD_ULOGIC is
begin
if ( i = 1 ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l = '1') then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r = '1') then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l) then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r) then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (l) then
ll := r;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (r) then
ll := l;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
-- function std_ulogic_to_std_logic(b : std_ulogic) return std_logic is
-- variable result: std_logic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
-- function std_logic_to_std_ulogic(b : std_logic) return std_ulogic is
-- variable result: std_ulogic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
function to_vector(input,num_bits: integer) return std_ulogic_vector is
variable vec: std_ulogic_vector(num_bits-1 downto 0);
variable a: integer;
begin
a := input;
for i in 0 to num_bits-1 loop
if ((a mod 2) = 1) then
vec(i) := '1';
else
vec(i) := '0';
end if;
a := a / 2;
end loop;
return vec;
end to_vector;
-- FUNCTION to_vector(input,num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
-- VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
-- VARIABLE weight:integer;
-- VARIABLE temp:integer;
-- BEGIN
-- weight := 2**(num_bits-1);
-- temp := input;
-- FOR i in result'HIGH DOWNTO result'LOW LOOP
-- IF temp >= weight THEN
-- result(i) := '1';
-- temp := temp - weight;
-- ELSE
-- result(i) := '0';
-- END IF;
-- weight := weight/2;
-- END LOOP;
-- RETURN result;
-- END to_vector;
--------------------------------------------------------------------
-- exp: Expand one bit into many
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
FOR i in result'HIGH DOWNTO result'LOW LOOP
result(i) := input;
END LOOP;
RETURN result;
END exp;
--------------------------------------------------------------------
-- exp: Expand n bits into m bits
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC_VECTOR; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
result(input'high-input'low downto 0) := input;
result(num_bits-1 downto input'high-input'low+1) := (others => '0');
RETURN result;
END exp;
--------------------------------------------------------------------
-- conv_integer
--------------------------------------------------------------------
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer is
variable result: INTEGER;
begin
assert ARG'length <= 31
report "ARG is too large in CONV_INTEGER"
severity FAILURE;
result := 0;
for i in ARG'range loop
result := result * 2;
if(ARG(i) = 'H' or ARG(i) = '1') then
result := result + 1;
end if;
end loop;
return result;
end;
--------------------------------------------------------------------
-- "+" Increment function
--------------------------------------------------------------------
function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable Q: STD_ULOGIC_VECTOR(L'range);
variable A: STD_ULOGIC;
begin
A := R;
for i in L'low to L'high loop
Q(i) := L(i) xor A;
A := A and L(i);
end loop;
return Q;
end;
--------------------------------------------------------------------
-- "+" adder function
--------------------------------------------------------------------
-- function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) + to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- "-" Decrement function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
-- variable Q: STD_ULOGIC_VECTOR(L'range);
-- variable A: STD_ULOGIC;
-- begin
-- A := R;
-- for i in L'low to L'high loop
-- Q(i) := L(i) xor A;
-- A := A and not L(i);
-- end loop;
-- return Q;
-- end;
--------------------------------------------------------------------
-- "-" subtractor function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) - to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic_vector) return natural is
variable result: natural := 0;
begin
for t1 in l'range loop
result := result * 2;
if (l(t1) = '1') or (l(t1) = 'H') then
result := result + 1;
end if;
end loop;
return result;
end to_int;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic) return natural is
variable result: natural := 0;
begin
if (l = '1') or (l = 'H') then
result := 1;
else
result := 0;
end if;
return result;
end to_int;
--------------------------------------------------------------------
-- Reduce Functions
--------------------------------------------------------------------
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '1';
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not and_reduce(ARG);
end;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not or_reduce(ARG);
end;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result xor ARG(i);
end loop;
return result;
end;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not xor_reduce(ARG);
end;
--------------------------------------------------------------------
-- Some useful generic functions
--------------------------------------------------------------------
--//// Zero Extend ////
--
-- Function zxt
--
FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
-- Hidden function. Synthesis directives are present in its callers
BEGIN
qt := q;
IF i < q'length THEN
qs := qt( (q'length-i+1) TO qt'right);
ELSIF i > q'length THEN
qs := (OTHERS=>'0');
qs := qs(1 TO (i-q'length)) & qt;
ELSE
qs := qt;
END IF;
RETURN qs;
END;
FUNCTION maximum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 > arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
FUNCTION minimum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 < arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
--------------------------------------------------------------------
-- Comparision functions
--------------------------------------------------------------------
--
-- Equal functions.
--
TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
CONSTANT eq_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Equal for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
result := eq_table( l, r );
RETURN result ;
END;
FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Arithmetic Equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := FALSE;
RETURN result ;
END IF;
END LOOP;
RETURN TRUE;
END;
TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
-- ----------------------------------------------------
-- | U X 0 1 Z W L H D | |
-- ----------------------------------------------------
( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
);
FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
VARIABLE lt : std_ulogic_vector ( 1 to ml );
VARIABLE rt : std_ulogic_vector ( 1 to ml );
VARIABLE res : std_ulogic_fuzzy_state;
-- Greater-than-or-equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GTE" ;
begin
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'RANGE LOOP
res := ge_fuzzy_table( lt(i), rt(i) );
CASE res IS
WHEN 'U' => RETURN FALSE;
WHEN 'X' => RETURN FALSE;
WHEN 'T' => RETURN TRUE;
WHEN 'F' => RETURN FALSE;
WHEN OTHERS => null;
END CASE;
END LOOP;
result := TRUE ;
RETURN result;
end ;
--
-- Greater Than functions.
--
CONSTANT gtb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
-- Greater-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
result := gtb_table( l, r );
RETURN result ;
END ;
FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Greater-than for two logic unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := gt( lt(i), rt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--
-- Less Than functions.
--
CONSTANT ltb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Less-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
result := ltb_table( l, r );
RETURN result ;
END;
FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Less-than for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
ltt := zxt( l, ml );
rtt := zxt( r, ml );
FOR i IN ltt'range LOOP
IF NOT eq( ltt(i), rtt(i) ) THEN
result := lt( ltt(i), rtt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--------------------------------------------------------------------
-- "keep" Retain Last value when floated
--------------------------------------------------------------------
procedure keep(signal X: inout STD_LOGIC) is
begin
if(X = 'Z') then
if(X'last_value = '0') then
X <= 'L';
elsif(X'last_value = '1') then
X <= 'H';
else
X <= 'Z';
end if;
else
X <= 'Z';
end if;
end keep;
---------------------------------------------------------------------
-- log base 2 function
---------------------------------------------------------------------
function log2 ( A: in integer ) return integer is
variable B : integer;
begin
B := 1;
for i in 0 to 31 loop
if not ( A > B ) then
return ( i );
exit;
end if;
B := B * 2;
end loop;
end log2;
end UTIL;
`timescale 1ns/1ps
`include "gn4124_bfm.svh"
`include "if_wb_master.svh"
`include "if_wb_slave.svh"
module main;
reg clk_125m_pllref = 0;
reg clk_20m_vcxo = 0;
reg clk_ext = 0;
reg rst_n = 0;
reg adc0_dco = 0;
reg adc0_fr = 0;
always #5ns adc0_dco <= ~adc0_dco;
always #50ns clk_ext <= ~clk_ext;
always #4ns clk_125m_pllref <= ~clk_125m_pllref;
always #20ns clk_20m_vcxo <= ~clk_20m_vcxo;
IGN4124PCIMaster I_Gennum ();
wire ddr_cas_n, ddr_ck_p, ddr_ck_n, ddr_cke;
wire ddr_ldm, ddr_ldqs_p, ddr_ldqs_n, ddr_odt, ddr_ras_n, ddr_reset_n;
wire ddr_udm, ddr_udqs_n, ddr_udqs_p, ddr_we_n;
wire [15:0] ddr_dq;
wire [13:0] ddr_a;
wire [2:0] ddr_ba;
wire ddr_zio, ddr_rzq;
pulldown(ddr_rzq);
spec_top_fmc_adc_100Ms
#(
.g_simulation("TRUE"),
.g_calib_soft_ip("FALSE")
) DUT (
.clk20_vcxo_i(clk_20m_vcxo),
.adc0_dco_p_i(adc0_dco),
.adc0_dco_n_i(~adc0_dco),
.adc0_fr_p_i(adc0_fr),
.adc0_fr_n_i(~adc0_fr),
.DDR3_CAS_N (ddr_cas_n),
.DDR3_CK_N(ddr_ck_n),
.DDR3_CK_P (ddr_ck_p),
.DDR3_CKE (ddr_cke),
.DDR3_LDM (ddr_ldm),
.DDR3_LDQS_N (ddr_ldqs_n),
.DDR3_LDQS_P (ddr_ldqs_p),
.DDR3_ODT (ddr_odt),
.DDR3_RAS_N (ddr_ras_n),
.DDR3_RESET_N (ddr_reset_n),
.DDR3_UDM (ddr_udm),
.DDR3_UDQS_N (ddr_udqs_n),
.DDR3_UDQS_P (ddr_udqs_p),
.DDR3_WE_N (ddr_we_n),
.DDR3_DQ (ddr_dq),
.DDR3_A (ddr_a),
.DDR3_BA (ddr_ba),
.DDR3_ZIO (ddr_zio),
.DDR3_RZQ (ddr_rzq),
`GENNUM_WIRE_SPEC_PINS(I_Gennum)
);
ddr3 #(
.DEBUG(1)
) mem (
.rst_n(ddr_reset_n),
.ck(ddr_ck_p),
.ck_n(ddr_ck_n),
.cke(ddr_cke),
.cs_n(1'b0),
.ras_n(ddr_ras_n),
.cas_n(ddr_cas_n),
.we_n(ddr_we_n),
.dm_tdqs({ddr_udm, ddr_ldm}),
.ba(ddr_ba),
.addr(ddr_a),
.dq(ddr_dq),
.dqs({ddr_udqs_p, ddr_ldqs_p}),
.dqs_n({ddr_udqs_n, ddr_ldqs_n}),
.tdqs_n(),
.odt(ddr_odt)
);
int adc_div = 0;
always@(posedge adc0_dco)
if(adc_div==3)
begin
adc0_fr <= 1;
adc_div <= 0;
end else begin
adc0_fr <= 0;
adc_div <= adc_div + 1;
end
initial begin
CBusAccessor acc;
uint64_t rv;
@(posedge I_Gennum.ready);
acc = I_Gennum.get_accessor();
#40us;
acc.set_default_xfer_size(4);
acc.read(0, rv);
$display("ID: %x", rv);
acc.write('h100c,'h1000); // host addr
acc.write('h1010,0);
acc.write('h1014,'h1000); // len
acc.write('h1018, 0); // next
acc.write('h101c,0);
acc.write('h1008,'h0);
acc.write('h1020,'h0); // attrib: pcie -> host
acc.write('h1000,'h1); // xfer start
end
endmodule // main
vsim -t 1ps -L unisim -L XilinxCoreLib work.main -novopt
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
do wave.do
radix -hexadecimal
run 100us
wave zoomfull
radix -hexadecimal
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/clk_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/rst_n_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_irq_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_target_addr_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_host_addr_h_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_host_addr_l_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_len_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_start_l2p_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_done_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_error_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_byte_swap_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_ctrl_abort_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_valid_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_dframe_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_data_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_req_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/arb_ldm_gnt_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_edb_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l_wr_rdy_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_rdy_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/tx_error_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_clk_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_adr_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_dat_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_dat_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_sel_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_cyc_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_stb_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_we_o
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_ack_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_stall_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/p2l_dma_cyc_i
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/fifo_rst
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/fifo_rst_t
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_rd
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_wr
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_empty
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_full
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_dout
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_din
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_rd
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_wr
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_empty
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_full
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_dout
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_din
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_current_state
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/s_l2p_header
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_len_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_address_h
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_address_l
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_data_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_64b_address
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_len_header
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_byte_swap
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_last_packet
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_lbe_header
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_data_l
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_valid
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/data_fifo_valid
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/addr_fifo_valid
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/target_addr_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/dma_length_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_timeout_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/wb_timeout_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_cyc_t
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_dma_stb_t
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/wb_ack_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/wb_read_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_cyc_start
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/wb_cyc_start
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/l2p_cyc_cnt
add wave -noupdate -group l2p_dma /main/DUT/cmp_gn4124_core/cmp_l2p_dma_master/wb_cyc_cnt
add wave -noupdate -group Top /main/DUT/clk20_vcxo_i
add wave -noupdate -group Top /main/DUT/pll25dac_sync_n_o
add wave -noupdate -group Top /main/DUT/pll20dac_sync_n_o
add wave -noupdate -group Top /main/DUT/plldac_din_o
add wave -noupdate -group Top /main/DUT/plldac_sclk_o
add wave -noupdate -group Top /main/DUT/led_red_o
add wave -noupdate -group Top /main/DUT/led_green_o
add wave -noupdate -group Top /main/DUT/aux_leds_o
add wave -noupdate -group Top /main/DUT/aux_buttons_i
add wave -noupdate -group Top /main/DUT/pcb_ver_i
add wave -noupdate -group Top /main/DUT/carrier_one_wire_b
add wave -noupdate -group Top /main/DUT/L_CLKp
add wave -noupdate -group Top /main/DUT/L_CLKn
add wave -noupdate -group Top /main/DUT/L_RST_N
add wave -noupdate -group Top /main/DUT/P2L_RDY
add wave -noupdate -group Top /main/DUT/P2L_CLKn
add wave -noupdate -group Top /main/DUT/P2L_CLKp
add wave -noupdate -group Top /main/DUT/P2L_DATA
add wave -noupdate -group Top /main/DUT/P2L_DFRAME
add wave -noupdate -group Top /main/DUT/P2L_VALID
add wave -noupdate -group Top /main/DUT/P_WR_REQ
add wave -noupdate -group Top /main/DUT/P_WR_RDY
add wave -noupdate -group Top /main/DUT/RX_ERROR
add wave -noupdate -group Top /main/DUT/L2P_DATA
add wave -noupdate -group Top /main/DUT/L2P_DFRAME
add wave -noupdate -group Top /main/DUT/L2P_VALID
add wave -noupdate -group Top /main/DUT/L2P_CLKn
add wave -noupdate -group Top /main/DUT/L2P_CLKp
add wave -noupdate -group Top /main/DUT/L2P_EDB
add wave -noupdate -group Top /main/DUT/L2P_RDY
add wave -noupdate -group Top /main/DUT/L_WR_RDY
add wave -noupdate -group Top /main/DUT/P_RD_D_RDY
add wave -noupdate -group Top /main/DUT/TX_ERROR
add wave -noupdate -group Top /main/DUT/VC_RDY
add wave -noupdate -group Top /main/DUT/GPIO
add wave -noupdate -group Top /main/DUT/DDR3_CAS_N
add wave -noupdate -group Top /main/DUT/DDR3_CK_N
add wave -noupdate -group Top /main/DUT/DDR3_CK_P
add wave -noupdate -group Top /main/DUT/DDR3_CKE
add wave -noupdate -group Top /main/DUT/DDR3_LDM
add wave -noupdate -group Top /main/DUT/DDR3_LDQS_N
add wave -noupdate -group Top /main/DUT/DDR3_LDQS_P
add wave -noupdate -group Top /main/DUT/DDR3_ODT
add wave -noupdate -group Top /main/DUT/DDR3_RAS_N
add wave -noupdate -group Top /main/DUT/DDR3_RESET_N
add wave -noupdate -group Top /main/DUT/DDR3_UDM
add wave -noupdate -group Top /main/DUT/DDR3_UDQS_N
add wave -noupdate -group Top /main/DUT/DDR3_UDQS_P
add wave -noupdate -group Top /main/DUT/DDR3_WE_N
add wave -noupdate -group Top /main/DUT/DDR3_DQ
add wave -noupdate -group Top /main/DUT/DDR3_A
add wave -noupdate -group Top /main/DUT/DDR3_BA
add wave -noupdate -group Top /main/DUT/DDR3_ZIO
add wave -noupdate -group Top /main/DUT/DDR3_RZQ
add wave -noupdate -group Top /main/DUT/adc0_ext_trigger_p_i
add wave -noupdate -group Top /main/DUT/adc0_ext_trigger_n_i
add wave -noupdate -group Top /main/DUT/adc0_dco_p_i
add wave -noupdate -group Top /main/DUT/adc0_dco_n_i
add wave -noupdate -group Top /main/DUT/adc0_fr_p_i
add wave -noupdate -group Top /main/DUT/adc0_fr_n_i
add wave -noupdate -group Top /main/DUT/adc0_outa_p_i
add wave -noupdate -group Top /main/DUT/adc0_outa_n_i
add wave -noupdate -group Top /main/DUT/adc0_outb_p_i
add wave -noupdate -group Top /main/DUT/adc0_outb_n_i
add wave -noupdate -group Top /main/DUT/adc0_spi_din_i
add wave -noupdate -group Top /main/DUT/adc0_spi_dout_o
add wave -noupdate -group Top /main/DUT/adc0_spi_sck_o
add wave -noupdate -group Top /main/DUT/adc0_spi_cs_adc_n_o
add wave -noupdate -group Top /main/DUT/adc0_spi_cs_dac1_n_o
add wave -noupdate -group Top /main/DUT/adc0_spi_cs_dac2_n_o
add wave -noupdate -group Top /main/DUT/adc0_spi_cs_dac3_n_o
add wave -noupdate -group Top /main/DUT/adc0_spi_cs_dac4_n_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_dac_clr_n_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_led_acq_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_led_trig_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_ssr_ch1_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_ssr_ch2_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_ssr_ch3_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_ssr_ch4_o
add wave -noupdate -group Top /main/DUT/adc0_gpio_si570_oe_o
add wave -noupdate -group Top /main/DUT/adc0_si570_scl_b
add wave -noupdate -group Top /main/DUT/adc0_si570_sda_b
add wave -noupdate -group Top /main/DUT/adc0_one_wire_b
add wave -noupdate -group Top /main/DUT/fmc0_prsnt_m2c_n_i
add wave -noupdate -group Top /main/DUT/fmc0_sys_scl_b
add wave -noupdate -group Top /main/DUT/fmc0_sys_sda_b
add wave -noupdate -group Top /main/DUT/sys_clk_in
add wave -noupdate -group Top /main/DUT/sys_clk_125_buf
add wave -noupdate -group Top /main/DUT/sys_clk_250_buf
add wave -noupdate -group Top /main/DUT/sys_clk_125
add wave -noupdate -group Top /main/DUT/sys_clk_250
add wave -noupdate -group Top /main/DUT/sys_clk_fb
add wave -noupdate -group Top /main/DUT/sys_clk_pll_locked
add wave -noupdate -group Top /main/DUT/ddr_clk
add wave -noupdate -group Top /main/DUT/ddr_clk_buf
add wave -noupdate -group Top /main/DUT/l_clk
add wave -noupdate -group Top /main/DUT/powerup_reset_cnt
add wave -noupdate -group Top /main/DUT/powerup_rst_n
add wave -noupdate -group Top /main/DUT/sw_rst_fmc0_n
add wave -noupdate -group Top /main/DUT/sw_rst_fmc0_n_o
add wave -noupdate -group Top /main/DUT/sw_rst_fmc0_n_i
add wave -noupdate -group Top /main/DUT/sw_rst_fmc0_n_load
add wave -noupdate -group Top /main/DUT/sys_rst_n
add wave -noupdate -group Top /main/DUT/fmc0_rst_n
add wave -noupdate -group Top /main/DUT/cnx_master_out
add wave -noupdate -group Top /main/DUT/cnx_master_in
add wave -noupdate -group Top /main/DUT/cnx_slave_out
add wave -noupdate -group Top /main/DUT/cnx_slave_in
add wave -noupdate -group Top /main/DUT/gn_wb_adr
add wave -noupdate -group Top /main/DUT/dma_ctrl_wb_adr
add wave -noupdate -group Top /main/DUT/wb_dma_adr
add wave -noupdate -group Top /main/DUT/wb_dma_dat_i
add wave -noupdate -group Top /main/DUT/wb_dma_dat_o
add wave -noupdate -group Top /main/DUT/wb_dma_sel
add wave -noupdate -group Top /main/DUT/wb_dma_cyc
add wave -noupdate -group Top /main/DUT/wb_dma_stb
add wave -noupdate -group Top /main/DUT/wb_dma_we
add wave -noupdate -group Top /main/DUT/wb_dma_ack
add wave -noupdate -group Top /main/DUT/wb_dma_stall
add wave -noupdate -group Top /main/DUT/wb_dma_err
add wave -noupdate -group Top /main/DUT/wb_dma_rty
add wave -noupdate -group Top /main/DUT/wb_dma_int
add wave -noupdate -group Top /main/DUT/wb_ddr_adr
add wave -noupdate -group Top /main/DUT/wb_ddr_dat_o
add wave -noupdate -group Top /main/DUT/wb_ddr_sel
add wave -noupdate -group Top /main/DUT/wb_ddr_cyc
add wave -noupdate -group Top /main/DUT/wb_ddr_stb
add wave -noupdate -group Top /main/DUT/wb_ddr_we
add wave -noupdate -group Top /main/DUT/wb_ddr_ack
add wave -noupdate -group Top /main/DUT/wb_ddr_stall
add wave -noupdate -group Top /main/DUT/dma_irq
add wave -noupdate -group Top /main/DUT/dma_irq_p
add wave -noupdate -group Top /main/DUT/trig_irq_p
add wave -noupdate -group Top /main/DUT/acq_end_irq_p
add wave -noupdate -group Top /main/DUT/irq_sources
add wave -noupdate -group Top /main/DUT/irq_to_gn4124
add wave -noupdate -group Top /main/DUT/irq_sources_2_led
add wave -noupdate -group Top /main/DUT/ddr_wr_fifo_empty
add wave -noupdate -group Top /main/DUT/dma_eic_irq
add wave -noupdate -group Top /main/DUT/fmc0_eic_irq
add wave -noupdate -group Top /main/DUT/led_red
add wave -noupdate -group Top /main/DUT/led_green
add wave -noupdate -group Top /main/DUT/gpio_stat
add wave -noupdate -group Top /main/DUT/gpio_ctrl_1
add wave -noupdate -group Top /main/DUT/gpio_ctrl_2
add wave -noupdate -group Top /main/DUT/gpio_ctrl_3
add wave -noupdate -group Top /main/DUT/gpio_led_ctrl
add wave -noupdate -group Top /main/DUT/gn4124_status
add wave -noupdate -group Top /main/DUT/p2l_pll_locked
add wave -noupdate -group Top /main/DUT/ddr3_status
add wave -noupdate -group Top /main/DUT/ddr3_calib_done
add wave -noupdate -group Top /main/DUT/spi_din_t
add wave -noupdate -group Top /main/DUT/spi_ss_t
add wave -noupdate -group Top /main/DUT/carrier_owr_en
add wave -noupdate -group Top /main/DUT/carrier_owr_i
add wave -noupdate -group Top /main/DUT/led_pwm_update_cnt
add wave -noupdate -group Top /main/DUT/led_pwm_update
add wave -noupdate -group Top /main/DUT/led_pwm_val
add wave -noupdate -group Top /main/DUT/led_pwm_val_down
add wave -noupdate -group Top /main/DUT/led_pwm_cnt
add wave -noupdate -group Top /main/DUT/led_pwm
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/clk_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/rst_n_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/status_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_dq_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_a_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_ba_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_ras_n_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_cas_n_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_we_n_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_odt_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_rst_n_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_cke_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_dm_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_udm_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_dqs_p_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_dqs_n_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_udqs_p_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_udqs_n_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_clk_p_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_clk_n_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_rzq_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/ddr3_zio_b
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_clk_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_sel_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_cyc_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_stb_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_we_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_addr_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_data_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_data_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_ack_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb0_stall_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_count_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_overflow_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_error_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_count_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_underrun_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_error_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_clk_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_sel_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_cyc_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_stb_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_we_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_addr_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_data_i
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_data_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_ack_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/wb1_stall_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_count_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_overflow_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_error_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_full_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_empty_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_count_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_underrun_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_error_o
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_instr
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_bl
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_byte_addr
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_cmd_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_mask
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_data
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_count
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_underrun
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_wr_error
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_data
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_count
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_overflow
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p0_rd_error
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_instr
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_bl
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_byte_addr
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_cmd_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_mask
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_data
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_count
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_underrun
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_wr_error
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_clk
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_en
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_data
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_full
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_empty
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_count
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_overflow
add wave -noupdate -group DDRC /main/DUT/cmp_ddr_ctrl/p1_rd_error
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/rst_n_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_clk_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_en_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_instr_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_bl_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_byte_addr_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_empty_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_full_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_clk_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_en_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_mask_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_data_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_full_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_empty_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_count_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_underrun_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_error_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_clk_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_en_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_data_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_full_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_empty_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_count_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_overflow_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_error_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_clk_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_sel_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_cyc_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stb_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_we_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_addr_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_data_i
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_data_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_ack_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall_o
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_wr_ack
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_ack
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_rd_en
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_en
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_cmd_full
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall_d
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall_dd
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_we_d
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_addr_d
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall_restart
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/addr_shift
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/wb_stall_cnt
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_burst_cnt
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/ddr_burst_cnt_d
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/read_cnt
add wave -noupdate -group WB1 /main/DUT/cmp_ddr_ctrl/cmp_ddr3_ctrl_wb_1/write_cnt
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/rst_n_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_clk_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_addr_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_data_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_data_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_cyc_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_sel_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_stb_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_we_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wb_ack_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/clk_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_i
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_load_o
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_ctrl_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_stat_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_cstart_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstartl_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_hstarth_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_len_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nextl_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_nexth_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_int_read
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_int_write
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw_delay
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw_read_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw_s0
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw_s1
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_lw_s2
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/dma_attrib_rwsel
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/ack_sreg
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/rddata_reg
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wrdata_reg
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/bwsel_reg
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/rwaddr_reg
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/ack_in_progress
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/wr_int
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/rd_int
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/bus_clock_int
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/allones
add wave -noupdate -group DmaWB /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_controller_wb_slave_0/allzeros
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/clk_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/rst_n_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_irq_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_carrier_addr_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_host_addr_h_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_host_addr_l_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_len_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_start_l2p_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_start_p2l_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_start_next_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_byte_swap_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_abort_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_done_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_error_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_carrier_addr_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_host_addr_h_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_host_addr_l_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_len_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_next_l_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_next_h_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_attrib_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/next_item_valid_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_clk_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_adr_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_dat_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_dat_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_sel_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_cyc_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_stb_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_we_i
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/wb_ack_o
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_stat
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_cstart
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstartl
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstarth
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_len
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nextl
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nexth
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_attrib
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_stat_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_cstart_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstartl_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstarth_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_len_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nextl_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nexth_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_attrib_load
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_stat_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_cstart_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstartl_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_hstarth_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_len_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nextl_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_nexth_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_attrib_reg
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_current_state
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_status
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_error_irq
add wave -noupdate -group DMACtrol /main/DUT/cmp_gn4124_core/cmp_dma_controller/dma_done_irq
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/rst_n_a_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/status_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_clk_p_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_clk_n_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_data_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dframe_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_valid_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_rdy_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_wr_req_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_wr_rdy_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/rx_error_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/vc_rdy_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_clk_p_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_clk_n_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_data_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dframe_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_valid_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_edb_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_rdy_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l_wr_rdy_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_rd_d_rdy_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/tx_error_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_irq_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/irq_p_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/irq_p_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_clk_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_adr_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_dat_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_sel_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_stb_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_we_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_cyc_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_dat_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_ack_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_reg_stall_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_clk_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_adr_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_dat_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_sel_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_stb_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_we_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_cyc_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_dat_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_ack_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_stall_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_err_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_rty_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_int_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_clk_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_adr_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_dat_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_sel_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_stb_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_we_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_cyc_o
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_dat_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ack_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_stall_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_err_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_rty_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_int_i
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/sys_clk
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/io_clk
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/serdes_strobe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_pll_locked
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/rst_reg
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/rst_n
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/rst
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/des_pd_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/des_pd_dframe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/des_pd_data
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_wr_rdy
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_rdy_wbm
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_rdy_pdm
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_hdr_start
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_hdr_length
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_hdr_cid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_hdr_last
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_hdr_stat
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_target_mrd
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_target_mwr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_master_cpld
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_master_cpln
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_d_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_d_last
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_d
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_be
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_addr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_addr_start
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_ser_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_ser_dframe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_ser_data
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l_wr_rdy_t
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l_wr_rdy_t2
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l_wr_rdy
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_rd_d_rdy_t
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_rd_d_rdy_t2
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p_rd_d_rdy
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_rdy_t
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_rdy_t2
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_rdy
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_edb
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_edb_t
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_edb_t2
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/tx_error_t2
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/tx_error_t
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/tx_error
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/wbm_arb_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/wbm_arb_dframe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/wbm_arb_data
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/wbm_arb_req
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_wbm_gnt
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/ldm_arb_req
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_ldm_gnt
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/ldm_arb_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/ldm_arb_dframe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/ldm_arb_data
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/pdm_arb_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/pdm_arb_dframe
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/pdm_arb_data
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/pdm_arb_req
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/arb_pdm_gnt
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_carrier_addr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_host_addr_h
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_host_addr_l
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_len
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_start_l2p
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_start_p2l
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_start_next
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_done
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_error
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_l2p_done
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_l2p_error
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_p2l_done
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_p2l_error
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_byte_swap
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_ctrl_abort
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_carrier_addr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_host_addr_h
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_host_addr_l
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_len
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_next_l
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_next_h
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_attrib
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/next_item_valid
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/dma_irq
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/csr_adr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_adr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_dat_s2m
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_dat_m2s
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_sel
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_cyc
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_stb
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_we
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_ack
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/l2p_dma_stall
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_adr
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_dat_s2m
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_dat_m2s
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_sel
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_cyc
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_stb
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_we
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_ack
add wave -noupdate -expand -group Gennum /main/DUT/cmp_gn4124_core/p2l_dma_stall
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {54925075 ps} 0}
configure wave -namecolwidth 282
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {54724018 ps} {55134178 ps}
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