天天看點

Verilog初級教程(7)Verilog子產品例化以及懸空端口的處理

博文目錄

    • 寫在前面
    • 正文
      • 按順序排列的端口連接配接
      • 按名稱排列的端口連接配接
      • 未連接配接/懸空端口處理
      • 關于子產品端口的說明
    • 參考資料
    • 交個朋友

此系列相關博文:

Verilog初級教程(6)Verilog子產品與端口

Verilog初級教程(5)Verilog中的多元數組和存儲器

Verilog初級教程(4)Verilog中的标量與向量

Verilog初級教程(3)Verilog 資料類型

Verilog初級教程(2)Verilog HDL的初級文法

Verilog初級教程(1)認識 Verilog HDL

晶片設計抽象層及其設計風格

Verilog以及VHDL所倡導的的代碼準則

FPGA/ASIC初學者應該學習Verilog還是VHDL?

  • 個人微信公衆号: FPGA LAB
  • 個人部落格首頁
  • 注:學習交流使用!

Verilog例化方式分為兩種,一種是按端口定義時的順序例化,一種是按端口名來例化。

下面将帶來這些内容的叙述以及對比,還有如何處理空置的端口等。

按順序排列的端口連接配接是例化的第一種方式,并不推薦,但是必須知道,因為還是有一些代碼使用這種例化方式。

如下,如果我設計了一個子產品:

module mydesign ( input  x, y, z,     // x is at position 1, y at 2, x at 3 and
                    output o);          // o is at position 4
 
  endmodule
 
           

那麼按端口順序例化的話,如下所示:

module tb_top;
    wire [1:0]  a;
    wire        b, c;
 
    mydesign d0  (a[0], b, a[1], c);  // a[0] is at position 1 so it is automatically connected to x
                                      // b is at position 2 so it is automatically connected to y
                                      // a[1] is at position 3 so it is connected to z
                                      // c is at position 4, and hence connection is with o
  endmodule
           

還是按上面那個例子,我定了一個子產品:

module mydesign ( input  x, y, z,     // x is at position 1, y at 2, x at 3 and
                    output o);          // o is at position 4
 
  endmodule
 
           

如果按端口名字例化,如下:

module tb_top;
    wire [1:0]  a;
    wire        b, c;
	mydesign d0(
	.x(a[0]),
	.y(b),
	.z(a[1]),
	.o(c)
	);
 
  endmodule
           

我們推薦使用按名字進行例化的方式,因為這種方式不考慮順序,不容易出錯。

一般自動生成例化模闆的軟體或插件,也幾乎全是生成這種例化模闆的。如果生成按順序例化的模闆,那也就注定黃了。

這些都不是重點,重點是下一個話題,我們在做實際項目中也會常常看看有未連接配接的端口,我們如何認為呢?或者如何處理呢?

未連接配接到例化子產品中的端口按高阻态處理。如下:

還是拿上面設計的子產品為例:

module mydesign ( input  x, y, z,     // x is at position 1, y at 2, x at 3 and
                    output o);          // o is at position 4
 
  endmodule
 
           

我們對這個子產品進行例化使用:

module design_top(
	input [1:0] a,
	output c
);
  mydesign d0   (              // x is an input and not connected, hence a[0] will be Z
                .y (a[1]),
                .z (a[1]),
                .o ());        // o has valid value in mydesign but since
                               // it is not connected to "c" in design_top, c will be Z
endmodule
           

可以看到端口x,就連寫都沒寫,是以,可以認為是一個未連接配接的懸空端口,是一個高阻态;

端口o,雖然寫了,但是也沒連接配接到頂層子產品中的任意一個端口上,是以頂層的端口c也是一個高阻态。

下面舉一個移位寄存器的例子,看看有些端口未連接配接,生成的硬體原理圖是什麼樣的。

先從一個觸發器看起:

// Module called "dff" has 3 inputs and 1 output port
module dff (   input       d,
              input       clk,
              input       rstn,
              output reg  q);
 
  // Contents of the module  
  always @ (posedge clk) begin
    if (!rstn)
      q <= 0;
    else 
      q <= d;
  end
endmodule
           

通過例化觸發器形成移位寄存器,移位寄存器如果端口都連接配接了:

module shift_reg (   input   d,
                    input    clk,
                    input   rstn,
                    output   q);
 
  wire [2:0] q_net;
  dff u0 (.d(d),         .clk(clk), .rstn(rstn), .q(q_net[0]));
  dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q(q_net[1]));
  dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
  dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
 
endmodule
           

RTL原理圖:

Verilog初級教程(7)Verilog子產品例化以及懸空端口的處理

如果有一些端口未連接配接:

module shift_reg (   input   d,
                    input    clk,
                    input   rstn,
                    output   q);
 
  wire [2:0] q_net;
 
  dff u0 (.d(d),         .clk(clk), .rstn(rstn), .q(q_net[0]));
  dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q());             // Output q is left floating
  dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q());             // Output q is left floating
  dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
 
endmodule
           

RTL原理圖為:

Verilog初級教程(7)Verilog子產品例化以及懸空端口的處理

在仿真中,由于端口懸空了,是以,輸出也是高阻态z。

Verilog初級教程(7)Verilog子產品例化以及懸空端口的處理

所有的端口聲明都隐含地聲明為wire,是以在這種情況下端口方向就足夠了。然而需要存儲值的輸出端口應該聲明為 reg 資料類型,并且可以在程式塊中使用,比如 always 和 initial only。

輸入或inout類型的端口不能聲明為reg,因為它們是由外部連續驅動的,不應該存儲值,而是盡快反映外部信号的變化。連接配接兩個不同向量大小的端口是完全合法的,但以向量大小較小的端口為準,而另一個寬度較大的端口的剩餘位将被忽略。

繼續閱讀