SPI_Test/tb/testbench/sysreg_tb/sysreg_monitor.sv

228 lines
5.7 KiB
Systemverilog
Raw Permalink Normal View History

2024-06-25 16:41:01 +08:00
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