Verilog代码优化技巧

Verilog代码优化技巧:


1. 条件b为TRUE时,将c赋值给a;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b)
		a <= c;
	else
  		a <= a;

🎿时序逻辑里,后面的else如果不写的话,综合时会自动插入门控时钟。也就是说,只有满足if和else if里的条件,时钟fclk才有效,否则fclk无效,寄存器不翻转,从而达到节省功耗的目的;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b)
		a <= c;

2. 条件b为TRUE时, 若c为TURE将d赋值给a,否则将a赋值给a。

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b)
		a <= c ? d : a;

👾其实b, c均为TRUE时,a才翻转,因此完全可以写成

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b & c)
		a <= d;

3. b为true时,将a1+a2赋值给a,否则若c为true,则将a3+a4赋值给a;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b)
		a <= a1 + a2;
	else if(c)
		a <= a3 + a4;

💎直接这样写会综合出两个加法器,但实际上b和c两个分支不可能同时运行,因此只需要一个加法器即可:

assign a_tmp0 = b ? a1 : a3;
assign a_tmp1 = b ? a2 : a4;
assign a_tmp = a_tmp0 + a_tmp1;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b | c)
		a <= a_tmp;

4. 设存在2bit寄存器cnt, 和4bit寄存器a, 当输入b_vld为1时,将1bit数据b写进cnt对应的a的位置; 例如cnt为2‘b11, 则a[3] <= b;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b_vld)
		case(cnt)
			'd0: a[0] <= b;
			'd1: a[1] <= b;
			'd2: a[2] <= b;;
			default : a[3] <= b;
		endcase

🏆这样写有个缺点是,如果cnt和a的位宽很大,那case就会写的非常的长;每次只会更新cnt对应的位宽,那我们可以设一个wire变量a_tmp,当cnt==i时,将对应的a_tmp[i]赋值为b,否则和a[i]一样; b_vld有效时,将a_tmp赋值给a;

genvar  i;
generate 
for (i = 0 ; i < 4 ; i++)
	begin:  a_value
		assign a_tmp[i] = cnt==i ? b ? a[i];
	end
endgenerate

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a <= 0;
	else if(b_vld)
 		a <= a_tmp;

5. 多个1bit信号的翻转

always@(posedge fclk or negedge frstn)
	if(!frstn)
		a_1d <= 0;
	else if(vld)
 		a_1d <= a;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		b_1d <= 0;
	else if(vld)
 		b_1d <= b;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		c_1d <= 0;
	else if(vld)
 		c_1d <= c;

always@(posedge fclk or negedge frstn)
	if(!frstn)
		d_1d <= 0;
	else if(vld)
 		d_1d <= d;

🎯一般来说,4bit以下的寄存器,即使没有以else结尾,综合工具也不会自动插入门控时钟。因为插入门控时钟需要额外的电路,为了4bit以下的寄存器做门控时钟,节省的功耗和需要增加的,面积相比,不划算。

always@(posedge fclk or negedge frstn)
	if(!frstn)
	begin
		a_1d <= 0;
		b_1d <= 0;
		c_1d <= 0;
		d_1d <= 0;
	end
	else if(vld)
	begin
		a_1d <= a;
		b_1d <= b;
		c_1d <= c;
		d_1d <= d;
	end

🎮如上段代码所示,这样的话,综合工具就会将a_1d,b_1d,c_1d和d_1d,看成一个大的寄存器去处理,就会插入门控时钟了;但需要注意的是,a_1d,b_1d,c_1d和d_1d,的翻转条件必须是一样的,否则不会看成一个整体去插入时钟,比如:

always@(posedge fclk or negedge frstn)
	if(!frstn)
	begin
		a_1d <= 0;
		b_1d <= 0;
		c_1d <= 0;
		d_1d <= 0;
	end
	else if(vld0)
	begin
	a_1d <= a;
	b_1d <= b;
	c_1d <= c;
     d_1d <=d;
	end
	else if(vld1)
	begin
	a_1d <= a;
	end

🌂a_1d的翻转条件是vld0 | vld1, 而其他寄存器是vld0,翻转条件不一样,综合时会将b_1d,c_1d和d_1d看成一个寄存器,将a_1d作为一个单独寄存器,去进行综合优化。


6. 总结

verilog设计里,主要思路就是两点:

  • 🎩1. 寄存器能不翻转就不翻转,寄存器的时钟能关掉就关掉:减小翻转功耗;
  • 👑2. 运算单元和寄存器,能复用就复用:减小芯片面积;
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值