Verilog 行为、RTL和门级之间的差异

Verilog 行为、RTL和门级之间的差异,verilog,Verilog,我试图完全理解Verilog的抽象级别之间的差异,我得到了每个级别的描述,但我仍然无法在游戏中得到它 对于这种情况,我将粘贴一些Verilog代码以及我对它们的看法: 以下代码处于行为级别 always @ (a or b or sel) begin y = 0; if (sel == 0) begin y = a; end else begin y = b; end end 这(只是一个例子)是门级的 module test(clk,

我试图完全理解Verilog的抽象级别之间的差异,我得到了每个级别的描述,但我仍然无法在游戏中得到它

对于这种情况,我将粘贴一些Verilog代码以及我对它们的看法:

  • 以下代码处于行为级别

    always  @ (a or b or sel)
      begin
        y = 0;
        if (sel == 0) begin
          y = a;
        end else begin
        y = b;
      end
    end
    
  • 这(只是一个例子)是门级的

    module test(clk,  ready, next, Q);
      input clk, enable, next;
      output Q;
    
      \**SEQGEN** reg_1 (.clear(1'b0), .next_state(next), .clocked_on(clk), .Q(Q), .synch_enable(enable) );
    
    endmodule
    
  • 我不知道这段代码是RTL还是Gate级别(我希望always关键字使这段代码成为RTL而不是Gate级别)

  • 我已经知道,
    initial begin
    end
    不可合成,只用于测试。现在我有两个问题

  • 第三个(和第二个)代码是RTL还是Gate Leve?什么是好的RTL代码示例?我找到了这个,但那真的是RTL吗?对我来说,这看起来像是行为层面

  • 什么是Verilog网络列表?它是与门级别相同还是有上下文基础定义

  • 我很困惑,因为在一些网站上,我不知道他们是在说“这是一个使用逻辑门的Verilog代码”还是“这是门级的Verilog代码”

    如果有人想解释更多关于这个话题的细节,我会非常高兴:)

  • 行为层面
  • RTL级别(不必是门级别,但必须是基元级别)
  • 一个混合工作模块/测试台,全部封装在一个模块中。这不是使用Verilog进行设计的最佳方法,但可以作为一个教学示例。事实上,此示例实际上是两个模块:
  • 可以认为是行为的测试台,即使它使用RTL编码将要测试的模块实例化为测试台驱动的REG和电线:

    module testbench_dff;
      wire Q,Q_BAR;
      reg D,CLK;
    
      // Instantiate the unit under test
      dff_from_nand uut (.CLK(CLK), .D(D), .Q(Q), .Q_BAR(Q_BAR) );
    
      // Testbench
      initial begin
        $monitor("CLK = %b D = %b Q = %b Q_BAR = %b",CLK, D, Q, Q_BAR);
        CLK = 0;
        D = 0;
        #3  D = 1;
        #3  D = 0;
        #3  $finish;
      end   
    
      always  #2  CLK = ~CLK;
    
    endmodule
    
    正在测试的被测单元(UUT),它是这样一个模块(显然是一个RTL级-门级-模块):


    我的理解是,RTL级模块是一个明确给出逻辑方程的模块。行为模块有过程(在Verilog中总是使用
    块,尽管逻辑方程可以在这些块中使用)任何非平凡的Verilog设计都将同时具备这两种功能。

    RTL:寄存器传输级,一种抽象硬件功能,使用可合成的
    块和
    赋值
    语句编写(可转换为门级).Pure RTL不实例化子模块。RTL可以包含用于引导合成器的子模块。Structural RTL(通常仍称为RTL)是包含其他RTL模块的模块。例如:FSM(有限状态机)

    RTL和行为的关键区别在于合成的能力。如果你看到
    延迟、
    等待
    语句、
    while
    循环、
    强制
    /
    释放
    语句或分层引用,这就是行为。从技术上讲,存在一些罕见的可原谅的异常,但如果这是个问题

    门级(也称结构):仅由门和模块描述的逻辑。无
    始终
    块或
    赋值
    语句。这是硬件中真实门的代表


    VerilogNetlist是设计中使用的Verilog模块的集合。它可以是一个或多个文件。它可以是RTL、行为和结构的混合。通常它主要是结构的,尤其是大型设计。

    对不起(英语问题),您的dff是RTL或门级的(我也有英语问题;)这个特定的实现将是门级实现,可以用作netlistsoo,从我展示的示例来看,第二个代码将是门级的?这是一个模糊的领域,没有完整的设计背景。只有原样:我称之为结构性;通常不是只有一个模块实例。由于模块名称
    test
    is,这意味着这是一个更符合行为定义的测试线束。
    module testbench_dff;
      wire Q,Q_BAR;
      reg D,CLK;
    
      // Instantiate the unit under test
      dff_from_nand uut (.CLK(CLK), .D(D), .Q(Q), .Q_BAR(Q_BAR) );
    
      // Testbench
      initial begin
        $monitor("CLK = %b D = %b Q = %b Q_BAR = %b",CLK, D, Q, Q_BAR);
        CLK = 0;
        D = 0;
        #3  D = 1;
        #3  D = 0;
        #3  $finish;
      end   
    
      always  #2  CLK = ~CLK;
    
    endmodule
    
    module dff_from_nand (
      input wire CLK,
      input wire D,
      output wire Q,
      output wire Q_BAR
      );
    
      wire X,Y;
      nand U1 (X,D,CLK) ;
      nand U2 (Y,X,CLK) ;
      nand U3 (Q,Q_BAR,X);
      nand U4 (Q_BAR,Q,Y);
    endmodule
    
    always @* begin
      next_state = state;
      if (count>0) next_count = count - 1;
      case (state)
      IDLE :
        if(do_start) begin
          next_state = START;
          next_count = 2;
        end
      START :
        if (do_wait) begin
          next_count = count;
        end
        else if (count==0) begin
          next_state = RUN;
          next_count = count_from_input;
        end
      RUN :
        if (do_stop) begin
          next_state = IDLE;
        end
        if (do_wait) begin
          next_count = count;
        end
        else if (count==0) begin
          next_state = IDLE;
        end
      endcase
    end
    always @(posedge clk, negedge rst_n) begin
      if (!rst_n) begin
        count <= 0;
        state <= IDLE;
      end
      else begin
        count <= next_count;
        state <= next_state;
      end
    end
    
    always begin
      if (!clk_en && clk==1'b1) begin
        wait (clk_en);
      end
      #5 clk = ~clk;
    end