第一次写技术性的blog,就先选择一个看似简单的话题吧。

无论从算法上还是逻辑上,这个题目都非常简单,但是对于ASIC工程师,恐怕却是一个不小的挑战。

首先,看看我们的目标:

很简单吧,只要在响应的输入时钟沿上产生输出的翻转就可以了。但是对于ASIC工程师,却有很多东西是值得讨论的。

1.行为级的实现是非常简单的,只要你会写C,就可以简单的用verilog写出来,甚至连语法都基本一致:

always@( negedge resetn or posedge clk or negedge clk)

begin

if (resetn==1'b0)

begin

counter[2:0]<=3'd0;

out_clk<=1'b0;

end

else

begin

if (counter[2:0]==3'd5)

begin

counter[2:0]<=3'd0;

end

else

beign

counter[2:0]<= counter[2:0]+1;

end

if (counter[2:0]==3'd5 || counter[2:0]==3'd2)

begin

out_clk<=~out_clk;

end

end

end

不要不相信这种写法,现在甚至还有一些书仍然有类似的范例。其仿真结果也确实是正确的

但是如果你只是想做一个测试仿真用还可以,要是想做真正的芯片那会被人嘲笑的。因为这个逻辑在现有的条件下无法综合。没有支持2个时钟沿的寄存器。所以这个写不对不是因为逻辑问题,而纯粹是现在的半导体工艺问题,也许以后会有支持双沿的寄存器。

2.下面给出一个逻辑图,很值得回味的。

这个逻辑是用器件画出来的,所以肯定不存在物理上的实现问题。但是其工作过程在逻辑上却有些让人头痛。如果你的数字电路学的很扎实,可以写一下方程来验证一下。在实际的实验中我相信它也80%以上是工作的。

仿真图如下:

也许有人要问,既然仿真都是对的,那么为什么要说实际中是80%工作呢?

看到波形图上的clk1(黄色)上的那些毛刺了么,毛刺并不可怕,但是这个电路工作的基础却是那些毛刺,准确地说,那些毛刺是必须有的,是工作过程的比不可少的部份。这样的电路是否能正常工作就很让人匪夷所思了。

我们能不能让电路的正常功能不依赖于毛刺呢?

小结一下:

以上的思路都是试图在输入的clk上做改造,试图在恰当的地方取正沿,恰当的地方取反沿。但是要知道,这一定会导致竞争和冒险。虽然逻辑上是可性的,但是实践中却没有那么简单。这个时候,我们需要调整一下思路了:

能不能营造一个安全的时机来切换时钟沿的选择?显然,这需要在切换时钟沿时,强制时钟输出固定电平,当切换完成后,在取消这个强制条件。对么?我们来试试看。

3. 看看以下的代码,也是一段有趣的东西。

always@(negedge resetn or posedge clk)
begin
    if (resetn==1'b0)
    begin
        cnt1[1:0]<=2'd0;
    end
    else
    begin
        if(cnt1[1:0]==2'd2)
        begin
            cnt1[1:0]<=2'd0;
        end
        else
        begin
            cnt1[1:0]<=cnt1[1:0]+1;
        end
    end
end

always@(negedge resetn or negedge clk)
begin
    if (resetn==1'b0)
    begin
        cnt2[1:0]<=2'd0;
    end
    else
    begin
        if(cnt2[1:0]==2'd2)
        begin
            cnt2[1:0]<=2'd0;
        end
        else
        begin
            cnt2[1:0]<=cnt2[1:0]+1;
        end
    end
end

always@*
begin
    if (cnt1[1:0]==2'd2 || cnt2[1:0]==2'd0)
    begin
        clk1 = 1'b0;
    end
    else if (cnt1[1:0]==1'b1)
    begin
        clk1 = ~clk;
    end
    else
    begin
        clk1 = clk;
    end
end

always@(negedge resetn or posedge clk1)
begin
    if (resetn==1'b0)
    begin
        clk_out<=1'b0;
    end
    else
    begin
        clk_out<=~clk_out;
    end
end

最后用的时钟clk1是clk和clk的反,但是在切换之间加上的强制为0的逻辑。

这段代码肯定是可综合的,而且简单的约束一下时序就可以生产。

但重要的是看了这段逻辑后我们突然明白了一件事情:要想长生质量好的3分频时钟,我们似乎必须要用到clk的下降沿来做点控制逻辑,这是被反复求证后逼出来的(不知道其它人是否有同感)。那么我们为什么不愿意用下降沿触发的的寄存器呢?因为有些库里可能没有这样的器件,而必须在时钟树上上加反向。如果有下降沿的寄存器,那么今后的扫瞄链又要多一些麻烦,虽然这些麻烦都可以客服,但是作为一个成熟的工程师要明白:尽量不要给自己找麻烦。在工程上,最平常的东西最可靠。

4. 到这里我们的命题似乎解决了,但是我们的思考还不应该停止。既然我们要用clk的下降沿,呢就完全可以打破以前的思路,来看看这个新的手段能给我们带来什么。

always@(negedge resetn or posedge clk)
begin
    if (resetn==1'b0)
    begin
        cnt1[1:0]<=2'd0;
        clk1<=1'b0;
    end
    else
    begin
        if(cnt1[1:0]==2'd2)
        begin
            cnt1[1:0]<=2'd0;
            clk1<=1'b1;
        end
        else
        begin
            cnt1[1:0]<=cnt1[1:0]+1;
            clk1<=1'b0;
        end
    end
end

always@(negedge resetn or negedge clk)
begin
    if (resetn==1'b0)
    begin
        clk2<=2'd0;
    end
    else
    begin
        clk2<=clk1;
    end
end

assign clk_out = clk1 | clk2;

代码似乎更简单了,思路也完全变了。这回的思路是:先做一个简单的3分频电路,然后再调整占空比。以这个思路,所有的1/N分频都可以解决。

很高兴么?其实是有点失落。我们费了很大的周折,最后的结果竟然是这么传统的分频方法(后加一些调整),如果早知道是这样恐怕都没有人愿意浪费时间来就此问题专门的讨论。

但是我们对结果满意么?似乎有点疑虑。因为我们更喜欢寄存器做最后的输出,而对组合逻辑输出总是觉得不那么妥当。至少我的内心一致有这样的情节。

5. 最后的总结:

写这个东西并不是真的要讨论3分频电路,至少对于我来说不是,我只想说明一个ASIC工程师在面对一个问题时,从理想到现实到现实的挣扎过程。只有每天都经历这个过程的人才明白ASIC工程师的含义和价值。

有时会有人问我做ASIC前端好好事后端好,我不能答。我比较不出好坏,但是我知道要是你想做前端工程师就要时常面对上述的思考过程,这是纯粹脑力的耗费,而结果往往让别人觉得很简单,所以有时你还要承受这样的不平衡。因为对于一个没有真正经历过ASIC工程的人,你耗费的脑力和解释都是苍白的,而这个人很可能就是你的老板。

关于3分频电路的讨论相关推荐

  1. 数字芯片设计中的时钟分频电路,你了解多少?

    时钟分频电路在数字芯片设计中非常常见,而且也非常重要,正确的符合要求的数字分频电路对功能的正确与否至关重要.现在数字电路设计中的时钟分频主要包括以下几种方法: 1.寄存器分频 寄存器分频就是利用寄存器 ...

  2. IC/FPGA校招笔试题分析(二)任意切换的时钟分频电路

    今天的笔试题是某芸科技的现场笔试题,数字前端的笔试题,要求很简单,就是现场写出代码实现: 任意切换1-8分频,且无论奇分频还是偶分频,占空比均为50%,我至今仍然认为,在那种紧张且时间有限的情况下(本 ...

  3. 【Verilog HDL 训练】第 11 天(分频电路)

    设计一个占空比50%的三分频电路. 针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的.针对其中的错误,我令立博文记录之:[ Verilog ]alw ...

  4. FPGA笔试题解析(五):串并转换与奇分频电路

    题目:使用状态机实现序列检测器? 序列检测器的状态机实现,以前的博文写的很多,这里贴出两个简单易懂的,看需要的部分即可: 序列检测器的Moore状态机实现 序列检测器的Mealy状态机实现 题目:用V ...

  5. Verilog实现之任意分频电路

    一.行波时钟 任意分频电路,相信很多人都听说过这个专业名词,好多视频上都说不建议使用计数器产生的分频时钟.其实在FPGA领域当中,由寄存器分频产生的时钟还有一个学名叫做,行波时钟.是由时序逻辑产生比如 ...

  6. verilog分频电路

    二分频电路: module div2( input clk, input rst_n, output reg clk_o );always@(posedge clk or negedge rst_n) ...

  7. FPGA分频电路实现(奇数,偶数,小数半分频,任意分频)

    https://blog.csdn.net/weixin_43950612/article/details/104687942(简介明了,奇数,偶数,小数,任意分频) http://www.myexc ...

  8. 奇数分频电路—5分频(verilog实现)

    文章目录 前言 占空比不为50%的奇数分频 占空比为50%的5分频电路 扩展 前言 前文我们讲到,可以通过计数器的方法实现偶数分频,实现方式可以参考4分频电路实现 那么对于奇数分频电路应该如何实现呢? ...

  9. 占空比可调的分频电路实现

    在时序逻辑电路中,除了实现时钟的奇偶分频,还会涉及到时钟的占空比问题,现就该问题进行如下分析. 实现占空比为50%的分频电路很简单,对于偶分频电路只需将cnt计数到一半时进行输出q的翻转即可.比如8分 ...

最新文章

  1. java 中的 Annotation 注解学习笔记
  2. 2021年春季学期-信号与系统-第九次作业参考答案-第二小题
  3. Android用户界面开发(2):ListView
  4. hive 插入数据映射到hbase_大数据基础知识:Hadoop分布式系统介绍
  5. python数据结构 树_python数据结构之二叉树的统计与转换实例
  6. Eclipse 报java.lang.OutOfMemoryError: PermGen space错
  7. Java部分A+B正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。现给定A、DA
  8. java sqlserver 死锁_sqlserver数据库发生死锁处理
  9. hadoop环境安装及简单Map-Reduce示例
  10. PHPCMS 核心代码与 www 分离部署
  11. Aligned公司在凤凰城建设数据中心将采用微电网的电力
  12. 联想笔记本S10电池拆解
  13. 第八章、Zigbee模块的性能及测试
  14. HDOJ 5773 The All-purpose Zero
  15. 计算机应用后期影音制作,WindowsLive影音制作分步说明.docx
  16. 用python实现自动化翻译
  17. Second season twenty-fourth episode,Rachel‘s ex-boyfriend is going to marry Rachel‘s maid of honor
  18. 第一章:Activiti工作流教程
  19. 微光集市-商品及其商品信息的显示(版本1.0)
  20. 第一次玩switch,需不需要再买一个任天堂Pro手柄

热门文章

  1. (一)D3D9渲染原理
  2. d3d透视逆向篇:第5课:D3D9游戏黑屏优化2 DrawIndexedPrimitive
  3. 非负大整数加法---网易校招附加题
  4. java集合(超详细)
  5. 钉钉应用开发服务器API错误码原因及解决方法
  6. 凌动z3735f运行64位linux,iwork8平板电脑安装ubuntu,Z3735d/f系列CPU通用
  7. 阿里服务器配置随笔记 centos 服务器 Linux 部分命令合集
  8. 玩转WSL 2(一)——WSL的介绍和安装
  9. mysql优化之in内子查询
  10. cadence安装完怎么打开_为何cadence软件在虚拟机里安装成功了以后打不开