fantastic88 发表于 2012-3-29 17:41:46

请教一个 关于延时输出的问题

我想写个死区控制的模块,不看语法,输出pwm=flag?0:pwm11;flag是死区控制标志(同时也是计数器控制标志),in的上升沿输出一段时间的0,其他情况,输出都跟着输入走;
我的程序如下:
module suqu(rst,clk,pwm11,pwm1);
`define DEADTIME 100;
input rst,clk,pwm11;
output pwm;
wire pwm11;
reg pwm,flag; //flag死区标志位,=1则死区开通,计数器开始计数
reg cnt;
always@(posedge clk or posedge rst)
if (rst)
pwm1<=0;
else
begin
if(!flag)
pwm<=pwm11;
else
pwm<=0;
end

always @(posedge clk or posedge rst)
if(rst)
cnt<=0;
else
begin
if(flag)
cnt<=cnt+1;
if(cnt==`DEADTIME+1)
cnt<=0;
end

always @ (posedge pwm11)
if(cnt==`DEADTIME)
flag<=0;
else
flag<=1;
endmodule

语法是没问题的,但是输出几乎都是0,原因我也是知道的,因为最后一个 always @ (posedge pwm11),pwm11上升沿时检测到了,flag变成了0,可是计数时间到了,却没办法清零flag。flag 又不能在不能的always语句中,求大神指点迷津啊!
本来我写了个死区控制很简单就是
always @ (posedge pwm11)
for(i=0;i<`DEADTIME;i=i+1)
@(posedge clk)
用来延迟,但是这个可能不能综合

fantastic88 发表于 2012-3-29 21:13:01

本帖最后由 fantastic88 于 2012-3-29 23:00 编辑

我改了一下 看似是对的,但是还是有问题
module suqu(rst,clk,pwm11,pwm1,flag,tt);
`define DEADTIME 2
input rst,clk,pwm11;
output pwm1,flag,tt;
wire pwm11;
reg pwm1,flag,tt; //flag死区标志位,=1则死区开通,计数器开始计数,tt为计数器溢出信号
reg cnt;
always@(posedge clk or posedge rst)
if (rst)
pwm1<=0;
else
begin
if(!flag)
pwm1<=pwm11;
else
pwm1<=0;
end
always @(posedge clk or posedge rst)
if(rst)
        begin
        cnt<=0;
        tt<=0;
        //flag<=0;
        end
else
begin
        if(flag)
                begin
                if(cnt<`DEADTIME)
                        begin
                        tt<=0;
                        cnt<=cnt+1;
                        end
                else if(cnt==`DEADTIME)
                        begin
                        cnt<=0;
                        tt<=1;
                        end
                               else
                                     tt<=0;
                end
       
end

always @ (posedge pwm11 or posedge tt)
if(tt)
flag<=0;
else if(pwm11)
flag<=1;
endmodule
就第一下好一点 ,后面flag都是0估计是《= 和= 之间这种问题吧,一个状态没过去就到下一个状态了,求解!

fantastic88 发表于 2012-4-1 10:52:28

:dizzy:...........

jahero 发表于 2012-4-1 19:55:23

是不是这个问题 当tt驱动flag时 flag变0了 然后flag又驱动tt 但flag驱动信号的模块却只有一半

tao2000 发表于 2012-4-3 13:08:18

首先不要这样检测pwm11 的上升沿,楼主这样检测上升沿,相当于把pwm11当时钟用了。
使用如下的同步电路检测上升沿
always@(posedge clk) pwm11_r<=pwm11;
always@(posedge clk) pwm11_posedge<=(~pwm11_r) && pwm11;
这样当pwm11从0变为1时,pwm11_posedge就可以产生一个clk时钟宽度的脉冲。根据这个脉冲设计一个状态机就可以完成延时的工作了。

fantastic88 发表于 2012-4-4 16:34:37

回复 5# tao2000


    哦哦,你这样的方法的话,pwm11_posedge是不是比 PWM11 慢一个周期呢? 我这样的方法不行,非要用状态机啊?
我也写过这样的:
    always@(posedge clk orposedge rst)
if(rst)
temp<=0;
else
begin
temp<=pwm_in; //存入当前PWM值
temp<=temp;//记录前一个PWM值
end

always@(posedge clk) //存在这个问题:flag比temp慢一个周期,没有同步跟住PWM
case (temp)
01: flag<=1;
11: begin
       if(tt)
       flag<=0;
       else
       flag<=1;
       end
default: flag<=0;
endcase

tao2000 发表于 2012-4-6 19:16:23

看来我没有说明白,首先为什么不能这样检测上升沿?像这样检测上升沿的结果是,在最开始因为tt复位,flag为0,但是当pwm11第一次上升沿过后,flag就永远是1。因为你使用时钟上升沿来检测时钟本身。下面是综合后的RTL电路,可以看到寄存器的D端是1。

即使这样可以正确的判断pwm11的上升沿,产生符合要求的flag,后续电路还有问题。Flag从pwm11时钟域进入了clk时钟域,有发生亚稳态的危险。
至于使用同步方法检测上升沿,滞后一个时钟周期,你可以在后面的延迟中少延迟1个时钟周期。当然这样死区至少都是1个时钟周期了。这个就要看你的实际要求了。
最后提一句,只要涉及到时序电路,广义上都可以理解为状态机。

fantastic88 发表于 2012-4-7 16:21:58

回复 7# tao2000


   对的,我一开始也是遇到flag只能是1变不回来,所以我加了tt,是计数器满了清零信号。所以我觉得您说的第一个问题可以解决。至于你说的亚稳态什么我还不太懂,不过我会换个方法的,不用pwm11做时钟,非常感谢!能否加个qq 296515749,我现在还很迷茫,不过我不会很烦的~

fantastic88 发表于 2012-4-7 20:28:40

回复 8# fantastic88


    哎,用那个方法 DEADTIME 至少为2个CLK ,flag_posedge延迟一个周期, 我在要根据它弄一个flag_cnt 来控制 计数器 延迟一个周期。计数完成关掉又延迟一个周期,不过最后pwm11从高变低又延迟一个周期,相当于整个波形往后走了一个clk,这到没事。。。
   不能同步吗,慢一拍的总感觉别扭啊,,,,
页: [1]
查看完整版本: 请教一个 关于延时输出的问题