首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >范围检查功能

范围检查功能
EN

Code Review用户
提问于 2020-12-23 16:09:40
回答 1查看 259关注 0票数 4

这是一个问题: Verilog代码和用于检测给定数字输入范围的testbench。如果输入号码在12到49之间,那么输出是'1‘,否则'0’。范围应该容易编程。

我正在使用EDA操场,cadence xcelium 20.09模拟器和EP波也是存在的。这是否适合这个问题的代码?而且.

Verilog正常读取整数吗?例如,如果我输入一个二进制数,那么我应该提到位数,然后是像4b'0011这样的二进制位。我在if循环中直接输入了12,所以它会自动检测它是一个整数吗?

下面是链接:https://www.edaplayground.com/x/7sQM

设计

代码语言:javascript
复制
module range_detect(y,x);
  input [9:0]x;
  output reg y;
  always @(x)
    begin
      if(x>=12 && x<=49)
        begin
        y=1;
          $display("Input: %d lies between 12 and 49",x);
        end
      else
        begin
        y=0;
          $display("Input: %d does not lie between 12 and 49",x);
        end
    end
endmodule

Testbench

代码语言:javascript
复制
module testbench;
  reg [9:0]in;
  wire out;
  range_detect rd(out,in);
  initial
    begin
      $dumpfile("dump.vcd");
      $dumpvars(1,testbench);
      in=12;
      #2 in=11;
      #2 in=51;
      #2 in=34;
      #2 in=61;
      #2 in=19;
      #2 in=18;
      #2 $stop;
    end
endmodule
EN

回答 1

Code Review用户

回答已采纳

发布于 2020-12-23 18:24:05

Verilog对整数的解释是灵活的。它将54'b0101解释为相同的数值。是的,它将12解释为if语句中的整数。

您的代码在edaplayground上进行了正确的模拟,并且在将设计代码从测试平台中分离出来方面做得很好。以下是一些具体的建议。

如果您希望您的设计代码是可综合的,最好将$display语句移到testbench中。这也要求您在testbench中复制逻辑,但这在创建testbench检查器时是必要的。

为了调试目的,显示仿真时间也是有帮助的:$time

此外,为了调试,最好在整个层次结构中转储信号。目前,您只需转储testbench信号。如果不带参数地调用$dumpvars,也会将设计变量转储到VCD文件中。

驱动特定值到输入的替代方法(12、11、51等)是在repeat循环中驱动随机值。这使得您可以轻松地更改您所驱动的值的数量和范围。下面的代码{$random} % 60返回一个0-59范围内的值。

您的rd实例按位置使用连接,这对于少量端口(2)来说很好,就像您已经使用的那样。但是,最好使用按名称连接的方法来提高代码的可读性,并帮助防止连接错误。例如:.x (in)

在您的设计中,最好使用ANSI风格的端口声明来减少重复端口名。

最好使用隐式灵敏度列表always @*,因为当适当的信号发生变化时,它会自动触发块。这避免了一个常见的Verilog问题,人们在更改代码体时忘记从列表中添加或删除信号。

要使范围可编程,一个常见的方法是使用parameters,它们可以在设计和测试平台上声明。例如,您可以使用MINMAX而不是12和49 (所有的大写都是惯例)。添加描述参数合法值的注释也很有帮助。

下面是编码所有内容的另一种方法:

代码语言:javascript
复制
module range_detect (
    input [9:0] x,
    output reg y
);

parameter MIN = 12;
parameter MAX = 49;

always @* begin
    if ((x>=MIN) && (x<=MAX)) begin
        y = 1;
    end else begin
        y = 0;
    end
end
endmodule


module testbench;
    reg [9:0] in;
    wire out;

    // MIN must be smaller than MAX.
    // MAX must be smaller than 1024.
    parameter MIN = 12;
    parameter MAX = 49;

    range_detect #(
        .MIN (MIN),
        .MAX (MAX)
    )
    rd (
        .x  (in),
        .y  (out)
    );

    always @* begin
        if ((in>=MIN) && (in<=MAX)) begin
            $display($time, "  Input: %0d lies between %0d and %0d", in, MIN, MAX);
        end else begin
            $display($time, "  Input: %0d does not lie between %0d and %0d", in, MIN, MAX);
        end
    end

    initial begin
        $dumpfile("dump.vcd");
        $dumpvars;
        repeat (10) #2 in = {$random} % 60;
        #2;
    end
endmodule

您可以简单地更改testbench中的parameter值,它们将传播到设计中。

我使用4空格缩进,因为我认为更容易看到代码的不同层次的逻辑。

我在术语(如(x>=MIN) )周围添加了括号,这样我就不必考虑哪些操作符具有更高的优先级,这也有助于我直观地解析代码。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/253829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档