verilog算法小结(一)

1、RTL中基本上不用for语句,它会被综合器展开为所有变量情况的执行语句,每个变量独立占用寄存器资源,造成资源浪费。

   For语句大多数用在testbeach中。

   能复用的的处理模块尽量复用,即使所有操作都不能复用,也要用case语句展开处理。

2、if—else if—else 应该避免使用,因为它综合出来会产生“优先级”,消耗资源。

   if—if  、case是平行结构的,不产生“优先级”。

   尽量使用 case 和 if—if 。

3、系统上复用模块节省的面积远比代码上优化来的实惠的多。

4、使用FPGA,还是CPLD:

   FPGA 触发器资源丰富;——时序逻辑设计

   CPLD 组合逻辑资源丰富。——组合逻辑设计

5、只采用同步时序电路,不采用异步时序电路。

扫描二维码关注公众号,回复: 1483573 查看本文章

6、延时:

   同步时序电路的延时最常用的设计方法是用分频或倍频的时钟或者同步计数器完成所需要的延时。

   对于比较大的和特殊定时要求的延时,一般用高速时钟产生一个计算器;

   对于比较小的延时,可以用一个D触发器打一下。

   # n 一般只用在testbeach,在电路综合时会被忽略,所以不用。

 

常用代码总结:

 

D触发器:

always @(posedge clk or negedge rst)

       if(rst == 0)

              dout <= 0;

       else dout <= din;

 

应用:1、由于是在clk上升沿才打入,所以可以消除din存在的毛刺。

      2、延时

 

Gray码计数器:

000-001-011-010-110-100-101-111

module gray_cnt(

//input

clk,

rst

//output

gray_cnt_out);

input     clk;

input     rst;

output [4:0]gray_cnt_out;

reg   [4:0]gray_cnt_out;

reg   [4:0]cnt;

reg   [4:0]gray_cnt_temp;

integer    i;

 

always @(posedge clk or negedge rst)

begin

       if (rst ==0)

              cnt <=0;

       else

              cnt <= cnt+1;

end

 

always @(cnt)              //二进制 转 gray

begin

       gray_cnt_temp[4:0] = cnt[4:0];

       for(i=0;i<=4;i++)

              gray_cnt_temp[i-1] = cnt[i-1]^cnt[i];

end

 

always @(posedge clk or negedge rst)

begin

       if (rst=0)

              gray_cnt_out <= 0;

       else

              gray_cnt_out <= gray_cnt_temp;

end

endmodule

 

应用:时钟域设计中,计数器值由时钟域a传到时钟域b采用gray码。因为它每次只变一位,消除毛刺。

 

 

时钟始能:

作用:基于clk建立clk_en信号做为时钟始能输入,能有效改变整个FF的时钟,从而使系统存在多个时钟。(不需要PLL分频)

避免了亚稳态发生,提高设计可靠性

 

状态机模块:

应该采用三段式法:

三段法好处:可读性好;利于软件综合优化;滤除毛刺。

always @(posedge clk or negedge rst)              //下一个状态 赋给 当前状态

begin

       if(rst == 0)

              current_state = 0;

       else

              current_state = next_state;

end

 

always @(in or current_state)                   //根据输入和当前状态定义下一个状态

begin

       case(current_state)

              S0:

                     if (in ==1)

                            next_state = S1;

                     else

                            next_state = S0;

              S1:

                     next_state = S2;

              S2:

                     next_state = S3;

              S3:

                     next_state =S0;

              default:

                     next_state = S0;

endcase

end

 

always @(posedge clk or nengedge rst)               //定义输出

begin

       if (rst ==0)

              out <= 0;

       else if (next_state == S3)

              out <= !in;

       else

              out <= 0;

end

endmodule

 

 

状态机的三种编码:

1、  二进制——浪费资源,容易产生毛刺

2、  gray编码——顺利跳变时不产生毛刺

3、  one-hot编码——“一个萝卜一个坑”,只需要用一位参与编码。

one-hot分2种:index编码和非index编码

       index:  state = 0;1;2;3;4;5;6;7;8………..

 非index:  state = 000001;000010;000100;001000;010000;100000;……..

 

采用index编码,它综合出来的LE少,Fmax最大。

 

 

 

B  = ~A+1;              //补码运算

 

 

 

速度与面积平衡:

一个算法要多次调用几个相同或类似的函数或模块;

考虑速度,忽略面积:写多个函数,分别调用对应的函数。——函数多,面积大;多个函数可以同时运算,速度快。

 

考虑面积,忽略速度:尽量写成一个函数,只调用这个函数。——函数少,面积小;每次只能运行一个函数,速度慢。

 

面积换速度:

可以采用复制面积的方法,来提高速度。

猜你喜欢

转载自blog.csdn.net/kebu12345678/article/details/80567751