今天的笔试题是某芸科技的现场笔试题,数字前端的笔试题,要求很简单,就是现场写出代码实现:

任意切换1-8分频,且无论奇分频还是偶分频,占空比均为50%,我至今仍然认为,在那种紧张且时间有限的情况下(本科大约预留15分钟),真的能设计出这种可任意切换的分频电路(之前有所准备的话可以),反正我是没写出来,笔试归来,我花了多个小时的时间写了一个且仿真了下。

个人认为,这个电路的设计的步骤分为两部分,

第一:

确定整体架构,包括输入输出:如何任意切换?我写了一个分频模块,其中一个输入为div,你输入1到8,可实现1到8的分频。

第二:

确定分频实现电路,分频大家都会写,实现过程可分为奇分频的实现以及偶分频的实现,这两种的实现方法是不一样的,偶分频简单,直接计数即可,奇分频需要三个步骤,第一个步骤就是计数,第二个步骤就是下降沿采样,第三个步骤就是相与或相或,具体实现方法后面再说。


思路简述:

上面说了这个电路的设计分为两部分,第一部分确定整体架构,其中最重要的是输入输出:

 input clk,input [3:0] div,input rst_n,output clk_out

确定好输入输出之后,我们想,我们是否需要一个使能信号,当输入分频述div后,我们让某一种分频模式使能,我们有8中分频模式,总不能傻傻地设置8个使能变量吧,en1,en2,...,en8;

当然这样很不好看,而且不利于后面程序编写,我的方式是:

 reg [7:0] fre_en;

每次只能使能一位,fre_en[i]使能代表i+1分频模式有效。

通过div的值来确认某种模式使能,其实现如下:

 localparam DIV1 = 1, DIV2 = 2, DIV3 = 3, DIV4 = 4;localparam DIV5 = 5, DIV6 = 6, DIV7 = 7, DIV8 = 8;reg [7:0] fre_en;always@(posedge clk or negedge rst_n) beginif(~rst_n) beginfre_en <= 0;endelse begincase(div)DIV1: fre_en <= 8'b0000_0001;DIV2: fre_en <= 8'b0000_0010;DIV3: fre_en <= 8'b0000_0100; DIV4: fre_en <= 8'b0000_1000;DIV5: fre_en <= 8'b0001_0000;DIV6: fre_en <= 8'b0010_0000;DIV7: fre_en <= 8'b0100_0000;DIV8: fre_en <= 8'b1000_0000;endcaseendend

我们说了,分频分为奇分频和偶分频,二者都有计数的过程,但是这里想做出一点改变,因为1分频等于没分频,2分频直接对输出时钟取反即可,其他分频就和计数有关了。

我们写一个计数器,用于其他分频模式,8分频需要计数次数最多,我们设计数器位数为4位,其实3位就够了。

根据模式使能确定计数次数。

//计数模块reg [3:0] fre_cnt;always @(posedge clk or negedge rst_n) beginif(~rst_n) beginfre_cnt <= 0;end else begincase(1'b1)fre_en[0]: begin;endfre_en[1]: begin;endfre_en[2]: begin //3分频计数if(fre_cnt < 2) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[3]: beginif(fre_cnt < 3) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0; endfre_en[4]: beginif(fre_cnt < 4) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[5]: beginif(fre_cnt < 5) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0; endfre_en[6]: beginif(fre_cnt < 6) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[7]: beginif(fre_cnt < 7) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;  endendcase endend

有了计数模块,就可以设计分频实现模块了,根据分频使能来确定分频模式,不同的分频模式对应不同的分频实现方式。

reg clk_out_r;reg clk_even;always @(posedge clk or negedge rst_n) beginif(~rst_n) beginclk_even <= 0;clk_out_r <= 0;end else begincase(1'b1)fre_en[0]: begin //1 分频;endfre_en[1]: begin //2 分频clk_even <= ~clk_even;endfre_en[2]: begin //3 分频if(fre_cnt == 1) clk_out_r <= ~clk_out_r;else if(fre_cnt == 2)  clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r;endfre_en[3]: begin //4 分频if(fre_cnt == 1) clk_even <= ~clk_even;else if(fre_cnt ==3) clk_even <= ~clk_even;else clk_even <= clk_even;endfre_en[4]: begin //5分频if(fre_cnt == 2) clk_out_r <= ~clk_out_r;else if(fre_cnt == 4) clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r;  endfre_en[5]: begin // 6分频if(fre_cnt == 2) clk_even <= ~clk_even;else if(fre_cnt == 5) clk_even <= ~clk_even;else clk_even <= clk_even;endfre_en[6]: begin //7 分频if(fre_cnt == 3) clk_out_r <= ~clk_out_r;else if(fre_cnt == 6) clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r; endfre_en[7]: begin //8 分频if(fre_cnt == 3) clk_even <= ~clk_even;else if(fre_cnt == 7) clk_even <= ~clk_even;else clk_even <= clk_even; endendcase  endend

解释下上面的几个reg变量以及wire变量的意义,由于考虑到奇数分频最后的输出clk_out需要一段组合逻辑,所以需要使能wire类型。

这就导致这个分频实现模块里不能直接使用clk_out作为左值。

用clk_even用作偶分频输出clk_out的缓冲;

至于clk_out_r,以及clk_out_rr是为了奇分频而声明的。

这里提一下奇分频的实现原理:(之前写过Verilog HDL 训练】第 11 天(分频电路))

假如N为奇数,那么进行N分频,需要先设计一个占空比为(N-1)/2 : N的分频输出clk_out_r,之后用时钟下降沿采样clk_out_r得到clk_out_rr;最后将clk_out_r或上clk_out_rr即可。

具体可参考上面引用的博文。

至于偶分频,则需要计数一半反转一次,计数结束反转一次即可。

好了,下面继续解决奇分频的下降沿采样问题:

//下降沿采样模块reg clk_out_rr;always @(negedge clk or negedge rst_n) beginif(~rst_n) beginclk_out_rr <= 0;end else begincase(1'b1)fre_en[0]: ;fre_en[1]: ;fre_en[2]: beginclk_out_rr <= clk_out_r;endfre_en[3]: ;fre_en[4]: beginclk_out_rr <= clk_out_r;endfre_en[5]: ;fre_en[6]: beginclk_out_rr <= clk_out_r;endfre_en[7]: ;endcase endend

最后输出分频时钟:

//产生分频时钟 assign clk_out = ( fre_en[0] | fre_en[1] | fre_en[3] | fre_en[5] | fre_en[7] )? clk_even : clk_out_r | clk_out_rr;

由于一次输入只能有一个使能位有效,所以上述assign自然明白了吧。

大概就是这么多了,给出一个简单的仿真,文章的最后会给出完整的代码以及仿真代码。

先给出一个仿真,假如输入div为5,则进行5分频,则:

假如输入div为6则进行6分频:

先5分频在1分频:

完美切换。

最后的最后给出完整版程序以及测试。


完整版程序:


//任意切换1——8分频电路设计(某芸科技),无论是奇分频还是偶分频,占空比均为50%module Fre_Div(input clk,input [3:0] div,input rst_n,output clk_out);localparam DIV1 = 1, DIV2 = 2, DIV3 = 3, DIV4 = 4;localparam DIV5 = 5, DIV6 = 6, DIV7 = 7, DIV8 = 8;reg [7:0] fre_en;always@(posedge clk or negedge rst_n) beginif(~rst_n) beginfre_en <= 0;endelse begincase(div)DIV1: fre_en <= 8'b0000_0001;DIV2: fre_en <= 8'b0000_0010;DIV3: fre_en <= 8'b0000_0100; DIV4: fre_en <= 8'b0000_1000;DIV5: fre_en <= 8'b0001_0000;DIV6: fre_en <= 8'b0010_0000;DIV7: fre_en <= 8'b0100_0000;DIV8: fre_en <= 8'b1000_0000;endcaseendendreg clk_out_r;reg clk_even;always @(posedge clk or negedge rst_n) beginif(~rst_n) beginclk_even <= 0;clk_out_r <= 0;end else begincase(1'b1)fre_en[0]: begin //1 分频;endfre_en[1]: begin //2 分频clk_even <= ~clk_even;endfre_en[2]: begin //3 分频if(fre_cnt == 1) clk_out_r <= ~clk_out_r;else if(fre_cnt == 2)  clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r;endfre_en[3]: begin //4 分频if(fre_cnt == 1) clk_even <= ~clk_even;else if(fre_cnt ==3) clk_even <= ~clk_even;else clk_even <= clk_even;endfre_en[4]: begin //5分频if(fre_cnt == 2) clk_out_r <= ~clk_out_r;else if(fre_cnt == 4) clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r;  endfre_en[5]: begin // 6分频if(fre_cnt == 2) clk_even <= ~clk_even;else if(fre_cnt == 5) clk_even <= ~clk_even;else clk_even <= clk_even;endfre_en[6]: begin //7 分频if(fre_cnt == 3) clk_out_r <= ~clk_out_r;else if(fre_cnt == 6) clk_out_r <= ~clk_out_r;else clk_out_r <= clk_out_r; endfre_en[7]: begin //8 分频if(fre_cnt == 3) clk_even <= ~clk_even;else if(fre_cnt == 7) clk_even <= ~clk_even;else clk_even <= clk_even; endendcase  endend//下降沿采样模块reg clk_out_rr;always @(negedge clk or negedge rst_n) beginif(~rst_n) beginclk_out_rr <= 0;end else begincase(1'b1)fre_en[0]: ;fre_en[1]: ;fre_en[2]: beginclk_out_rr <= clk_out_r;endfre_en[3]: ;fre_en[4]: beginclk_out_rr <= clk_out_r;endfre_en[5]: ;fre_en[6]: beginclk_out_rr <= clk_out_r;endfre_en[7]: ;endcase endend//产生分频时钟assign clk_out = fre_en[0] ? clk :( (  fre_en[1] | fre_en[3] | fre_en[5] | fre_en[7] )? clk_even : clk_out_r | clk_out_rr );//计数模块reg [3:0] fre_cnt;always @(posedge clk or negedge rst_n) beginif(~rst_n) beginfre_cnt <= 0;end else begincase(1'b1)fre_en[0]: begin;endfre_en[1]: begin;endfre_en[2]: begin //3分频计数if(fre_cnt < 2) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[3]: beginif(fre_cnt < 3) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0; endfre_en[4]: beginif(fre_cnt < 4) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[5]: beginif(fre_cnt < 5) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0; endfre_en[6]: beginif(fre_cnt < 6) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;endfre_en[7]: beginif(fre_cnt < 7) fre_cnt <= fre_cnt + 1;else fre_cnt <= 0;  endendcase endendendmodule

测试:

module Sim_Freq_Div();reg clk;reg rst_n;reg [3:0] div;wire clk_out;initial beginclk = 0;forever#2 clk = ~clk;endinitial beginrst_n = 0;div = 5;#15rst_n = 1;#60div = 1;endFre_Div fre_div_tb(.clk(clk),.rst_n(rst_n),.div(div),.clk_out(clk_out));endmodule

IC/FPGA校招笔试题分析(二)任意切换的时钟分频电路相关推荐

  1. IC/FPGA校招笔试题分析(三)

    还有1天就要进行某瓦科技的面试了,今天晚上赶紧复习下上次它的笔试题: 1.一个四位十六个状态的格雷码计数器,起始值为1001,经过100个时钟脉冲作用之后的值为(). 首先,算出100个脉冲后跑了多少 ...

  2. IC/FPGA校招笔试题分析(四)再看Moore状态机实现序列检测器

    参加了几次笔试,发现序列检测器是常考的内容,而之前认为序列检测器真的很简单,但是这次X疆的笔试题做完之后,我怀疑自己了. 画状态转移图的时候,我开始犹豫了,我怕我会没考虑全,甚至有点晕. 人家又问: ...

  3. IC/FPGA校招笔试题分析(一)

    某发科的一个题目,仅仅给出下面一个电路图,让你画出Q1,Q2以及Q3的波形,并描述电路功能. 可以看出,这个电路很简单(可tm的当时就是没做出来),我当时疑惑的是初值是什么,输入初值是什么? 可想想和 ...

  4. FPGA校招笔试题分析

    仅仅给出下面一个电路图,让你画出Q1,Q2以及Q3的波形,并描述电路功能 第一个触发器的输入是第二个以及第三个触发器的输出的反馈,是Q1与Q2的或非:实际上就是同步三分频电路: 只要触发器复位有初值即 ...

  5. IC/FPGA笔试/面试题分析(八)近期IC/FPGA笔试面试讨论群题目汇总解析

    背景:IC前端设计/FPGA笔(面)试交流群,欢迎同行加入 自从开始邀请同行加入笔试面试交流群之后,目前已经有40多位同行加入,大家踊跃发言,各抒己见,让各自受益匪浅. 今天的这篇博文是将近期部分题目 ...

  6. IC/FPGA笔试/面试题分析(七)建立时间和保持时间类型考题汇总分析

    自从召集2020届校招同行加入新建立的"IC/FPGA校招笔试面试交流群",见识到了很多关于建立时间和保持时间分析的题目,在为别人解答疑惑,以及别人为自己解答疑惑的同时,自己对于知 ...

  7. IC/FPGA笔试/面试题分析(九)关于FIFO最小深度计算的问题

    IC/FPGA逻辑设计笔试题中最常见的体型莫过于FIFO最小深度的计算了,以前看到过计算FIFO最小深度,需要代入公式,直到看到这篇文档,才觉得使用逻辑分析的方法来看更能让人理解的更为深刻. 文档把计 ...

  8. IC/FPGA笔试/面试题分析(十一)基础概念(三态门等)

    上篇博文写了一些有关CMOS门电路的基础内容,相信认真看完,一定能画出各种CMOS门电路:CMOS门电路,这些是最常考的基础内容. 下面简单介绍一下其他概念题目: 1. 解释一下Vih,Vil,Vol ...

  9. IC/FPGA笔试/面试题分析(十)CMOS门电路

    目录 CMOS介绍 CMOS非门 CMOS与非门 CMOS或非门 CMOS或门 CMOS与门 CMOS与或式 CMOS或与非 CMOS介绍 MOS管分为NMOS和CMOS,二者成对出现在电路中,且二者 ...

最新文章

  1. java map 队列_Java:queue队列,map集合
  2. 中国CIO最关心的八大问题(下)
  3. struts2的核心和工作原理
  4. mysql %3c%3e sql优化_SQL注入技术和跨站脚本攻击的检测(2)
  5. 记一次 Spring Boot 项目启动卡住问题排查记录
  6. 文献记录(part19)--Cross modal similarity learning with active queries
  7. SQLite.NET (32位) 在64位环境中无法正常调试
  8. 网页设计中 透明效果的使用技巧
  9. Springboot01创建第一个程序
  10. C/C++ Socket编程Http下载的简单实现
  11. linux asm 使用情况,在Linux 6上使用UDEV解决 ASM存储设备问题( single path)
  12. 论文笔记——分布式深度学习框架下基于性能感知的DBS—SGD算法
  13. win7安装mysql后“应用程序无法启动因为应用程序的并行配置不正
  14. Wolfram|Alpha搜索引擎
  15. html中banner怎么写,banner图欣赏
  16. ImportError: sys.meta_path is None, Python is likely shutting down 解决方案
  17. Google Chrome Helper CPU占用过高的解决办法
  18. SpringCloud入门 —— SSO 单点登录
  19. 【BZOJ4864】【BeiJing 2017 Wc】神秘物质(Splay)
  20. 优思学院|利用Excel进行双样本t检验

热门文章

  1. CSS大小设置实例——盒子模型
  2. 一学长毕业临走前和我说的话
  3. 我在Archlinux下使用的软件
  4. RedHat开机启动流程
  5. 计算机术语的英文全称,计算机英文名词缩写
  6. 语言全局变量跨文件_C 语言课上不会讲的一些问题
  7. xpdf将pdf转换为html,(WordExcelPDF文件转换成HTML整理.docx
  8. java两人猜数字游戏,java之猜数字游戏
  9. 计算机中算术逻辑单元负责,算术逻辑单元
  10. linux虚拟机处理器设置,虚拟机linux cpu核数