module module_name(port_list);
(端口声明)
(数据类型声明)
(电路功能)
(时序规范)
endmodule
注意:
input
——输入端口output
——输出端口inout
——双向端口1.Net数据类型——表示进程之间的物理互联
类型 | 定义 |
---|---|
wire |
表示一个节点或者连接 |
tri |
表示一个三态节点 |
supply0 |
逻辑0 |
supply1 |
逻辑1 |
2.寄存器数据类型——表示暂时存储数据的变量,也可以表示寄存或者组合节点
寄存器数据类型只能在进程声明、任务或者功能中赋值 reg
类型变量,不能是逻辑门输出,或者 assign
语句的输出。
reg [7:0] out;
'd
或者'D
) 16'd255
= 16位宽十进制数字'h
或者'H
) 8'h9a
= 8位宽十六进制数字'b
或者'B
) 'B1010
= 32位宽二进制数字'o
或者'O
) 'o21
= 32位宽八进制数字-8'd13
X
为未知值;Z
为高阻抗值initial模块——用与初始化仿真的行为说明(被综合器忽略)。在时间0启动,顺序执行,用于初始化、监视、波形和其他进程,在仿真时只执行一次。
always模块——使用行为说明,用于描述电路功能。如果有多个always模块,同时执行每个模块。在时间0启动,以循环的方式连续执行行为说明。
注:initial
和always
模块不能进行嵌套。
阻塞赋值(=)——按顺序模块中指定的次序执行
非阻塞赋值(<=)——不对顺序模块后的声明进行阻塞赋值,支持对赋值的调度。
if…else…声明:按条件从上到下顺序执行
if(条件1)
表达式1;
else
if(条件2)
else
表达式2;
case声明:对条件进行评估,并行执行
case (条件)
常量条件1:
表达式1;
常量条件2:
表达式2;
...
...
default:
表达式n;
endcase
forever循环声明:不断执行
//50个时间单位的时钟周期,永久循环
initial
begin
clk = 0;
forever #25 clk = ~clk;
end
repeat循环声明:执行一定的次数
//重复8次循环操作,temp右移8位
if(ratate == 1)
repeat(8)
begin
temp = data[15];
data = { data << 1,temp };
end
while循环声明:如果表达式为真。则执行
//从0到100计数,到101是退出循环
while (cnt < 101)
begin
cnt = cnr + 1;
end
for循环声明:循环开始时立即执行一次,如果表达式为真,则继续执行
integer i ;
assign a = 1
for ( i = 4 ;i <= 7 ;i = i + 1)
begin
a = a + i;
end
函数定义
示例:乘法器
function [15:0] mull;
input [7:0] a,b;
reg [15:0] r;
integer i;
begin
if (a[0] == 1)
r = b;
else r = 0;
for(i = 1;i <= 7;i = i+1)
begin
if(a[i] == 1)
r = r + (b << i);
end
mult = r;
end
endfunction
函数调用:assign mult_out = mult (a,b)
任务定义
任务示例:加法器
module tasks;
//任务定义
//任务不需要传递函数
task add;
input a,b;
output c;
begin
c = a + b;
endtask
//任务调用
initial
begin init1
reg p;
add(1,0,p); //按数值出现的顺序进行传递
$display("p = %d",p);
end
endmodule
/*********************************************
模块名:fre_div(clk,rst_n,clkout)
功能:分频器
对系统时钟50MHZ进行N分频 clkout=50MHZ/N
端口:
clk——系统时钟50MHZ
rst_n——低电平复位端口
clkout——输出端口
*********************************************/
module fre_div(clk,rst_n,clkout);
//端口声明
input clk;
input rst_n;
output clkout;
//数据类型声明
reg clkout;
parameter WIDTH = 10; //位宽
parameter N = 1000; //分频系数
reg [WIDTH-1:0] CNT;
//电路功能
//always进程,时钟上升沿或复位下降沿触发
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
CNT<=0;
clkout1<=0;
end
else
begin
if (CNT==N/2-1)
begin
clkout<=~ clkout;
CNT<=0;
end
else
begin
CNT<=CNT+1;
end
end
end
endmodule