245 lines
5.7 KiB
Systemverilog
245 lines
5.7 KiB
Systemverilog
|
//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
|