一、前言
本系列旨在提供100%准确的数字IC设计/验证手撕代码环节的题目,原理,RTL设计,Testbench和参考仿真波形,每篇文章的内容都经过仿真核对。快速导航链接如下:
1.奇数分频
2.偶数分频
3.半整数分批
4.小数/分数分频
5.序列检测器
6.模三检测器
7.饮料机
8.异步复位,同步释放
9.边沿检测(上升沿,下降沿,双边沿)
10.全加器,半加器
11.格雷码转二进制
12.单bit跨时钟域(打两拍,边沿同步,脉冲同步)
13.奇偶校验
14.伪随机数生成器[线性反馈移位寄存器]
15.同步FIFO
16.无毛刺时钟切换电路
应当说,手撕代码环节是面试流程中既重要又简单的一个环节,跟软件类的岗位相比起来,数字IC的手撕代码题目固定,数量有限,属于整个面试中必得分的一个环节,在这个系列以外,笔者同样推荐数字IC求职者使用“HdlBits”进行代码的训练
链接如下
HDLBits — Verilog Practice
二、边沿检测电路题目
1.使用Verilog语言,设计上升沿边沿检测电路。
2.使用Verilog语言,设计下降沿边沿检测电路。
3.使用Verilog语言,设计双沿边沿检测电路。
三、边沿检测电路原理
这里为了解释原理,我们需要对边沿电路的特点进行分析
对于一个上升沿电路来说,假如用clk信号与寄存器进行采样,前一拍采到了0,后一拍输入结果为1,那么通过组合逻辑的运算,前一拍用A表示,后一拍用B表示,“!A & B”就是我们需要的上升沿检测。
同理,对于下降沿来说,前一拍采到1,后一拍输入结果为0,A&!B,就是我们需要的下降沿检测电路。
对于双边沿来说,输出是** “!A & B + A&!B” **,即 A^B 异或操作
具体的时序图如下
四、RTL设计
module edge_detect(clk,rst_n,signal,up_edge,down_edge,both_edge); input clk; input signal; input rst_n; output up_edge; output down_edge; output both_edge; reg signal_r; always@(posedge clk or negedge rst_n) begin if(!rst_n) signal_r <= 1'b0; else signal_r <= signal; end assign up_edge = !signal_r & signal; assign down_edge = signal_r & !signal; assign both_edge = signal_r ^ signal; endmodule
五、Testbench设计
`timescale 1ns / 1ps module edge_detect_tb () ; reg clk; reg rst_n; reg signal; wire up_edge; wire down_edge; wire both_edge; edge_detect u1(.clk(clk), .rst_n(rst_n), .signal(signal), .up_edge(up_edge), .down_edge(down_edge), .both_edge(both_edge)); always #5 clk = !clk; initial begin clk = 0; rst_n = 1; signal = 0; #10 rst_n = 0; #23 rst_n = 1; #16 signal = 1; #50 signal = 0; #40 $stop; end endmodule
六、结果分析
如图所示的上升沿和下降沿,电路的output检测到了边沿到来,显示在三个wire型output上,电路设计符合预期。