加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[verilog]if……else的一种糟糕的用法

(2010-11-30 08:58:46)
标签:

杂谈

分类: FPGA

module test(
 aclr,
 out,
 sop,
 clk
 );

input clk,aclr;
output [4:0] out;
output sop;
reg[4:0] out;
reg sop;
reg[4:0] in;
always@(posedge clk or posedge aclr)
begin
 if(aclr)
 begin
  in <=5'd0;
  out<=5'd0;
  sop<=1'b0;
 end
 else begin
  //
//  if(in==5'd31)
//   in<=5'd0;
//  else
//   in<=in+5'd1;
  //
  if(in==5'd0)
  begin
   in<=in+5'd1;
   sop<=1'b0;
   out<=5'd25;
  end
  else if(in==5'd1)
  begin
   in<=in+5'd1;
   sop<=1'b0;
   out<=5'd24;
  end
  else if(in==5'd5)
  begin
   in<=in+5'd1;
   sop<=1'b0;
   out<=5'd23;
  end
  else if(in==5'd30)
  begin
   in<=in+5'd1;
   sop<=1'b1;
   out<=5'd23;
  end
  else if(in==5'd31)
  begin
   in<=5'd0;
   sop<=1'b0;
   out<=5'd23;
  end
  else
  begin
   sop<=1'b0;
  end
 end
end
endmodule

以上的代码功能很简单:当aclr为高时,对电路异步复位;当aclr为低时,5位寄存器in开始+1计数;当计数器计到特定的值时,对out进行赋值;当计数器为特定的值时对sop信号赋值;

在quartus中综合出电路中,sop和in还有out寄存器前面各有5个串联的多路选择器,对应这几个if……else语句,可见这个if……else若用得不好,是多么费逻辑资源。

    对以上电路进行分析,容易发现,只有当in==30时,sop赋1,对于其它in值,sop赋0,所以对于sop只用一个if else就足够了

    同理in==31时  in<=in+5'd1 对于其它in值,in<=in+5'd1,所以只用一个if……else就行了。

    基于以上考虑,对电路作了改进:

module ddd(
 aclr,
 out,
 sop,
 clk
 );

input clk,aclr;
output [4:0] out;
output sop;
reg[4:0] out;
reg sop;
reg[4:0] in;
always@(posedge clk)
begin
 if(aclr)
 begin
  in <=5'd0;
  out<=5'd0;
  sop<=1'b0;
 end
 else begin
  
  if(in==5'd31)
   in<=5'd0;
  else
   in<=in+5'd1;
  //
  if(in==5'd30)
   sop<=1'b1;
  else
   sop<=1'b0;
  if(in==5'd0)
  begin
   out<=5'd25;
  end
  else if(in==5'd1)
  begin
   out<=5'd24;
  end
  else if(in==5'd5)
  begin
   out<=5'd23;
  end
  else if(in==5'd30)
  begin
   out<=5'd23;
  end
  else if(in==5'd31)
  begin
   out<=5'd23;
  end
 end
end
endmodule

这样的写法确实可以节省逻辑资源,并减少sop和in的输入信号的延时。

但时out前面仍然有多个串联的选择器,故想到用case语句对out赋值

本想这样用

reg[4:0] out_tem;

always@(in)

case(in)

5'd0:……

5'd1:……

……

5'd31:……

default:

out_tem=out_tem;

endcase

 

always@(posedge clk or posedge aclr)

begin

   if(aclr)

      out<=5'd0;

   else

      out<=out_tem;

end

 

但发现这样的case语句综合出来的out_tem为触发器,按理说这样的思路是没有错的啊,因为in的每一种情况我都对out_tem赋了值,把out_tem作为多路选择器的一路输入信号再反回out_tem为什么不行呢?这里有点搞不懂了。于是只好换了另一种办法,用casex语句把所有的情况都一一列出:

module ddd(
 aclr,
 out,
 sop,
 clk
 );

input clk,aclr;
output [4:0] out;
output sop;
reg[4:0] out;
reg sop;
reg[4:0] in;
reg[4:0] out_tem;
always@(in)
casex(in)
 5'b00000:out_tem=5'd25;
 5'b00001,
 5'b0001x,
 5'b00100:out_tem=5'd24;
 5'b00101,
 5'b0011x,
 5'b01xxx,
 5'b10xxx,
 5'b110xx,
 5'b1110x:out_tem=5'd23;
 5'b11110:out_tem=5'd20;
 5'b11111:out_tem=5'd21;
endcase
always@(posedge clk or posedge aclr)
begin
 if(aclr)
 begin
  in <=5'd0;
  out<=5'd0;
  sop<=1'b0;
 end
 else begin
  out<=out_tem;
  
  if(in==5'd31)
   in<=5'd0;
  else
   in<=in+5'd1;
  //
  if(in==5'd30)
   sop<=1'b1;
  else
   sop<=1'b0;
 end
end
endmodule

经过这样的处理后,基本上消除了那种信号经过很多个选择器串连后为寄存器提供输入的情况。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有