verilog学习——building block(1)

verilog学习——building block

(一)verilog模块

一个模块(module)是实现特定功能的代码块,模块可以嵌入到其他模块中;
语法:
模块声明在关键字module和endmodule后,模块名紧跟在关键字module中,还可以声明可选的端口列表,注意,端口声明列表中声明的端口不能在模块正文中重新声明。

module <name> ([port_list]);
	// Contents of the module
endmodule

// A module can have an empty portlist
module name;
	// Contents of the module
endmodule

模块代表实现某些行为特征的设计单元,并将在综合过程中转换为数字电路。

顶级模块(top-level moodules)
顶级模块是包含所有其他模块的模块,不会在其他任何模块中实例化;
例如,设计模块通常在顶级测试台模块中实例化,以便通过提供输入激励来运行仿真模拟。但是,测试平台不会在任何其他模块中实例化,因为它是一个封装其他所有内容的块,因此是顶级模块。
分层名称
模块可以在彼此内部实例化,就会形成分层结构;顶层模块称为根模块。访问时需要用到“.“分隔符。

design.mod_inst2.mod_inst2.a

(二)Verilog 端口

1.端口类型
端口是一组信号,充当特定模块的输入和输出,是与其通信的主要方式。端口就像引脚一样,用来发送和接受外部世界的信号。
默认情况下,端口被视为wire类型的网络
端口类型:

Input:从外部接收值;
Output:向外部发送值;
Inout:发送或接收值

2.语法
声明为inout的端口可以同时充当输入和输出。

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

多个端口不能使用相同的名称。

3.signed端口(signed ports)
Signed属性可以附加到端口声明或net/reg声明中,默认情况下。隐式网络是无符号的;

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

4.端口variations
Verilog1995版本,模块声明必须首先列出括号内的端口名称,然后在模块正文中定义的这些端口的方向。

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

2001年引入了ANSI-C样式的端口命名,并允许在端口列表中指定类型。

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

如果端口声明不包含 net 或变量类型,则可以再次在 net 或变量类型声明中声明端口。

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实例化

模块可以在其他模块中实例化,这些实例的端口可以与父模块内的其他信号连接。
端口连接可以通过有序列表或者按名称完成。

  1. 按有序列表划分的端口连接:
    在端口实例化中列出的端口表达式与父模块内的信号之间建立联系的一种方法是通过有序列表。
    端口按特定顺序连接,该顺序由该端口在模块声明的端口列表中的位置确定。
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
  1. 按名称划分的端口连接
    圆点 . 表示圆点后面的端口名称属于设计。设计端口必须连接到的信号名称在括号内给出 ( ) 。
module design_top;
	wire [1:0]  a;
	wire        b, c;

	mydesign d0  ( .x (a[0]),    // signal "x" in mydesign should be connected to "a[0]" in this module (design_top)
	               .y (b),       // signal "y" in mydesign should be connected to "b" in this module (design_top)
	               .z (a[1]),
	               .o (c));
endmodule
  1. 未连接/浮动端口
    未连接到实例化模块中任何wire电线的端口具有高阻抗值;
    所有端口声明都隐式声明为wire。需要存储值的output端口应声明为reg数据类型,可以在过程块中使用,例如always和initial;input和inout不能声明为reg,不应存储值。

(四)Verilog assign语句

  1. Verilog赋值语法
    赋值语法以关键字assign开头,后跟信号名称,可以是单一信号,也可以是不同信号网的串联。将右侧的表达式或者信号进行评估,将其分配给左侧的网络。
assign <net_expression> = [drive_strength] [delay] <expression of different signals or constant value>

规则:
① LHS 应始终是标量或向量网络或标量和向量网络的串联,而不是标量或向量寄存器。
② RHS 可以包含标量或向量寄存器以及函数调用。
③ 每当 RHS 上的任何操作数值发生变化时,LHS 都将使用新值进行更新。
④ Assign语句被称为连续赋值,并且始终处于活动状态。
连续赋值语句可用于表示verilog中的组合门。
2. reg变量赋值
使用assign语句驱动或赋值reg变量是错误的,因为reg变量能够存储数据,不需要连续驱动。Reg信号只能在程序块中驱动,如initial,always
3. 隐式连续赋值
使用assign语句赋值为显示赋值,verilog中还允许隐式赋值;

wire [1:0] a;
assign a = x & y; 			// Explicit assignment

wire [1:0] a = x & y; 	// Implicit assignment
  1. 组合逻辑设计
    Verilog代码
module combo (	input 	a, b, c, d,
								output  o);

  assign o = ~((a & b) | c ^ d);

endmodule

对应的组合门:

在这里插入图片描述

(五)Verilog运算符

1.verilog算术运算符
除法或者模数运算符的第二个操作数是0,则结果是X;
如果幂运算符的任一操作数为实数,则结果也为实数;
如果幂运算符的第二个操作数为0,则结果为1.

a+b;a-b,a*b,a/b,a%b,a**b  加减乘除 模运算 幂

2.verilog关系运算符
任一操作数为x或者z,则结果为x;
关系运算符的优先级低于算术运算符,且所有关系运算符的优先级相同。

a<b,a>b,a<=b,a>=b,小于 大于 小于等于 大于等于;

3.verilog相等运算符
相等运算符之间具有相同的优先级,且优先级低于关系运算符;
如果逻辑相等式 () 或逻辑不等式 (!=) 的任一操作数是 X 或 Z,则结果将为 X。可以使用大小写相等运算符 (=) 或大小写不等式运算符 (!==) 进行匹配,包括 X 和 Z,并且始终具有已知值。
a === b,a等于b,包括x和z;
a! == b,a不等于b,包括x和z;
a == b,a等于b,结果可能未知;
a != b;a不等于b,结果可能未知。
4.verilog逻辑运算符
逻辑and,逻辑or,
如果任一操作数为x,则结果为x;
逻辑非运算符,操作数是x时,则结果也为x;

a&&b,a||b,!a;

5.verilog按位运算符
按位进行运算,将一个操作数中的位,与另一个操作数中的对应的位进行运算;
& |

data1(1) & data2(x) = x
data1(1) & data2(z) = x
data1(x) & data2(0) = 0
data1(x) & data2(1) = x
data1(x) & data2(x) = x
data1(x) & data2(z) = x
data1(z) & data2(0) = 0
data1(z) & data2(1) = x
data1(z) & data2(x) = x
data1(z) & data2(z) = x

6.换挡运算符
逻辑移位运算符:<< >>
算数移位运算符:<<< >>>

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
序列检测器是一种电路,用于检测输入信号序列是否符合某种特定的模式。在Verilog HDL语言中,可以使用状态机来实现序列检测器。以下是一个简单的序列检测器的Verilog HDL代码示例: ```verilog module sequence_detector( input clk, // 时钟信号 input reset, // 复位信号 input data, // 输入数据信号 output reg match // 匹配信号 ); // 定义状态 typedef enum logic [1:0] { STATE_IDLE, // 空闲状态 STATE_S1, // 状态1 STATE_S2, // 状态2 STATE_S3 // 状态3 } state_t; // 定义状态转移表 parameter [3:0] TRANS_TABLE [0:3] = '{4'b0000, 4'b0001, 4'b0010, 4'b0100}; // 定义当前状态变量和下一个状态变量 reg [1:0] state, next_state; // 初始化状态为IDLE initial begin state = STATE_IDLE; end // 定义状态机逻辑 always @ (posedge clk, posedge reset) begin if (reset) begin state <= STATE_IDLE; end else begin state <= next_state; end end // 定义状态转移逻辑 always @ (*) begin case (state) STATE_IDLE: begin if (data) begin next_state = STATE_S1; end else begin next_state = STATE_IDLE; end end STATE_S1: begin if (!data) begin next_state = STATE_IDLE; end else if (data) begin next_state = STATE_S2; end end STATE_S2: begin if (!data) begin next_state = STATE_IDLE; end else if (data) begin next_state = STATE_S3; end end STATE_S3: begin if (!data) begin next_state = STATE_IDLE; match = 1; end else begin next_state = STATE_S3; end end endcase end endmodule ``` 这个序列检测器可以检测输入数据信号是否符合“1101”这个模式。输入数据信号通过data端口输入,匹配结果通过match端口输出。当输入数据信号符合“1101”这个模式时,match信号会被置为1。如果输入数据信号不符合模式,match信号会保持为0。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值