在VERILOG语言里面,几乎每个代码中出现最多的应该是reg这个关键字,如果问reg是什么,很多初学者会很爽快的回答是寄存器,因为书本上就是这么写的。应该再想想有没有别的补充?下面我就用几个例子说明这个回答不完全正确,同时引出多种不同的reg用法:
1,reg生成寄存器:
module my_dff(
input clk,
input d,
output q,
);
reg q;
always @ (posedge clk) q<=d;
endmodule
2,起到wire的作用
module my_and(
input a,
input b,
output c,
);
reg c;
always @* c<=a&b;
endmodule
3,生成了锁存器
module my_lacth(
input d,
input e,
output q
);
always @* if(e)q=d;
endmodule
简单做做分析:
1,reg生成寄存器 flip-flop 是有条件的,就是在时钟的边缘触发赋值。
2,在电平触发进程中(一个always块 一般叫做一个进程)reg可能被综合成一根线(例子2 my_and)也可能被综合成一个LATCH锁存器,这取决于reg赋值条件是否全部被罗列出,在例子2中,赋值条件被全部罗列出,任何一个条件都对应一个reg的输出,因此只起到一个连线作用;在例子3中,赋值条件没有被全部列出,具体说在e为0的情况下没有输出明确列出,编译器认为在e==0情况下保存原来数据不变化,所以就生成的锁存器。
3,在例子2中,这种使用reg代替wire或是输出的写法很普遍,也很灵活。
4, 在例子3中,我们这里是故意生成的latch锁存器,有时候很多情况下应为条件没有罗列完整而生成了我们不需要的锁存器。如何在编程中避免生成不需要的latch呢,很简单,在电平触发进程中,有一个if 就配合上一个else,有个case 就配合上一个default.这是用一种形式保障内容的不出错。
5,在verilog中reg的生成的是什么,再次回答这个问题,我们有了更多的答案,但是更重要是理解生成时候生成什么。
6,我还总结出一种reg生成RAM块的应用,等专门做介绍。
|