xyzabc 发表于 2016-3-22 11:56:46

请教: 输入信号为什么必须要时钟同步?


module test1 ( input        nRST,
             input        clk,
             input        Ctrl,

             output        Pulse,
             output   led );
                                       

reg   cnt;
reg   state;

/*---------------------------------*/
//reg CTRL;       
                               
//always @( posedge clk )
//        CTRL <= Ctrl;


/*---------------------------------*/
always @( posedge clk )
begin
if(!nRST )
   begin
   cnt <= 4'd0;
   state <= 2'd0;
   end
else
    case(state)
        0:
             if(Ctrl)        state <= 2'd1;        //这里用CTRL没有问题
                       
        1:               
             if(cnt==0)
                cnt <= cnt+4'd1;
             else
                begin
                cnt <= 4'd0;
                state <= 2'd2;
                      end
        2:
             if(cnt==0)
                cnt <= cnt+4'd1;
             else
                begin
                cnt <= 4'd0;
                state <= 2'd0;
                end
                               
        default:
             state <= 2'd0;

        endcase
end

assign    Pulse = ( state==2'd2);

assign    led = ~Ctrl;
assign    led = ~Pulse;
assign    led = 2'b11;

endmodule


上面代码用Ctrl控制产生脉冲,实际下载到板子不能工作,复位后如果Ctrl为高,可以输出脉冲,但只要切换Ctrl后,就再也不输出脉冲了。如果用时钟同步的CTRL(注释部分),则工作正常,不明白为什么?



wx85105157 发表于 2016-3-22 14:20:40

两次编译出来消耗的资源是一样的么?有可能被优化掉了。

WM_CH 发表于 2016-3-22 18:14:02

这个就是亚稳态问题了吧亲。
外部来的信号,必须经过两次D触发器进行时钟同步之后,才能当作内部信号来用。
第一次经过D触发器时假如外部信号被采集为亚稳态信号(外部信号的电压 被采集为处于逻辑电平0和1之间,称为亚稳态),则输出是“不定态”,但是这个不定态是可以被当作“逻辑电平0和1”使用的。
就是第一个D触发器输出结果非0即1。
第二次经过D触发器,只是为了防止经过第一次D触发器之后,电平仍是“亚稳态”的这种意外情况。说白了第二个D触发器,只是为了防止意外,保险起见。

其实你可以理解,经过第一个D触发器是在把外部信号同步到内部。
还可以理解为 为了增强外部信号的驱动能力。

最主要的,是防止亚稳态情况出现。
涉及到外部信号输入时,一定要注意亚稳态情况!!

串口、SPI、IIC等等接收的信号,都是外部信号。。。
不知道说的对不对。。。互相交流





ziruo2002ab 发表于 2016-3-22 20:54:11

被编译器编译成什么东东了?
我觉得这个程序比较简单,可以到RTL层直接分析硬件实现
分析到底哪里出了问题

xyzabc 发表于 2016-3-22 21:00:44

ziruo2002ab 发表于 2016-3-22 20:54
被编译器编译成什么东东了?
我觉得这个程序比较简单,可以到RTL层直接分析硬件实现
分析到底哪里出了问题 ...

其实编译没什么问题,比较了下,用同步过的外部信号仅仅只是多了个D触发器。而且我用仿真2个都是没问题的,后来想了下,仿真的时候用的是同一个时钟,所以外部信号实际上是同步的,也就是不能说明问题

agilityChen 发表于 2016-3-22 22:39:08

状态机你也敢用异步信号来推!!一个亚稳态就不知道进到哪个状态里死掉了。

735953120@qq.co 发表于 2016-3-22 23:16:47

WM_CH 发表于 2016-3-22 18:14
这个就是亚稳态问题了吧亲。
外部来的信号,必须经过两次D触发器进行时钟同步之后,才能当作内部信号来用。 ...

说的很在理一般情况用两个寄存器来将输入数据存储起来,这样使用的数据亚稳态几率小很多;你说的这个可以理解成用同步寄存器链来消除亚稳态问题

jm2011 发表于 2016-3-23 11:09:58

本帖最后由 jm2011 于 2016-3-23 11:23 编辑

我的看法:
1: 当你将Ctrl拉低,状态机一直在case 0,结果本来就是这样的,不知道你说的不再输出脉冲是什么意思,(是不是先拉低再拉高,这个时候依然不能输出脉冲?);当然在实际的使用上应该把异步信号打上两拍是最好的;
2:要是我做的话,我会将cnt抽出来,形成一个单独的always来做;不知道我这样想的对不对,有一个单独的计数器,输出一个信号到一个状态机,这个状态机会根据这个计数器的信号来判断自己的 状态;我觉的这样更像一个硬件结构,如下图所示:

对于第二点,需要得到大家的意见,相互学习,相互提高:)

far_infrared 发表于 2016-3-23 11:22:16

jm2011 发表于 2016-3-23 11:09
我的看法:
1: 当你将Ctrl拉低,状态机一直在case 0,结果本来就是这样的,不知道你说的不再输出脉冲是什 ...

一般来说,写状态机要控制流和数据流分开,就是说状态跳转时就不要给数据流赋值,数据流根据状态在另外一个always中,这样写清晰。

jm2011 发表于 2016-3-23 11:25:35

far_infrared 发表于 2016-3-23 11:22
一般来说,写状态机要控制流和数据流分开,就是说状态跳转时就不要给数据流赋值,数据流根据状态在另外一 ...

控制流的产生一个always,数据流的产生一个always,状态转移一个always;这个是不是就是所谓的三段式的写法?

far_infrared 发表于 2016-3-23 11:36:34

jm2011 发表于 2016-3-23 11:25
控制流的产生一个always,数据流的产生一个always,状态转移一个always;这个是不是就是所谓的三段式的写 ...

对,我比较喜欢这样用,看着简洁,调试也方便。

jm2011 发表于 2016-3-23 11:37:34

far_infrared 发表于 2016-3-23 11:36
对,我比较喜欢这样用,看着简洁,调试也方便。

这次真的是学习了{:handshake:} ,让你这样一说,我也清晰了好多;

以前一直不知道为什么要三段式的;

McuPlayer 发表于 2016-3-23 11:40:06

跨时钟域的问题,这是很常见的

xyzabc 发表于 2016-3-23 15:08:41

far_infrared 发表于 2016-3-23 11:22
一般来说,写状态机要控制流和数据流分开,就是说状态跳转时就不要给数据流赋值,数据流根据状态在另外一 ...

谢谢,受益匪浅

xyzabc 发表于 2016-3-23 15:09:50

jm2011 发表于 2016-3-23 11:09
我的看法:
1: 当你将Ctrl拉低,状态机一直在case 0,结果本来就是这样的,不知道你说的不再输出脉冲是什 ...

先拉低再拉高,这个时候依然不能输出脉冲。谢谢,受益匪浅

jm2011 发表于 2016-3-23 22:50:06

xyzabc 发表于 2016-3-23 15:09
先拉低再拉高,这个时候依然不能输出脉冲。谢谢,受益匪浅

明天去单位跑一下板子去,抓一下波形看看 。。。。

感觉这个问题很奇怪。

jm2011 发表于 2016-3-24 09:43:08

本帖最后由 jm2011 于 2016-3-24 09:46 编辑

在DE0-NANO的板子上实测了一下,没有发现楼主说的问题,Crtl来回的切换都能看见LED的闪烁;

我的时钟比较高,只修改了计数器的范围,其它的和楼主的一样;个人认为这个简单的电路,对Ctrl打不打一排不会影响状态机的运行;

我现在主要不理解的是,1:如果Ctrl第一次是亚稳态的时候状态机会跑到那里去,2:如果Ctrl从亚稳态恢复到稳态,这个状态机还能不能继续跑下去?

javascript:;

xyzabc 发表于 2016-3-24 11:43:31

jm2011 发表于 2016-3-24 09:43
在DE0-NANO的板子上实测了一下,没有发现楼主说的问题,Crtl来回的切换都能看见LED的闪烁;

我的时钟比较 ...


谢谢你的热心,我用的芯片是EPM240,之前试过很多次,刚才又试了下,确实不行。但按照你说的将cnt独立出来改成下面的代码,确实可以


module   test( inputnRST,
                     inputclk,
                     inputCtrl,

                     outputPulse,
                     outputled );
               
reg cnt;
reg state;
reg cntRst;

wire cntEnd;

/*------------------------------------*/
always @( posedge clk )
begin
if( !nRST || cntRst )
    cnt <= 25'd0;
else
    cnt <= cnt+25'd1;
end
       

/*------------------------------------*/
always @( state )
begin
    case(state)
          0,2:
                  cntRst = 1;
          1,3:
                  cntRst = 0;
    endcase
end


/*------------------------------------*/
always @( posedge clk )
begin
if(!nRST )
    state <= 2'd0;
else
    case(state)
         0:
            if(Ctrl)    state <= 2'd1;
          1:               
             if(cntEnd)    state <= 2'd2;
          2:               
             state <= 2'd3;
         3:
            if(cntEnd)    state <= 2'd0;
    endcase
end

assign cntEnd = cnt;
assign Pulse = ( state==1'b1);

assign led = ~Ctrl;
assign led = ~Pulse;
assign led = 2'b11;


endmodule
页: [1]
查看完整版本: 请教: 输入信号为什么必须要时钟同步?