一、前言
本系列旨在提供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
二、半整数分频题目
用verilog实现3.5分频电路
用verilog实现N.5分频电路
三、半整数分频原理
在第四章,我们实现了小数分频和分数分频,正常已经涵盖了半整数分频的部分,那么我们为什么现在还要来单独强调半整数分频呢?
理由有二
1、虽然说第四章的小说分频可以用来实现半整数分频,但是正对于半个周期的特殊分频,我们可以使用更为有效的电路结构来缩小实现所需的面积,优化面积的价值,就是单独讨论半整数分频的意义之一。
2、对于使用小数分频法得到的,以3.5分频为例,需要使用一个四分频和一个三分频,七个周期内,输出两个1,这个平均概念使clock jitter很大,时钟信号的质量得不到保证,用新的方法得到的分频信号可以做出每一个周期都是3.5T的效果,时钟抖动为零,信号的质量更好,以下提出的设计方法主要是因为这个优点
半整数分频可以实现50%占空比吗?
很困难
对于3.5分频来说,需要1.75个时钟周期进行一次翻转,这种存在1/4周期的翻转很难仅仅通过数字电路/Verilog取实现,因此我们不将占空比作为关注的重点,仅仅考量3.5分频的电路结构
具体原理
用上升沿和下降沿各产生一个7分频的时钟信号,这两个信号的距离是3.5个时钟周期,用逻辑或的形式,即可产生无抖动3.5分频信号
四、RTL设计
module half_divide (clk,rst_n,clk_out); input clk; input rst_n; output clk_out; reg [3:0] p_cnt; reg [3:0] n_cnt; wire p_out; wire n_out; always@(posedge clk or negedge rst_n) if(!rst_n) p_cnt <= 4'd0; else if(p_cnt < 4'd6) p_cnt <= p_cnt + 1'b1; else p_cnt <= 4'd0; always@(negedge clk or negedge rst_n) if(!rst_n) n_cnt <= 4'd0; else if(n_cnt < 4'd6) n_cnt <= n_cnt + 1'b1; else n_cnt <= 4'd0; assign p_out = p_cnt == 4'd0 ? 1 : 0; assign n_out = n_cnt == 4'd4 ? 1 : 0; assign clk_out = p_out || n_out; endmodule
五、半整数分频的Testbench
`timescale 1ns /1ps module half_dividet_tb(); reg clk; reg rst_n; wire clk_out; half_divide u1(.clk(clk),.rst_n(rst_n),.clk_out(clk_out)); always #5 clk = ~clk; initial begin clk = 0; rst_n =1; #15 rst_n = 0; #24 rst_n = 1; #4000 $stop; end endmodule
六、结果分析
可以发现,当信号复位后,clk_out作为输出,的周期为35ns,即完成了3.5分频的目标