天天看點

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

博文目錄

    • 寫在前面
    • 正文
      • 子產品
      • 端口
        • 端口類型
        • Verilog 1995與Verilog 2001對比
    • 參考資料
    • 交個朋友

前五篇文章已經将Verilog的零碎知識點講解的差不多了,從這篇開始,就從子產品開始了。

子產品化設計思想是Verilog的核心,也是數字設計的核心,子產品化設計就像搭建積木一樣搭建數字電路。

這篇部落格,講解子產品使用verilog 2001修訂版風格,通過例子是最好的學習方法。

  • 個人微信公衆号: FPGA LAB
  • 個人部落格首頁

使用Verilog設計數字電路,其實就是設計大大小小的子產品,子產品互相例化,最後組成一個頂層子產品,也就是整個設計了。

下面給出最基本的子產品模闆:

module module_name(
	input i_clk,
	input i_a,
	input [3:0] i_b,
	input i_en,
	output o_out,	
	inout [3:0] o_c
	//your input/ouput/inout ports
);

//your sequential logic
always@(posedge i_clk) begin
//your sequential logic
end

//your combinational logic
always@(*) begin
//your logic
end

assign o_c = i_en ? i_b : 4'hz;
//......

//institation other module
a_module inst(
.i_clk(i_clk),
.i_a(i_a),
.o_c(o_c),
);

endmodule
           

如果子產品内的變量位寬參數化,則子產品模闆為:

module exam_module #(
parameter c_WIDTH = 8,
parameter c_DEPTH = 16 
)(
//input 
input i_a,
//inout
inout io_b,
//output 
output o_c
);

//the same as before module


endmodule
           

例化帶參數的子產品:

module top_module(
// input/output/inout ports define
);

//other logics

//institation module with parameter
exam_module #(
.c_WIDTH(8),
.c_DEPTH(6)
)inst0(
//ports parts
);



endmodule
           

端口是一組信号, 用作特定子產品的輸入和輸出, 并且是與之通信的主要方式。将子產品視為放置在 PCB上的預制晶片,很明顯,與晶片通信的唯一方法是通過其引腳。端口就像引腳,設計人員将其用于發送和接收來自外界的信号。

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

端口描述

  • input 設計子產品隻能使用其input端口從外部接收值
  • output 設計子產品隻能使用其output端口将值發送到外部
  • inout 設計子產品可以使用其inout端口發送或接收值

預設情況下,端口類型為wire類型。

文法

input  [net_type] [range] list_of_names;   // Input port
  inout  [net_type] [range] list_of_names;   // Input & Output port
  output [net_type] [range] list_of_names;   // Output port driven by a wire
  output [var_type] [range] list_of_names;   // Output port driven by a variable
           

例如:

module  my_design ( input wire      clk,
                    input           en,
                    input           rw,
                    inout [15:0]    data,
                    output           int );
 
  // Design behavior as Verilog code
 
endmodule
           

注:端口名字不能一樣,如下是不合規的:

input  aport;         // First declaration - valid
  input  aport;         // Error - already declared
  output aport;         // Error - already declared
           

有符号端口聲明

可以使用signed屬性來聲明有符号端口,預設情況下是無符号的端口。

module ( 
           input signed a, b,  // a, b are signed from port declaration
           output reg signed c // c is signed from reg declaration
           );
  
  endmodule
           

可以參考資料:http://suo.im/5OkJ5D

先看Verilog 1995是如何定義端口的:

Verilog 經過了一些修改, 1995 年的原始 IEEE 版本采用以下方式聲明端口。在這裡,

子產品聲明必須首先在方括号内列出端口的名稱,然後再在子產品主體内定義這些端口的方向。

module test (a, b, c);
 
  input   [7:0] a;            // inputs "a" and "b" are wires
  input   [7:0] b;  
  output   [7:0] c;       // output "c" by default is a wire
 
  // Still, you can declare them again as wires to avoid confusion
  wire   [7:0] a;
  wire   [7:0] b;
  wire   [7:0] c;
endmodule
 
 
module test (a, b, c);
 
  input  [7:0] a, b;
  output [7:0] c;           // By default c is of type wire
 
  // port "c" is changed to a reg type
  reg    [7:0] c;           
endmodule
           

Verilog 2001修訂:

ANSI-C 樣式的端口命名是在 2001 年引入的, 允許在端口清單中指定類型。

module test ( input [7:0]  a,
                            b,     // "b" is considered an 8-bit input
              output [7:0]  c);
 
  // Design content        
endmodule
 
module test ( input wire [7:0]  a,   
              input wire [7:0]  b,     
              output reg [7:0]  c);
 
  // Design content
endmodule
           

如果端口聲明包含網絡或變量類型,則認為該端口已完全聲明。在網絡或變量類型聲明中重新聲明相同的端口是非法的。

module test ( input      [7:0] a,       // a, e are implicitly declared of type wire
            output reg [7:0] e );
 
   wire signed [7:0] a;     // illegal - declaration of a is already complete -> simulator dependent
   wire        [7:0] e;     // illegal - declaration of e is already complete
 
   // Rest of the design code
endmodule
           

如果端口聲明不包含網絡或變量類型,則可以再次在網絡或變量類型聲明中聲明端口。

module test ( input      [7:0] a,
              output     [7:0] e);
 
     reg [7:0] e;              // Okay - net_type was not declared before
 
     // Rest of the design code
endmodule