From 0edd7374d36632772734cb71aa15b31cd856e127 Mon Sep 17 00:00:00 2001 From: JaewonHur Date: Thu, 19 Dec 2019 18:29:09 +0900 Subject: [PATCH 1/3] fix multiply signed_overflow bug (only for serial multiplier) --- rtl/verilog/mor1kx_execute_alu.v | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/rtl/verilog/mor1kx_execute_alu.v b/rtl/verilog/mor1kx_execute_alu.v index 8bd771ff..e4dee9f9 100644 --- a/rtl/verilog/mor1kx_execute_alu.v +++ b/rtl/verilog/mor1kx_execute_alu.v @@ -258,6 +258,20 @@ endgenerate // Can't detect unsigned overflow in this implementation assign mul_unsigned_overflow = 0; + // One signed overflow detection for all multiplication implmentations + assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || + (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : + // Same signs, check for negative result + // (should be positive) + ((a[OPTION_OPERAND_WIDTH-1] == + b[OPTION_OPERAND_WIDTH-1]) && + mul_result[OPTION_OPERAND_WIDTH-1]) || + // Differring signs, check for positive result + // (should be negative) + ((a[OPTION_OPERAND_WIDTH-1] ^ + b[OPTION_OPERAND_WIDTH-1]) && + !mul_result[OPTION_OPERAND_WIDTH-1]); + end // if (FEATURE_MULTIPLIER=="THREESTAGE") /* verilator lint_off WIDTH */ else if (FEATURE_MULTIPLIER=="PIPELINED") begin : pipelinedmultiply @@ -285,6 +299,7 @@ endgenerate // Can't detect unsigned overflow in this implementation assign mul_unsigned_overflow = 0; + assign mul_signed_overflow = 0; end // if (FEATURE_MULTIPLIER=="PIPELINED") else if (FEATURE_MULTIPLIER=="SERIAL") begin : serialmultiply @@ -345,6 +360,8 @@ endgenerate |mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1: OPTION_OPERAND_WIDTH]; + assign mul_signed_overflow = (mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH] == 32'h0 || mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH] == 32'hffffffff) ? 0:1; + // synthesis translate_off `ifndef verilator always @(posedge mul_valid) @@ -372,6 +389,20 @@ endgenerate assign mul_unsigned_overflow = OPTION_OPERAND_WIDTH==64 ? 0 : |mul_full_result[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH]; + // One signed overflow detection for all multiplication implmentations + assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || + (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : + // Same signs, check for negative result + // (should be positive) + ((a[OPTION_OPERAND_WIDTH-1] == + b[OPTION_OPERAND_WIDTH-1]) && + mul_result[OPTION_OPERAND_WIDTH-1]) || + // Differring signs, check for positive result + // (should be negative) + ((a[OPTION_OPERAND_WIDTH-1] ^ + b[OPTION_OPERAND_WIDTH-1]) && + !mul_result[OPTION_OPERAND_WIDTH-1]); + assign mul_valid = 1; end else if (FEATURE_MULTIPLIER=="NONE") begin @@ -379,6 +410,7 @@ endgenerate assign mul_result = 0; assign mul_valid = 1'b1; assign mul_unsigned_overflow = 0; + assign mul_signed_overflow = 0; end else begin // Incorrect configuration option From 374f9065a0de52f484da2959782195f6d1c518d5 Mon Sep 17 00:00:00 2001 From: JaewonHur Date: Thu, 19 Dec 2019 18:31:06 +0900 Subject: [PATCH 2/3] fix multiply signed_overflow bug (only for serial multiplier) r1 --- rtl/verilog/mor1kx_execute_alu.v | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/rtl/verilog/mor1kx_execute_alu.v b/rtl/verilog/mor1kx_execute_alu.v index e4dee9f9..47f7192f 100644 --- a/rtl/verilog/mor1kx_execute_alu.v +++ b/rtl/verilog/mor1kx_execute_alu.v @@ -422,20 +422,6 @@ endgenerate end endgenerate - // One signed overflow detection for all multiplication implmentations - assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || - (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : - // Same signs, check for negative result - // (should be positive) - ((a[OPTION_OPERAND_WIDTH-1] == - b[OPTION_OPERAND_WIDTH-1]) && - mul_result[OPTION_OPERAND_WIDTH-1]) || - // Differring signs, check for positive result - // (should be negative) - ((a[OPTION_OPERAND_WIDTH-1] ^ - b[OPTION_OPERAND_WIDTH-1]) && - !mul_result[OPTION_OPERAND_WIDTH-1]); - assign mul_result_o = mul_result; generate From c0843f7128492b3d5fb8984d045bed081e85b7d7 Mon Sep 17 00:00:00 2001 From: JaewonHur Date: Mon, 23 Dec 2019 00:19:04 +0900 Subject: [PATCH 3/3] fix multiply signed_overflow bug, handle the case when one of the operand is 0 --- rtl/verilog/mor1kx_execute_alu.v | 47 ++++++++++++-------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/rtl/verilog/mor1kx_execute_alu.v b/rtl/verilog/mor1kx_execute_alu.v index 47f7192f..eecf66da 100644 --- a/rtl/verilog/mor1kx_execute_alu.v +++ b/rtl/verilog/mor1kx_execute_alu.v @@ -258,20 +258,6 @@ endgenerate // Can't detect unsigned overflow in this implementation assign mul_unsigned_overflow = 0; - // One signed overflow detection for all multiplication implmentations - assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || - (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : - // Same signs, check for negative result - // (should be positive) - ((a[OPTION_OPERAND_WIDTH-1] == - b[OPTION_OPERAND_WIDTH-1]) && - mul_result[OPTION_OPERAND_WIDTH-1]) || - // Differring signs, check for positive result - // (should be negative) - ((a[OPTION_OPERAND_WIDTH-1] ^ - b[OPTION_OPERAND_WIDTH-1]) && - !mul_result[OPTION_OPERAND_WIDTH-1]); - end // if (FEATURE_MULTIPLIER=="THREESTAGE") /* verilator lint_off WIDTH */ else if (FEATURE_MULTIPLIER=="PIPELINED") begin : pipelinedmultiply @@ -360,8 +346,6 @@ endgenerate |mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1: OPTION_OPERAND_WIDTH]; - assign mul_signed_overflow = (mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH] == 32'h0 || mul_prod_r[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH] == 32'hffffffff) ? 0:1; - // synthesis translate_off `ifndef verilator always @(posedge mul_valid) @@ -389,20 +373,6 @@ endgenerate assign mul_unsigned_overflow = OPTION_OPERAND_WIDTH==64 ? 0 : |mul_full_result[(OPTION_OPERAND_WIDTH*2)-1:OPTION_OPERAND_WIDTH]; - // One signed overflow detection for all multiplication implmentations - assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || - (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : - // Same signs, check for negative result - // (should be positive) - ((a[OPTION_OPERAND_WIDTH-1] == - b[OPTION_OPERAND_WIDTH-1]) && - mul_result[OPTION_OPERAND_WIDTH-1]) || - // Differring signs, check for positive result - // (should be negative) - ((a[OPTION_OPERAND_WIDTH-1] ^ - b[OPTION_OPERAND_WIDTH-1]) && - !mul_result[OPTION_OPERAND_WIDTH-1]); - assign mul_valid = 1; end else if (FEATURE_MULTIPLIER=="NONE") begin @@ -422,6 +392,23 @@ endgenerate end endgenerate + // One signed overflow detection for all multiplication implmentations + assign mul_signed_overflow = (FEATURE_MULTIPLIER=="NONE") || + (FEATURE_MULTIPLIER=="PIPELINED") ? 1'b0 : + // When either a or b is 0, result should not + // be negative + ((a == 0 || b == 0) && mul_result[OPTION_OPERAND_WIDTH-1]) || + // Same signs, check for negative result + // (should be positive) + ((a[OPTION_OPERAND_WIDTH-1] == + b[OPTION_OPERAND_WIDTH-1]) && + mul_result[OPTION_OPERAND_WIDTH-1]) || + // Differring signs, check for positive result + // (should be negative) + ((a[OPTION_OPERAND_WIDTH-1] ^ + b[OPTION_OPERAND_WIDTH-1]) && + !mul_result[OPTION_OPERAND_WIDTH-1]); + assign mul_result_o = mul_result; generate