今天给大侠带来的是一周掌握FPGA Verilog HDL 语法,今天开启第三天。
赋值语句
在Verilog HDL语言中,信号有两种赋值方式:
(1).非阻塞(Non_Blocking)赋值方式( 如 b <= a; )
1) 块结束后才完成赋值操作。
2) b的值并不是立刻就改变的。
3) 这是一种比较常用的赋值方法。(特别在编写可综合模块时)
(2).阻塞(Blocking)赋值方式( 如 b = a; )
always @( posedge clk )
begin
b<=a;
c<=b;
end
always @(posedge clk)
begin
b=a;
c=b;
end
块名即标识该块的一个名字,相当于一个标识符。
块内说明语句可以是参数说明语句、reg型变量声明语句、integer型变量声明语句、real型变量声明语句、time型变量声明语句、事件(event)说明语句。
下面举例说明,[例4]:
fork
'h35; 50 r =
100 r = 'hE2;
'h00; 150 r =
200 r = 'hF7;
250 -> end_wave; //触发事件end_wave.
join
fork
250 -> end_wave;
'hF7; 200 r =
150 r = 'h00;
'hE2; 100 r =
50 r = 'h35;
join
if_else语句
if语句是用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。Verilog HDL语言提供了三种形式的 if 语句。
(1).if(表达式)语句 例如:
if ( a > b ) out1 <= int1;
(2).if(表达式) 语句1 else 语句2 例如:
if(a>b) out1<=int1;
else out1<=int2;
(3).
if(表达式1) 语句1;
else if(表达式2) 语句2;
else if(表达式3) 语句3;
........
else if(表达式m) 语句m;
else 语句n;
例如:
if(a>b) out1<=int1;
else if(a==b) out1<=int2;
else out1<=int3;
六点说明:
(1). 三种形式的if语句中在if后面都有“表达式”,一般为逻辑表达式或关系表达式。系统对表达式的值进行判断,若为0,x,z,按“假”处理,若为1,按“真”处理,执行指定的语句。
(2). 第二、第三种形式的if语句中,在每个else前面有一分号,整个语句结束处有一分号。例如:
这是由于分号是Verilog HDL语句中不可缺少的部分,这个分号是if语句中的内嵌套语句所要求的。如果无此分号,则出现语法错误。但应注意,不要误认为上面是两个语句(if语句和else语句)。它们都属于同一个if语句。else子句不能作为语句单独使用,它必须是if语句的一部分,与if配对使用。
(3). 在if和else后面可以包含一个内嵌的操作语句(如上例),也可以有多个操作语句,此时用begin和end这两个关键词将几个语句包含起来成为一个复合块语句。如:
if(a>b)
begin
out1<=int1;
out2<=int2;
end
else
begin
out1<=int2;
out2<=int1;
end
注意在end后不需要再加分号。因为begin_end内是一个完整的复合语句,不需再附加分号。
(4). 允许一定形式的表达式简写方式。如下面的例子:
if(expression) 等同与 if( expression == 1 )
if(!expression) 等同与 if( expression != 1 )
(5). if语句的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套。一般形式如下:
if(expression1)
if(expression2) 语句1 (内嵌if)
else 语句2
else
if(expression3) 语句3 (内嵌if)
else 语句4
应当注意if与else的配对关系,else总是与它上面的最近的if配对。如果if与else的数目不一样,为了实现程序设计者的企图,可以用begin_end块语句来确定配对关系。例如:
if( )
begin
if( ) 语句1 (内嵌if)
end
else
语句2
这时begin_end块语句限定了内嵌if语句的范围,因此else与第一个if配对。注意begin_end块语句在if_else语句中的使用。因为有时begin_end块语句的不慎使用会改变逻辑行为。见下例:
if(index>0)
for(scani=0;scani<index;scani=scani+1)
if(memory[scani]>0)
begin
$display("...");
memory[scani]=0;
end
else /*WRONG*/
$display("error-indexiszero");
尽管程序设计者把else写在与第一个if(外层if)同一列上,希望与第一个if对应,但实际上else是与第二个if对应,因为它们相距最近。正确的写法应当是这样的:
if(index>0)
begin
for(scani=0;scani
1 )if(memory[scani]>0)
begin
$display("...");
memory[scani]=0;
end
end
else /*WRONG*/
$display("error-indexiszero");
(6) .if_else例子。
下面的例子是取自某程序中的一部分。这部分程序用if_else语句来检测变量index以决定三个寄存器modify_segn中哪一个的值应当与index相加作为memory的寻址地址。并且将相加值存入寄存器index以备下次检测使用。程序的前十行定义寄存器和参数。
//定义寄存器和参数。
reg [31:0] instruction, segment_area[255:0];
reg [7:0] index;
reg [5:0] modify_seg1, modify_seg2, modify_seg3;
parameter
segment1=0, inc_seg1=1,
segment2=20, inc_seg2=2,
segment3=64, inc_seg3=4,
data=128;
//检测寄存器index的值
if(index
begin
instruction = segment_area[index + modify_seg1];
index = index + inc_seg1;
end
else if(index
begin
instruction = segment_area[index + modify_seg2];
index = index + inc_seg2;
end
else if (index<data)
begin
instruction = segment_area[index + modify_seg3];
index = index + inc_seg3;
end
else
instruction = segment_area[index];
Day 3 就到这里,Day 4 继续开始case语句,大侠保重,告辞。
END
往期精选
FPGA技术江湖广发江湖帖
无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有,QQ微信双选,FPGA技术江湖打造最纯净最专业的技术交流学习平台。
FPGA技术江湖微信交流群
加群主微信,备注姓名+学校/公司+专业/岗位进群
FPGA技术江湖QQ交流群
备注姓名+学校/公司+专业/岗位进群