Сравнение является постоянным из-за беззнаковой арифметической ошибки в verilog с verilator

Я использую следующую логику для реализации 2-битного насыщающего счетчика в бимодальном предикторе в Verilog, и я также использую verilator следующим образом:

• For each branch, maintain a 2-bit saturating counter:
-if the branch is taken: counter = min(3,counter+1)
-if the branch is not taken: counter = max(0,counter-1)
• If (counter >= 2), predict taken, else predict not taken

module Bimodal(
input clk,
input reset,
input taken, //from ALU unit in execute stage
input branch, //from control unit in decode stage
input [31:0] instrAddr, // current address taken from fetch/decode stage
output reg predicted_taken_or_not);

reg [1:0] saturating_counter [0:1023];


integer i;
parameter max_val = 3 ;
parameter min_val = 0 ;

assign predicted_taken_or_not = saturating_counter[instrAddr[11:2]]>= 2'd2 && branch? 1'd1 : 1'd0;


// write ports to update the 2-bit saturating counter
always @(posedge clk) begin

if(reset) begin
 for(int i=0; i<1024; i++) begin
    saturating_counter[i] = 2'd1;
 end
end

else if (taken) begin
if(max_val>saturating_counter[instrAddr[11:2]]+1)
    saturating_counter[instrAddr[11:2]]<=saturating_counter[instrAddr[11:2]]+1;
else
    saturating_counter[instrAddr[11:2]]<=max_val;
end

else if (~taken) begin
if(min_val>saturating_counter[instrAddr[11:2]]-1)
   saturating_counter[instrAddr[11:2]]<=min_val;
else
    saturating_counter[instrAddr[11:2]]<=saturating_counter[instrAddr[11:2]]-1;
end

end

endmodule

Но я получаю следующую ошибку

%Warning-UNSIGNED: Bimodal.v:36: Comparison is constant due to unsigned arithmetic
%Warning-UNSIGNED: Use "/* verilator lint_off UNSIGNED */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)
%Error: Command Failed /home/verilator-3.884/verilator_bin -O4 --cc MIPS.v --exe sim_main.cpp

Есть ли что-то, что я делаю не так?

2 ответа

Решение

Помните, regs в verilog являются значениями без знака, а все, что вы назначаете для reg, является положительным значением без знака. И все неопределяемые значения, которые вы сравниваете с нулем, будут больше или равны нулю. Если вы хотите подписанное сравнение, вы можете использовать $signed() директивы.

if(min_val>$signed(saturating_counter[instrAddr[11:2]]-1))

Ваш компилятор в настоящее время настроен на сбой при определенных предупреждениях. Корень проблемы может заключаться в том, что ваш параметр min_val в настоящее время равен 0. Одновременно вы только проверяете, является ли min_val (который всегда равен 0, если вы не переопределяете параметр где-либо) больше, чем 2-битное значение в RHS (справа) стороны), которая не имеет знака. Это означает, что оно никогда не может быть отрицательным.

Is 0 > 0 ?  No
Is 0 > 1 ?  No
is 0 > 2 ?  No
Is 0 > 3 ?  No

Ответ всегда Нет, поэтому результат постоянен в соответствии с предупреждением.

Вы надеялись проверить

Is 0 > 0 ? No
Is 0 > 1 ? No
Is 0 > -2 ? Yes
Is 0 > -1 ? Yes

Если это необходимо, вам необходимо изменить тип логики или изменить сравнение.

Другие вопросы по тегам