Verilog基础语法(4)之模块和端口及其例化和处理

一、模块与端口

1、模块

Verilog进行FPGA/IC设计值,通常划分为各个子模块,木模块之间可能相互例化,并在顶层统一例化,并连接成一个顶层模块文件。
基本的模块模板:

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

2、端口

端口类型/端口描述

  • input 设计模块只能使用其input端口从外部接收值
  • output 设计模块只能使用其output端口将值发送到外部
  • inout设计模块可以使用其inout端口发送或接收值
module  my_design ( input wire      clk,
                    input           en,
                    input           rw,
                    inout [15:0]    data,
                    output           int );
 
  // Design behavior as Verilog code 
endmodule

关于模块端口的说明
当不定义端口数据类型时,默认为wire型,端口名不能重复,需要存储值的输出端口应该声明为 reg 数据类型,并且可以在程序块中使用,比如 always 和 initial only。

输入或inout类型的端口不能声明为reg,因为它们是由外部连续驱动的,不应该存储值,而是尽快反映外部信号的变化。连接两个不同向量大小的端口是完全合法的,但以向量大小较小的端口为准,而另一个宽度较大的端口的剩余位将被忽略。

有符号端口声明

可以使用signed属性来声明有符号端口,默认情况下是无符号的端口。

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

2001年verilog修订:模块端口声明:

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

二、模块例化与端口处理

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
  1. 按端口排序顺序例化

  module tb_top;
    wire [1:0]  a;
    wire        b, c;
 
    mydesign d0  (a[0], b, a[1], c);  // a[0] 连接 x
                                      // b 连接 y
                                      // a[1] 连接 z
                                      // c 连接  o
  endmodule
  1. 按端口名例化
  module tb_top;
    wire [1:0]  a;
    wire        b, c;
	mydesign d0(
	.x(a[0]),
	.y(b),
	.z(a[1]),
	.o(c)
	); 
  endmodule

未连接/悬空端口处理
未连接到例化模块中的端口按高阻态处理。如下:

module design_top(
	input [1:0] a,
	output c
);
  mydesign d0   (              // x 没有写, a[0] = Z 以高阻态显示
                .y (a[1]),
                .z (a[1]),
                .o ());        // o 虽然写了,但是没有连接任何端口信号,
                               // 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原理图:
在这里插入图片描述
当有些端口未连接时:

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原图:
在这里插入图片描述
对其进行仿真,由于短口味连接即悬空了,输出为高阻态z

在这里插入图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Verilog基础语法主要包括模块声明、端口声明、信号声明和语句。 1. 模块声明 Verilog中一个模块代表一个电路。模块模块名、端口声明和语句组成。模块声明的基本语法如下: ``` module module_name (port_list); // statements endmodule ``` 其中,module_name是模块名,port_list是端口列表,多个端口之间用逗号隔开。 2. 端口声明 端口声明用来声明模块的输入输出端口端口声明的基本语法如下: ``` input [n:0] input_port; output [m:0] output_port; ``` 其中,n和m是端口位宽减一,[n:0]和[m:0]表示端口是一个位宽为n+1和m+1的向量。input表示输入端口,output表示输出端口。 3. 信号声明 信号声明用来声明模块中的信号。信号声明的基本语法如下: ``` reg [n:0] signal_name; wire [m:0] signal_name; ``` 其中,n和m是信号位宽减一,[n:0]和[m:0]表示信号是一个位宽为n+1和m+1的向量。reg表示寄存器类型的信号,wire表示连线类型的信号。 4. 语句 Verilog中的语句包括组合逻辑语句和时序逻辑语句。组合逻辑语句用于描述电路的组合逻辑,时序逻辑语句用于描述电路的时序行为,如时钟、状态机等。 组合逻辑语句的基本语法如下: ``` assign output_port = input_port1 & input_port2; ``` 其中,&表示逻辑与运算符,assign表示连续赋值语句。 时序逻辑语句的基本语法如下: ``` always @(posedge clk) begin // statements end ``` 其中,posedge表示时钟上升沿触发,clk是时钟信号,begin和end用来标识时序逻辑语句的作用域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值