SystemVerilog 条件语句语法错误

SystemVerilog conditional statement syntax error

我正在尝试练习 SystemVerilog 并尝试基于此图实现 ALU(算术逻辑单元):

我在 EDA playground 上在线模拟 SystemVerilog 代码(https://www.edaplayground.com/x/mYi):

ALU:

module alu(
  input  [31:0] a,
  input  [31:0] b,
  input  [2:0] f,
  output [31:0] result,

);

  /*000*/
  if (f[0]==0 && f[1]==0 && f[2]===0)
    begin
    assign result = a & b;
    end
  /*001*/
  else (f[0]==0 && f[1]==0 && f[2]==1)
    begin
    assign result = a | b;
    end
  /*010*/
  else (f[0]==0 && f[1]==1 && f[2]==0)
    begin
    assign result = a + b;
    end
  /*011 not used*/ 
  else (f[0]==0 && f[1]==1 && f[2]==1)
    begin
    assign result = -1;
    end
  /*100*/
  else (f[0]==1 && f[1]==0 && f[2]==0)
    begin
    assign result = a & ~b;
    end 
  /*101*/  
  else (f[0]==1 && f[1]==0 && f[2]==1)  
    begin
    assign result = a | ~b;
    end
  /*110*/
  else (f[0]==1 && f[1]==1 && f[2]==0) 
    begin
    assign result = a - b;
    end
  /*111 slt*/
  else
    begin
    assign result = -1; 
    end

endmodule

部分测试台:

module testharness();
  reg  [31:0] a;
  reg  [31:0] b;
  reg  [2:0] f;
  reg  [31:0] result;


//DUT (Device Under Test)
alu alu_0 (
  .a   (a),
  .b   (b),
  .f    (f),
  .result (result)
);

// Test program
initial begin
     /*000*/
  f[0]=0; 
  f[1]=1;
  f[2]=0;
  /*0+0*/
  a[0]=0;
  b[0]=0;

  $display( "a (%d) + b (%d) = %d%d%d%d", a[0], b[0], result[0], result[1]);
   /*000*/
  f[0]=0;
  f[1]=1;
  f[2]=0;
  /*0+1*/
  a[0]=0;
  b[0]=1;

 $display( "a (%d) + b (%d) = %d%d", a[0], b[0], result[0], result[1]);

     /*000*/
  f[0]=0;
  f[1]=1;
  f[2]=0;
  /*1+1*/
  a[0]=1; 
  b[0]=1; 

  $display( "a (%d) + b (%d) = %d%d", a[0], b[0], result[0], result[1]);

  $finish;
end

endmodule

我一直收到这个错误:

错误 VCP2000 "Syntax error. Unexpected token: (. Expected tokens: '???' , ';' , 'always' , 'and' , 'assign' ... ." "design.sv" 15 9

这是行:

else (f[0]==0 && f[1]==0 && f[2]==1)
    begin
    assign result = a | b;
    end

我没有看到任何明显的东西。

谢谢

我认为您使用 always 语句和连续赋值混淆了组合逻辑。正如其他用户之前提到的,我也认为如果您能看一下一些基本的 Verilog 教程会很好。 Asic-world.com 有一些很好的入门教程,例如 Deepak Kumar Tala 的 Verilog in One Day

但是,让我试着向您解释一下。您在示例中使用的是 连续赋值语句 。您可以在 IEEE Std 1800-2012 的第 10.3.2 节中找到更多相关信息。手册说:

Assignments on nets or variables shall be continuous and automatic. In other words, whenever an operand in the right-hand expression changes value, the whole right-hand side shall be evaluated.

这里不是这种情况,因为所有赋值语句的右侧操作数都是相同的。它不是自动的,因为它取决于您的 if 语句。看看下面这个非常简单的例子。如果你总是希望 result 成为 a & b,你可以使用下面的代码。但是,您可以想象,对于更复杂的逻辑,这会变得相当冗长。

module alu(
  input  [31:0] a,
  input  [31:0] b,
  output [31:0] result,

);

    assign result = (a & b);

endmodule

这就是 SystemVerilog 提供程序块的原因,例如 alwaysalways_combalways_latchalways_ff(IEEE 标准 1800-2012 中的第 9 节)。对于您的示例,您应该使用 always_comb。引用手册第9.2.2.2节:

SystemVerilog provides a special always_comb procedure for modeling combinational logic behavior.

有了这个,我们可以将您的代码重写为

module alu(
  input  [31:0] a,
  input  [31:0] b,
  input  [2:0] f,
  output [31:0] result,

);

  reg [31:0] result_;   

  always_comb 
  begin
    /*000*/
    if (f[0]==0 && f[1]==0 && f[2]===0)
    begin
      result_ = a & b;
    end
    /*001*/
    else if (f[0]==0 && f[1]==0 && f[2]==1)
    begin
      result_ = a | b;
    end
    /*010*/
    else if (f[0]==0 && f[1]==1 && f[2]==0)
    begin
      result_ = a + b;
    end
    /*011 not used*/ 
    else if(f[0]==0 && f[1]==1 && f[2]==1)
    begin
      result_ = -1;
    end
    /*100*/
    else if (f[0]==1 && f[1]==0 && f[2]==0)
    begin
      assign result = a & ~b;
    end 
    /*101*/  
    else if (f[0]==1 && f[1]==0 && f[2]==1)  
    begin
      result_ = a | ~b;
    end
    /*110*/
    else if (f[0]==1 && f[1]==1 && f[2]==0) 
    begin
      result_ = a - b;
    end
    /*111 slt*/
    else
    begin
      result_ = -1; 
    end
  end // End of always_comb

  assign result = result_;

endmodule

请注意,您可以连续分配 wire,但您需要将变量声明为 reg 才能在 always 块中使用它。这就是我使用 result_ 而不是直接分配 result 的原因。在代码块的最后,我不断地将result_赋值给result。 Asic-world.com 也有关于 difference between regs and wires.

的教程

如果你不想考虑是使用reg还是wire,你也可以使用新关键字logic

编辑:正如 Oldfart 所指出的,我最初忘记修复您的 if...else 语句。在您的代码中,您总是使用 else 而不是 else if。这可能也是编译器向您抛出错误的直接原因。