//2024-06-24,randc with random search class spi_driver; static bit my_cmd=1'b0; static bit[24:0] last_addr; static int last_size; //MOSI data pkt, other input_signals are not packed spi_trans m_trans; //interface virtual spi_if vif; //MOSI data_stream input to SPI(DUT) bit stream[$]; //parameter for randomization int pktnum; int interval; int half_sclk; bit autarchy; rand int error_time; constraint cstr{ error_time <= 544; error_time >= -544; } covergroup SYSAddr; coverpoint m_trans.addr{ bins IDR = {[25'h00:25'h03]}; bins VIDR = {[25'h04:25'h07]}; bins DATER = {[25'h08:25'h0B]}; bins VERR = {[25'h0C:25'h0F]}; bins TESTR = {[25'h10:25'h13]}; bins IMR = {[25'h14:25'h17]}; bins ISR = {[25'h18:25'h1B]}; bins SFRTR = {[25'h1C:25'h1F]}; bins SFRR = {[25'h20:25'h23]}; bins CH0RSTR = {[25'h24:25'h27]}; bins CH1RSTR = {[25'h28:25'h2B]}; bins CH2RSTR = {[25'h2C:25'h2F]}; bins CH3RSTR = {[25'h30:25'h33]}; bins DBGCFGR = {[25'h34:25'h37]}; bins MISR = {[25'h40:25'h43]}; } option.per_instance = 1; endgroup covergroup INSTRAddr; coverpoint m_trans.addr{ bins INSTRCTION[8192] = {[25'h010_0000:25'h010_7FFF]}; } option.per_instance = 1; endgroup covergroup DATAAddr; coverpoint m_trans.addr{ bins DATA[8192] = {[25'h020_0000:25'h020_7FFF]}; } option.per_instance = 1; endgroup covergroup CTRAddr; coverpoint m_trans.addr{ bins MCUPARAR0 = {[25'h30_0000:25'h30_0003]}; bins MCUPARAR1 = {[25'h30_0004:25'h30_0007]}; bins MCUPARAR2 = {[25'h30_0008:25'h30_000B]}; bins MCUPARAR3 = {[25'h30_000C:25'h30_000F]}; bins MCURESR0 = {[25'h30_0010:25'h30_0013]}; bins MCURESR1 = {[25'h30_0014:25'h30_0017]}; bins MCURESR2 = {[25'h30_0018:25'h30_001B]}; bins MCURESR3 = {[25'h30_001C:25'h30_001F]}; bins RTIMR = {[25'h30_0098:25'h30_009B]}; bins ICNTR = {[25'h30_009C:25'h30_009F]}; bins FSIR = {[25'h30_00A0:25'h30_00A3]}; bins MODMR = {[25'h30_0100:25'h30_0103]}; bins INTPMR = {[25'h30_0104:25'h30_0107]}; bins MIXNCOCR = {[25'h30_0108:25'h30_010B]}; bins MIXNFCWHR = {[25'h30_010C:25'h30_010F]}; bins MIXNFCWLR = {[25'h30_0110:25'h30_0113]}; bins MIXNPHAR = {[25'h30_0114:25'h30_0117]}; bins MIXMR = {[25'h30_0118:25'h30_011B]}; bins MIXODTR = {[25'h30_011C:25'h30_011F]}; bins MIXODFR = {[25'h30_0120:25'h30_0123]}; bins ROLER = {[25'h30_0128:25'h30_012B]}; bins MIXNCOSCER = {[25'h30_012C:25'h30_012F]}; bins MODDOTR = {[25'h30_0130:25'h30_0133]}; bins STR = {[25'h30_0134:25'h30_0137]}; } option.per_instance = 1; endgroup covergroup ENVELOPEIDAddr; coverpoint m_trans.addr{ bins ENVELOPEID[64] = {[25'h040_0000:25'h040_00FF]}; } option.per_instance = 1; endgroup covergroup ENVELOPEDATAAddr; coverpoint m_trans.addr{ bins ENVELOPEDATA[8192] = {[25'h050_0000:25'h050_7FFF]}; } option.per_instance = 1; endgroup covergroup DACAddr; coverpoint m_trans.addr{ bins PRBSCR = {[25'h060_0000:25'h060_0003]}; bins SET0CR = {[25'h060_0004:25'h060_0007]}; bins SET1CR = {[25'h060_0008:25'h060_000B]}; bins SET2CR = {[25'h060_000C:25'h060_000F]}; bins SET3CR = {[25'h060_0010:25'h060_0013]}; bins SET4CR = {[25'h060_0014:25'h060_0017]}; bins SET5CR = {[25'h060_0018:25'h060_001B]}; bins SET6CR = {[25'h060_001C:25'h060_001F]}; bins SET7CR = {[25'h060_0020:25'h060_0023]}; bins SET8CR = {[25'h060_0024:25'h060_0027]}; bins SET9CR = {[25'h060_0028:25'h060_002B]}; bins SET10CR = {[25'h060_002C:25'h060_002F]}; bins SET11CR = {[25'h060_0030:25'h060_0033]}; bins SET12CR = {[25'h060_0034:25'h060_0037]}; bins SET13CR = {[25'h060_0038:25'h060_003B]}; bins SET14CR = {[25'h060_003C:25'h060_003F]}; bins SET15CR = {[25'h060_0040:25'h060_0043]}; bins DACADDR = {[25'h060_0044:25'h060_0047]}; bins DACDW = {[25'h060_0048:25'h060_004B]}; bins DACREF = {[25'h060_004C:25'h060_004F]}; bins PRBSRST0 = {[25'h060_0050:25'h060_0053]}; bins PRBSSET0 = {[25'h060_0054:25'h060_0057]}; bins PRBSRST1 = {[25'h060_0058:25'h060_005B]}; bins PRBSSET1 = {[25'h060_005C:25'h060_005F]}; bins PRBSREV = {[25'h060_0060:25'h060_0063]}; bins CALSIG = {[25'h060_0064:25'h060_0067]}; bins CALEND = {[25'h060_0068:25'h060_006B]}; bins CALRSTN = {[25'h060_006C:25'h060_006F]}; bins CALDIVRSTN = {[25'h060_0070:25'h060_0073]}; } option.per_instance = 1; endgroup covergroup MCUAddr; coverpoint m_trans.addr{ bins MCUPARAR0 = {[25'h70_0000:25'h70_0003]}; bins MCUPARAR1 = {[25'h70_0004:25'h70_0007]}; bins MCUPARAR2 = {[25'h70_0008:25'h70_000B]}; bins MCUPARAR3 = {[25'h70_000C:25'h70_000F]}; bins MCURESR0 = {[25'h70_0010:25'h70_0013]}; bins MCURESR1 = {[25'h70_0014:25'h70_0017]}; bins MCURESR2 = {[25'h70_0018:25'h70_001B]}; bins MCURESR3 = {[25'h70_001C:25'h70_001F]}; bins CWFR0 = {[25'h70_0040:25'h70_0043]}; bins CWFR1 = {[25'h70_0044:25'h70_0047]}; bins CWFR2 = {[25'h70_0048:25'h70_004B]}; bins CWFR3 = {[25'h70_004C:25'h70_004F]}; bins CWPRR = {[25'h70_0050:25'h70_0053]}; bins GAPR0 = {[25'h70_0054:25'h70_0057]}; bins GAPR1 = {[25'h70_0058:25'h70_005B]}; bins GAPR2 = {[25'h70_005C:25'h70_005F]}; bins GAPR3 = {[25'h70_0060:25'h70_0063]}; bins GAPR4 = {[25'h70_0064:25'h70_0067]}; bins GAPR5 = {[25'h70_0068:25'h70_006B]}; bins GAPR6 = {[25'h70_006C:25'h70_006F]}; bins GAPR7 = {[25'h70_0070:25'h70_0073]}; bins LCPR = {[25'h70_0074:25'h70_0077]}; bins AMPR0 = {[25'h70_0078:25'h70_007B]}; bins AMPR1 = {[25'h70_007C:25'h70_007F]}; bins AMPR2 = {[25'h70_0080:25'h70_0083]}; bins AMPR3 = {[25'h70_0084:25'h70_0087]}; bins BIASR0 = {[25'h70_0088:25'h70_008B]}; bins BIASR1 = {[25'h70_008C:25'h70_008F]}; bins BIASR2 = {[25'h70_0090:25'h70_0093]}; bins BIASR3 = {[25'h70_0094:25'h70_0097]}; bins RTIMR = {[25'h70_0098:25'h70_009B]}; bins ICNTR = {[25'h70_009C:25'h70_009F]}; bins FSIR = {[25'h70_00A0:25'h70_00A3]}; bins INTPSELR = {[25'h70_00A4:25'h70_00A7]}; } option.per_instance = 1; endgroup covergroup DBGAddr; coverpoint m_trans.addr{ bins DBGAddr[1024] = {[25'h190_0000:25'h190_0FFF]}; } option.per_instance = 1; endgroup covergroup PLLAddr; coverpoint m_trans.addr{ bins INTPLL_REFCTRL = {[25'h1f0_0000:25'h1f0_0003]}; bins INTPLL_PCNT = {[25'h1f0_0004:25'h1f0_0007]}; bins INTPLL_PFDCTRL = {[25'h1f0_0008:25'h1f0_000B]}; bins INTPLL_SPDCTRL = {[25'h1f0_000C:25'h1f0_000F]}; bins INTPLL_PTATCTRL = {[25'h1f0_0010:25'h1f0_0013]}; bins INTPLL_FLLCTRL = {[25'h1f0_0014:25'h1f0_0017]}; bins INTPLL_SELCTRL = {[25'h1f0_0018:25'h1f0_001B]}; bins INTPLL_VCOCTRL = {[25'h1f0_001C:25'h1f0_001F]}; bins INTPLL_VCOFBADJ = {[25'h1f0_0020:25'h1f0_0023]}; bins INTPLL_AFCCTRL = {[25'h1f0_0024:25'h1f0_0027]}; bins INTPLL_AFCCNT = {[25'h1f0_0028:25'h1f0_002B]}; bins INTPLL_AFCLDCNT = {[25'h1f0_002C:25'h1f0_002F]}; bins INTPLL_AFCPRES = {[25'h1f0_0030:25'h1f0_0033]}; bins INTPLL_AFCLDTCC = {[25'h1f0_0034:25'h1f0_0037]}; bins INTPLL_AFCFBTCC = {[25'h1f0_0038:25'h1f0_003B]}; bins INTPLL_DIVCFG = {[25'h1f0_003C:25'h1f0_003F]}; bins INTPLL_TCLKCFG = {[25'h1f0_0040:25'h1f0_0043]}; bins INTPLL_DCLKSEL = {[25'h1f0_0044:25'h1f0_0047]}; bins INTPLL_STATUS = {[25'h1f0_0048:25'h1f0_004B]}; bins INTPLL_SYNCFG = {[25'h1f0_004C:25'h1f0_004F]}; bins INTPLL_UPDATE = {[25'h1f0_0050:25'h1f0_0053]}; bins INTPLL_CLKRXPD = {[25'h1f0_0054:25'h1f0_0057]}; } option.per_instance = 1; endgroup function new(); SYSAddr = new(); INSTRAddr = new(); DATAAddr = new(); CTRAddr = new(); ENVELOPEIDAddr = new(); ENVELOPEDATAAddr = new(); DACAddr = new(); MCUAddr = new(); DBGAddr = new(); PLLAddr = new(); endfunction extern task do_drive(); extern task make_pkt(spi_trans tr); endclass : spi_driver task spi_driver::do_drive(); $display("pkt_num:\t%0d",pktnum); while(!vif.rstn) begin vif.csn = 1'b1; vif.sclk = 1'b1; @(posedge vif.clk); end while(pktnum>0) begin m_trans = new(); if(!m_trans.randomize() with { cmd==my_cmd; (cmd==1'b0 || data.size()==last_size); (cmd==1'b0 || addr==last_addr); // addr[24:20] == 5'h0 || //sys // addr[24:20] == 5'h1 || //instruction srams // addr[24:20] == 5'h2 || //data srams // addr[24:20] == 5'h3 || //awg // addr[24:20] == 5'h4 || //envelope id srams // addr[24:20] == 5'h5 || //envelope data srams // addr[24:20] == 5'h6 || //dac // addr[24:20] == 5'h7 || //mcu // addr[24:20] == 5'h19 || //dbg srams // addr[24:20] == 5'h1F ; //pll addr[24: 20] == 5'h6; addr[1:0] == 0; // data.size == 2; interval == 50; }) $fatal(0,"Randomize Failed"); if(m_trans.cmd == 1'b0) begin last_addr = m_trans.addr; last_size = m_trans.data.size(); end my_cmd = ~my_cmd; //Autarchy: Testcase force to assign some params interval = m_trans.interval; if(!autarchy) begin half_sclk = m_trans.half_sclk; end if((m_trans.addr <= 25'h000_001F) && ((m_trans.addr + (m_trans.data.size()-1) * 4) >= 25'h000_001C)) m_trans.data[(25'h000_001C - m_trans.addr)/4] = m_trans.data[(25'h000_001C - m_trans.addr)/4] % 4 + 1; make_pkt(m_trans); // $display(m_trans.addr); SYSAddr.sample(); INSTRAddr.sample(); DATAAddr.sample(); CTRAddr.sample(); ENVELOPEIDAddr.sample(); ENVELOPEDATAAddr.sample(); DACAddr.sample(); MCUAddr.sample(); DBGAddr.sample(); PLLAddr.sample(); repeat(interval) @(posedge vif.clk); pktnum--; end $finish(0); //$display(SYSAddr.get_inst_coverage()); //$display(MCUAddr.get_inst_coverage()); //$display(AWGAddr.get_inst_coverage()); endtask : do_drive task spi_driver::make_pkt(spi_trans tr); int i=0,j=0; int cs_time,mo_time; //*****************initialize chip_select and input_clk******************// vif.csn <= 1'b1; vif.sclk <= 1'b1; vif.mosi <= stream[0]; vif.cfgid <= tr.cfgid; @(posedge vif.clk); vif.csn <= 1'b0; vif.sclk <= 1'b1; //unpack into bitstream stream.delete(); tr.unpack(stream); //mosi valid time: time for bitstream to be all sent //csn valid_time: maybe a delay after or ahead of mosi_finished mo_time = (stream.size()+1)*2*half_sclk; cs_time = (pktnum==1) ? (mo_time + error_time%mo_time) : mo_time; //$display("***************************ONE PKT DRIVERED***************************"); //$display("half_sclk:\t%0d\t\t\t\t\t\t **",half_sclk); //$display("interval:\t%0d\t\t\t\t\t\t **",interval); //$display("error_time:\t%0d\t\t\t\t\t\t **",error_time); //$display("data_size:\t%0d\t\t\t\t\t\t **",tr.data.size()); //$display("cmd:\t\t%0d\t\t\t\t\t\t **",tr.cmd); //$display("id:\t\t%h\t\t\t\t\t\t **",tr.cfgid); //$display("addr:\t\t%h\t\t\t\t\t\t **",tr.addr); //$display(stream); //if(!tr.cmd) //for(i=0;i