fix bugs for mask-logic, vcpop instructions;

Change-Id: Ica3542103ffe208d29bfefdbafe24de5fce065b7
diff --git a/hdl/verilog/rvv/design/rvv_backend_alu_unit_mask.sv b/hdl/verilog/rvv/design/rvv_backend_alu_unit_mask.sv
index d7f1a43..f1e2405 100644
--- a/hdl/verilog/rvv/design/rvv_backend_alu_unit_mask.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_alu_unit_mask.sv
@@ -46,9 +46,10 @@
 
   // execute 
   logic   [`VLEN-1:0]                     src2_data;
+  logic   [`VLEN-1:0]                     src2_data_vcpop;
   logic   [`VLEN-1:0]                     src2_data_viota;
   logic   [`VLEN-1:0]                     src1_data;
-  logic   [`VLEN-1:0]                     tail_data;
+  logic   [`VLEN-1:0]                     tail_mask;
   logic   [`VLEN-1:0]                     result_data;
   logic   [`VLEN-1:0]                     result_data_andn;
   logic   [`VLEN-1:0]                     result_data_and; 
@@ -63,7 +64,8 @@
   logic   [`VLEN-1:0]                     result_data_vmsif;
   logic   [`VLEN-1:0]                     result_data_vmsbf;
   logic   [`VLEN-1:0]                     result_data_vfirst;
-  logic   [`VLEN/16-1:0][4:0]             result_data_vcpop;
+  logic   [`VLENB-1:0][$clog2(`BYTE_WIDTH):0]          result_data_vcpop8;
+  logic   [`XLEN-1:0]                     result_data_vcpop;
   logic   [`VLEN-1:0][$clog2(`VLEN)-1:0]               result_data_viota;
   logic   [`VLEN-1:0][$clog2(`BYTE_WIDTH):0]           result_data_viota_per8;
   logic   [`VLENB-1:0][$clog2(`VLEN)-1:0]              result_data_viota8;
@@ -107,7 +109,7 @@
   // get tail mask
   generate
     for(j=0;j<`VLEN;j++) begin: GET_TAIL
-      assign tail_data[j] = j<vl;
+      assign tail_mask[j] = j<vl;
     end
   endgenerate
 
@@ -224,6 +226,7 @@
     // initial the data
     src2_data       = 'b0;
     src1_data       = 'b0;
+    src2_data_vcpop = 'b0; 
     src2_data_viota = 'b0; 
 
     // prepare source data
@@ -276,12 +279,17 @@
           end
           VWXUNARY0: begin
             case(vs1_opcode)
-              VCPOP,
+              VCPOP: begin
+                if (vm==1'b1)
+                  src2_data_vcpop = vs2_data&tail_mask;
+                else
+                  src2_data_vcpop = vs2_data&tail_mask&v0_data; 
+              end
               VFIRST: begin
                 if (vm==1'b1)
-                  src2_data = vs2_data&tail_data;
+                  src2_data = vs2_data&tail_mask;
                 else
-                  src2_data = vs2_data&tail_data&v0_data; 
+                  src2_data = vs2_data&tail_mask&v0_data; 
               end
             endcase
           end
@@ -291,9 +299,9 @@
               VMSOF,
               VMSIF: begin
                 if (vm==1'b1)
-                  src2_data = vs2_data&tail_data;
+                  src2_data = vs2_data;
                 else
-                  src2_data = vs2_data&tail_data&v0_data; 
+                  src2_data = vs2_data&v0_data; 
               end
               VIOTA: begin
                 if (vm==1'b1)
@@ -338,17 +346,22 @@
       end
     end
   end
-
+  
   // vcpop
   generate
-    for(j=0;j<`VLEN/16;j++) begin: GET_PARTIAL_SUM_VCPOP
-      assign result_data_vcpop[j] = (((src2_data[16*j+0] +src2_data[16*j+1] ) + (src2_data[16*j+2] +src2_data[16*j+3] )) +
-                                     ((src2_data[16*j+4] +src2_data[16*j+5] ) + (src2_data[16*j+6] +src2_data[16*j+7] ))) + 
-                                    (((src2_data[16*j+8] +src2_data[16*j+9] ) + (src2_data[16*j+10]+src2_data[16*j+11])) +
-                                     ((src2_data[16*j+12]+src2_data[16*j+13]) + (src2_data[16*j+14]+src2_data[16*j+15])));
+    for(j=0; j<`VLENB;j++) begin: GET_VCPOP_PER8
+      assign result_data_vcpop8[j] = f_vcpop8(src2_data_vcpop[8*j +: 8]);
     end
   endgenerate
 
+  always_comb begin
+    result_data_vcpop = 'b0;
+
+    for(int i=0;i<`VLENB;i++) begin
+      result_data_vcpop = result_data_vcpop+result_data_vcpop8[i];
+    end
+  end
+   
   // viota 
   generate
     for(j=0; j<`VLENB;j++) begin: GET_VIOTA_PER8
@@ -399,7 +412,7 @@
       assign result_data_viota32[j] = result_data_viota[{uop_index,j[$clog2(`VLEN/`WORD_WIDTH)-1:0]}];
     end
   endgenerate
-
+  
   // vid
   generate
     for(j=0;j<`VLENB;j++) begin: GET_VID8
@@ -470,10 +483,7 @@
           VWXUNARY0: begin
             case(vs1_opcode)
               VCPOP: begin
-                result_data = 'b0;
-                for(int i=0;i<`VLEN/16;i++) begin
-                  result_data = result_data + result_data_vcpop[i];
-                end
+                result_data = result_data_vcpop;
               end
               VFIRST: begin
                 result_data = result_data_vfirst;
@@ -590,7 +600,7 @@
                     if (vm==1'b1)
                       result.w_data[j] = result_data[j];
                     else 
-                      result.w_data[j] = (tail_data[j]==1'b1)&(v0_data[j]==1'b0) ? vd_data[j] : result_data[j]; 
+                      result.w_data[j] = v0_data[j] ? result_data[j] : vd_data[j]; 
                   end
                   VIOTA,
                   VID: begin
@@ -678,25 +688,75 @@
     f_xnor = ~(vs2_data ^ vs1_data);
   endfunction
 
+  // vcpop
+  function [2:0] f_vcpop4;
+    input logic [3:0] src;
+    
+    case(src)
+      4'b0000: begin
+        f_vcpop4 = 3'd0;
+      end
+      4'b0001,
+      4'b0010,
+      4'b0100,
+      4'b1000: begin
+        f_vcpop4 = 3'd1;
+      end
+      4'b0011,
+      4'b0101,
+      4'b1001,
+      4'b0110,
+      4'b1010,
+      4'b1100: begin
+        f_vcpop4 = 3'd2;
+      end
+      4'b0111,
+      4'b1011,
+      4'b1101,
+      4'b1110: begin
+        f_vcpop4 = 3'd3;
+      end
+      4'b1111: begin
+        f_vcpop4 = 3'd4;
+      end
+      default: begin
+        f_vcpop4 = 3'd0;
+      end
+    endcase
+  
+  endfunction
+
+  function [3:0] f_vcpop8;
+    input logic [7:0] src;
+     
+    logic [3:0] vcpop4_hi;
+    logic [3:0] vcpop4_lo;
+
+    vcpop4_hi = f_vcpop4(src[7:4]);
+    vcpop4_lo = f_vcpop4(src[3:0]);
+
+    f_vcpop8 = vcpop4_hi+vcpop4_lo;
+  endfunction
+
   // find first 1 from LSB
   function [`VLEN-1:0] f_first1;
     input logic [`VLEN-1:0] src2;
 
-    f_first1 = (~(src2-1)) & src2;
+    f_first1 = (~(src2-1'b1)) & src2;
   endfunction
 
   // set from [0] to [first_1_index]
   function [`VLEN-1:0] f_vmsif;
     input logic [`VLEN-1:0] src2;
 
-    f_vmsif = (src2-1) & src2;
+    f_vmsif = (src2-1'b1) | src2;
   endfunction
 
   // set from [0] to [first_1_index-1]
   function [`VLEN-1:0] f_vmsbf;
     input logic [`VLEN-1:0] src2;
 
-    f_vmsbf = {1'b0, (src2[`VLEN-1:1]-1) & src2[`VLEN-1:1]};
+    f_vmsbf = {1'b0, (src2[`VLEN-1:1]-1'b1) | src2[`VLEN-1:1]};
   endfunction
 
   // viota
diff --git a/hdl/verilog/rvv/design/rvv_backend_alu_unit_shift.sv b/hdl/verilog/rvv/design/rvv_backend_alu_unit_shift.sv
index c79494f..6ea10a2 100755
--- a/hdl/verilog/rvv/design/rvv_backend_alu_unit_shift.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_alu_unit_shift.sv
@@ -660,11 +660,13 @@
 
   // overflow check for vnclipu and vnclip 
   generate 
-    for (j=0;j<`VLEN/`WORD_WIDTH;j++) begin: GET_OVERFLOW
+    for (j=0;j<`VLEN/`WORD_WIDTH/2;j++) begin: GET_OVERFLOW
       always_comb begin
         // initial
         upoverflow[   4*j +: 4] = 'b0;
         underoverflow[4*j +: 4] = 'b0;
+        upoverflow[   4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
+        underoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
           
         case(vs2_eew)
           EEW16: begin
@@ -672,69 +674,57 @@
               SHIFT_SRL: begin
               // unsigned overflow check for vnclipu
                 if(uop_index[0]==1'b0) begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)};
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = 'b0;
-                  end
+                  upoverflow[4*j +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)};
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
                 end
                 else begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = 'b0;
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+3], round16[4*(j-`VLEN/`WORD_WIDTH/2)+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+2], round16[4*(j-`VLEN/`WORD_WIDTH/2)+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+1], round16[4*(j-`VLEN/`WORD_WIDTH/2)+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)  ], round16[4*(j-`VLEN/`WORD_WIDTH/2)  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)};
-                  end
+                  upoverflow[4*j +: 4] = 'b0;
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)};
                 end
               end
               SHIFT_SRA: begin
               // signed overflow check for vnclip
                 if(uop_index[0]==1'b0) begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b0)};
+                  upoverflow[4*j +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b0)};
   
-                    underoverflow[4*j +: 4] = {
-                      ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b1)};
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = 'b0;
-                    underoverflow[4*j +: 4] = 'b0;
-                  end
+                  underoverflow[4*j +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b1)};
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
+                  underoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
                 end
                 else begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = 'b0;
-                    underoverflow[4*j +: 4] = 'b0;
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+3], round16[4*(j-`VLEN/`WORD_WIDTH/2)+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+3][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+2], round16[4*(j-`VLEN/`WORD_WIDTH/2)+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+2][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+1], round16[4*(j-`VLEN/`WORD_WIDTH/2)+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+1][`HWORD_WIDTH-1]==1'b0),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)  ], round16[4*(j-`VLEN/`WORD_WIDTH/2)  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)  ][`HWORD_WIDTH-1]==1'b0)};
+                  upoverflow[4*j +: 4] = 'b0;
+                  underoverflow[4*j +: 4] = 'b0;
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b0),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='b0)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b0)};
   
-                    underoverflow[4*j +: 4] = {
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+3], round16[4*(j-`VLEN/`WORD_WIDTH/2)+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+3][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+2], round16[4*(j-`VLEN/`WORD_WIDTH/2)+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+2][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)+1], round16[4*(j-`VLEN/`WORD_WIDTH/2)+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)+1][`HWORD_WIDTH-1]==1'b1),
-                      ({cout16[4*(j-`VLEN/`WORD_WIDTH/2)  ], round16[4*(j-`VLEN/`WORD_WIDTH/2)  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*(j-`VLEN/`WORD_WIDTH/2)  ][`HWORD_WIDTH-1]==1'b1)};
-                  end
+                  underoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout16[4*j+3], round16[4*j+3][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+3][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j+2], round16[4*j+2][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+2][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j+1], round16[4*j+1][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j+1][`HWORD_WIDTH-1]==1'b1),
+                    ({cout16[4*j  ], round16[4*j  ][`BYTE_WIDTH +: `BYTE_WIDTH]}!='1)&(round16[4*j  ][`HWORD_WIDTH-1]==1'b1)};
                 end
               end
             endcase
@@ -744,57 +734,45 @@
               SHIFT_SRL: begin
               // unsigned overflow check for vnclipu
                 if(uop_index[0]==1'b0) begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0,
-                      ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0};
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = 'b0;
-                  end
+                  upoverflow[4*j +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0};
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
                 end
                 else begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = 'b0;
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)+1], round32[2*(j-`VLEN/`WORD_WIDTH/2)+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0,
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)  ], round32[2*(j-`VLEN/`WORD_WIDTH/2)  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0};
-                  end
+                  upoverflow[4*j +: 4] = 'b0;
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0),1'b0};
                 end
               end
               SHIFT_SRA: begin
               // unsigned overflow check for vnclip
                 if(uop_index[0]==1'b0) begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j+1][`WORD_WIDTH-1]==1'b0),1'b0,
-                      ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j  ][`WORD_WIDTH-1]==1'b0),1'b0};
+                  upoverflow[4*j +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j+1][`WORD_WIDTH-1]==1'b0),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j  ][`WORD_WIDTH-1]==1'b0),1'b0};
   
-                    underoverflow[4*j +: 4] = {
-                      ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j+1][`WORD_WIDTH-1]==1'b1),1'b0,
-                      ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j  ][`WORD_WIDTH-1]==1'b1),1'b0};
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = 'b0;
-                    underoverflow[4*j +: 4] = 'b0;
-                  end
+                  underoverflow[4*j +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j+1][`WORD_WIDTH-1]==1'b1),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j  ][`WORD_WIDTH-1]==1'b1),1'b0};
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
+                  underoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = 'b0;
                 end
                 else begin
-                  if(j<`VLEN/`WORD_WIDTH/2) begin
-                    upoverflow[4*j +: 4] = 'b0;
-                    underoverflow[4*j +: 4] = 'b0;
-                  end
-                  else begin
-                    upoverflow[4*j +: 4] = {
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)+1], round32[2*(j-`VLEN/`WORD_WIDTH/2)+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*(j-`VLEN/`WORD_WIDTH/2)+1][`WORD_WIDTH-1]==1'b0),1'b0,
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)  ], round32[2*(j-`VLEN/`WORD_WIDTH/2)  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*(j-`VLEN/`WORD_WIDTH/2)  ][`WORD_WIDTH-1]==1'b0),1'b0};
+                  upoverflow[4*j +: 4] = 'b0;
+                  underoverflow[4*j +: 4] = 'b0;
+
+                  upoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j+1][`WORD_WIDTH-1]==1'b0),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='b0)&(round32[2*j  ][`WORD_WIDTH-1]==1'b0),1'b0};
   
-                    underoverflow[4*j +: 4] = {
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)+1], round32[2*(j-`VLEN/`WORD_WIDTH/2)+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*(j-`VLEN/`WORD_WIDTH/2)+1][`WORD_WIDTH-1]==1'b1),1'b0,
-                      ({cout32[2*(j-`VLEN/`WORD_WIDTH/2)  ], round32[2*(j-`VLEN/`WORD_WIDTH/2)  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*(j-`VLEN/`WORD_WIDTH/2)  ][`WORD_WIDTH-1]==1'b1),1'b0};
-                  end
+                  underoverflow[4*(j+`VLEN/`WORD_WIDTH/2) +: 4] = {
+                    ({cout32[2*j+1], round32[2*j+1][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j+1][`WORD_WIDTH-1]==1'b1),1'b0,
+                    ({cout32[2*j  ], round32[2*j  ][`HWORD_WIDTH +: `HWORD_WIDTH]}!='1)&(round32[2*j  ][`WORD_WIDTH-1]==1'b1),1'b0};
                 end
               end
             endcase
diff --git a/hdl/verilog/rvv/design/rvv_backend_decode_ctrl.sv b/hdl/verilog/rvv/design/rvv_backend_decode_ctrl.sv
index 388a50a..620dfe1 100644
--- a/hdl/verilog/rvv/design/rvv_backend_decode_ctrl.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_decode_ctrl.sv
@@ -160,16 +160,16 @@
         uop_index_din = uop_de2uq[0][`NUM_DE_UOP-1].uop_index + 1'b1;    
       uop_index_enable_unit1: begin
         case(quantity)
-          'd0:
+          3'd0:
             uop_index_din = uop_de2uq[1][3].uop_index + 1'b1; 
-          'd1:
+          3'd1:
             uop_index_din = uop_de2uq[1][2].uop_index + 1'b1; 
-          'd2:
+          3'd2:
             uop_index_din = uop_de2uq[1][1].uop_index + 1'b1; 
-          'd3:
+          3'd3:
             uop_index_din = uop_de2uq[1][0].uop_index + 1'b1; 
-          'd4:
-            uop_index_din = uop_de2uq[1][0].uop_index; 
+          3'd4:
+            uop_index_din = 'b0; 
         endcase
       end
     endcase
diff --git a/hdl/verilog/rvv/design/rvv_backend_decode_unit_ari.sv b/hdl/verilog/rvv/design/rvv_backend_decode_unit_ari.sv
index 0cd9714..136cde9 100644
--- a/hdl/verilog/rvv/design/rvv_backend_decode_unit_ari.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_decode_unit_ari.sv
@@ -2799,7 +2799,7 @@
                     (inst_vs1[4:3]==2'b0)&
                     ((inst_nr==NREG1)|(inst_nr==NREG2)|(inst_nr==NREG4)|(inst_nr==NREG8))
                    )
-                  check_special          = 1'b1;
+                  check_special = 1'b1;
 
                 `ifdef ASSERT_ON
                   assert #0 (check_special==1'b1)
@@ -3030,7 +3030,8 @@
                 case(vs1_opcode_vwxunary)
                   VCPOP,
                   VFIRST: begin
-                    check_special   = 1'b1;
+                    if(csr_vstart=='b0)
+                      check_special  = 1'b1;
                   end
                   VMV_X_S: begin
                     if(inst_vm==1'b1)
@@ -3058,7 +3059,8 @@
                   VMSIF,
                   VMSOF,
                   VIOTA: begin
-                    check_special = check_vd_overlap_v0&check_vd_overlap_vs2;
+                    if(csr_vstart=='b0)
+                      check_special = check_vd_overlap_v0&check_vd_overlap_vs2;
                   end
                   VID: begin
                     if(inst_vs2=='b0)
@@ -3358,7 +3360,7 @@
   `ifdef ASSERT_ON
     `ifdef TB_SUPPORT
       `rvv_forbid((inst_valid==1'b1)&(inst_encoding_correct==1'b0))
-      else $warning("pc(%d) instruction will be discarded directly.\n",inst.inst_pc);
+      else $warning("pc(0x%h) instruction will be discarded directly.\n",inst.inst_pc);
     `else
       `rvv_forbid((inst_valid==1'b1)&(inst_encoding_correct==1'b0))
       else $warning("This instruction will be discarded directly.\n");
@@ -3368,17 +3370,20 @@
 // get the start number of uop_index
   always_comb begin
     // initial
-    uop_vstart      = 'b0;
+    uop_vstart = 'b0;
 
     case(eew_max)
+      EEW1: begin
+        uop_vstart = 'b0;
+      end
       EEW8: begin
-        uop_vstart  = csr_vstart[4 +: `UOP_INDEX_WIDTH];
+        uop_vstart = csr_vstart[4 +: `UOP_INDEX_WIDTH];
       end
       EEW16: begin
-        uop_vstart  = csr_vstart[3 +: `UOP_INDEX_WIDTH];
+        uop_vstart = csr_vstart[3 +: `UOP_INDEX_WIDTH];
       end
       EEW32: begin
-        uop_vstart  = csr_vstart[2 +: `UOP_INDEX_WIDTH];
+        uop_vstart = csr_vstart[2 +: `UOP_INDEX_WIDTH];
       end
     endcase
   end
@@ -3402,7 +3407,7 @@
     
     case(emul_max)
       EMUL1: begin
-        uop_index_max = 'd0;
+        uop_index_max = 'b0;
       end
       EMUL2: begin
         uop_index_max = 'd1;
@@ -3930,6 +3935,8 @@
   end
  
   // update ignore_vma and ignore_vta
+  // some instructions use vm as an extra opcode, so it needs ignore vma policy.
+  // the instructions whose EEW_vd=1b can write the result to TAIL elements, so it needs ignore vta policy.
   always_comb begin
     for(int i=0;i<`NUM_DE_UOP;i=i+1) begin: GET_IGNORE
       uop[i].ignore_vma = 'b0;
@@ -4032,7 +4039,7 @@
                 OPIVV,
                 OPIVX,
                 OPIVI: begin
-                  uop[i].v0_valid   = !inst_vm;
+                  uop[i].v0_valid = !inst_vm;
                 end
               endcase
             end 
@@ -4041,7 +4048,30 @@
               case(inst_funct3)
                 OPIVV,
                 OPIVX: begin
-                  uop[i].v0_valid   = !inst_vm;
+                  uop[i].v0_valid = !inst_vm;
+                end
+              endcase
+            end
+          endcase
+        end
+        valid_opm: begin
+          // OPI*
+          case(funct6_ari.ari_funct6)
+            VWXUNARY0: begin
+              case(vs1_opcode_vwxunary)
+                VCPOP,
+                VFIRST: begin
+                  uop[i].v0_valid = !inst_vm;
+                end
+              endcase
+            end
+            VMUNARY0: begin
+              case(vs1_opcode_vmunary)
+                VMSBF,
+                VMSOF,
+                VMSIF,
+                VIOTA: begin
+                  uop[i].v0_valid = !inst_vm;
                 end
               endcase
             end
diff --git a/hdl/verilog/rvv/design/rvv_backend_decode_unit_lsu.sv b/hdl/verilog/rvv/design/rvv_backend_decode_unit_lsu.sv
index de350f9..ab0615c 100644
--- a/hdl/verilog/rvv/design/rvv_backend_decode_unit_lsu.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_decode_unit_lsu.sv
@@ -2104,7 +2104,7 @@
   `ifdef ASSERT_ON
     `ifdef TB_SUPPORT
       `rvv_forbid((inst_valid==1'b1)&(inst_encoding_correct==1'b0))
-      else $warning("pc(%d) instruction will be discarded directly.\n",inst.inst_pc);
+      else $warning("pc(0x%h) instruction will be discarded directly.\n",inst.inst_pc);
     `else
       `rvv_forbid((inst_valid==1'b1)&(inst_encoding_correct==1'b0))
       else $warning("This instruction will be discarded directly.\n");
@@ -2117,6 +2117,9 @@
     uop_vstart      = 'b0;
 
     case(eew_max)
+      EEW1: begin
+        uop_vstart = 'b0;
+      end
       EEW8: begin
         uop_vstart  = csr_vstart[4 +: `UOP_INDEX_WIDTH];
       end
diff --git a/hdl/verilog/rvv/design/rvv_backend_dispatch.sv b/hdl/verilog/rvv/design/rvv_backend_dispatch.sv
index e1287f1..c56acb3 100755
--- a/hdl/verilog/rvv/design/rvv_backend_dispatch.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_dispatch.sv
@@ -431,7 +431,7 @@
 `ifdef TB_SUPPORT
             assign uop_dp2rob[i].uop_pc       = uop_uop2dp[i].uop_pc; 
 `endif
-            assign uop_dp2rob[i].w_index      = uop_uop2dp[i].vd_index;
+            assign uop_dp2rob[i].w_index      = uop_uop2dp[i].rd_index_valid ? uop_uop2dp[i].rd_index : uop_uop2dp[i].vd_index;
             assign uop_dp2rob[i].w_type       = uop_uop2dp[i].rd_index_valid ? XRF : VRF;
             assign uop_dp2rob[i].byte_type    = uop_operand_byte_type[i].vd;
             assign uop_dp2rob[i].vector_csr   = uop_uop2dp[i].vector_csr;
diff --git a/hdl/verilog/rvv/design/rvv_backend_dispatch_opr_byte_type.sv b/hdl/verilog/rvv/design/rvv_backend_dispatch_opr_byte_type.sv
index 5c9b866..4584573 100644
--- a/hdl/verilog/rvv/design/rvv_backend_dispatch_opr_byte_type.sv
+++ b/hdl/verilog/rvv/design/rvv_backend_dispatch_opr_byte_type.sv
@@ -58,10 +58,18 @@
         eew_max       = EEW16;
         eew_max_shift = 2'h1;
       end
-      else begin
+      else if ((uop_info.vs1_eew==EEW8)||(uop_info.vs2_eew==EEW8)||(uop_info.vd_eew==EEW8)) begin
         eew_max       = EEW8;
         eew_max_shift = 2'h0;
       end
+      else if ((uop_info.vs1_eew==EEW1)||(uop_info.vs2_eew==EEW1)||(uop_info.vd_eew==EEW1)) begin
+        eew_max       = EEW1;
+        eew_max_shift = 2'h0;
+      end
+      else begin
+        eew_max       = EEW_NONE;
+        eew_max_shift = 2'h0;
+      end
     end
 
     genvar i;
@@ -114,19 +122,20 @@
 
         for (i=0; i<`VLENB; i++) begin : gen_vs1_byte_type
             // ele_index = uop_index * (VLEN/vs1_eew) + BYTE_INDEX[MSB:vs1_eew]
-            assign vs1_enable[i] = (uop_info.vm || uop_info.ignore_vma) ? 1'b1 : vs1_enable_tmp[BYTE_INDEX[i] >> vs1_eew_shift];
+            assign vs1_enable[i] = uop_info.vm ? 1'b1 : vs1_enable_tmp[BYTE_INDEX[i] >> vs1_eew_shift];
             assign vs1_ele_index[i] = uop_vs1_start + (BYTE_INDEX[i] >> vs1_eew_shift);
             always_comb begin
-                if (vs1_ele_index[i] >= uop_info.vl) 
-                    operand_byte_type.vs1[i] = uop_info.ignore_vta ? BODY_ACTIVE 
-                                                                   : TAIL;
+                if (uop_info.ignore_vta&uop_info.ignore_vma)
+                    operand_byte_type.vs1[i] = BODY_ACTIVE;       
+                else if (vs1_ele_index[i] >= uop_info.vl) 
+                    operand_byte_type.vs1[i] = TAIL;
                 else if (vs1_ele_index[i] < {1'b0, uop_info.vstart}) 
                     operand_byte_type.vs1[i] = NOT_CHANGE; // prestart
                 else if (vs1_ele_index[i] > uop_vd_end) 
                     operand_byte_type.vs1[i] = BODY_INACTIVE;
                 else begin 
-                    operand_byte_type.vs1[i] = vd_enable[i] ? BODY_ACTIVE
-                                                            : BODY_INACTIVE;
+                    operand_byte_type.vs1[i] = (vd_enable[i] || uop_info.ignore_vma) ? BODY_ACTIVE
+                                                                                     : BODY_INACTIVE;
                 end
             end
         end
@@ -181,19 +190,20 @@
 
         for (i=0; i<`VLENB; i++) begin : gen_vs2_byte_type
             // ele_index = uop_index * (VLEN/vs2_eew) + BYTE_INDEX[MSB:vs2_eew]
-            assign vs2_enable[i] = (uop_info.vm || uop_info.ignore_vma) ? 1'b1 : vs2_enable_tmp[BYTE_INDEX[i] >> vs2_eew_shift];
+            assign vs2_enable[i] = uop_info.vm ? 1'b1 : vs2_enable_tmp[BYTE_INDEX[i] >> vs2_eew_shift];
             assign vs2_ele_index[i] = uop_vs2_start + (BYTE_INDEX[i] >> vs2_eew_shift);
             always_comb begin
-                if (vs2_ele_index[i] >= uop_info.vl) 
-                    operand_byte_type.vs2[i] = uop_info.ignore_vta ? BODY_ACTIVE 
-                                                                   : TAIL; 
+                if (uop_info.ignore_vta&uop_info.ignore_vma)
+                    operand_byte_type.vs2[i] = BODY_ACTIVE;       
+                else if (vs2_ele_index[i] >= uop_info.vl) 
+                    operand_byte_type.vs2[i] = TAIL; 
                 else if (vs2_ele_index[i] < {1'b0, uop_info.vstart}) 
                     operand_byte_type.vs2[i] = NOT_CHANGE; // prestart
                 else if (vs2_ele_index[i] > uop_vd_end) 
                     operand_byte_type.vs2[i] = BODY_INACTIVE;
                 else begin 
-                    operand_byte_type.vs2[i] = vd_enable[i] ? BODY_ACTIVE
-                                                            : BODY_INACTIVE;
+                    operand_byte_type.vs2[i] = (vd_enable[i] || uop_info.ignore_vma) ? BODY_ACTIVE
+                                                                                     : BODY_INACTIVE;
                 end
             end
         end
@@ -236,19 +246,20 @@
 
         for (i=0; i<`VLENB; i++) begin : gen_vd_byte_type
             // ele_index = uop_index * (VLEN/vd_eew) + BYTE_INDEX[MSB:vd_eew]
-            assign vd_enable[i] = (uop_info.vm || uop_info.ignore_vma) ? 1'b1 : vd_enable_tmp[BYTE_INDEX[i] >> vd_eew_shift];
+            assign vd_enable[i] = uop_info.vm ? 1'b1 : vd_enable_tmp[BYTE_INDEX[i] >> vd_eew_shift];
             assign vd_ele_index[i] = uop_vd_start + (BYTE_INDEX[i] >> vd_eew_shift);
             always_comb begin
-                if (vd_ele_index[i] >= uop_info.vl) 
-                    operand_byte_type.vd[i] = uop_info.ignore_vta ? BODY_ACTIVE 
-                                                                  : TAIL;       
+                if (uop_info.ignore_vta&uop_info.ignore_vma)
+                    operand_byte_type.vd[i] = BODY_ACTIVE;       
+                else if (vd_ele_index[i] >= uop_info.vl) 
+                    operand_byte_type.vd[i] = TAIL;       
                 else if (vd_ele_index[i] < {1'b0, uop_info.vstart}) 
                     operand_byte_type.vd[i] = NOT_CHANGE;     // prestart
                 else if (vd_ele_index[i] > uop_vd_end) 
                     operand_byte_type.vd[i] = BODY_INACTIVE;
                 else begin 
-                    operand_byte_type.vd[i] = vd_enable[i] ? BODY_ACTIVE
-                                                           : BODY_INACTIVE;
+                    operand_byte_type.vd[i] = (vd_enable[i] || uop_info.ignore_vma) ? BODY_ACTIVE
+                                                                                    : BODY_INACTIVE;
                 end
             end
         end