verilog入门经验(一)always块使用

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

verilog⼊门经验(⼀)always块使⽤
1. 信号的产⽣及always块使⽤注意事项
1.1 不要在不同的always块内为同⼀个变量赋值。

即某个信号出现在<=或=左边时,只能在⼀个always块内。

(详细解释见 Verilog HDL 与数字电路设计 P38)
所以注意,在产⽣⼀个信号时,所有产⽣该信号的条件都应放在⼀个always块内考虑。

1.2 不要在同⼀个always块内同时使⽤阻塞赋值(=)和⾮阻塞赋值(<=)。

1.3 使⽤always块描述组合逻辑时使⽤阻塞赋值(=),在使⽤always块描述时序逻辑时使⽤⾮阻塞赋值(<=)。

简单理解可以是,在电平敏感的always块内使⽤阻塞赋值,在边沿敏感的always块内使⽤⾮阻塞赋值。

1.4 任何在always块内被赋值的变量都必须是寄存器型(reg)。

即<=或=左边的信号,必须是reg型,<=或=右边的信号可以是reg型也可以是wire型。

另,端⼝声明中被声明为input或inout型的端⼝,只能被定义为线⽹型(wire);被声明为output型的端⼝,则可以被定义为线⽹型(wire)或者寄存器型(reg)。

如果不定义,则默认为线⽹型(wire)。

1.5 always的敏感列表中可以同时包括多个电平敏感事件,也可以同时包括多个边沿敏感事件,但不能同时有电平和边沿敏感事件。

另外,敏感列表中,同时包括⼀个信号的上升沿敏感事件和下降沿敏感事件也是不允许的,因为这两个事件可以合并为⼀个电平事件。

2. 总clk的使⽤
always敏感列表⾥的边沿触发事件,就是⼀个clk信号,所以在制定ucf时,边沿触发事件信号都要被定义在clk IO端⼝上,有时随意分配的clk IO端⼝在Implement时也会出错。

需要到ucf中⽤
NET "polin" CLOCK_DEDICATED_ROUTE = FALSE; //polin为边沿触发事件信号
语句来规避错误。

所以在⼀个程序中,要尽量使⽤主clk作为always块的边沿触发信号。

如果有些变量要通过某个信号的边沿触发来产⽣,那尽量将这个边沿触发信号做成⼀个判断条件,然后在产⽣变量时仍⽤主clk触发。

例程:要得到LCD⼤尺⼨屏POL信号的2分频、8分频、16分频...,在控制板上拨动开关设置不同的状态,输出polout切换到不同的pol输⼊的分频信号。

思路,定义⼀个counter(cnt_pol)对输⼊pol信号进⾏计数,则cnt_pol的bit0位与pol输⼊信号⼀致,cnt_pol的bit1位为pol信号的2分
频,bit2位为pol的4分频,bit3位为pol的8分频,bit4位为pol的16分频...
counter计数有两种⽅法,⼀种是直接使⽤pol作为边沿触发事件计数:
reg [8:0] cnt_pol;
always @ (posedge polin or negedge rst)
if(!rst) cnt_pol <= 0;
else cnt_pol <= con_pol +1;
(程序中还有⼀个主clk信号clkin作为其它信号的主时钟)
上⾯这种⽅法⽐较简单,但是polin就作为了⼀个clk信号,只能定义到FPGA的clk IO端⼝,并且实现时容易报错。

另⼀种⽅法是,采⽤主时钟信号为cnt_pol计数的边沿敏感事件:
reg [8:0] cnt_pol;
reg pold;
wire cnt_event;
always @ (posedge clkin or negedge rst)
if (!rst) pold <= 0;
else pold <= polin;
assign cnt_event = polin & pold;
always @ (posedge clkin or negedge rst)
if (!rst) cnt_pol <= 0;
else if (!cnt_event) ;
else cnt_pol <= cnt_pol +1;
这样,程序⽐较多,但整个程序(包括其它部分)只有clkin是clk信号,避免了上述问题。

相关文档
最新文档