Update tb: 1. fix xrf retire condition in monitor 2. Fix vcpop/vfirst logic 3. Fix tail elements behavior of mask producing instructions. Now it will writeback calculation result for tail element. Change-Id: I9629e3b80b92935b90368a179e432dd7c44e2393
diff --git a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_monitor.sv b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_monitor.sv index cb8baa0..65c252c 100644 --- a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_monitor.sv +++ b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_monitor.sv
@@ -107,7 +107,8 @@ // `uvm_info(get_type_name(),$sformatf("rt_uop=0x%1x, rt_last_uop=0x%1x",rvs_if.rt_uop, rvs_if.rt_last_uop), UVM_HIGH) for(int rt_idx=0; rt_idx<`NUM_RT_UOP; rt_idx++) begin if(rvs_if.rt_uop[rt_idx]) begin - while(!(rvs_if.rt_vrf_valid_rob2rt[rt_idx] && (rvs_if.rt_vrf_data_rob2rt[rt_idx].uop_pc === tr.pc))) begin + while(!(rvs_if.rt_vrf_valid_rob2rt[rt_idx] && (rvs_if.rt_vrf_data_rob2rt[rt_idx].uop_pc === tr.pc)) && + !(rvs_if.rt_xrf_valid_rvv2rvs[rt_idx] && rvs_if.rt_xrf_ready_rvs2rvv[rt_idx] && (rvs_if.rt_xrf_rvv2rvs[rt_idx].uop_pc === tr.pc))) begin `uvm_info(get_type_name(), $sformatf("Monitor rx_queue pc(0x%8x) mismatch with DUT pc(0x%8x), discarded.", tr.pc, rvs_if.rt_vrf_data_rob2rt[rt_idx].uop_pc), UVM_HIGH) `uvm_info(get_type_name(), tr.sprint(),UVM_HIGH) tr = inst_rx_queue.pop_front();
diff --git a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_transaction.sv b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_transaction.sv index 7e2f95d..f028568 100644 --- a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_transaction.sv +++ b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvs_agent_rvs_transaction.sv
@@ -51,6 +51,8 @@ lmul_e src2_emul; lmul_e src3_emul; vext_e src1_func_vext; + vwxunary0_e src1_func_vwxunary0; + vmunary0_e src1_func_vmunary0; rand logic [`XLEN-1:0] rs_data; @@ -243,17 +245,33 @@ `uvm_field_enum(oprand_type_e,dest_type,UVM_ALL_ON) `uvm_field_int(dest_idx,UVM_ALL_ON) - `uvm_field_enum(oprand_type_e,src1_type,UVM_ALL_ON) if(src1_type == FUNC && inst_type == ALU && alu_inst == VXUNARY0) begin + `uvm_field_enum(oprand_type_e,src1_type,UVM_ALL_ON) `uvm_field_enum(vext_e,src1_func_vext,UVM_ALL_ON) - end else begin + `uvm_field_int(src1_idx,UVM_ALL_ON) + end else if(src1_type == FUNC && inst_type == ALU && alu_inst == VWXUNARY0) begin + `uvm_field_enum(oprand_type_e,src1_type,UVM_ALL_ON) + `uvm_field_enum(vwxunary0_e,src1_func_vwxunary0,UVM_ALL_ON) + `uvm_field_int(src1_idx,UVM_ALL_ON) + end else if(src1_type == FUNC && inst_type == ALU && alu_inst == VMUNARY0) begin + `uvm_field_enum(oprand_type_e,src1_type,UVM_ALL_ON) + `uvm_field_enum(vmunary0_e,src1_func_vmunary0,UVM_ALL_ON) + `uvm_field_int(src1_idx,UVM_ALL_ON) + end else if(src1_type != UNUSE) begin + `uvm_field_enum(oprand_type_e,src1_type,UVM_ALL_ON) `uvm_field_int(src1_idx,UVM_ALL_ON) end - `uvm_field_enum(oprand_type_e,src2_type,UVM_ALL_ON) - `uvm_field_int(src2_idx,UVM_ALL_ON) - `uvm_field_enum(oprand_type_e,src3_type,UVM_ALL_ON) - `uvm_field_int(src3_idx,UVM_ALL_ON) - `uvm_field_int(rs_data,UVM_ALL_ON) + if(src2_type != UNUSE) begin + `uvm_field_enum(oprand_type_e,src2_type,UVM_ALL_ON) + `uvm_field_int(src2_idx,UVM_ALL_ON) + end + if(src3_type != UNUSE) begin + `uvm_field_enum(oprand_type_e,src3_type,UVM_ALL_ON) + `uvm_field_int(src3_idx,UVM_ALL_ON) + end + if(src1_type == XRF || src2_type == XRF) begin + `uvm_field_int(rs_data,UVM_ALL_ON) + end if(is_rt) begin @@ -296,6 +314,8 @@ use_vm_to_cal = 0; if(src1_type == FUNC && inst_type == ALU && alu_inst == VXUNARY0) $cast(src1_func_vext,src1_idx); + if(src1_type == FUNC && inst_type == ALU && alu_inst == VWXUNARY0) $cast(src1_func_vwxunary0,src1_idx); + if(src1_type == FUNC && inst_type == ALU && alu_inst == VMUNARY0) $cast(src1_func_vmunary0,src1_idx); // rs random data if(src1_type != XRF && src2_type != XRF) rs_data = 'x; @@ -363,6 +383,10 @@ inst = "vmv.v"; else inst = "vmerge"; + end else if(alu_inst inside {VWXUNARY0}) begin + inst = src1_func_vwxunary0.name(); + end else if(alu_inst inside {VMUNARY0}) begin + inst = src1_func_vmunary0.name(); end else begin inst = this.alu_inst.name(); end @@ -377,9 +401,10 @@ FUNC: begin if(inst_type == ALU && alu_inst == VXUNARY0 && src1_idx inside{VSEXT_VF4, VSEXT_VF4}) begin suf1 = "f4"; src1 = ""; - end - if(inst_type == ALU && alu_inst == VXUNARY0 && src1_idx inside{VSEXT_VF2, VSEXT_VF2}) begin + end else if(inst_type == ALU && alu_inst == VXUNARY0 && src1_idx inside{VSEXT_VF2, VSEXT_VF2}) begin suf1 = "f2"; src1 = ""; + end else if(inst_type == ALU && alu_inst inside {VMAND, VMOR, VMXOR, VMORN, VMNAND, VMNOR, VMANDN, VMXNOR}) begin + suf1 = "m"; src1 = $sformatf("v%0d",this.src1_idx); end end default: begin suf1 = "?"; src1 = "?"; end @@ -388,12 +413,16 @@ VRF: begin if(inst_type == ALU && alu_inst inside {VWADDU_W, VWADD_W, VWSUBU_W, VWSUB_W}) begin suf2 = "w"; src2 = $sformatf("v%0d",this.src2_idx); + end else if(inst_type == ALU && alu_inst inside {VMAND, VMOR, VMXOR, VMORN, VMNAND, VMNOR, VMANDN, VMXNOR, + VWXUNARY0, VMUNARY0}) begin + suf2 = "m"; src2 = $sformatf("v%0d",this.src2_idx); end else begin suf2 = "v"; src2 = $sformatf("v%0d",this.src2_idx); end end XRF: begin suf2 = "x"; src2 = $sformatf("x%0d",this.src2_idx); end IMM: begin suf2 = "i"; src2 = $sformatf("%0d",$signed(this.src2_idx)); end + default: begin suf1 = "?"; src1 = "?"; end endcase if(vm == 0) begin if(inst_type == ALU && use_vm_to_cal == 1) begin
diff --git a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_behavior_model.sv b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_behavior_model.sv index 834f2a8..86a2df3 100644 --- a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_behavior_model.sv +++ b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_behavior_model.sv
@@ -151,6 +151,7 @@ bit is_widen_inst; bit is_widen_vs2_inst; bit is_narrow_inst; + bit is_mask_producing_inst; bit use_vm_to_cal; bit vm; @@ -246,6 +247,10 @@ VWMUL, VWMULU, VWMULSU, VWMACCU, VWMACC, VWMACCUS, VWMACCSU}); is_widen_vs2_inst = inst_tr.inst_type == ALU && (inst_tr.alu_inst inside {VWADD_W, VWADDU_W, VWSUBU_W, VWSUB_W}); is_narrow_inst = inst_tr.inst_type == ALU && (inst_tr.alu_inst inside {VNSRL, VNSRA, VNCLIPU, VNCLIP}); + is_mask_producing_inst = inst_tr.inst_type == ALU && (inst_tr.alu_inst inside {VMAND, VMOR, VMXOR, VMORN, VMNAND, VMNOR, VMANDN, VMXNOR, + VMADC, VMSBC, + VMSEQ, VMSNE, VMSLTU, VMSLT, VMSLEU, VMSLE, VMSGTU, VMSGT, + VMUNARY0}); use_vm_to_cal = inst_tr.use_vm_to_cal; // 1.0 illegal inst check @@ -399,6 +404,8 @@ src2_emul = src2_emul * src2_eew / eew; src1_eew = EEW1; src1_emul = src1_emul * src1_eew / eew; + // Special case: In this case, DUT will writeback all bits in dest. + elm_idx_max = `VLEN; end if(inst_tr.inst_type == ALU && inst_tr.alu_inst inside {VMADC, VMSBC, VMSEQ, VMSNE, VMSLTU, VMSLT, VMSLEU, VMSLE, VMSGTU, VMSGT}) begin @@ -412,6 +419,8 @@ src2_emul = src2_emul * src2_eew / eew; src1_eew = EEW1; src1_emul = src1_emul * src1_eew / eew; + // Special case: In this case, DUT will writeback all bits in dest. + elm_idx_max = `VLEN; end if(inst_tr.inst_type == ALU && inst_tr.alu_inst inside {VMUNARY0} && inst_tr.src1_idx inside {VIOTA, VID}) begin src2_eew = EEW1; @@ -616,27 +625,45 @@ endcase if(elm_idx < vstart) begin - `uvm_info("MDL", $sformatf("element[%2d]: pre-start", elm_idx), UVM_LOW) // pre-start: do nothing + if(is_mask_producing_inst) begin + // If is mask producing operation, it will write with calculation results. + `uvm_info("MDL", $sformatf("element[%2d]: pre-start, mask producing operation", elm_idx), UVM_LOW) + elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); + end else begin + `uvm_info("MDL", $sformatf("element[%2d]: pre-start", elm_idx), UVM_LOW) + end end else if(elm_idx >= vl) begin - // tail - `uvm_info("MDL", $sformatf("element[%2d]: tail", elm_idx), UVM_LOW) - if(vtype.vta == AGNOSTIC) begin - if(all_one_for_agn) begin - dest = '1; - elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); + // tail + if(is_mask_producing_inst) begin + // If is mask producing operation, it will write with calculation results. + `uvm_info("MDL", $sformatf("element[%2d]: tail, mask producing operation", elm_idx), UVM_LOW) + dest = alu_handler.exe(inst_tr, dest, src2, src1, src0); + elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); + end else begin + `uvm_info("MDL", $sformatf("element[%2d]: tail", elm_idx), UVM_LOW) + if(vtype.vta == AGNOSTIC) begin + if(all_one_for_agn) begin + dest = '1; + elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); + end + end else begin end - end else begin end end else if(!(vm || this.vrf[0][elm_idx] || use_vm_to_cal)) begin // body-inactive - `uvm_info("MDL", $sformatf("element[%2d]: body-inactive", elm_idx), UVM_LOW) - if(vtype.vma == AGNOSTIC) begin - if(all_one_for_agn) begin - dest = '1; - elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); - end + if(is_mask_producing_inst) begin + `uvm_info("MDL", $sformatf("element[%2d]: body-inactive, mask producing operation", elm_idx), UVM_LOW) + elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); end else begin + `uvm_info("MDL", $sformatf("element[%2d]: body-inactive", elm_idx), UVM_LOW) + if(vtype.vma == AGNOSTIC) begin + if(all_one_for_agn) begin + dest = '1; + elm_writeback(dest, inst_tr.dest_type, dest_reg_idx_base, elm_idx, dest_eew); + end + end else begin + end end end else begin // body-active @@ -797,7 +824,7 @@ bit overflow; bit underflow; int mask_count; - bit first_mask_bit; + bit found_first_mask; int first_mask_idx; pure virtual function alu_unsigned_t exe (rvs_transaction inst_tr, alu_unsigned_t dest, alu_unsigned_t src2, alu_unsigned_t src1, alu_unsigned_t src0); pure virtual function alu_unsigned_t _roundoff_unsigned(alu_unsigned_t v, int unsigned d); @@ -806,7 +833,7 @@ this.overflow = 1'b0; this.underflow = 1'b0; this.mask_count = 'b0; - this.first_mask_bit = 1'b0; + this.found_first_mask = 1'b0; this.first_mask_idx = 'b0; endfunction: reset virtual function void set_vxrm(vxrm_e val); @@ -1439,74 +1466,69 @@ //---------------------------------------------------------------------- // Ch31.15.1. Vector Mask-Register Logical Instructions function TD _vmand(T2 src2, T1 src1); - _vmand = src1 & src2; + _vmand = src2 & src1; endfunction : _vmand function TD _vmor(T2 src2, T1 src1); - _vmor = src1 | src2; + _vmor = src2 | src1; endfunction : _vmor function TD _vmxor(T2 src2, T1 src1); - _vmxor = src1 ^ src2; + _vmxor = src2 ^ src1; endfunction : _vmxor function TD _vmorn(T2 src2, T1 src1); - _vmorn = src1 | ~src2; + _vmorn = src2 | ~src1; endfunction : _vmorn function TD _vmnand(T2 src2, T1 src1); - _vmnand = ~(src1 & src2); + _vmnand = ~(src2 & src1); endfunction : _vmnand function TD _vmnor(T2 src2, T1 src1); - _vmnor = ~(src1 | src2); + _vmnor = ~(src2 | src1); endfunction : _vmnor function TD _vmandn(T2 src2, T1 src1); - _vmandn = src1 & ~src2; + _vmandn = src2 & ~src1; endfunction : _vmandn function TD _vmxnor(T2 src2, T1 src1); - _vmxnor = ~(src1 ^ src2); + _vmxnor = ~(src2 ^ src1); endfunction : _vmxnor //---------------------------------------------------------------------- // 31.15.2. Vector count population in mask vcpop.m function TD _vcpop(T2 src2); - if(this.elm_idx == 0) begin - _vcpop = 0; - this.mask_count = 0; - end else begin - _vcpop = this.mask_count; - this.mask_count += src2; - end + this.mask_count += src2; + _vcpop = this.mask_count; endfunction: _vcpop //---------------------------------------------------------------------- // 32.15.3. vfirst find-first-set mask bit function TD _vfirst(T2 src2); - if(!this.first_mask_bit) begin - this.first_mask_idx = '0; - end else if(src2 && !this.first_mask_bit) begin - this.first_mask_bit = 1'b1; + if(src2 && !this.found_first_mask) begin + this.found_first_mask = 1'b1; this.first_mask_idx = this.elm_idx; end else begin this.first_mask_idx = this.first_mask_idx; end _vfirst = this.first_mask_idx; + `uvm_info("MDL", $sformatf("found_first_mask=%0d, first_mask_idx=%0d, elm_idx=%0d", + found_first_mask, first_mask_idx, elm_idx),UVM_HIGH) endfunction: _vfirst //---------------------------------------------------------------------- // 32.15.4. vmsbf.m set-before-first mask bit function TD _vmsbf(T2 src2); - if(!first_mask_bit) begin + if(!found_first_mask) begin _vmsbf = 1'b1; end else begin _vmsbf = 1'b0; end - if(src2 & ~first_mask_bit) begin - first_mask_bit = 1'b1; + if(src2 & ~found_first_mask) begin + found_first_mask = 1'b1; end endfunction: _vmsbf //---------------------------------------------------------------------- // 32.15.5. vmsif.m set-including-first mask bit function TD _vmsof(T2 src2); - if(src2 & ~first_mask_bit) begin - first_mask_bit = 1'b1; + if(src2 & ~found_first_mask) begin + found_first_mask = 1'b1; _vmsof = 1'b1; end else begin _vmsof = 1'b0; @@ -1516,10 +1538,10 @@ //---------------------------------------------------------------------- // 32.15.6. vmsof.m set-only-first mask bit function TD _vmsif(T2 src2); - if(src2 & ~first_mask_bit) begin - first_mask_bit = 1'b1; + if(src2 & ~found_first_mask) begin + found_first_mask = 1'b1; end - if(!first_mask_bit) begin + if(!found_first_mask) begin _vmsif = 1'b1; end else begin _vmsif = 1'b0;