【问题标题】:Usage of 'begin/end' in design modules在设计模块中使用“开始/结束”
【发布时间】:2022-01-17 12:50:01
【问题描述】:

我尝试使用 icarus verilog 在 EDA Playground 上制作 BCD 计数器进行模拟。在我的第一次尝试中,我在没有使用 beginend 关键字的情况下编写了 always 块:

module bcdcounter(out, clock, reset);
  output [3:0] out;
  input clock, reset;
  
  reg [3:0] outstate= 4'd0;
  reg [1:0] state= 2'd0;
  
  always@(posedge reset)
    case(state)
      2'd0: state <=2'd1;
      2'd1: state <=2'd2;
      2'd2: state <=2'd0;
    endcase
  
  always@(posedge clock or state)
    if(!state) 
      outstate <= 4'd0;
  if(state == 2'd1) 
    if(outstate != 4'd9)
      outstate <= outstate +4'd1;
  else 
    outstate <= 4'd0;
  if(state == 2'd2) 
    outstate <= outstate;
  
  assign out = outstate;
    
endmodule

我检查时生成了以下输出:

design.sv:21: syntax error
design.sv:21: error: Invalid module instantiation
design.sv:23: syntax error
design.sv:23: error: Invalid module instantiation
design.sv:25: syntax error
design.sv:25: error: Invalid module instantiation
Exit code expected: 0, received: 1

但是,一旦我添加了一些 beginend 关键字,它确实可以正常工作:

module bcdcounter(out, clock, reset);
  output [3:0] out;
  input clock, reset;
  
  reg [3:0] outstate= 4'd0;
  reg [1:0] state= 2'd0;
  
  always@(posedge reset)
    case(state)
      2'd0: state <=2'd1;
      2'd1: state <=2'd2;
      2'd2: state <=2'd0;
    endcase
  
  always@(posedge clock or state)
    begin
      if(!state)
        outstate <=4'd0;
      if(state==2'd1)
        begin
          if(outstate!=4'd9)
            outstate<= outstate+4'd1;
          else outstate<= 4'd0;
        end
      if(state==2'd2)
        outstate<=outstate;
    end
  
  assign out = outstate;
    
endmodule

我们什么时候需要在设计模块中使用beginend 关键字?任何帮助将不胜感激。

【问题讨论】:

    标签: verilog system-verilog


    【解决方案1】:

    当您在特定块中有多个语句时,您需要begin end。示例

    //Single line statement hence no begin end needed
    always@(posedge clk)
      a <= b &c;
    
     //Multiple lines hence begin end is needed
    always@(posedge clk)
    begin
     if(reset)
      a <= 'd0;
     else 
      a <= b & c;
    end
    

    同样适用于if elsecase 语句等。

    【讨论】:

    • 所以基本上你想说如果我的块中有多个语句,建议将这些语句括在开始和结束之间。
    • 感谢您的回答。如果您或其他任何人知道更多用途,我将不胜感激。
    • 这不是一个很好的例子。此代码中不需要开始/结束。您需要显示多个语句。
    【解决方案2】:
    always 块中有多个 语句时,

    begin/end 关键字是必需的。

    在您的第一个 always 块中,您不需要开始/结束,因为 case 语句被视为单个语句。

    但是,在您的第二个 always 块中,您有 3 个顶级 if 语句,这意味着您需要在 begin/end 中将它们组合在一起。这是带有不同空格的代码,以清楚地显示单独的语句:

    always@(posedge clock or state) begin
    
        // Statement 1
        if(!state) outstate <= 4'd0;
    
        // Statement 2
        if(state == 2'd1) 
            if(outstate != 4'd9)
                outstate <= outstate +4'd1;
            else 
                outstate <= 4'd0;
    
        // Statement 3
        if(state == 2'd2) outstate <= outstate;
    
    end  
    

    由于这段代码编译时没有语法错误,它演示了几件事:

    1. 显示的开始/结束关键字是强制性的
    2. 不需要其他开始/结束关键字

    但是,其他开始/结束关键字是可选的。您可以决定在每个if 语句中使用它们。这是另一种编写代码的方式:

    always@(posedge clock or state) begin
    
        if (!state) begin 
            outstate <= 4'd0;
        end
    
        if (state == 2'd1) begin
            if (outstate != 4'd9) begin
                outstate <= outstate +4'd1;
            end else begin
                outstate <= 4'd0;
            end
        end
    
        if (state == 2'd2) begin
            outstate <= outstate;
        end
    
    end  
    

    同样的规则适用于initialfinal 程序块,就像它们适用于always 块一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2010-11-13
      • 2019-09-08
      相关资源
      最近更新 更多