Verilog语法
Verilog HDl行为语句
一、过程语句
1.initial
2.always
3.在一个模块中使用initial和always的次数是不受限的。initial语句常用于仿真中的初始化,initial过程快中的语句仅执行一次;always块内的语句是不断重复执行的。
4.always过程语句模板
always @(敏感信号表达式)
begin
//过程赋值
//if-else,case,casex,casez选择语句
//while,repeat,for循环
//task,function调用
end
(1)always 语句通常是带有触发条件的,触发条件写在敏感信号表达式中,只有当条件满足时,才执行begin—-end。
(2)敏感信号表达式又称事件表达式或者敏感信号列表,即当该表达式中变量的值改变时,就会引发块内语句执行。列出影响块内取值的所有信号。两个或以上用or 连接。
例
@(a)
@(a or b)
@(poseedge clock) //当clock的上升沿到来时
@(negedge clock) //当clock的下降沿到来时
@(posdedge clk or negedge reset)
(3)敏感信号列表举例(4选1 数据选择器)
module
mux4_1(out,in0,in1,in2,in3,sel);
output out;
output in0,in1,in2,in3;
input [1:0] sel;
reg out;
always@(in0 or in1 or in2 or in3 or sel)//敏感信号列表***
case(sel)
2'b00:out=in0;
2'b01:out=in1;
2'b10:out=in2;
2'b11:out=in3;
default:out=2'bx;
endcase
endmodule
(4)posedge 和negedge 关键字
对于时序电路,事件通常是由时钟边沿触发的。Verilog提供posedge 和negedge 关键字来描述
【例】同步置数,同步清零的计数器
module count(out,data,load,reset,clk);
output[7:0] out;
input[7:0] data;
input load,clk,reset;
reg[7:0] out;
always@(poseedge clk)//clk上升沿触发
begin
if(!reset) out=8'h00
else if(load) out=data;
else out=out+1;
end
endmodule
(5)always过程语句使用注意事项
在always中被赋值的变量一定要定义成为reg类型
5.块语句
(1)块语句是由块标志符begin-end或者fork-join界定的一组语句,当块语句中只包含一条语句时,块标志符可以缺省。
(2)begin-end串行块中的语句按串行方式执行。
如
begin //begin-end 之间的语句按顺序执行
regb=rega;
regc=regb;
end
注意:begin-end相当于{},当一个块中有多条赋值语句的条件时使用。
6.赋值语句
(1)持续赋值语句
assign 为持续赋值语句,用于对wire型变量的赋值。
assign c=a&b;
在上面的赋值中,a,b,c三个变量皆为wire型变量,a和b信号的任何变化,都可以随时反映到c上来。
(2)过程赋值语句
过程赋值语句多用于reg型变量进行赋值。过程赋值分为阻塞和非阻塞赋值两种方式。
非阻塞赋值:
赋值符号为“<=”,如b<=a;
在整个过程快结束时才完成赋值操作,即b的值并不是立刻改变的。
//非阻塞赋值
module non_block(c,b,a,clk);
output c,b;
input clk,a;
reg c,b;
always@(posedge clk)
begin
b<=a;
c<=b;
end
endmodule
阻塞赋值:
赋值符号"=",如b=a;
在该语句结束时就立即完成赋值操作,即b的值在该条语句结束后立刻改变。
a,clkl
//阻塞赋值
module block(c,b,a,clk)
output c,b;
input a,clk;
reg c,b;
always@(posedge clk)
begin
b=a;
c=b;
end
endmodule
条件语句
if-else语句三种使用
(1)if(表达式)语句1;
(2)if(表达式)语句1;
else 语句2;
(3)if(表达式)语句1;
else if(表达式) 语句2;
else if(表达式) 语句3;
......
else 语句n;
注意:当语句中有多条赋值语句时一定要有begin-end括起来
例:模为60的BCD码加法计数器P148
module count60(qout,cout,data,load,reset,clk)
output[7:0]
output cout;
input[7:0] data;
input load,clk,reset;
reg[7:0]qout;
always@(posedge clk)
begin
if(reset)qout<=0; //同步复位
else if(load)qout<=data;//同步置数
else
begin
if(qout[3:0]==9)//地位是否为9
begin
qout[3:0]<=0;//回0,并判断高位是否为5
if(qout[7:4]==5)qout[7:4]<=0;
else
qout[7:4]<=qout[7:4]+1;//高位不为5,则加一
end
else //低位不为9,则加一
qout[3:0]<=qout[3:0]+1;
end
assign cout=(qout=8'h59)?1:0;
//产生进位输出信号
endmodule
case语句
case(敏感表达式)
值1:语句1;
值2:语句2;
值3:语句3;
......
值n:语句n;
default:语句n+1;
endcase
BCD码——共阴极七段数码管显示译码器
module decode4_7(a,b,c,d,e,f,g,D3,D2,D1,D0);
output reg,a,b,c,d,e,f,g;//分别连接到a-f
input D3,D2,D1,D0;
always@(*)
begin
case(D3,D2,D1,D0)
4'd0:{a,b,c,d,e,f,g}=7'b1111110;
4'd1:{a,b,c,d,e,f,g}=7'b0110000;
4'd2:{a,b,c,d,e,f,g}=7'b1101101;
4'd3:{a,b,c,d,e,f,g}=7'b1111001;
4'd4:{a,b,c,d,e,f,g}=7'b0110011;
4'd5:{a,b,c,d,e,f,g}=7'b1011011;
4'd6:{a,b,c,d,e,f,g}=7'b1011111;
4'd7:{a,b,c,d,e,f,g}=7'b1110000;
4'd8:{a,b,c,d,e,f,g}=7'b1111111;
4'd9:{a,b,c,d,e,f,g}=8'b1111011;
defalt:
{a,bc,d,e,f,g}=7'b1111110;
endcase
end
endmodule
case 的变体语句
casez
casex:把不予与考虑的位扩展到未知x,即不关注值为高阻和未知x的那些位,只关注其它位的比较结果。
用casez描述的数据选择器
module mux_casez(out,a,b,c,d,seltct);
output out;
input a,b,c,d;
input[3:0] select;
reg out;
always@(select or a or b or c or d )
begin
casez(select)
4'b???1:out=a;
4'b??1?:out=b;
4'b?1??:out=c;
4'b1???:out=d;
endcase
end
endmodule