//For system_regfile, the ROreg: isr is updated by the intrrupt_status //at last clk_posedge due to dff(status->irisr) & dff(irisr->isr) class sys_refmodel; virtual sysreg_if vif; virtual spi_if wif; virtual sram_if#(25,32) xif; //interrupt buffer bit[31:0] irisr = 32'b0; bit irisr_clr = 1'b0; //poor-quality register model bit[31:0] rm[17]; //members to be sent to scoreboard int rst_error[5]; bit[31:0] dout[$]; sysreg_trans sysout[$]; function new(); endfunction extern task do_imitate(); extern task RWreg_write (bit[24:0] addr,bit[32:0] din); extern task ROreg_update (bit[24:0] addr ); extern task reg_read (bit[24:0] addr ); extern task rst_check (bit[31:0] rst_time,int i ); extern task output_trace (bit[24:0] addr ); endclass : sys_refmodel task sys_refmodel::do_imitate(); int i=0,j=0; rm[ 0] = 32'h41574743; //IDR rm[ 1] = 32'h55535443; //VIDR rm[ 2] = 32'h20220831; //DATER rm[ 3] = 32'h00000001; //VERR rm[ 4] = 32'h01234567; //TESTR rm[ 5] = 32'b0; //IMR rm[ 6] = 32'b0; //ISR rm[ 7] = 32'd300; //SFRTR rm[ 8] = 32'd0; //SFRR rm[ 9] = 32'd0; //CH0RSTR rm[10] = 32'd0; //CH1RSTR rm[11] = 32'd0; //CH2RSTR rm[12] = 32'd0; //CH3RSTR rm[13] = 32'd0; //DBGCFGR rm[14] = 32'd0; rm[15] = 32'd0; rm[16] = 32'd0; //MISR fork while(1) begin: write_reg_RW @(negedge xif.wren); RWreg_write(xif.addr,xif.din); end: write_reg_RW while(1) begin: update_reg_RO ROreg_update(xif.addr); end: update_reg_RO while(1) begin: read_reg @(negedge xif.rden); repeat(3) @(posedge xif.clk); reg_read(xif.addr); end: read_reg begin: rst_port for(i=0;i<5;i++) begin automatic int rst_i = i; fork while(1) begin @(negedge xif.wren); if(xif.addr[24: 2]==23'h08+rst_i) rst_check(rm[7],rst_i); end join_none end wait fork; end: rst_port while(1) begin: dbg_port @(negedge xif.wren); output_trace(xif.addr); end: dbg_port join endtask: do_imitate task sys_refmodel::RWreg_write(bit[24:0] addr,bit[32:0] din); //delay caused by decoder @(posedge wif.clk); case(addr[24: 2]) 23'h04: rm[ 4] = din; //TESTR 23'h05: rm[ 5] = din; //IMR 23'h07: rm[ 7] = din; //SFRTR 23'h0d: rm[13] = {rm[13][31:6],din[5:0]}; //DBGCFGR endcase // $display("addr:%0h",addr); // $display("rm[%d]:%h",addr[24:2],rm[addr[24: 2]]); // $display("din:%h",din); endtask: RWreg_write task sys_refmodel::ROreg_update(bit[24:0] addr); //irisr->isr @(posedge wif.clk); rm[ 6] = irisr ; rm[14] = irisr & rm[5] ; //intr_status->irisr if(irisr_clr) irisr = vif.status; else irisr = irisr | vif.status ; endtask: ROreg_update task sys_refmodel::reg_read(bit[24:0] addr); case(addr[24: 2]) 23'h00: dout.push_back(rm[ 0]); //IDR 23'h01: dout.push_back(rm[ 1]); //VIDR 23'h02: dout.push_back(rm[ 2]); //DATER 23'h03: dout.push_back(rm[ 3]); //VERR 23'h04: dout.push_back(rm[ 4]); //TESTR 23'h05: dout.push_back(rm[ 5]); //IMm 23'h06: dout.push_back(rm[ 6]); //ISR 23'h07: dout.push_back(rm[ 7]); //SFRTR 23'h08: dout.push_back(rm[ 8]); //SFRR 23'h09: dout.push_back(rm[ 9]); //CH0RSTR 23'h0a: dout.push_back(rm[10]); //CH1RSTR 23'h0b: dout.push_back(rm[11]); //CH2RSTR 23'h0c: dout.push_back(rm[12]); //CH3RSTR 23'h0d: dout.push_back(rm[13]); //DBGCFGR 23'h0e: dout.push_back(0); 23'h10: begin //MISR dout.push_back(rm[16]); irisr_clr = 1'b1; end 23'h11: dout.push_back(0); endcase // $display("dout:%h",dout[$]); @(posedge wif.clk); irisr_clr = 1'b0; endtask: reg_read task sys_refmodel::rst_check(bit[31:0] rst_time,int i); int cnt=0; //delay caused by decoder @(posedge wif.clk); cnt = rst_time; //$display("%h",addr); //$display("rst_time:%h",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\t@%t",$realtime); case(i) 0: $display("rst_module:\tSYS"); 1: $display("rst_module:\tch0"); 2: $display("rst_module:\tch1"); 3: $display("rst_module:\tch2"); 4: $display("rst_module:\tch3"); endcase $display("cnt:\t%d",cnt); $display("soft_rstn:\t%b",vif.soft_rstn[i]); end endtask: rst_check task sys_refmodel::output_trace(bit[24:0] addr); if(addr[24:20] == 5'h0); begin sysreg_trans tr_temp; bit irq = |rm[14]; //delay caused by decoder @(posedge wif.clk); @(negedge wif.clk); tr_temp = new(); tr_temp.dbg_enable = rm[13][0:0]; //DBGCFGR tr_temp.dbg_data_sel = rm[13][1:1]; tr_temp.dbg_ch_sel = rm[13][3:2]; tr_temp.irq = irq; sysout.push_back(tr_temp); end // $display("addr:%0h",addr); //$display("rm:%h",rm[addr[24: 2]]); //$display("din:%h",din); endtask: output_trace