记分板模块
🏓

记分板模块

Created
Jul 31, 2024 03:32 PM
Tags
`ifndef SCOREBOARD `define SCOREBOARD class scoreboard; virtual alu_reg_interface reg_intf; mailbox mon2scb; int pass_cnt,fail_cnt; function new (virtual alu_reg_interface reg_intf_new, mailbox mon2scb_new); this.reg_intf = reg_intf_new; if(mon2scb_new == null)begin $display("%0t -> scoreboard : ERROR -> mon2scb is null",$time); $finish; end else this.mon2scb = mon2scb_new; endfunction task get_ctrl_reg_value(output bit value); bit[15:0] rd_data; rd_data = reg_intf.peek("cfg_cfg_ctrl"); value = rd_data[0]; $display("%0t -> scoreboard : read CFG_CTRL_REG value : %0h",$time,rd_data); endtask task run(); transaction exp_tr; transaction act_tr; string data_str; bit ctrl_reg_value; forever begin mon2scb.get(act_tr); get_ctrl_reg_value(ctrl_reg_value); exp_tr = predict_result(act_tr, ctrl_reg_value); data_str = {"\n \t Actual ", act_tr.convert2string(), "\n \t Predicted ", exp_tr.convert2string()}; if(act_tr.compare(exp_tr)) begin pass_cnt++; $display("%0t -> scoreboard : PASS => %s",$time,data_str); end else begin fail_cnt++; $display("%0t -> scoreboard : FAIL => %s",$time,data_str); end end endtask function transaction predict_result(transaction cmd, bit is_invert); transaction exp_tr; bit[15:0] result; exp_tr = new(); exp_tr.A = cmd.A; exp_tr.B = cmd.B; exp_tr.op = cmd.op; case (cmd.op) add_op: result = cmd.A + cmd.B; and_op: result = cmd.A & cmd.B; xor_op: result = cmd.A ^ cmd.B; mul_op: result = cmd.A * cmd.B; div_op: if(cmd.B == 0) result = 'h0; else result = cmd.A / cmd.B; endcase if(is_invert) exp_tr.result = ~result; else exp_tr.result = result; $display("%0t -> scoreboard : op is %s, A is %h, B is %h, exp_result is %h",$time,cmd.op.name(),cmd.A,cmd.B,exp_tr.result); return exp_tr; endfunction : predict_result endclass `endif
关于记分板模块的原理也应该熟悉。