verilog笔记-避免产生锁存器、延迟参照时间、循环语句

夏老师的书

case语句中需要注意的点:
casez
用来处理不考虑高阻值Z的比较过程

reg [7:0] ir;
casez(ir)
	8`b1???????:instruction1(ir);
	8`b01??????:instruction2(ir);
	8`b00010???:instruction3(ir);
	8`b000001??:instruction4(ir);
endcase

casex
用来处理不考虑高阻值Z与不定值的比较过程

reg [7:0] ir;
casez(ir)
	8`b1???????:instruction1(ir);
	8`b01??????:instruction2(ir);
	8`b00010???:instruction3(ir);
	8`b000001??:instruction4(ir);
endcase

2.操作不当生成锁存器
在always块中,如果在给定的条件下变量没有赋值,这个变量将会保持原值,也就是说将生成一个锁存器。

///有锁存器
always @(al or d)
	begin
		if(al) q = d;
	end

///无锁存器
always @(al or d)
	begin
		if(al) q = d;
		else q = 0;
	end

case语句中如果没有default语句,则除特殊值以外,其他值都会保持原值,便生成了锁存器。

///有锁存器
always @(sel [1:0] or a or b)
case(sel[1:0])
	2`b00:q<=a;
	2`b01 :q<=b;
endcase

///无锁存器
always @(sel [1:0] or a or b)
case(sel[1:0])
	2`b00:q<=a;
	2`b01 :q<=b;
	default:q<= `b0;
endcase	

3.循环语句
forever语句:常用于产生周期性的波形,用来作为仿真测试信号。与always的区别在于不能单独写在语句中,必须卸载initial块中。
repeat语句:通常是常量表达式。

//使用repeat语句实现乘法器
parameter  size = 8,longsize = 16;
ref [size:1]  opa,opb;
rge[longsize:1] result;

begin:mult
	reg [longsize:1] shift)opa,shift_opb;
	shift_opa = opa;
	shift_opb = opb;
	result = 0;
	repeat(size)
	begin
	if(shift_opb[1])
		result = result + shift_opa;

	shift_opa = shift_opa <<1;
	shift_opb = shift_opb >>1;
	end
end

4.顺序块与并行块
顺序块中的语句是一条接一条按顺序执行的,只有之前的语句执行结束才能执行后面的语句(除了带内嵌延迟控制的非阻塞赋值语句);延迟是相对上一条语句执行完成的仿真时间的。

并行块(fork-join)语句并行执行,执行顺序是由各自语句内延迟或者时间控制决定的;语句的延迟是相对于块语句开始执行的时刻而言的。

//带延迟的顺序块
reg x,y;
reg[1:0] z,w;

initial
begin
	x = 1`b0;
	#5 y = 1`b1;
	#10 z = {
    
    x,y};
	#20 w = {
    
    y,x};
end

//并行块
reg x,y;
reg[1:0] z,w;

initial
fork
	x = 1`b0;
	#5 y = 1`b1;
	#10 z = {
    
    x,y};
	#20 w = {
    
    y,x};
join

注意竞争-冒险现象。

猜你喜欢

转载自blog.csdn.net/Wangwenshuaicsdn/article/details/130145949
今日推荐