verilog里可不可以同时对上升沿和下降沿计数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了verilog里可不可以同时对上升沿和下降沿计数相关的知识,希望对你有一定的参考价值。

always@(posedge eoc or negedge I/O_CLK)
i<=i+1;
这个可以实现吗

你这种写法可以实现,不过变量I/O_CLK,这种写法不合法,建议写成IO_CLK,还有verilog中一般不建议直接使用negedge去检测除复位信号以外的信号的下降沿,因为FPGA中的寄存器基本上都是上升沿敏感的,如果直接使用negedge去检测下降沿会多产生额外的一个非门,建议使用如下方法:
//电平检测模块
1 reg F1,F2; // F2 Previous State, F1 Current State
2 always@(posedge CLK or negedge RSTn)
3 if(!RSTn)
4 begin
5 F1<=1'b0;
6 F2<=1'b0;
7 end
8 else
9 begin
10 F1<= A;
11 F2<= F1;
12 end
13
14 wire Aup = F1 & !F2; //当Aup为1时,表明产生了一个上升沿
15 wire Adown = F2 & !F1//当Adown为1,时表明产生了一个下升沿

注意Aup,Adown变高后,只会持续一个时钟周期,就会归零,所以你可以
再做一个计数器,专门检测Aup,Adown,从而到达计数的目的。
对了,如果你想检测eoc 的上升沿,同时检测I/O_CLK的下降沿,可以这么写,

充分利用FPGA的并行特性嘛。
//------------------------------------------------------------------------------
1 reg F1,F2; // F2 Previous State, F1 Current State
2 always@(posedge CLK or negedge RSTn)
3 if(!RSTn)
4 begin
5 F1<=1'b0;
6 F2<=1'b0;
7 end
8 else
9 begin
10 F1<= eoc;
11 F2<= F1;
12 end
13
14 wire eocUp = F1 & !F2; //检测eoc的上升沿
//-------------------------------------------------------------------------------------
1 reg F3,F4; // F4 Previous State, F3 Current State
2 always@(posedge CLK or negedge RSTn)
3 if(!RSTn)
4 begin
5 F3<=1'b0;
6 F4<=1'b0;
7 end
8 else
9 begin
10 F3<= IO_CLKDown;
11 F4<= F3;
12 end
13
14 wire IO_CLKDown = F4 & !F3; //检测IO_CLK的下降沿
纯手打,望采纳,欢迎追问~~
参考技术A 不可综合,但是可以行为仿真。
如果要实现综合的话,需要2组寄存器分别作用于一个clock, 然后输出用加法器。

verilog抓外部低频输入信号的上升沿和下降沿

  版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址

  http://www.cnblogs.com/Colin-Cai/p/7220107.html 

  作者:窗户

  QQ:6679072

  E-mail:6679072@qq.com

  已经很久很久很久,没有真正在正式工作中设计过数字电路,有的只是在业余的时候玩玩。

  想起最早的时候,学习数字电路设计,用的是原理图。习惯于用原理图去思考,后来用VHDL,再后来习惯了verilog那和C语言一样的运算符以及简洁的表达,不再喜欢VHDL的累赘。之所以用HDL,最初的想法仅仅是因为原理图画起来累,理解起来繁琐且不便于修改罢了,脑子里最开始总是不断在真实电路和HDL代码中映射。

  现在EDA的技术越来越发达,我一朋友从事IC设计,却从来不理解原理图设计,让我一度匪夷所思,后来想想可能只是因为他没有经历过我们以前那个阶段罢了。

  闲话不多说了,回到这个主题,这其实是数字设计中经常遇到的问题。初学者看到的就是,这还不简单,直接把这个信号引入当D触发器的时钟,结果超复杂的异步设计,陷入万劫深渊无法自拔,这还没包括外部信号可能会有干扰而产生毛刺。

  首先,我们要先默认,外部输入的信号频率要低过主频,否则无法处理,其次,外部输入的信号是可能会有毛刺的。

  

  如上所示是一个毛刺,不能当时发生了上升沿。

  如上所示,只是上升沿的过程出现了毛刺,不能当成是多个上升沿发生。

  那么我们得想办法把毛刺过滤。毛刺发生的情况并不多,于是我们就想,每次系统时钟上升沿(或下降沿)的时候都对外部数字信号采样,当外部真正的电平(也就是去掉毛刺之后)是低电平的时候,采样也绝大多数都是低电平,采到高电平的毛刺是凤毛麟角,高电平也同理。

  再进一步我们就会想,如果连续采到n个电平是高电平,那么实际电平就是高电平;反之,如果连续采到n个电平是低电平,那么实际电平就是低电平;如果连续抓的n个电平有高有低,则实际电平就是之前保持的。

  如此就得到了过滤毛刺之后的真实信号,然后再用真实信号连续两个系统时钟的值来判断上升沿下降沿。

  于是有了如下设计

`timescale 1ns / 1ns
module top
(
 nRst,
 clk,
 in,
 en_posedge
);
input nRst, clk, in;
output en_posedge;

parameter W=3;
reg [W-1:0]in_reg;
always@(negedge nRst or posedge clk)
if(!nRst)
        in_reg <= {W{1\'b0}};
else
        in_reg <= {in_reg[W-2:0], in};

reg in_filter, in_filter_last;
always@(negedge nRst or posedge clk)
if(!nRst)
        in_filter <= 1\'b0;
else case({&in_reg, |in_reg})
        2\'b00: in_filter <= 1\'b0;
        2\'b11: in_filter <= 1\'b1;
        default: in_filter <= in_filter;
        endcase

always@(negedge nRst or posedge clk)
if(!nRst)
        in_filter_last <= 1\'b0;
else
        in_filter_last <= in_filter;

reg en_posedge;
always@(negedge nRst or posedge clk)
if(!nRst)
        en_posedge <= 1\'b0;
else if((!in_filter_last) & in_filter)
        en_posedge <= 1\'b1;
else
        en_posedge <= 1\'b0;

endmodule

所描述的电路长这样

 

再来做一个testbench

`timescale 1ns / 1ns
module tb;
reg nRst, clk, in;
wire en_posedge;

top t
(
 nRst,
 clk,
 in,
 en_posedge
);

initial
forever
begin
clk = 0;
#10;
clk = 1;
#10;
end

initial
begin
in=0;
nRst=1;
#5;
nRst=0;
#20;
nRst=1;
#1000;
in=1;
#20;
in=0;
#1000;
repeat(3)
        begin
        in=1;
        #20;
        in=0;
        #20;
        end
in=1;
#1000;
$stop;
end


endmodule

 仿真图如下

只认出了一次上升沿。抓取下降沿同理。

再来说说设计中的

parameter W=3;

这里的W代表着,设计可以过滤掉小于W-1个系统时钟周期的毛刺。

另外,in_reg和in_filter、in_filter_last要么全1要么全0,取决于默认情况下(一般是指无通信的时候)外部输入信号是什么电平。

想起以前工程中真的出现过问题,悲哀的教训,后来仔细想了很久,虽然看上去不难实现,但的确是吸取教训之后的设计结果。

以上是关于verilog里可不可以同时对上升沿和下降沿计数的主要内容,如果未能解决你的问题,请参考以下文章

verilog可以对同一个时钟进行上升沿和下降沿采样吗

Verilog hdl 如何检测时钟的上升沿和下降沿?

施耐德st编程语言里上升沿和下降沿的符号是啥

verilog抓外部低频输入信号的上升沿和下降沿

verilog中如何在时钟的上升沿和下降沿分别对同一变量赋不同的值,

verilog 中的上升沿 下升沿 延时怎样规定