一些电路的综合结果
阻塞赋值 = 一般不带D-Q延时;非阻塞赋值<= 带D-Q延时。阻塞和非阻塞是针对块内下一条语句而言,阻塞赋值会阻塞后面语句执行(后面的逻辑例化于阻塞逻辑之后),在完成该条阻塞赋值后再执行后面的语句。这也与D-Q延时对电路的影响一致。
//组合逻辑
always_combbegin:comb_led
LEDR[2:0]='0;//默认
for(int i =0;i<4;i++)begin
if(KEY[1])begin
LEDR[2:0]+=1;
end
end
end:comb_led
电路描述:0状态LEDR[2:0],在KEY[1]使能下进行4次阻塞加1。加法运算过程中KEY[1]的改变会影响加1的次数。值得注意的是的4次阻塞加1延时很小,使能在功能上是有效,但这种设计是否符合设计的意图。
//锁存器
always_latchbegin:latch_led
if(KEY[2])//锁存器使能
LEDR[3:2]= SW[4:3];//使能输出
end:latch_led
电路描述:锁存器电路,在KEY[2] =1的时候输出结果为SW[4:3],在KEY[2] =0时,锁存器锁存。
//时序逻辑,不带使能
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[5:4]<='0;//异步复位
elsebegin
LEDR[5:4]<= SW[4:3];//同步输出= else
if(KEY[1])
LEDR[5:4]<= SW[6:5];//同步输出
end
end:ff_led
电路描述:触发器,0时刻与其他时刻一致,KEY[1] = 0,时钟上沿同步输出为SW[4:3],KEY[1] = 1, 时钟上沿同步输出为SW[4:3]。对于时序电路,一般由复位置默认值。
//时序逻辑,带使能
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[5:4]<='0;//异步复位
else
if(KEY[1]) //带使能
LEDR[5:4]<= SW[6:5];//同步输出
end:ff_led
电路描述:带使能的触发器,在KEY[1] = 1时,时钟上沿LEDR[5:4]的值更新,否则在时钟上沿保持。
//循环,循环中直取,下轮取锁存器值,锁存输出
always_latchbegin:lacth_led
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]= LEDR[4:0]+1;
end
end: lacth_led
电路描述:组合逻辑中分支不完整,形成锁存器。i=0时,从锁存器取值;其他情况,D侧取值。
//循环,每次取锁存器缓存,输出
always_latchbegin: lacth_led
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]<= LEDR[4:0]+1;
end
end: lacth_led
电路描述:组合逻辑中分支不完整,形成锁存器。所有i,LEDER从锁存器取值。由于每次for循环,由于是非阻塞赋值,4条赋值语句在Out端取到相同值,赋值结果也相同。因此,会被优化等效为一条赋值语句,这也是综合后的结果只有一个加法器的原因。
//不带0时刻初值,一轮循环开始取Buffer值,组合逻辑
always_combbegin:comb_led
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]= LEDR[4:0]+1;
else
LEDR[4:0]='0;
end
end: comb_led
电路描述:在KEY[1]有效时,每一轮循环开始从Buffer中取值,其他由中间态取值。
//不带0时刻初值,每个取值均取Buffer值,组合逻辑
always_combbegin: comb_led
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]<= LEDR[4:0]+1;
else
LEDR[4:0]<='0;
end
end: comb_led
电路描述:在KEY[1]有效时,均从Buffer端取值,4次循环等效一条语句。
//带0时刻初值,循环开始取初值,组合逻辑
always_combbegin: comb_led
LEDR[4:0]='0;
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]= LEDR[4:0]+1;//else赋初值
end
end: comb_led
电路描述:带0时刻初值的加法,每次加法取输出端更新的值。
//带0时刻初值,每个取值均取Buffer值,组合逻辑
always_combbegin: comb_led
LEDR[4:0]<='0;
for(int i =0;i<3;i++)begin
if(KEY[1])
LEDR[4:0]<= LEDR[4:0]+1;
end
end: comb_led
电路描述:每次取值都经过Buffer缓存,0时刻非阻塞赋值被优化。
//带0时刻初值,D端取值,时序逻辑
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[4:0]<='0;//异步复位
elsebegin
LEDR[4:0]='0;
for(int i =0;i<3;i++)begin
if(KEY[1]) //无使能
LEDR[4:0]= LEDR[4:0]+1;
end
end
end:ff_led
电路描述:带0时刻初值,因此第一次取值从D侧取值。阻塞赋值,取值位于D侧。
// Q端取值,时序逻辑
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[4:0]<='0;//异步复位
elsebegin
LEDR[4:0]<='0;
for(int i =0;i<3;i++)begin
if(KEY[1]) //无使能
LEDR[4:0]<= LEDR[4:0]+1;
end
end
end:ff_led
电路描述:非阻塞赋值,0时刻初值无效。不能写为LEDR[4:0]='0;不能在同一块内对同一变量进行不同类型的赋值。
//i=0,Q端取值,i=其他,D侧取值,时序逻辑
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[4:0]<='0;//异步复位
elsebegin
for(int i =0;i<3;i++)begin
if(KEY[1]) //带使能
LEDR[4:0]= LEDR[4:0]+1;
end
end
end:ff_led
电路描述:时序电路,每轮循环开始取Q端值,其他循环取中间态值。每个时钟进行三次加法操作。
//Q端取值,时序逻辑
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])
LEDR[4:0]<='0;//异步复位
elsebegin
for(int i =0;i<3;i++)begin
if(KEY[1]) //带使能
LEDR[4:0]<= LEDR[4:0]+1;
end
end
end:ff_led
电路描述:非阻塞赋值,在使能有效时,每个时钟进行一次加法操作。
//时序逻辑,阻塞非阻塞混用
logic[4:0] tmp;
always_ff@(posedge CLOCK_50 ornegedge KEY[0])begin:ff_led
if(!KEY[0])begin
LEDR[4:0]<='0;
end
elsebegin
tmp[4:0]=SW[4:0];
for(int i =0;i<3;i++)begin
if(KEY[1])begin
tmp[4:0]= tmp[4:0]+1;
LEDR[4:0]<= tmp;
tmp[4:0]= tmp[4:0]+3;
end
end
end
end:ff_led
电路描述:电路的输出总是随着输入进行一轮更新(不讨论for循环结束前输入改变的情况)。电路中的非阻塞赋值,不会阻塞前两次循环中的+3操作。最后一次循环,非阻塞赋值前的tmp值修改会影响非阻塞赋值结果,之后的tmp修改由于不影响输出,被优化掉。