8 位 ALU 第 46 行:无法简化运算符 DIV

8bit ALU line 46: Can not simplify operator DIV

大家好,我只是想问一下如何调试第 46 行中的“无法简化运算符 DIV”。在 Verilog 模块 (Xilinx) 中。预先感谢您的提示和帮助:))

这是我的 8 位 ALU 的代码

module alu_8fctn (a, b, opcode, rslt, rslt_mul);
input [3:0] a, b;
input [2:0] opcode;
output [3:0] rslt;
output [7:0] rslt_mul;
wire [3:0] a, b; //inputs are wire
wire [2:0] opcode;
reg [3:0] rslt; //outputs are reg
reg [7:0] rslt_mul;
//define operation codes
parameter add_op = 3'b000,
            sub_op = 3'b001,
            mul_op = 3'b010,
            div_op = 3'b011,
            and_op = 3'b100,
            or_op = 3'b101,
            xor_op = 3'b110,
            xnor_op = 3'b111;
//perform the operations
always @(a or b or opcode)
begin
case (opcode)
            add_op : rslt = a + b;
            sub_op : rslt = a - b;
            mul_op : rslt_mul = a * b;
            div_op : rslt = a / b;
            and_op : rslt = a & b;
            or_op : rslt = a | b;
            xor_op : rslt = a ^ b;
            xnor_op: rslt = a ^~ b;
            default: rslt = 8'b0000_0000;
endcase
end
endmodule

您的 Xilinx 在 a / b 方面似乎有问题。合成器可能很难用可变除数进行优化;特别是如果它们可以为零。

Xilinx 应该有一些用于划分的预定义模块(如果没有,您可以随时制作自己的模块)

wire [3:0] rslt_div;
<XilinxPrividedDividerModuleName> div ( rslt_div, a, b);
always @*
  ...
  div_op : rslt = a / b;
  ...

其他问题: rsltrslt_mul 是推断锁存器,因为它们并非在所有条件下都被赋值。在 mul_op 中,rslt_mul 仅在 mul_op 中赋值,这是唯一未赋值的条件 rslt

参考What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?

简单的解决方案是在 case 语句之前给 rsltrslt_mul 一个 initial/default 值。

always @*
begin
  rslt = 4'h0;
  rslt_mul = 8'h00;
  case (opcode)
    // ... you other code
  endcase
end

另请注意,always @(a or b or opcode) 是 Verilog-1995 编写敏感度列表的方式。自 Verilog-2001 以来,首选方式是 always @*(或同义词 always @(*))。 SystemVerilog 在 always_comb 中更进了一步,如果推断出锁存器,一个好的工具应该标记错误。

您可能还想考虑 ANSI 样式模块 headers(自 Verilog-2001 起也可用),它比 Verilog-1995 模块 header 样式更简洁且更不容易出现错别字。

module alu_8fctn (
  input [3:0] a, b,
  input [2:0] opcode,
  output reg [3:0] rslt,
  output reg [7:0] rslt_mul );

  //define operation codes
  parameter add_op = 3'b000,
  ...