基于verilog的边沿检测电路
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在时序逻辑电路中,少不了“沿”。always块敏感信号中可以通过关键字posedge和negedge来提取信号的上升沿和下降沿。但是如果在程序块内部需要某个信号的上升沿或者下降沿、或者对于按钮触发的模块,由于按钮按下的持续时间很长,相当于一个电平信号,而不是脉冲信号,这时就需要边沿检测电路将其处理成单时钟周期宽度的脉冲信号。下面介绍几种基于verilog的边沿检测电路。(软件平台为quartus11.1,ModelSim-Altera 10.0)
方法1:
①Verilog源码
module detecEdge (clk,rst_n,din,pos_clk,neg_clk,doub_clk);
input clk,rst_n,din;
output pos_clk,neg_clk,doub_clk;
reg ctl_this, ctl_last;
always @(posedge clk or negedge rst_n) //同步复位(注意与异步复位的区别)
begin
if(!rst_n) //低有效
begin
ctl_this <= 0;
ctl_last <= 0;
end
else begin //注意非阻塞赋值的作用
ctl_this <= din; //din的当前时钟值
ctl_last <= ctl_this; //din的前一个时钟值
end
end
//assign pos_clk = (ctl_last == 0 && ctl_this == 1)? 1:0; //上升沿检测
//assign neg_clk = (ctl_last == 1 && ctl_this == 0)? 1:0; //下降沿检测
assign pos_clk = ctl_this & (!ctl_last); //上升沿检测
assign neg_clk = ctl_last & (!ctl_this); //下降沿检测
assign doub_clk = ctl_last ^ ctl_this; //双边沿检测
endmodule
②RTL综合图
③消耗资源
④Modelsim仿真
testbench源码:
`timescale 1ns/1ps
module testbench;
reg clk, rst_n, din;
wire pos_clk, neg_clk, doub_clk;
//调用detecEdge模块
detecEdge inst(
.clk(clk),
.rst_n(rst_n),
.din(din),
.pos_clk(pos_clk),
.neg_clk(neg_clk),
.doub_clk(doub_clk)
);
initial //输入信号初始化
begin
rst_n = 0;
clk = 0;
din = 0;
#50;
rst_n = 1;
end
always #100 din = ~din; //输入激励
always #5 clk = ~clk; //系统时钟endmodule
仿真波形:
由仿真结果知,当din上升沿到来时,pos_clk输出一个脉冲信号(宽度为1个clk),同理,当din下降沿到来时,neg_clk输出一个脉冲信号,doub_clk在din的上升沿和下降沿都输出脉冲信号。
方法2:
①Verilog源码
module detecEdge(clk,rst_n,din,pos_clk,neg_clk,doub_clk);
input clk;
input rst_n;
input din;
output pos_clk;
output neg_clk;
output doub_clk;
reg [2:0] ctl_r; //din状态寄存器
always @(posedge clk or negedge rst_n) //注意异步复位与同步复位
if(!rst_n) //低有效
begin
ctl_r <= 3'b000;
end
else begin
ctl_r <= {ctl_r[1:0], din};
end
assign pos_clk = (!ctl_r[2]) & ctl_r[1]; //上升沿检测
assign neg_clk = (!ctl_r[1]) & ctl_r[2]; //下降沿检测
assign doub_clk = ctl_r[2] ^ ctl_r[1]; //双边沿检测
endmodule
或者:
module detecEdge(clk,rst_n,din,pos_clk,neg_clk,doub_clk);
input clk;
input rst_n;
input din;
output pos_clk;
output neg_clk;
output doub_clk;
reg ctl_r0, ctl_r1, ctl_r2;
always @(posedge clk or negedge rst_n)
if(!rst_n) //低有效
begin
ctl_r0 <= 1'b0;
ctl_r1 <= 1'b0;
ctl_r2 <= 1'b0;
end
else
begin
ctl_r0 <= din;
ctl_r1 <= ctl_r0;
ctl_r2 <= ctl_r1;
end
assign pos_ clk = (!ctl_r2) & ctl _r1;
assign neg_ clk = (!ctl_r1) & ctl_r2;
assign doub_clk = ctl_r1 ^ ctl_r2;
②RTL综合图
③消耗资源