原创 逻辑分析仪设计总结

2009-8-21 22:27 2266 7 13 分类: 测试测量


作品的图片:http://blog.ednchina.com/opencv2008/37005/gallery.aspx


文章下载pdf



 



 //参考混乱的笔记《logic_analyse分析笔记》



 一、界面以及FPGA的模块



 知道逻辑分析仪基本运行是如何操作的很重要,关系着内部的控制结构



1)逻辑分析仪界面



     1.操作



     1)单次触发



     2)连续触发



     3)停止



     2.触发设置



       触发深度(只显示)



       触发电平



       触发条件



       触发位置



       采样方式



       采样时钟



2  信号源界面



       输出频率



       输出幅度



3  状态显示



       触发位置



       光标移动以及测量



       放大缩小



4)内部模块



     1. 触发模块:



     2. 时钟模块:



     3. 数据采集模块:



     4. 与单片机的接口: 



     5. 信号源模块



 二、设计



 1.内部运行的过程



    FIFO的数据设置可以复位的情况下进行设置,系统复位结束以后,FIFO处于空状态,fifo的满信号作为triger模块的控制信号



    ,只有fifo存贮满了以后才能够触发,这样做是为了方便对触发位置进行控制,但是这样也带来了一个问题,就是FPGA



    FIFO满的时候输入的数据状态不确定,如果刚好满足触发条件,就会产生触发,那么在后面看到的触发位置就会很混乱,



    虽然也可以说是触发条件满足。这个问题是在后面的触发模块里面首先检测一个边沿以后再去使能触发功能(主要是字触发和



    脉宽触发)。触发信号发出以后,触发信号一直有效,作为控制触发位置计数器的使能,计数器在达到预设的触发位置值以后



    ,给单片机发出触发结束信号,并且停止FIFO采集数据(作为其使能信号)。



   



    然后单片机可以对数据采集处理,下一次的采集之前通过复位使里面的状态复位,就可以按照设定的参数采集数据



  



2.触发位置控制



  触发位置的控制是由触发位置计数器控制的,该计数器的使能由触发信号控制,触发信号有效后,计数器开始工作,在达到预设的



  数值之后停止计数。发出采集结束信号



 



  由于触发位置的数据和实际的触发信号发出以及从采集结束信号到fifo停止采集的时钟延时,所以在计算的时候需要对偏差的



  时钟作调整



 



  3.触发设计



  首先外部信号相对于内部的时钟是一个异步的信号,做同步处理是很重要的,能够很好的避免毛刺(错误的)的出现。



  但是触发信号引入的时钟偏于需要在单片机处理的时候做一下校正



 1
边沿触发的时候不是使用外部信号的上升沿,而是使用首先利用2D触发器,通过检测触发器输出的信号来判断边沿的情况



      这种方法,即把时钟同步带FPGA的时钟域,也很好的进行边沿的检测,不够要注意一个问题,就是竞争想象



      ,如果D触发器的数据输出在上升沿,数据的检测也在上升沿就会出现触发位置的偶然偏差,如果检测放在下降沿就会很好的避免



      这种情况



     
///////////////////////////////////////////////////////



      //边沿检测代码



     
always@(posedge clk or negedge rst)



      begin



       if(!rst)



          begin



             d_0<=1'bx;



             d_1<=1'bx;



          end



        else



          begin



             d_0 <= data_in;



             d_1 <= d_0;



          end



        end



        //边沿的判断



       
always@(negedge clk or negedge rst)// competition if detect in posdege
注意竞争现象



        begin



         
if(!rst)



              trigger <= 1'b0;



          else



          begin



            
if(d_1==1'b0 && d_0==1'b1)



                
trigger<=1'b1;



          end



        end



   
//////////////////////////////////////////////////////////////////////////



  2
电平的触发和边沿触发相似,只是在第二个always触发条件成立的条件改一下就可以了



  3)字触发



       单级的字触发很简单,但是设计中引入的fifo满的时候不确定问题会使触发位置有10%的概率出现的位置不是在边沿



       为了解决这个问题,在设计的时候使用边沿的检测手段只不过触发器和比较器变成8



      
//////////////////////////////////////////////////////////////////////////////



       always @(
posedge clk or negedge rst)



        begin



        if(!rst)



        begin



            d_0 <= 8'bxxxxxxxx;



            d_1 <= 8'bxxxxxxxx;



        end



        else



        begin



            d_0 <= data_in;



            d_1 <= d_0;



        end



        end



       



       
always@(negedge clk or negedge rst)



        begin



         
if(!rst)



           
begin 



                 trigger <= 1'b0;



             end



          else
if((d_0  ==  trigger_word) && (d_1 !=
trigger_word)) //2
次的数据不一样,才能够触发



                     trigger <= 1'b1;



        end



      
//////////////////////////////////////////////////////////////////////////////



       多级的字触发必须借助状态机来实现,通过状态之间的转换来实现,这里fifo引进的不确定问题对触发没有影响



  4)脉宽触发



       以高电平大于等于为例:信号首先经过系统时钟的一个同步,然后控制计数器的工作状态,在数据是低电平的时候,计数器内部的复位



       信号有效,计数器处于0的状态;在data有效后,首先会将计数器恢复能够工作的状态,然后开始计数,如果



       中间的计数值大于设定值,那么触发信号有效,计数器清零位有效,直到复位信号



       鉴于FIFO满信号的时候输入数据的不确定,首先检测数据流中的边沿,然后才使能该模块,避免不确定带来的



       触发不稳定  



       数据进入后先经过一个时钟同步,然后第二个时钟使内部计数器的清零信号无效,在计数器的值达到要求之后



       下一个时钟使触发控制信号有效,接着的一个时钟使触发信号有    ,所以会有四个时钟的偏移



      



       其他的脉宽触发的原理是一样的,只不过在判断的条件上做了修改而已



      
/////////////////////////////////////////////////////////////////////////////////////



       //高脉冲大于等于的代码



       //信号同步到系统时钟



        always @
( posedge clk or negedge rst)



        begin



           
if(!rst)



               
data <= 1'b0;



            else



           
begin



               
if(valid)           //
使能有效后,数据才可以进入,否则数据为0



                   
data <= data_in;



               
else



                
   data <= 1'b0;    



            end



       



        end



        //脉冲宽度测量,data作为控制信号



       
always@(negedge rst or posedge clk)



        begin



          
if(!rst )



               
cnt <= 16'h0000;



           else
if(rst_cnt)



                cnt <= 16'h0000;



           else
if(data)



               
cnt <= cnt + 16'h0001;                    



        end



        //同时检测数据的大小 如果数据大于设定的脉宽,发送触发条件,计数器清零位有效



        //如果不满足触发条件,那么data低电平清除计数器的值,高电位使能其



       
always@(negedge rst or negedge clk )



        begin



           if(!rst)



           begin



               
tri_valid <= 1'b0;



               
rst_cnt   <= 1'b0;



           end



           else
if(data)



                begin



                    if(cnt >= pulse_length)



                    begin



                        tri_valid <= 1'b1;



                        rst_cnt   <= 1'b1;



                    end



                    else



                    begin



                        tri_valid <= 1'b0; 



                        rst_cnt   <= 1'b0;



                    end



       



               
end



         
else  if(!data)



               
begin



                    tri_valid <= 1'b0; 



                   
rst_cnt   <= 1'b1;



               
end



        end



        //触发信号锁存



        always
@(negedge rst or posedge tri_valid)



        begin



           
if(!rst)



               
trigger_ok <= 1'b0;



            else



                trigger_ok <= 1'b1; 



        end



   
/////////////////////////////////////////////////////



    为了解决fifo满的时候不确定带来的问题,信号进入的时候需要首先检测到边沿然后使能valid信号,才能产生触发



    条件 ,代码可以参考边沿触发



   4.接口设计



     数据口可以通过使用双向口来完成数据的输入输出,不过需要一个管教来控制内部的三态门的状态,这个可以使用



     wr来做,直这样的话,剩下的 8位地址线完全数据控制的使用



   5.存储单元



    最开始是使用内部的FIFO,以为fifo存满以后数据会覆盖原先的数据,但是实际看到数据是存满以后就不会在输入数据



    使用双口RAM又会需要地址很多的问题,直接把2个计数器来控制ram的地址,把他们封装在一起,就可以当作FIFO来用



   6.调试



    内部逻辑分析仪的还是用 signaltap,可以看大Fpga的内部信号,调试很方便,只不过占用一些ram块而已。复位的问题我就是



    通过这个看到的,还有触发位置的判断也是



   7. 信号源



     信号的频率为了方便控制,我使用了累加器来做,高8位输出信号作为分频信号,这8位的最低位作为循环序列的



     驱动时钟,这样频率控制就很容易



   8.时钟的设计



     这里需要修改,因为偶数分频不能够在所有场合满足要求


状态机的设计:pdf




  



PARTNER CONTENT

文章评论6条评论)

登录后参与讨论

zhangshaobing517_935512703 2009-8-25 14:20

74系列挺多的,有没有具体的指标?

用户216060 2009-8-25 13:50

师哥,我也想做74芯片测试仪,请问如果用AT89S52单片机的最小系统和CPLD怎么来实现? 外围电路怎么设计?

用户158304 2009-8-23 21:57

楼主好厉害啊! 顺便说一下,刚浏览了您的一些文章,觉得自己真的好无知啊!看了之后很有感触啊~ 向您学习!

zhangshaobing517_935512703 2009-8-23 16:55

如果比赛可以让使用 我非乐坏不可

ilove314_323192455 2009-8-23 12:50

不错啊,不过使用TFT屏还是没我直接使用VGA屏来得大,哈哈

用户538075 2009-8-22 00:34

顶起楼主!
相关推荐阅读
zhangshaobing517_935512703 2011-03-21 01:28
KC24RT-300调试笔记
项目中需要使用LED驱动器,主要是为了让一串LED发出的光照一致,所以在试验中采用LED串联的方式比较好点,LED并联容易导致LED发光的 不均匀以及寿命减少。我在项目中采用金升阳公司的KC24RT-...
zhangshaobing517_935512703 2010-11-19 14:53
线程中CreateEvent和SetEvent及WaitForSingleObj
首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面.CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象.EVENT有两种状态:发信...
zhangshaobing517_935512703 2010-11-15 13:29
VS2008 BEGIN
Visual Studio 2008环境与VC6.0的环境存在着比较大的区别,下面就一些小小的区别在这里做一些探讨,欢迎指教!1、如果是调试控制台程序,很多时候点击“启动调试”后是一闪而过,此时可有两...
zhangshaobing517_935512703 2010-11-01 20:38
使用MFC的数组类
 MFC的数组类支持的数组类似于C++中的常规数组,可以存放任何数据类型。C++的常规数组在使用前必须将其定义成能够容纳所有可能需要的元素,而MFC数组类创建的对象可以根据需要动态地增大或减小,数组的...
zhangshaobing517_935512703 2010-09-07 13:14
循环
 循环设计的注意的事情:(1)双重循环的跳出问题,break只挑出所在的循环,如果使用双层FOR循环,单个BREAK就不可能跳出所有的双层(2)在迭代的时候,注意起始和终止的条件,尤其是终止问题(3)...
zhangshaobing517_935512703 2010-09-02 01:09
图像处理改进
1.特征点提取的算法  标志点的提取算法对结果的影响虽然没有经过试验或者计算的推算,每1个pix的偏差对结果的影响有多大,但是不可避免的,要想获得高精度的  测量结果,高精度的提取对结果的影响还是很大...
EE直播间
更多
我要评论
6
7
关闭 站长推荐上一条 /1 下一条