228 lines
5.7 KiB
Systemverilog
228 lines
5.7 KiB
Systemverilog
class spi2sysreg_refmodel;
|
|
|
|
virtual sysreg_if vif;
|
|
virtual spi_if wif;
|
|
virtual sram_if xif;
|
|
|
|
static int pktnum;
|
|
|
|
|
|
//Vars as reg_model
|
|
bit[31:0] imr=32'b0;
|
|
bit[31:0] isr=32'b0;
|
|
bit[31:0] intr=32'b0;
|
|
bit[31:0] rst_time=32'd300;
|
|
|
|
|
|
//Vars in rst-check
|
|
int rst_error[4]={32'b0,32'b0,32'b0,32'b0};
|
|
|
|
|
|
|
|
function new();
|
|
endfunction
|
|
extern task do_imitate();
|
|
extern task reg_updata(bit cmd,int size,bit[1:0] chip,bit[15:0] addr,bit[32:0] din_temp);
|
|
extern task intr_collect(bit[15:0] addr);
|
|
extern task rst_check(bit[31:0] rst_time,int i,int pkt_i);
|
|
|
|
endclass : spi2sysreg_refmodel
|
|
|
|
task spi2sysreg_refmodel::do_imitate();
|
|
|
|
//Vars in Progress_kill
|
|
int pkt_i=0;
|
|
//Temp Vars
|
|
bit[31:0] cmd_temp;
|
|
bit[31:0] din_temp;
|
|
bit[1 :0] chip;
|
|
bit[15:0] addr=16'b0;
|
|
int size;
|
|
bit cmd=0;
|
|
int i=0,j=0;
|
|
|
|
fork
|
|
|
|
while(1) begin: spi_refmodel
|
|
if(pkt_i==pktnum) break;
|
|
@(negedge wif.csn);
|
|
for(j=0;j<27;j++) begin
|
|
@(posedge wif.sclk or posedge wif.csn)
|
|
if(wif.error_check | wif.csn) break;
|
|
cmd_temp[j] = wif.mosi;
|
|
end
|
|
cmd = cmd_temp[0];
|
|
size = cmd_temp[1] ? 16 : 1;
|
|
chip = {<<{cmd_temp[6 :5 ]}};
|
|
addr = {<<{cmd_temp[26:11]}};
|
|
//$display("addr:%0h",addr);
|
|
//$display("cmd:%0h",cmd);
|
|
|
|
repeat(5) @(posedge wif.sclk);
|
|
for(j=0;j<32;j++) begin
|
|
@(posedge wif.sclk or posedge wif.csn)
|
|
if(wif.error_check | wif.csn) break;
|
|
din_temp[31-j] = wif.mosi;
|
|
end
|
|
|
|
@(posedge wif.csn);
|
|
|
|
end: spi_refmodel
|
|
|
|
|
|
|
|
while(1) begin: sysreg_refmodel
|
|
if(pkt_i==pktnum) break;
|
|
if(wif.csn) @(negedge wif.csn);
|
|
//Not 32,"rden" occurs before the 32nd posedge sclk
|
|
repeat(31) @(posedge wif.sclk);
|
|
//if write,wait for din_temp update
|
|
if(!cmd) @(posedge wif.csn);
|
|
reg_updata(cmd,size,chip,addr,din_temp);
|
|
end: sysreg_refmodel
|
|
|
|
|
|
|
|
while(1) begin: intr_regmodel
|
|
if(pkt_i==pktnum) break;
|
|
intr_collect(addr);
|
|
end: intr_regmodel
|
|
|
|
|
|
|
|
begin: rst_checker
|
|
for(i=0;i<4;i++) begin
|
|
automatic int rst_i = i;
|
|
fork
|
|
while(1) begin
|
|
if(pkt_i==pktnum) break;
|
|
@(negedge wif.csn);
|
|
//$display("check_rst%0d",rst_i);
|
|
repeat(32) @(posedge wif.sclk);
|
|
if(!cmd & addr[15: 2]==14'h09+rst_i & chip==2'b00)
|
|
rst_check(rst_time,rst_i,pkt_i);
|
|
end
|
|
join_none
|
|
end
|
|
wait fork;
|
|
end: rst_checker
|
|
|
|
|
|
|
|
repeat(pktnum) begin: kill_progress
|
|
@(negedge wif.csn);
|
|
pkt_i++;
|
|
end: kill_progress
|
|
|
|
join
|
|
|
|
endtask: do_imitate
|
|
|
|
|
|
task spi2sysreg_refmodel::reg_updata(
|
|
bit cmd,
|
|
int size,
|
|
bit[1:0] chip,
|
|
bit[15:0] addr,
|
|
bit[32:0] din_temp
|
|
);
|
|
int i=0,j=0;
|
|
|
|
if(cmd) begin
|
|
@(posedge xif.rden);
|
|
isr = intr;
|
|
$display("intr:%0h",intr);
|
|
@(posedge wif.csn);
|
|
end
|
|
|
|
else begin
|
|
@(posedge xif.wren);
|
|
repeat(2) @(posedge wif.clk);
|
|
@(negedge wif.clk);
|
|
case(addr[15: 2])
|
|
14'h05: imr = (chip==2'b00) ? din_temp : imr;
|
|
14'h08: rst_time = (chip==2'b00) ? din_temp : rst_time;
|
|
endcase
|
|
//$display("addr:%0h",addr);
|
|
$display("imr:%0h",imr);
|
|
//$display("rst_time:%0h",rst_time);
|
|
end
|
|
|
|
endtask: reg_updata
|
|
|
|
task spi2sysreg_refmodel::intr_collect(bit[15:0] addr);
|
|
|
|
@(negedge wif.clk);
|
|
//each MISR read should clr INTR once
|
|
if(addr[15: 2] == 14'h07 && xif.rden)
|
|
intr = 32'b0;
|
|
//No else: whether clr INTR or not,we need to check the follow interrupt status
|
|
begin
|
|
intr[31] = vif.pll_lock | intr[31];
|
|
intr[30] = vif.pll_lost_lock | intr[30];
|
|
intr[ 5] = vif.ch0_dbg_upd | intr[ 5];
|
|
intr[ 4] = vif.ch0_dbg_fifo_e | intr[ 4];
|
|
intr[ 3] = vif.ch0_dbg_fifo_f | intr[ 3];
|
|
intr[ 2] = vif.ch0_ldst_addr_unalgn | intr[ 2];
|
|
intr[ 1] = vif.ch0_dec_err | intr[ 1];
|
|
intr[ 0] = vif.ch0_exit_irq | intr[ 0];
|
|
intr[13] = vif.ch1_dbg_upd | intr[13];
|
|
intr[12] = vif.ch1_dbg_fifo_e | intr[12];
|
|
intr[11] = vif.ch1_dbg_fifo_f | intr[11];
|
|
intr[10] = vif.ch1_ldst_addr_unalgn | intr[10];
|
|
intr[ 9] = vif.ch1_dec_err | intr[ 9];
|
|
intr[ 8] = vif.ch1_exit_irq | intr[ 8];
|
|
intr[21] = vif.ch2_dbg_upd | intr[21];
|
|
intr[20] = vif.ch2_dbg_fifo_e | intr[20];
|
|
intr[19] = vif.ch2_dbg_fifo_f | intr[19];
|
|
intr[18] = vif.ch2_ldst_addr_unalgn | intr[18];
|
|
intr[17] = vif.ch2_dec_err | intr[17];
|
|
intr[16] = vif.ch2_exit_irq | intr[16];
|
|
intr[29] = vif.ch3_dbg_upd | intr[29];
|
|
intr[28] = vif.ch3_dbg_fifo_e | intr[28];
|
|
intr[27] = vif.ch3_dbg_fifo_f | intr[27];
|
|
intr[26] = vif.ch3_ldst_addr_unalgn | intr[26];
|
|
intr[25] = vif.ch3_dec_err | intr[25];
|
|
intr[24] = vif.ch3_exit_irq | intr[24];
|
|
end
|
|
|
|
endtask: intr_collect
|
|
|
|
|
|
|
|
task spi2sysreg_refmodel::rst_check(bit[31:0] rst_time,int i,int pkt_i);
|
|
int cnt=0;
|
|
|
|
@(posedge xif.wren);
|
|
repeat(2) @(posedge wif.clk);
|
|
|
|
//$display("start rst check:%d",rst_time);
|
|
cnt = rst_time;
|
|
//$display("rst_time:%d",sys_cnt);
|
|
while(cnt>0) begin
|
|
@(posedge wif.clk);
|
|
if(vif.soft_rstn[i])
|
|
break;
|
|
cnt--;
|
|
end
|
|
|
|
@(negedge wif.clk);
|
|
if(cnt!=0 | !vif.soft_rstn[i]) begin
|
|
rst_error[i]++;
|
|
$display("\nScoreBoard(ERROR): rst_time_error");
|
|
case(i)
|
|
0: $display("rst_module:\tSYS");
|
|
1: $display("rst_module:\tMCU");
|
|
2: $display("rst_module:\tAWG");
|
|
3: $display("rst_module:\tDAC");
|
|
endcase
|
|
$display("cnt:\t%d",cnt);
|
|
$display("soft_rstn:\t%b",vif.soft_rstn[i]);
|
|
$display("rst cmd time: @%0dth pkt.\n",pkt_i);
|
|
end
|
|
//else
|
|
//$display("\nScoreBoard: @%0dth pkt, sys_rst successfully!\n",sys_i_save);
|
|
if(!wif.csn) @(posedge wif.csn);
|
|
|
|
endtask: rst_check
|