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
语句代表一个锁存器,因为您 而不是 在语句的每个分支中分配它的所有输出。您至少有两个其他信号,carry
和 alu_out
,它们构成闩锁。它是您需要的闩锁行为吗?
如果你需要闩锁,那么
如果您编写一个状态设备,例如 'latch',您应该对块的输出使用非阻塞赋值 <=
。
因此,除了分配给 'temp' 和 'temp2'.
之外,您必须在所有地方将阻塞分配替换为非阻塞分配
如果您需要组合逻辑,我建议您预先使用默认值初始化所有内容。
always @* begin
alu_overflow = 1'b0;
alu_out = 0;
cary = 0;
if (alu_enable)
...
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
语句代表一个锁存器,因为您 而不是 在语句的每个分支中分配它的所有输出。您至少有两个其他信号,carry
和 alu_out
,它们构成闩锁。它是您需要的闩锁行为吗?
如果你需要闩锁,那么
如果您编写一个状态设备,例如 'latch',您应该对块的输出使用非阻塞赋值
<=
。因此,除了分配给 'temp' 和 'temp2'.
之外,您必须在所有地方将阻塞分配替换为非阻塞分配
如果您需要组合逻辑,我建议您预先使用默认值初始化所有内容。
always @* begin
alu_overflow = 1'b0;
alu_out = 0;
cary = 0;
if (alu_enable)
...