[笔记] 输入信号的边沿检测

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

如果两个数据进行比较时,并没有同步且出现相差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的宏功能模块手册,才能如意地解决了这个问题。我觉得很多问题我都经常这样地犯错,老是没发现,等问题解决了才恍然大悟,意识到自己又犯同样的错误,不清楚如何才能做到根除这个缺点。

 

posted on 2012-08-25 09:48  zlh840  阅读(731)  评论(0编辑  收藏  举报

导航