zoukankan      html  css  js  c++  java
  • [笔记] 输入信号的边沿检测

    上升沿检测,下降沿检测,及电平变化检测的方法可以用下面介绍的来实现。在程序中经常用到,要做到灵活地应用!!!

    如果两个数据进行比较时,并没有同步且出现相差1个或者2个时钟就可以同步的情况,我们将快的数据通过寄存器缓冲下就可以了,以实现同步比较。

    遇到将电平变成脉冲的情况是将flag_level电平经过一个寄存器缓存下得到flag_level_r,然后assign flag_pulse=flag_level ^ flag_level_r;就可以得到脉冲flag_pulse。

    如果遇到将脉冲变成电平的情况是可以采用如下方式。-------wenfan程序中常用到。 

    assign DE_Test_Result <= (DE_Differ && Detect_Enable)? 1'b1 : 1'b0;//脉冲方式输出。

    或者如下

    assign DE_Test_Result <= DE_Test_Result_r ;//电平方式输出,但会延时一个时钟输出

     always@(posedge clk or posedge rst)
     begin
      if(rst)
      begin
       DE_error_status <= 1'b0;
       DE_Test_Result_r <= 1'b0;
      end
      else if(Detect_Enable)
       case(DE_error_status)
        1'b0 :
        begin
         DE_Test_Result_r <= 1'b0;
         if(DE_Differ)
          DE_error_status <= 1'b1;
        end
        1'b1 :
        begin
         DE_Test_Result_r <= 1'b1;
        end
        default:;
       endcase
     end

    //可以修改成如下方式:这样可以省掉一个寄存器,与上面一样,仍会延时一个时钟输出

    always@(posedge clk or posedge rst)
     begin
      if(rst)
      begin
       DE_Test_Result_r <= 1'b0;
      end
      else if(Detect_Enable)
       case(DE_Test_Result_r)
        1'b0 :
        begin
         if(DE_Differ)
             DE_Test_Result_r <= 1'b1;
        end
        1'b1 :
        begin
            DE_Test_Result_r <= 1'b1;
        end
        default:;
       endcase
     end

    //最后结合上面的仿真结果又可以写成如下

     wire DE_Test_Result_en;
    reg DE_Test_Result_r;
    //assign DE_Test_Result = DE_Test_Result_r;//这个输出与上面一样,会延时一个时钟

    assign DE_Test_Result = DE_Test_Result_r || DE_Test_Result_en;//GOOD!可以避免延时一个时钟输出。
    assign DE_Test_Result_en = (DE_Differ && Detect_Enable)? 1'b1 : 1'b0;//帧开始采用脉冲的方式使能
    always@(posedge clk or posedge reset)//帧开始采用电平的方式输出
    begin
    if(reset)
        DE_Test_Result_r<= 1'b0;
    else if(DE_Test_Result_en)
           DE_Test_Result_r <= 1'b1;
    end
    应用如下:
    方法一:
    //reg frame_start_r;//帧开始采用电平的方式
    //assign frame_start = frame_start_r;
    //always@(posedge clk or posedge reset)
    //begin
    // if(reset)
    //   frame_start_r <= 1'b0;
    // else
    // begin  
    //  case(frame_start_r)
    //    1'b0: begin
    //      if (cnt == N && rx_data[20])
    //          frame_start_r <= 1'b1;
    //      end
    //    1'b1: frame_start_r <= 1'b1;
    //    default:;
    //  endcase       
    // end
    //end
    方法二:
    //assign frame_start = (cnt>= N && rx_data[20]) ? 1'b1 : 1'b0;//帧开始采用脉冲的方式
    方法三:(最好!!!!!!!!!!!!!!)
    wire frame_start_en;//这种方法是结合了上面的语句实现电平输出
    reg frame_start_r;
    //assign frame_start = frame_start_r;//帧开始采用脉冲的方式使能,这个会延时一个时钟
    assign frame_start = frame_start_r || frame_start_en;//modify,这个可以不用延时一个时钟输出,GOOD!
    assign frame_start_en = (cnt>= N && rx_data[20]) ? 1'b1 : 1'b0;//帧开始采用脉冲的方式使能
    always@(posedge clk or posedge reset)//帧开始采用电平的方式输出
    begin
     if(reset)
         frame_start_r <= 1'b0;
     else if(frame_start_en)
           frame_start_r <= 1'b1;
    end

    方法四:在看洪鸿榕代码时,发现他是这样实现功能的。

    reg frame_start_en; //Ronnie use this method;//脉冲方式输出,但会延时一个时钟输出

    assign frame_start = frame_start_r; //电平方式输出,但会延时一个时钟输出

    always@(posedge clk or posedge reset)

    begin

    if(reset)

    begin

             frame_start_en  <= 1'b0;

          frame_start_r  <= 1'b0;

      end

      else if(cnt>= N && rx_data[20])

    begin

             frame_start_en  <= 1'b1;

          frame_start_r  <= 1'b1;

      end

      else

      begin

             frame_start_en  <= 1'b0;

          frame_start_r  <= frame_start_r;

      end

    end

    最近在做需要用4组5通道7位的LVDS发送模块去点亮55寸的4K2K pannel。但手头上只有Spartan3板子,一块Spartan3板子最多只有2组5通道7位的LVDS发送模块,因此需要用到两块Spartan3板子来实现。遇到的最大问题就是如何处理两块板子的同步,尤其是信号源输出的同步处理。在做的过程中,我向洪鸿榕学到很多东西,我觉得他懂很多,我有时需要结合Blog和书本才能大悟。比如他在处理两块板子信号源同步时,用到的语句,我看了半天,没明白。后来看他无双大师的博客才明白。现做如下归纳:

    来源:http://www.cnblogs.com/oomusou/archive/2008/07/09/modelsim_altera_tutorial.html modelsim仿真

    http://www.cnblogs.com/oomusou/archive/2008/07/06/verilog_edge_detection_circuit.html 边沿检测实现

    http://www.cnblogs.com/oomusou/archive/2009/01/30/modelsim_pre_post_simulate.html Quartus II调用modelsim_altera仿真

    http://www.cnblogs.com/oomusou/archive/2009/02/17/modelsim_megafunction.html Quartus II调用Megafunction并在modelsim_altera仿真设置

    输入信号的边沿检测包括上升沿,下降沿和双边沿这三种检测。检测是通过clk的上升沿来触发的,主要是看信号上升沿次数,下降沿次数,相应的触发次数也一样。

    问题:什么时候会使用这种电路呢?

    答:如果input是异步信号,为了要让input与你同步的FSM一起处理,必须先经过边缘检测处理,使之与clk同步,然后才能跟你的FSM一起操作。

    问题:在Quartus II12.0上调用Modelsim_Altera仿真老是出错,错误的原因我也不明白,感觉程序没问题,反复试了好几次都没成,因此又从最基本的方法,还是没有解决问题。最后在洪鸿榕的帮助下终于解决了。他帮我安装了Quartus II12.0的一个补丁,有9G大,安装时间挺长且需要再重新破解license(这步我没进行,所以以提示license不对,搞得我都怀疑补丁安得有问题,人真的好奇怪,呵呵)。

    要想成为真正的程序高手就要从根本入手,而不是一味地追求快,当遇到问题时,又止步不前,这是最致使,我自己都反复犯这个错误。资料的根本就是它们的出处,如Arria V芯片有用到就要下载它的Datasheet,Modelsim_Altera工具要学会用就要从help中链接PDF文件。有了文件,最关键的就是看及理解,要有耐心,因为全部都是英文,不理解的地方可以请教,但不能再犯同样的错了,加油。

    问题:我在modelsim.ini中有看到如下所说的信息,但Quartus II每次调用Modesim SE还是会对Altera的相关库进行编译,这样又花了挺长时间,没明白为什么?明天继续想。。。

    http://www.cnblogs.com/oomusou/archive/2009/02/13/modelsim_lib_mapping.html  

    如何为ModelSim加入永久性的library mapping? (SOC) (ModelSim)

    问题:在Xilinx相关器件上如Spartan6和Spartan3A上实现过2组4通道7位的LVDS发送和接收模块。自以为是地认为在Altera的器件上也是这样,因此在进行LVDS发送模块的仿真时,一直以为是出错了,其实是正确的。还好是洪鸿榕叫我认真研读下Arria V及其LVDS的宏功能模块手册,才能如意地解决了这个问题。我觉得很多问题我都经常这样地犯错,老是没发现,等问题解决了才恍然大悟,意识到自己又犯同样的错误,不清楚如何才能做到根除这个缺点。

  • 相关阅读:
    PAT《数据结构学习与实验指导》实验项目集 2-09 2-10 2-11 2-12 2-13
    codeblocks+Mingw 下配置开源c++单元测试工具 google test
    编程之美 1.16 24点游戏
    PAT 1065 1066 1067 1068
    多线程批量执行等待全部结果
    使用Git和远程代码库
    CentOS下Crontab安装使用详细说明(转)
    安装和测试Kafka(转)
    MapReduce任务参数调优(转)
    Maven构建应用程序常用配置(转)
  • 原文地址:https://www.cnblogs.com/zlh840/p/2655656.html
Copyright © 2011-2022 走看看