一个Verilog模块主五个基本部分组成:
module mult_acc(out,ina,inb,clk,clr);
端口类型
input ——输入端口
output ——输出端口
inout ——双向端口
端口声明
eg:
input[7:0] ina,inb;
input clk,clr;
output[15:0] out;
类型 | 定义 |
---|---|
wire | 表示一个节点或连接 |
tri | 表示一个三态节点 |
supply0 | 逻辑0 |
supply1 | 逻辑1 |
eg
wire[7:0] out;
tri enable;
reg[7:0] out;
integer count;
数据类型 | 输入 | 输出 | 双向 |
---|---|---|---|
网数据类型 | YES | YES | YES |
寄存器数据类型 | NO | YES | NO |
wire adder_out=mult_out+out
等价于
wire adder_out;
assign adder=mult_out+out
module clock_gen(clk);
output clk;
reg clk;
initial
clk=1'b0;
always
#25 clk=-clk;
initial
#100 $finish;
endmodule
时间 | 执行的声明 |
---|---|
0 | clk=1‘b0 |
25 | clk=1‘b1 |
50 | clk=1‘b0 |
75 | clk=1‘b1 |
100 | $finish |
initial
begin
#5 a=b;
#10 c=d;
end
initial
begin
#5 a<=b;
#10 c<=d;
end
always @(a or b or sel)
always @(posedge clk or negedge clr)
always @(sela or selb or a or b or c)
begin
if(sela)
q=a;
else
if(selb)
q=b;
else
q=c;
end
CASE声明:
立即对所有条件进行评估;
没有优先级。
eg:
always @(sel or a or b or c or d)
begin
case(sel)
2'b00:
q=a;
2'b01:
q=b;
2'b10:
q=c;
default:
q=d;
endcase
end
注意:
casez认为case条件下的所有z值不重要;
casex认为case条件下的所有x和z值都不重要。
循环声明:
用于重复运算。
initial
begin
clk=0;
forever #25 clk=-clk;
end
if(rotate==1)
repeat(8)
begin
tmp=data[15];
data={data<<1,temp};
end
initial
begin
count=0;
while(count<101)
begin
$display("Count=%d",count);
count=count+1;
end
end
integer i;//declare the index for the FOR LOOP
always @(inp or cnt)
begin
result[7:4]=0;
result[3:0]=inp;
if(cnt==1)
begin
for(i=4;i<=7;i=i+1)
begin
result[i]=result[i-4];
end
result[3:0]=0;
end
注意:
必须用于always或者initial模块中;
这些行为声明也可以用在时钟进程中。
assign mult_out=mult(ina,inb);
stm_out(nxt,first,sel,filter);
注意:
函数和任务都是子程序;
用于可重复代码;
增加模块可读性;
二者区别:
eg:
函数定义——乘法器
function[15:0] mult;
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
Verilog模块实例——乘加器
module mult_acc(out,ina,inb,clk,clr);
input[7:0] ina,inb;
input clk,clr;
output[15:0] out;
wire[15:0] mult_out,adder_out;
reg[15:0] out;
parameter set=10;//常量
parameter hld=20;
assign adder_out=mult_out+out;
always @(posedge clk or posedge clr)
if(clr) out=16'h0000;
else out=adder_out;
//函数调用
assign mult_out=mult(ina,inb);
endmodule
任务实例
module tasks;
//任务定义
task add;//与函数不同,不需要传递参数
input a,b;
output c;
begin
c=a+b;
endtask
//任务调用
initial
begin:init1
reg p;
add(0,1,p);//按顺序进行传递
$dispaly("p=%b",p);
end
endmodule