Verilog 上的 Superlint LAT_NR_BLAS/MXCB 错误

Superlint on Verilog LAT_NR_BLAS/MXCB error

Verilog 上的 Superlint LAT_NR_BLAS/MXCB 错误 Superlint_Image

我用 Superlint 检查我的 Verilog 代码风格。 虽然我得到了预期的正确模拟结果,但它在 Superlint 中弹出了 2 个问题。我读过 superlint_reference.pdf 并且不知道如何正确修复它。

1.Problem_1_LAT_NR_MXCB 根据 superlint_reference.pdf,这是否意味着我必须将 ALL reg 分配给 所有分支机构。这似乎不是解决方案。

2.Problem_2_LAT_NR_BLAS - 该设计有一个或多个使用阻塞编码的锁存器 任务。 我将所有 =in always block 替换为 <= ,即将阻塞变为非阻塞,但它不起作用。

timescale 1ns/10ps

// ---------------------- define ---------------------- //

`define DataSize  32
`define ALUopSize  5
//define ALUop
`define ADDop     5'b00000
`define SUBop     5'b00001
`define ANDop     5'b00010
`define ORop      5'b00011
`define XORop     5'b00100
`define NORop     5'b00101
`define SRLop     5'b00110
`define ROTRop    5'b00111
`define NOTop     5'b01000
`define NANDop    5'b01001
`define MAXop     5'b01010
`define MINop     5'b01011
`define ABSop     5'b01100
`define SLTSop    5'b01101
`define SLLop     5'b01110
`define ROTLop    5'b01111
`define ADDUop    5'b10000
`define SRLUop    5'b10001

module ALU (alu_enable, alu_op, src1, src2, alu_out, alu_overflow);

// ---------------------- input  ---------------------- //
input                     alu_enable;
input   [`ALUopSize-1:0]  alu_op;
input   [`DataSize-1:0]   src1;
input   [`DataSize-1:0]   src2;

// ---------------------- output ---------------------- //
output   [`DataSize-1:0]  alu_out;
output                    alu_overflow;

// ----------------------  reg   ---------------------- //
reg    [`DataSize-1:0]    alu_out;
reg                       alu_overflow;
reg    [63:0]             temp;
reg    [63:0]             temp2;
reg                       carry;

always@(*)begin
  alu_overflow = 1'b0;
  if(alu_enable)begin
/************************************/
    case(alu_op)
        `ADDop  :  begin
            alu_out = src1 + src2;
            if((src1[31]==1'b0 && src2[31]==1'b0 && alu_out[31]==1'b1)||
                 (src1[31]==1'b1 && src2[31]==1'b1 && alu_out[31]==1'b0))
                alu_overflow = 1'b1;
            else
                alu_overflow = 1'b0;
            end
        `SUBop  :  begin
            alu_out = src1 - src2;
            if((src1[31]==1'b0 && src2[31]==1'b1 && alu_out[31]==1'b1)||
                 (src1[31]==1'b1 && src2[31]==1'b0 && alu_out[31]==1'b0))
                alu_overflow = 1'b1;
            else
                alu_overflow = 1'b0;
            end
        `ANDop  :  alu_out = src1 & src2;
        `ORop   :  alu_out = src1 | src2;
        `XORop  :  alu_out = src1 ^ src2;
        `NORop  :  alu_out = ~(src1 | src2);
        `SRLop  :  alu_out = $signed(src1) >>> $signed(src2);
        `ROTRop :  begin
            temp = {src1,src1};
            temp = temp >> (src2%32);
            alu_out = temp[31:0];
            end
        `NOTop  : alu_out = ~src1;
        `NANDop : alu_out = ~(src1&src2);
        `MAXop  : begin
            if($signed(src1) > $signed(src2))
                alu_out = src1;
            else
                alu_out = src2;
            end 
        `MINop  : begin
            if($signed(src1) < $signed(src2))
                alu_out = src1;
            else
                alu_out = src2;
            end 
        `ABSop  : begin
            if(src1[31] == 1'b1)
                    alu_out = (~src1) + 32'h01;
                else
                alu_out = src1;
            end
        `SLTSop  : begin
            if($signed(src1) < $signed(src2))
                alu_out = 32'h01;
            else
                alu_out = 32'h00;
            end
        `SLLop  :  alu_out = $signed(src1) <<< $signed(src2);
        `ROTLop :  begin
            temp2 = {src1,src1};
            temp2 = temp2 << (src2%32);
            alu_out = temp2[63:32];
            end
        `ADDUop : begin
            {carry,alu_out} = src1 + src2;
            if(carry)
                alu_overflow = 1'b1;
            else
                alu_overflow = 1'b0;
            end
        `SRLUop : alu_out = src1 >> src2;
    default : alu_out = 32'b0;
      endcase
/************************************/
    end
  else
    alu_out = 32'b0;
  end
endmodule

您的 case 语句代表一个锁存器,因为您 而不是 在语句的每个分支中分配它的所有输出。您至少有两个其他信号,carryalu_out,它们构成闩锁。它是您需要的闩锁行为吗?

如果你需要闩锁,那么

  1. 如果您编写一个状态设备,例如 'latch',您应该对块的输出使用非阻塞赋值 <=

  2. 因此,除了分配给 'temp' 和 'temp2'.

    之外,您必须在所有地方将阻塞分配替换为非阻塞分配

如果您需要组合逻辑,我建议您预先使用默认值初始化所有内容。

always @* begin
   alu_overflow = 1'b0;
   alu_out = 0;
   cary = 0;
   if (alu_enable)
      ...