本文从本人的163博客搬迁至此。

MFM是改进型频率调制的缩写,其本质是一种非归零码,是用于磁介质硬盘存储的一种调制方式。调制规则有两句话,即两个翻转条件:

1、为1的码元在每个码元的正中进行一次翻转;为0的码元不翻转。

2、对连续两个为0的码元,则在第一个为0的码元结束时翻转一次;单个的0码元不翻转。

设计过程:

若码元的同步时钟为CLK,不失一般性,假设CLK的上升沿开始产生新的码元,下降沿为该码元的正中。则MFM调制信号有可能在时钟的上升沿,也有可能在时钟的下降沿发生电平翻转。由于一个触发器不会在两个边沿都翻转,也就不可能由单个触发器的输出作为MFM调制的输出。一种合理的思路是分别由一个上升沿和一个下降沿触发器分别在上升沿和下降沿翻转,然后用它们的输出相异或的结果作为总输出。特别值得注意的是,异或具有如下的属性:参与异或的两个数,不论其中一个为01,只要另一个发生翻转,异或的结果一定会翻转。下面分别来实现MFM调制规则的两个条件,即在满足条件1时翻转的电路——设其输出为Dout1,和满足条件2时翻转的电路——设其输出为Dout2,再将它们异或为最终的MFM调制结果Dout。

条件1要求在为1的码元的正中进行一次翻转,比较容易实现,使用受控的触发器时钟即可。条件2较难实现,原因在于其对应的触发器需要在第二个码元为0的还没有到来之前,先就对是否存在两个连续为0的码元做出判断,并在第二个为0的码元开始出现的上升沿就先翻转。由于我们的电路不可能“未卜先知”地知道上升沿出现后的码元是否为0,只能让判断条件2的电路延迟(潜伏)一个时钟(CLK)周期后再发生翻转。当然由于条件2翻转的触发器电路,需要延迟一个CLK,条件1翻转的触发器电路也必须随之延迟一个时钟周期,以同步于条件2翻转的电路。图1中的DinD就是延迟一个时钟周期后的输入被调制信号。

图1 MFM调制电路及其时序

满足条件1的电路,应该由两部分构成。第一个部分在上升沿动作,完成延迟一个时钟周期。第二部分则在下降沿动作,当码元为1时在下降沿翻转Dout1,为一个T'触发器。

满足条件2的电路,也由两部分组成。第一个部分是一组下降沿移位寄存器,该移位寄存器有两个D触发器构成,负责保存最近两个下降沿时刻码元的值,当两个触发器同时为0时输出允许Dout2翻转的信号。第二个部分是在第一部分允许的条件下,在上升沿翻转的T'触发器,其输出就是Dout2。

从图中可以看到,本电路是一个典型的异步时序逻辑电路,为了在连续的一个/组下降沿和上升沿之间不间断地动作,满足条件1的电路和满足条件2的电路的前后两个部分所使用的时钟边沿都不相同。使用硬件描述语言时,需要分别使用两个always模块来对应上升沿和下降沿电路。由于上升沿电路和下降沿电路交叉出现在两个always模块中,这段VerilogHDL不太容易直接看懂。

 module MFM(

     input CLK,      //产生被调制信号的时钟,其周期等于被调制信号一个码元的宽度

     input Din,      //被调制信号

     input rst,      //复位信号

     output DinD,    //延迟了一个clk周期的被调制信号

     output Dout1,   //为1的码元在码元正中翻转的信号

     output Dout2,   //连续两个为0的码元,在两个码元之间翻转的信号

     output MFM_Dout //Dout1和Dout2异或的结果,也就是DOUT1和Dout2翻转时都翻转的信号。

     );

     reg DinD_reg;//这个寄存器的值将输入延迟了一个时钟周期

     reg Dout1_reg;//Dout1对应的寄存器

     reg Dout2_reg;//Dout2对应的寄存器

     reg[:] D_reg_n;   //在下降沿缓冲两级输入,以判断是否是连续两个0

     assign DinD = DinD_reg;

     assign Dout1 = Dout1_reg;

     assign Dout2 = Dout2_reg;

     assign MFM_Dout = Dout1^Dout2;

 //异或的属性就是不论第一个自变量为0还是1,只要第二个自变量变化,结果都会跟着变化,因此MFM_Dout可以在DOUT1和Dout2翻转时都翻转

     always @(posedge CLK or posedge rst)

     begin

         if(rst)

         begin

             DinD_reg <= ;

             Dout2_reg <= ;

         end

         else begin

             DinD_reg <= Din;

             if(~(D_reg_n[]|D_reg_n[]))

 //如果D_reg_n[0]和D_reg_n[1]都为0则翻转Dout2

                 Dout2_reg <= ~Dout2_reg;

         end

     end

     always @(negedge CLK or posedge rst)

      begin

          if(rst)

          begin

              Dout1_reg <= ;

              D_reg_n[:] <= 'b11;

          end

          else begin

              if (DinD == )

                  Dout1_reg <= ~Dout1_reg;

              D_reg_n[:] <= {D_reg_n[],Din};

 //缓冲两个下降沿时的输出,如果都为0,则需要在下一个上升沿翻转Dout2

          end

      end

 endmodule

上述代码在Vivado中综合后,得到下图所示的Schematic。

图2 在Vivado中综合后产生的Schematic

这个实例再次印证了用硬件描述语言开发硬件电路的那个准则:在开始描述之前,脑中应该先有电路的大概模型,否则不可能综合出满足要求的硬件电路。

一个有趣的异步时序逻辑电路设计实例 ——MFM调制模块设计笔记的更多相关文章

  1. 一个有趣的小例子,带你入门协程模块-asyncio

    一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...

  2. FPGA学习笔记(六)—— 时序逻辑电路设计

    用always@(posedge clk)描述        时序逻辑电路的基础——计数器(在每个时钟的上升沿递增1) 例1.四位计数器(同步使能.异步复位) // Module Name: coun ...

  3. 04-时序逻辑电路设计之计数器——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献 实验目的:以计数器为例学会简单的时序逻辑电路设计 实验平台:芯航线FPGA核心板 实验原理: 时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入 ...

  4. verilogHDL设计中的同步时序逻辑

    引用自夏宇闻教授 1.同步时序逻辑: 是指表示状态的寄存器组的值只能在唯一确定的触发条件发生改变. 只能由时钟的正跳变沿或者负跳变沿触发的状态机就是一例,always@(posedge clk). 1 ...

  5. 03-组合逻辑电路设计之译码器——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线——普利斯队长精心奉献 课程目标:    1. 再次熟悉Quartus II工程的建立以及完整的FPGA开发流程 2. 以译码器为例学会简单组合逻辑电路设计 实验平台:无 实验原理: 组合逻辑, ...

  6. 组合逻辑的Glitch与时序逻辑的亚稳态

    竞争(Race):一个门的输入有两个及以上的变量发生变化时,由于各个输入的组合路径的延时不同,使得在门级输入的状态改变非同时. 冒险或险象(Hazard):竞争的结果,如毛刺Glitch. 相邻信号间 ...

  7. 我的 FPGA 学习历程(09)—— 时序逻辑入门

    讲到这篇时,组合逻辑就告一段落了,下面是一些总结: 描述组合逻辑时,always 语句中的敏感信号列表中需要列出全部的可能影响输出的变量 描述组合逻辑时,always 语句中的赋值总是使用阻塞赋值符号 ...

  8. 从头学起Verilog(二):时序逻辑基础与回顾

    引言 时序逻辑对于数字电路设计十分重要,本文针对数字电路中的时序逻辑部分进行了系统的回顾. 存储器件 由于时序逻辑的输出不但受当前输入影响,还受之前的输入的影响,所以需要有存储单元对以前的输入进行存储 ...

  9. 【小贴士】关于transitionEnd/animate的一个有趣故事

    前言 在很久之前,我们项目有一个动画功能,功能本身很简单,便是典型的右进左出,并且带动画功能 以当时来说,虽然很简单,但是受限于框架本身的难度,就直接使用了CSS3的方式完成了功能 当时主要使用tra ...

随机推荐

  1. Input type=number 样式清除

    /* 普通IE浏览器 样式清除 */ input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{ -webkit-appear ...

  2. input radio单选框样式优化

    HTML代码: <form> <div> <input id="item1" type="radio" name="it ...

  3. Android--PullToRefreshListView的onRefreshComplete()不起作用的问题

    今天用到了网上开源的下拉刷新组件PullToRefreshListView的第三方下拉刷新的ListView 我们发现 有时候我们当使用它的onRefreshComplete()方法是,我们下拉出来的 ...

  4. 网站与phpwind用户同步的方法

    搭建了一个个人网站,希望使用phpwind来完成论坛功能.但很快就发现存在用户同步的问题,我的网站已经有了用户管理功能, phpwind论坛也有.因此用户同步注册,登陆和注销是必须要实现的. 网上说可 ...

  5. Python+Selenium笔记(十六)屏幕截图

    (一) 方法 方法 简单说明 save_screenshot(filename)   获取当前屏幕截图并保存为指定文件 filename:路径/文件名 get_screenshot_as_base64 ...

  6. Asp.Net MVC 模型(使用Entity Framework创建模型类)

    这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...

  7. Javaweb学习(二):Http通信协议

      当我们开始jsp/servlet编程之旅之前,我们还需要知道一些关于网络通讯方面的一些知识.这样能更加有助于我们的理解,希望大家能看懂我的描述,而不至于在学习的路上一知半解.(手动比❤) 认识Ht ...

  8. python基本语法:

    http://www.runoob.com/python/python-basic-syntax.html

  9. 2019 wannafly winter camp

    2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...

  10. beta冲刺————第三天(3/5)

    完善的具体内容: 前端: (1)可以进行修改文字大小背景 其中,金色的文字个人觉得很好看,点赞.(我很满意啊) (2)可以改变成夜间模式(也很不错啊) 后端: 尝试将本地的后端war文件,以及数据库传 ...