SystemVerilog条件语句语法错误

时间:2019-02-17 01:25:30

标签: verilog system-verilog

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

enter image description here

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

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“语法错误。意外的令牌:(。预期的令牌:'???',';','always','and','assign'...。”“ design.sv” 15 9

这是行:

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

我看不到任何明显的东西。

谢谢

1 个答案:

答案 0 :(得分:0)

我认为您正在使用always陈述和连续分配来混淆组合逻辑。正如其他用户之前提到的,我也认为如果您看一下一些基本的Verilog教程会很好。 Asic-world.com上有一些很棒的教程,例如Deepak Kumar Tala的Verilog in One Day

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

  

网络或变量的分配应是连续且自动的。在   换句话说,只要右侧表达式中的操作数发生变化   值,则应评估整个右侧。

这里不是这种情况,因为所有赋值语句的右侧操作数都相同。它不是自动的,因为它取决于您的if语句。看看下面这个非常简单的例子。如果您始终希望resulta & 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提供了一个特殊的always_comb过程来进行建模   组合逻辑行为。

这样,我们可以将您的代码重写为

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。这可能也是导致编译器向您抛出错误的直接原因。