这次想通过一个例子来带出一个思路,那就是实现一个同样的结果有很多种方法,我们要多花些脑筋选最安全的方法。
这次用一个pulse变长的例子吧。
相信很多人做设计的时候,会遇到说要求把一个pulse变长。
比如说一个clock长度的pulse,要变成2个,或3个,或4个,或N个clk长度。
如果要变得比较长,比如10几个或成百上千个clock,一般都会用计数器,我们这里先不讨论。
现在说最简单的,比如说1clk的pulse要变成3个clk长度吧。
看到这个要求,很多朋友就会说,超简单的,把这个pulse延迟3个or一下不就OK啦。
就象下面:
clk: __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
pul1: _______|""""""|________________
pul2: ___________|""""""|________________
pul3: _______________|""""""|________________
pulse: ______|""""""""""""""""""""|________________
verilog:
always @(negedge clk or negedge rstb)
if (~rstb) pul2 <= 0;
else pul2 <= pul1;
always @(negedge clk or negedge rstb)
if (~rstb) pul3 <= 0;
else pul3 <= pul2;
wire pulse = pul1 | pul2 | pul3;
大家是不是也是这样做的呢?这样来延长pulse,是不是真的就是方便又简洁的好做法呢?



最新回复
windzjy (2008-7-21 17:35:20)
windzjy (2008-7-21 17:40:10)
qingchuyu (2008-7-21 17:50:48)
i think this is easy for others ,
so there is no sense to exist.
i can't type Chinese now,i'm very sorry.
leolf (2008-7-21 18:09:20)
clk: __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
pul1: _______|""""""|________________
pul2: ____________|""""|________________
pul3: ________________|""""|________________
pulse: ______|"""""""|"""""|""""""|________________
因为register的反应延迟时间,所以这样产生的pulse理论上是会有glitch产生的。
所以,这种做法其实并不是最好的。
刚才有朋友也说了用计数器,不过如果2,3个clk的pulse也用计数器,就有点弄得复杂了。
其实我们同样可以使用register来延迟,但是对信号做一点小小的改变,效果就不同了。
New Verilog:
always @(negedge clk or negedge rstb)
if (~rstb) pul2 <= 0;
else if (pul1 == 1) pul2 <= 1;
always @(negedge clk or negedge rstb)
if (~rstb) pul3 <= 0;
else if (pul2 == 1) pul3 <= 1;
always @(negedge clk or negedge rstb)
if (~rstb) pul4 <= 0;
else if (pul3 == 1) pul4 <= 1;
always @(negedge clk or negedge rstb)
if (~rstb) pul5b <= 1;
else if (pul4 == 1) pul5b <= 0;
wire pulse = pul2 & pul5b;
从上面这个波形产生的pulse,理论上就会比较少一些glitch, 这里和上一个波形有一个clk的差别。
是因为我比较懒,不想打pulse的上升沿触发,大家知道大概的意思即可。波形如下。
clk: __|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|__|""|
pul1: _______|""""""|________________
pul2: ___________|"""""""""""""""""""""""""""""""""""""""
pul3: _______________|"""""""""""""""""""""""""""""""""
pul4: ___________________|"""""""""""""""""""""""""""""""""
pul5b: """""""""""""""""""""""""""""""""""|_________________
pulse: __________|"""""""""""""""""""|________________
当然,延长pulse应该还有其它方法,各位朋友可以把自己认为好的方法贡献出来给大家分享。
今天到这里,要专心干活了。
qingchuyu (2008-7-21 18:16:06)
i like you
hah
thanks for sharing these experience
hover_edacn (2008-7-21 18:20:17)
另外,对于同步设计来说,glitch不是一个严重问题。
leolf (2008-7-21 18:27:35)
QUOTE:
哪出问题了?对于glitch,没有总比有的好嘛。
leolf (2008-7-21 18:28:57)
QUOTE:
Thanks!You are obvious experience on these.
Hope can learn more from you.
hover_edacn (2008-7-21 18:31:04)
windzjy (2008-7-21 18:32:40)
pul1: _______|""""""|________________
pul2: ____________|""""|________________
pul3: ________________|""""|________________
pul4:___________________|''''''''|______________
pulse: __________|"""""""""""""'''''''''|_____________
用pul1和pul4做使能产生pulse
hymans0811 (2008-7-21 18:33:38)
leolf (2008-7-21 19:13:20)
QUOTE:
明白你的意思了。这种做法的确有一个缺点,就是没有rstb的话,只能扩展一个pulse。
如果你要第二个pulse,就做得点手脚在第二个pulse来之前rstb吧。
xishuai (2008-7-21 19:51:26)
x512775199 (2008-7-21 21:18:12)
hover_edacn (2008-7-22 10:22:08)
在同步设计中,信号的毛刺除了会增大动态功耗之外,并不会影响芯片正常工作。而且组合逻辑超过一定级数,毛刺是无法避免的。既然无法避免,索性不去考虑,按coding style的要求来设计就可以了。
wanynal (2008-7-22 11:26:41)
carsbus (2008-7-22 12:29:06)
wire pul5b;
assign pulse = pul5b;
always @(negedge clk or negedge rstb)
if (~rstb) pul2 <= 0;
else if (pul1 == 1) pul2 <= 1;
else if (pul5b == 0) pul2 <= 0;
always @(negedge clk or negedge rstb)
if (~rstb) pul3 <= 0;
else if (pul2 == 1) pul3 <= 1;
else if (pul5b == 0) pul3 <= 0;
always @(negedge clk or negedge rstb)
if (~rstb) pul4 <= 0;
else if (pul3 == 1) pul4 <= 1;
else if (pul5b == 0) pul4 <= 0;
always @(negedge clk or negedge rstb)
if (~rstb) pul5b <= 1;
else if (pul1 == 1) pul5b <= 1;
else if (pul4 == 1) pul5b <= 0;
或者:用4个dff,无毛刺。
wire pulse;
reg pul1, pul2;
reg [1:0] pul_counter;
assign pulse = pul2;
always @ (negedge clk or negedge rst_n)
if (~rst_n) pul_counter[1:0] <= 2'b00;
else if (pul1 == 1'b1) pul_counter[1:0] <= 2'b01;
else if (pul2 == 1'b1) pul_counter[1:0] <= pul_counter[1:0] + 1;
else if (pul1 == 1'b0 && pul2 == 1'b0) pul_counter[1:0] <= 2'b00;
always @ (negedge clk or negedge rst_n)
if (~rst_n) pul2 <= 1'b0;
else if (pul1 == 1'b1) pul2 <= 1'b1;
else if (pul_counter[1:0] == 2'b10) pul2 <= 1'b0;
ccj507 (2008-7-22 13:48:41)
x512775199 (2008-7-22 22:21:01)
gohigh008 (2008-7-23 15:25:25)
parameter WIDTH = 8;
parameter LONG = 22; // 1 < LONG < 256
reg [(`WIDTH-1):0] cnt;
reg pulse;
always @ (negedge clk or negedge rstb) begin
if (~rstb) begin
cnt <= {(`WIDTH){1'b0}};
end
else if (pul1==1'b1) begin
cnt <= {(`WIDTH){1'b0}};
end
else if (cnt==`LONG) begin
cnt <= cnt;
end
else begin
cnt <= cnt + 1'b1;
end
end
always @ (negedge clk or negedge rstb) begin
if (~rstb) begin
pulse <= 1'b0;
end
else if (pul1==1'b1) begin
pulse <= 1'b1;
end
else if (cnt==(`LONG-1)) begin
pulse <= 1'b0;
end
end