Update tb: 1. Fix vstart constraint: vl <=vlmax_max-1 2. Use byte_strobe for vrf retire check.

Change-Id: I382da8ccdc5daa5866fb84d997dc4e216f9be179
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 6856bb2..cb8baa0 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
@@ -97,7 +97,8 @@
 
 task rvs_monitor::rx_monitor();
   rvs_transaction tr;
-  logic [`VLEN-1:0] rt_vrf_strobe;
+  logic [`VLENB-1:0] rt_vrf_byte_strobe;
+  logic [`VLEN-1:0] rt_vrf_bit_strobe;
   bit vrf_overlap;
   tr = new("tr");
   forever begin
@@ -114,20 +115,21 @@
           // VRF
           if(rvs_if.rt_vrf_valid_rob2rt[rt_idx]) begin
             vrf_overlap = 0;
+            rt_vrf_byte_strobe = rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_strobe;
             for(int i=0; i<`VLENB; i++) begin
-              rt_vrf_strobe[i*8 +: 8] = {8{rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_strobe[i]}}; 
-            end
+              rt_vrf_bit_strobe[i*8 +: 8] = {8{rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_strobe[i]}}; 
+            end 
             foreach(tr.rt_vrf_index[i]) begin
               if(tr.rt_vrf_index[i] == rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_index) begin
-                tr.rt_vrf_strobe[i] |= rt_vrf_strobe;
-                tr.rt_vrf_data[i]   |= rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_data;
+                tr.rt_vrf_strobe[i] |= rt_vrf_byte_strobe;
+                tr.rt_vrf_data[i]   = rt_vrf_bit_strobe & rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_data | ~rt_vrf_bit_strobe & tr.rt_vrf_data[i];
                 vrf_overlap = 1;
                 `uvm_info(get_type_name(), $sformatf("Uops %0d also write vrf[%0d].", rt_idx, rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_index), UVM_HIGH)
               end
             end
             if(!vrf_overlap) begin
               tr.rt_vrf_index.push_back(rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_index);
-              tr.rt_vrf_strobe.push_back(rt_vrf_strobe);
+              tr.rt_vrf_strobe.push_back(rt_vrf_byte_strobe);
               tr.rt_vrf_data.push_back(rvs_if.rt_vrf_data_rob2rt[rt_idx].rt_data);
             end
           end
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 c51b28a..7e2f95d 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
@@ -12,6 +12,7 @@
   rand vtype_t           vtype;
   rand logic [`XLEN-1:0] vl;
        logic [`XLEN-1:0] vlmax;
+       logic [`XLEN-1:0] vlmax_max;
   rand logic [`XLEN-1:0] vstart;
   rand vxrm_e            vxrm;
 
@@ -60,7 +61,7 @@
 
   /* Write back info */
        reg_idx_t  rt_vrf_index  [$];
-       vrf_t      rt_vrf_strobe [$];
+       vrf_byte_t rt_vrf_strobe [$];
        vrf_t      rt_vrf_data   [$];
 
        reg_idx_t  rt_xrf_index [$];
@@ -85,6 +86,8 @@
     else  
       vl <= (`VLENB << vtype.vlmul) >> vtype.vsew;
     vstart <= vl;
+    vstart <= vlmax_max-1;
+    vl <= vlmax_max;
   }
 
   constraint c_vm {
@@ -269,6 +272,7 @@
   `uvm_object_utils_end
 
   extern function new(string name = "Trans");
+  extern function void pre_randomize();
   extern function void post_randomize();
   extern function void asm_string_gen();
 
@@ -279,7 +283,13 @@
   super.new(name);
 endfunction: new
 
+function void rvs_transaction::pre_randomize();
+  super.pre_randomize();
+  vlmax_max = 8 * `VLEN / 8;
+endfunction: pre_randomize
+
 function void rvs_transaction::post_randomize();
+  super.post_randomize();
   if(inst_type == ALU && (alu_inst inside {VADC, VSBC, VMADC, VMSBC, VMERGE_VMVV}))
     use_vm_to_cal = 1;
   else
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 173b560..834f2a8 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
@@ -36,7 +36,8 @@
   vrf_t [31:0] vrf;
   vrf_t [31:0] vrf_delay;
   vrf_t [31:0] vrf_temp;
-  vrf_t [31:0] vrf_strobe_temp;
+  vrf_t [31:0] vrf_bit_strobe_temp;
+  vrf_byte_t [31:0] vrf_byte_strobe_temp;
 
   logic [`XLEN-1:0] vlmax;
   logic [`XLEN-1:0] imm_data;
@@ -513,7 +514,7 @@
 
 
         vrf_temp = vrf;
-        vrf_strobe_temp = '0;
+        vrf_bit_strobe_temp = '0;
         `uvm_info("MDL",$sformatf("Prepare done!\nelm_idx_max=%0d\ndest_eew=%0d\nsrc2_eew=%0d\nsrc1_eew=%0d\ndest_emul=%2.4f\nsrc2_emul=%2.4f\nsrc1_emul=%2.4f\n",elm_idx_max,dest_eew,src2_eew,src1_eew,dest_emul,src2_emul,src1_emul),UVM_LOW)
         // --------------------------------------------------
         // 3. Operate elements
@@ -665,18 +666,29 @@
 
         // Writeback whole vrf
         vrf = vrf_temp;
+        for(int i=0; i<32; i++) begin
+          for(int j=0; j<`VLENB; j++) begin
+            vrf_byte_strobe_temp[i][j] = |vrf_bit_strobe_temp[i][j*8 +: 8];
+          end
+        end
         // --------------------------------------------------
         // 4. Retire transaction gen
         rt_tr   = new("rt_tr");
         rt_tr.copy(inst_tr);
         rt_tr.is_rt = 1;
         // VRF
+        // if(rt_tr.dest_type == VRF && !(|vrf_bit_strobe_temp)) begin
+        //   `uvm_warning("MDL/INST_CHECKER", $sformatf("pc=0x%8x: Instruction with no valid vrf wirte strobe will be ignored.",pc));
+        //   continue;
+        // end
         if(rt_tr.dest_type == VRF) begin
           for(int reg_idx=dest_reg_idx_base; reg_idx<dest_reg_idx_base+int'($ceil(dest_emul)); reg_idx++) begin
+            // FIXME: All 0s in vrf wirte strobe will not be executed in DUT.
+            // if(|vrf_byte_strobe_temp[reg_idx]) begin
             // All pre-start vreg will not be retired
             if((reg_idx - dest_reg_idx_base) >= (vstart / (`VLEN / dest_eew))) begin
               rt_tr.rt_vrf_index.push_back(reg_idx);
-              rt_tr.rt_vrf_strobe.push_back(vrf_strobe_temp[reg_idx]);
+              rt_tr.rt_vrf_strobe.push_back(vrf_byte_strobe_temp[reg_idx]);
               rt_tr.rt_vrf_data.push_back(vrf_temp[reg_idx]);
             end
           end
@@ -742,7 +754,7 @@
         elm_idx = elm_idx % (`VLEN / eew);
         for(int i=0; i<bit_count; i++) begin
           this.vrf_temp[reg_idx][elm_idx*bit_count + i] = result[i];
-          this.vrf_strobe_temp[reg_idx][elm_idx*bit_count + i] = 1'b1;
+          this.vrf_bit_strobe_temp[reg_idx][elm_idx*bit_count + i] = 1'b1;
         end
       end
       XRF: begin
@@ -1323,10 +1335,12 @@
     if(overflow) _vsaddu = '1;
   endfunction : _vsaddu
   function TD _vsadd(T2 src2, T1 src1);
-    logic signed [$bits(TD)-1:0] dest;
+    logic signed [$bits(TD):0] dest;
     dest = $signed(src2) + $signed(src1);
-    overflow  = dest[$bits(TD)-1] & ~src2[$bits(T2)-1] & ~src1[$bits(T1)-1]; 
-    underflow = ~dest[$bits(TD)-1] & src2[$bits(T2)-1] & src1[$bits(T1)-1]; 
+    // overflow  = dest[$bits(TD)-1] & ~src2[$bits(T2)-1] & ~src1[$bits(T1)-1]; 
+    // underflow = ~dest[$bits(TD)-1] & src2[$bits(T2)-1] & src1[$bits(T1)-1]; 
+    overflow  = dest[$bits(TD):$bits(TD)-1] == 2'b01;
+    underflow = dest[$bits(TD):$bits(TD)-1] == 2'b10;
     if(overflow)  begin _vsadd = '1; _vsadd[$bits(TD)-1] = 1'b0; end
     else if(underflow) begin _vsadd = '0; _vsadd[$bits(TD)-1] = 1'b1; end
     else begin _vsadd = dest; end
@@ -1336,10 +1350,12 @@
     if(underflow) _vssubu = '0;
   endfunction : _vssubu
   function TD _vssub(T2 src2, T1 src1);
-    logic unsigned [$bits(TD)-1:0] dest;
-    dest = $unsigned(src2) - $signed(src1);
-    overflow = dest[$bits(TD)-1] & ~src2[$bits(T2)-1] & src1[$bits(T1)-1]; 
-    underflow  = ~dest[$bits(TD)-1] & src2[$bits(T2)-1] & ~src1[$bits(T1)-1]; 
+    logic signed [$bits(TD):0] dest;
+    dest = $signed(src2) - $signed(src1);
+    // overflow = dest[$bits(TD)-1] & ~src2[$bits(T2)-1] & src1[$bits(T1)-1]; 
+    // underflow  = ~dest[$bits(TD)-1] & src2[$bits(T2)-1] & ~src1[$bits(T1)-1]; 
+    overflow  = dest[$bits(TD):$bits(TD)-1] == 2'b01;
+    underflow = dest[$bits(TD):$bits(TD)-1] == 2'b10;
     if(overflow)  begin _vssub = '1; _vssub[$bits(TD)-1] = 1'b0; end
     else if(underflow) begin _vssub = '0; _vssub[$bits(TD)-1] = 1'b1; end
     else begin _vssub = dest; end
@@ -1374,9 +1390,10 @@
     logic signed [$bits(TD)*2-1:0] dest;
     dest = $signed(src2) * $signed(src1);
     dest = _roundoff_signed(dest, $bits(TD)-1);
-    // FIXME: check
-    overflow = ^dest[$bits(TD):$bits(TD)-1];
+    overflow  = dest[$bits(TD):$bits(TD)-1] == 2'b01;
+    underflow = dest[$bits(TD):$bits(TD)-1] == 2'b10;
     if(overflow) begin _vsmul = '1; _vsmul[$bits(TD)-1] = 1'b0; end
+    else if(underflow) begin _vsmul = '0; _vsmul[$bits(TD)-1] = 1'b1; end
     else begin _vsmul = dest; end
   endfunction : _vsmul
 
diff --git a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_scoreboard.sv b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_scoreboard.sv
index 02863a4..67255c0 100644
--- a/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_scoreboard.sv
+++ b/hdl/verilog/rvv/sve/rvv_backend_tb/src/rvv_scoreboard.sv
@@ -103,7 +103,8 @@
 
   int        rt_vrf_num;
   reg_idx_t  rvs_rt_vrf_index , mdl_rt_vrf_index ;
-  vrf_t      rvs_rt_vrf_strobe, mdl_rt_vrf_strobe;
+  vrf_byte_t rvs_rt_vrf_byte_strobe, mdl_rt_vrf_byte_strobe;
+  vrf_t      rvs_rt_vrf_bit_strobe,  mdl_rt_vrf_bit_strobe;
   vrf_t      rvs_rt_vrf_data  , mdl_rt_vrf_data  ;
 
   string vreg_dut_val;
@@ -141,39 +142,46 @@
         rt_vrf_num = rvs_tr.rt_vrf_index.size();
         for(int i=0; i<rt_vrf_num; i++) begin
           rvs_rt_vrf_index  = rvs_tr.rt_vrf_index.pop_front();
-          rvs_rt_vrf_strobe = rvs_tr.rt_vrf_strobe.pop_front();
+          rvs_rt_vrf_byte_strobe = rvs_tr.rt_vrf_strobe.pop_front();
           rvs_rt_vrf_data   = rvs_tr.rt_vrf_data.pop_front();
           mdl_rt_vrf_index  = mdl_tr.rt_vrf_index.pop_front();
-          mdl_rt_vrf_strobe = mdl_tr.rt_vrf_strobe.pop_front();
+          mdl_rt_vrf_byte_strobe = mdl_tr.rt_vrf_strobe.pop_front();
           mdl_rt_vrf_data   = mdl_tr.rt_vrf_data.pop_front();
+          // Since RTL use byte_strobe for retire, 
+          //   MDL should generate byte_strobe, 
+          //   and SCB also need to expand byte_strobe to bit_strobe to compare data.
+          for(int bit_idx=0; bit_idx<`VLENB; bit_idx++) begin
+            rvs_rt_vrf_bit_strobe[bit_idx*8 +: 8] = {8{rvs_rt_vrf_byte_strobe[bit_idx]}}; 
+            mdl_rt_vrf_bit_strobe[bit_idx*8 +: 8] = {8{mdl_rt_vrf_byte_strobe[bit_idx]}}; 
+          end 
           if(rvs_rt_vrf_index !== mdl_rt_vrf_index) begin
             `uvm_error("RT_CHECKER", $sformatf("Retire VRF index mismatch:\nDUT retired vrf[%0d],\nMDL retired vrf[%0d].", 
                                                 rvs_rt_vrf_index, 
                                                 mdl_rt_vrf_index));
-          end else if(rvs_rt_vrf_strobe !== mdl_rt_vrf_strobe) begin
+          end else if(rvs_rt_vrf_byte_strobe !== mdl_rt_vrf_byte_strobe) begin
             vreg_dut_val = "0x";
             vreg_mdl_val = "0x";
             for(int i=`VLEN-1;i>=0;i-=16) begin
-              vreg_dut_val = $sformatf("%s%4h_",vreg_dut_val,rvs_rt_vrf_strobe[i-:16]);
-              vreg_mdl_val = $sformatf("%s%4h_",vreg_mdl_val,mdl_rt_vrf_strobe[i-:16]);
+              vreg_dut_val = $sformatf("%s%4h_",vreg_dut_val,rvs_rt_vrf_byte_strobe[i-:16]);
+              vreg_mdl_val = $sformatf("%s%4h_",vreg_mdl_val,mdl_rt_vrf_byte_strobe[i-:16]);
             end
             vreg_dut_val = vreg_dut_val.substr(0,vreg_dut_val.len()-2);
             vreg_mdl_val = vreg_mdl_val.substr(0,vreg_mdl_val.len()-2);
             `uvm_error("RT_CHECKER", $sformatf("Retire VRF strobe(bit) mismatch:\nDUT retired vrf_strobe[%0d] = %s,\nMDL retired vrf_strobe[%0d] = %s.", 
                                                rvs_rt_vrf_index, vreg_dut_val,
                                                mdl_rt_vrf_index, vreg_mdl_val));
-          end else if((rvs_rt_vrf_strobe & rvs_rt_vrf_data) !== (mdl_rt_vrf_strobe & mdl_rt_vrf_data)) begin
+          end else if((rvs_rt_vrf_bit_strobe & rvs_rt_vrf_data) !== (mdl_rt_vrf_bit_strobe & mdl_rt_vrf_data)) begin
             vreg_dut_val = "0x";
             vreg_mdl_val = "0x";
             for(int i=`VLEN-1;i>=0;i-=16) begin
-              vreg_dut_val = $sformatf("%s%4h_",vreg_dut_val,{rvs_rt_vrf_strobe & rvs_rt_vrf_data}[i-:16]);
-              vreg_mdl_val = $sformatf("%s%4h_",vreg_mdl_val,{mdl_rt_vrf_strobe & mdl_rt_vrf_data}[i-:16]);
+              vreg_dut_val = $sformatf("%s%4h_",vreg_dut_val,{rvs_rt_vrf_bit_strobe & rvs_rt_vrf_data}[i-:16]);
+              vreg_mdl_val = $sformatf("%s%4h_",vreg_mdl_val,{mdl_rt_vrf_bit_strobe & mdl_rt_vrf_data}[i-:16]);
             end
             vreg_dut_val = vreg_dut_val.substr(0,vreg_dut_val.len()-2);
             vreg_mdl_val = vreg_mdl_val.substr(0,vreg_mdl_val.len()-2);
             // `uvm_error("RT_CHECKER", $sformatf("Retire VRF mismatch:\nDUT retired vrf[%0d] = 0x%0x,\nMDL retired vrf[%0d] = 0x%0x.", 
-            //                                     rvs_rt_vrf_index, (rvs_rt_vrf_strobe & rvs_rt_vrf_data),
-            //                                     mdl_rt_vrf_index, (mdl_rt_vrf_strobe & mdl_rt_vrf_data)));
+            //                                     rvs_rt_vrf_index, (rvs_rt_vrf_bit_strobe & rvs_rt_vrf_data),
+            //                                     mdl_rt_vrf_index, (mdl_rt_vrf_bit_strobe & mdl_rt_vrf_data)));
             `uvm_error("RT_CHECKER", $sformatf("Retire VRF mismatch:\nDUT retired vrf[%0d] = %s,\nMDL retired vrf[%0d] = %s.", 
                                                 rvs_rt_vrf_index, vreg_dut_val,
                                                 mdl_rt_vrf_index, vreg_mdl_val));