390 lines
13 KiB
Systemverilog
390 lines
13 KiB
Systemverilog
//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<tr.data.size;i++)
|
|
//$display("mosi:\t\t%h\t\t **",tr.data[i]);
|
|
|
|
//********************drive the stream onto interface********************//
|
|
fork
|
|
|
|
|
|
//************************Make sclk************************//
|
|
begin
|
|
for(j=0;j<cs_time;j++) begin
|
|
if(j % half_sclk == 0 && j!=0)
|
|
vif.sclk <= ~vif.sclk;
|
|
@(posedge vif.clk);
|
|
end
|
|
vif.sclk = 1'b1;
|
|
@(posedge vif.clk);
|
|
vif.csn = 1'b1;
|
|
end
|
|
|
|
//************************Send data************************//
|
|
begin
|
|
for(i=0;i<mo_time;i++) begin
|
|
// data will be sampled at posedge,
|
|
// so prepare them at the negedge before each posedge
|
|
if(i % (2*half_sclk) == half_sclk)begin
|
|
vif.mosi <= stream[(i/half_sclk-1)/2];
|
|
//$write(vif.mosi);
|
|
//$display(i);
|
|
end
|
|
@(posedge vif.clk);
|
|
end
|
|
end
|
|
|
|
|
|
join
|
|
|
|
//$display("**********************************************************************");
|
|
|
|
endtask
|
|
|