移位寄存器分频原理与Verilog实现:从偶数到奇数分频
2026/9/20 18:42:44 网站建设 项目流程

简介:这是一份面向数字逻辑电路学习者及计算机相关专业学生的技术文档,专门讲解如何用移位寄存器实现分频。文档以74LS194和74LS138为核心,从固定比分频器到可编程分频器层层递进,给出具体电路图和波形分析,并总结分频系数计算规律,便于读者直接套用设计。资源为单个docx文件,容量仅98KB,内容精炼但覆盖完整,适合快速查阅或课堂补充。目前已有994人学习,是数字电路分频章节的实用参考资料。通过学习可清晰理解移位寄存器在时钟管理、频率合成中的应用,掌握根据地址输入控制分频比的编程思路,为后续通信系统或控制系统设计打下基础。

1. 从一道实验题说起:移位寄存器为什么能分频

1.1 这个标题背后的真实需求

先说个挺有意思的现象。很多人在数字逻辑电路课上学完触发器、时序逻辑之后,做的第一个综合性实验往往就是“用移位寄存器实现分频”。这个题目看起来简单,实际上暗藏不少门道——它考的不仅是你知不知道移位寄存器能移位,更考你能不能把“移位”这个动作跟“分频”这件事的本质联系起来。

“数字逻辑电路 用移位寄存器分频”这个课题,本质上是想让你搞清楚三件事:

  • 触发器级联成移位寄存器后,数据每移一位,输出相对于输入时钟到底滞后了多少个周期;
  • 如何利用这种滞后关系,让输出波形频率变为输入时钟的整数分之一;
  • 偶数分频容易做,奇数分频和50%占空比才是真正拉开差距的地方。

这个知识点在工程里并不冷门。FPGA开发中常见的时钟分频、串行通信中的波特率生成、数字信号处理里的时钟同步,底层都离不开移位寄存器分频这套思路。我当年调试一块音频编解码芯片的MCLK时钟树时,就亲手用移位寄存器搭过一版3分频,虽然最后量产换成了PLL,但那次的经验让我把“分频”这件事彻底吃透了。

1.2 这篇博文给你解决什么问题

如果你是正在学数字逻辑电路的学生,这篇内容能帮你把实验报告里“只会画图、不会讲原理”的尴尬补上;如果你是刚入门FPGA的开发者,这里面的Verilog代码和时序图画法可以直接抄作业;哪怕你已经工作多年,偶尔回看这些基础电路,也常会有“原来当年没真懂”的感慨。

我把这个课题拆成了五个部分:先说移位寄存器分频的原理本质,再讲偶数分频和奇数分频的实现套路,然后给出Verilog代码和Wavedrom时序图的实操方法,最后汇总几个我实际踩过的坑。每个部分的结论都基于仿真和实测,不是PPT层面的推演。

注意:本文所有实现均采用同步时序设计,所有触发器共用一个时钟源,这是保证分频电路稳定工作的最基本前提。任何异步级联的“ripple计数器”式分频,在工程上都不推荐,后面我会专门讲原因。

2. 移位寄存器分频的核心原理:移位即延时,延时即分频

2.1 从D触发器的“一拍”说起

要理解移位寄存器分频,先得建立一个概念:一个D触发器在时钟上升沿到来时,会把输入端的值“锁存”到输出端,输出的变化比输入慢一个时钟周期。这一拍的时间差,就是时序电路的灵魂。

类比一下日常生活:你喊一嗓子,山谷里隔一会儿传来回声。如果回声源不止一个,而是排成一串,你的喊声会依次经过它们,每一站都延迟一步。移位寄存器就是这么一串“回声站”——数据从第一级传到第二级、第三级,每传一级就晚一个时钟周期。

分频的本质,是把“周期”这个概念从时间域转换到“级数”域:既然输出每经过一拍才变化一次,那它变化的节奏自然就比输入时钟慢。慢多少,取决于你让数据在寄存器链里绕了多少圈。

下面这个示意图展示了4级移位寄存器的数据流动:

时钟周期: [1] [2] [3] [4] [5] [6] [7] [8] 输入数据: 1 0 1 0 1 0 1 0 Q1输出: - 1 0 1 0 1 0 1 Q2输出: - - 1 0 1 0 1 0 Q3输出: - - - 1 0 1 0 1 Q4输出: - - - - 1 0 1 0

你看,Q4的输出相比输入整整晚了4拍。如果你把Q4的信号反馈回输入端,这个延迟就会形成“振荡”——每4拍输出翻转一次,8拍完成一个完整周期,于是从Q4看出去,频率恰好是输入时钟的1/4。这就是4分频。

2.2 两种基本分频结构对比

用移位寄存器实现分频,大体有两条路线。我把它们列个表对比一下,方便你理解为什么绝大多数情况下我们选第二种。

结构方式实现思路优点缺点典型应用
环形计数器分频移位寄存器输出反馈到输入,数据循环移动结构简单,各输出相位均匀分频比N需要N个触发器,资源消耗大顺序脉冲发生器、多相时钟生成
移位寄存器+反馈逻辑分频将若干级输出组合成反馈函数,再送回输入分频比灵活,可配置性高反馈逻辑需要设计,分析稍复杂可编程分频器、序列发生器、时钟管理

我实际用下来,环形计数器适合分频比不大、但需要多路等间隔相位输出的场合,比如三相无刷电机的换相控制。而“移位寄存器+反馈逻辑”这种结构更有通用性——你只需要改变反馈连接方式,就能在同一个移位寄存器上实现不同分频比。

2.3 分频比与寄存器级数的数学关系

对于“反馈型”分频器,有一个非常实用的结论:如果要实现N分频(输出时钟周期是输入时钟的N倍),你需要一个M级的移位寄存器,其中M通常等于N(偶数分频)或者和N存在明确关系(奇数分频)

具体来说:

  • N为偶数时,寄存器级数M = N,数据从第一级移到最后一级再取反反馈回第一级;
  • N为奇数时,如果要严格的50%占空比,最少需要M = N级,但反馈的取法要把“赶上沿”和“赶下沿”两种路径组合起来,这个下一节细讲。

这个结论的推导逻辑其实来自“周期定义”:一个完整周期包含高电平和低电平两个阶段。如果高低电平的持续时间相同(50%占空比),那么每一段持续的时间就是N/2个输入时钟周期。你要让输出在N/2个时钟后翻转,就得让信号经过N/2拍的延迟再反向。移位寄存器天然提供整数的拍数延迟,所以N必须能被2整除,这就是偶数分频“顺理成章”的原因;奇数分频的难点也正在于这个“N/2不是整数”。

在实际工程里,我建议你选分频方案时先问自己两个问题:占空比有没有严格要求?输出相位精度需不需要对齐输入时钟边沿?如果两个都不要求,计数器分频比移位寄存器分频更省资源;如果要求严苛,移位寄存器方案才有不可替代的优势。

3. 偶数分频:最基础也是最容易出错的地方

3.1 用移位寄存器实现2分频的三种等价画法

2分频是分频电路的基本功。用移位寄存器实现时,一个不太为人知的事实是:级数不同,效果一样,但信号路径完全不同

方法一:一级D触发器,Q非端反馈回D端。这是教科书上“T触发器”的标准接法,但严格来说它只用了一个触发器,算不上“移位寄存器”。

方法二:两级D触发器串联(Q1→D2),Q2反馈到D1。这种接法数据在两个触发器之间绕圈,每两个时钟周期Q2翻转一次。好处是Q1和Q2输出正好相位相差一个时钟周期,如果需要两路正交时钟,这种结构天然提供。

方法三:只用一级D触发器,但D端接前一级的互补输出(即Q非)。本质上等同于方法一。

实际做实验时,很多同学喜欢用方法二,因为“更像移位寄存器”。但从可维护性角度,其实方法一最简洁——一个触发器解决2分频,何必多耗一个FF资源。

3.2 4分频和8分频:级联的两种接法别搞混

4分频、8分频这类2的幂次分频,有两种实现思路,很多人一开始很容易混。

思路A:把2分频电路级联。2分频的输出接下一级的时钟输入,形成“异步级联”。这种方法电路画起来简单,但每一级的输出相对输入时钟都有固定的传播延迟,级数多了之后,各级输出的时钟歪斜会越积越大,时序分析非常痛苦。

思路B:用4级/8级移位寄存器同步级联,所有触发器共用一个时钟,反馈从最后一级取。这种方法才是标准的“移位寄存器分频”。

举个例子,4分频用寄存器链实现:

module divide_by4_shiftreg ( input wire clk, input wire rst_n, output wire clk_out ); reg [3:0] shreg; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin shreg <= 4'b0000; end else begin shreg <= {shreg[2:0], ~shreg[3]}; end end assign clk_out = shreg[3]; endmodule

这里的关键点是~shreg[3]——这是反馈逻辑,让数据在寄存器链里取反循环。你仔细算一下:初始shreg全部为0,第一个时钟上升沿后shreg变为4'b0001(因为~shreg[3] = ~0 = 1),第二个上升沿变为4'b0011,以此类推,数据逐渐填充,到第8个时钟后shreg回到全0,刚好完成一个周期。

clk_out取的是最高位shreg[3],它的波形是“前4拍为0,后4拍为1”,周期为8个输入时钟周期,所以频率是输入时钟的1/8?等等,这里要注意了——我上面写的这个代码实际是2N分频!因为反馈里有一个取反操作,寄存器链里的数据每N拍翻转一次,输出完整周期需要2N拍。

这就是一个非常经典的翻车点:移位寄存器反馈分频时,如果反馈逻辑里带了反相器,分频比输出的是2×M分频(M为寄存器级数);如果不带反相器(直接反馈),得到的是环形计数器,输出周期为M拍,但通常不能构成等宽方波

3.3 偶数分频实操中的三个常见翻车点

第一,初始化状态不对。仿真时如果寄存器初值全0,前几个周期的输出波形并非理想方波,需要先经过“预填充”阶段。实验之前最好先置一个非全0的初值,或者干脆用复位信号把电路置成已知状态,否则你的示波器上会看到一段“毛刺期”。

第二,把“移位寄存器”和“计数器”的效果混为一谈。功能上二者都能分频,但计数器的输出是二进制编码,移位寄存器的输出是“独热码”或“密勒码”。如果你后级电路需要的是脉冲序列而非方波,选移位寄存器更自然;如果你只需要一个分频时钟,纯计数器反而省逻辑门。

第三,占空比不是50%的情况。偶数分频如果反馈取反,输出天然50%占空比,因为高低电平各占M拍;但如果直接取某个中间级输出而不加反馈,得到的可能是M对M的等宽输出,也可能是高电平M1拍、低电平M2拍的不等宽波形。画原理图之前先把波形图画出来,能避免很多低级错误。

4. 奇数分频与50%占空比:难题的真正解法

4.1 为什么奇数分频这么让人头疼

先说个必须认清的现实:用普通的单链移位寄存器做3分频、5分频、7分频,如果要求输出严格50%占空比,直接用“最高位反馈取反”的办法行不通。原因前面提过——奇数N除以2不是整数,你没法让信号在N/2拍精确翻转。

那是不是说移位寄存器就不能做奇数分频了?当然不是。工程上常见的思路有两种:

思路一(双沿采样法):用两个移位寄存器链,一个在时钟上升沿工作,一个在时钟下降沿工作,最后把两路输出相或。这是最经典、也最容易理解的奇数分频50%占空比实现方式。

思路二(状态机法):把移位寄存器拆成“状态寄存器”,用组合逻辑直接生成输出。本质上是在用有限状态机做分频,只是状态编码用了移位形式。

我重点讲思路一,因为它在工程里最实用。

4.2 5分频50%占空比:双沿采样法的详细拆解

以5分频为例。5分频要求输出周期是输入时钟的5倍,占空比50%意味着高电平持续2.5个时钟周期,低电平也持续2.5个时钟周期。问题是沿触发逻辑没法直接产生半拍——但你有两个边沿可以用啊。

具体做法:先不管占空比,用上升沿分频,产生一个高电平2拍、低电平3拍的输出clk_pos(这用普通的3级移位寄存器反馈就能做到);再用下降沿分频,产生一个高电平2拍、低电平3拍、相对clk_pos延迟半个时钟周期的输出clk_neg;然后把clk_pos和clk_neg相或,得到的高电平时间是“2拍 + 重叠的0.5拍”吗?不是——正确的相或结果是:高电平从clk_pos的上升沿开始,到clk_neg的下降沿结束,高电平持续时间是2拍加0.5拍,即2.5拍,低电平也是2.5拍。合计5拍,占空比50%。

下面是一个5分频的Verilog参考代码(基于D触发器级联实现双沿采样):

module divide_by5 ( input wire clk, input wire rst_n, output wire clk_out ); reg [4:0] shreg_pos; reg [4:0] shreg_neg; // 上升沿采样的移位寄存器链,实现5分频(不等宽) always @(posedge clk or negedge rst_n) begin if (!rst_n) shreg_pos <= 5'b00001; else shreg_pos <= {shreg_pos[3:0], shreg_pos[4]}; end // 下降沿采样的移位寄存器链,实现相位偏移半个时钟周期 always @(negedge clk or negedge rst_n) begin if (!rst_n) shreg_neg <= 5'b00001; else shreg_neg <= {shreg_neg[3:0], shreg_neg[4]}; end assign clk_out = shreg_pos[0] | shreg_neg[0]; // 相或,合成50%占空比 endmodule

注意这段代码里shreg_pos用的是循环右移(最高位反馈到最低位),这种接法会让shreg_pos[0]输出一个只有1拍高电平的脉冲序列,在循环5拍后重复。shreg_neg同理但晚半拍。两者相或后,合并出高电平2.5拍、低电平2.5拍的波形。

4.3 奇数分频的电路级实现:7474和门电路的组合

如果你做实验用的是74系列芯片而不是FPGA,电路图可以这样搭:

  • 用两片7474(双D触发器)搭出两条独立的5级环形移位寄存器?不对,一片7474只有2个触发器,5级需要3片,有点浪费。
  • 更经济的做法是用74164(8位串入并出移位寄存器)实现5级循环移位,再用两个触发器分别产生原始时钟沿采样后的相移版本,最后用一个或门合成。

对做实验的同学,我建议搭电路之前一定先把波形图用仿真器画出来。没有仿真波形直接接线,十有八九会在示波器上看到一堆莫名其妙的现象,尤其是反馈线接错导致的“分频比翻倍”或“占空比完全错乱”。

我这里提供一个Wavedrom编辑器的时序图描述片段,方便你在画波形图时直接参考。Wavedrom的语法非常简单,适合快速验证时序逻辑:

{ "signal": [ { "name": "clk", "wave": "p........." }, { "name": "q0", "wave": "0.1..0...." }, { "name": "q1", "wave": "0.01..0..." }, { "name": "q2", "wave": "0.001..0.." }, { "name": "clk_out", "wave": "0.1.0.1.0." } ]}

上面这个例子里,q0、q1、q2分别是移位寄存器各级输出,clk_out是某个组合后的输出信号。你可以用这个框架不断修改,直到自己调出符合预期的5分频50%占空比波形。

4.4 n和n+1分频切换时的相位误差问题

不少通信系统里的可变速率的时钟,需要动态在n分频和n+1分频之间切换,比如小数分频器(常见于PLL的Σ-Δ调制器)。这时候一个关键问题就来了:n分频和n+1分频的相位差是多少,切换瞬间会不会出现毛刺或相位跳变?

先说结论:分频比从n切换为n+1的瞬间,输出时钟的相位会有一个阶跃式突变——这个突变并不是理想的“瞬间对齐”,而是取决于切换时刻在分频周期中的位置。简单推导一下:假设n分频时输出周期为n·Tclk,n+1分频时输出周期为(n+1)·Tclk。在切换发生的那一个周期里,输出高电平(或低电平)的长度会突然多出或者少掉1个Tclk,这就造成输出时钟的“瞬时频率”偏离标称值。

如果你在PLL设计里用移位寄存器做多模分频器,必须记住:切换时刻要把分频器先置于预置态(比如把寄存器链清零或预置特定值),再切换反馈逻辑,才能避免输出一个极窄的毛刺脉冲。我在实验室里实测过,不做预置直接切换,输出波形上会出现一个宽度只有几纳秒的glitch,这在纯数字逻辑里不明显,但接到模拟锁相环的鉴频鉴相器上,会直接导致环路失锁。

5. Verilog实现与Wavedrom时序图实操

5.1 二分频、三分频、五分频的Verilog模板直接抄

这部分给一段可以直接跑的模板代码,覆盖2分频、3分频(50%占空比)、5分频(50%占空比)。

// ============ 二分频 ============ module div2 ( input wire clk, input wire rst_n, output wire clk_out ); reg q; always @(posedge clk or negedge rst_n) begin if (!rst_n) q <= 1'b0; else q <= ~q; end assign clk_out = q; endmodule // ============ 三分频(50%占空比,双沿相或法) ============ module div3 ( input wire clk, input wire rst_n, output wire clk_out ); reg [2:0] pos; reg [2:0] neg; always @(posedge clk or negedge rst_n) begin if (!rst_n) pos <= 3'b001; else pos <= {pos[1:0], pos[2]}; end always @(negedge clk or negedge rst_n) begin if (!rst_n) neg <= 3'b001; else neg <= {neg[1:0], neg[2]}; end assign clk_out = pos[0] | neg[0]; endmodule

你要注意两点:第一,三分频的代码里posneg都是3位循环移位寄存器,循环周期为3拍,pos[0]输出一个每3拍出现1拍高电平的窄脉冲。neg[0]是晚半拍的同样窄脉冲。相或后,两段窄脉冲之间的间隔被填上,形成1.5拍高电平+1.5拍低电平的输出。第二,初始化值必须是3'b001,不能是3'b000,否则电路永远不动作。

5.2 用Wavedrom Editor画时序图的具体姿势

Wavedrom Editor(网上的在线版本即可)是我目前见过最顺手的数字时序图工具。画二分频时钟的核心思路是:把时钟信号用连续电平描述,把分频输出信号按“延迟+翻转”规律描述。

二分频时序图可以这样写:

{ "signal": [ { "name": "clk", "wave": "p................" }, { "name": "clk_div2","wave": "0.1..0..1..0..1.." } ]}

.代表一个时钟周期的间隔,01代表低电平和高电平。如果你需要带箭头、标注捕捉沿,Wavedrom也支持配置"node""edge"字段。

实操提示:画时序图时不要手动数点,容易数错。先确定“一个完整输出周期占几个输入时钟周期”,再决定.的个数。比如二分频,一个输出周期占2个输入周期,所以clk_div2从0到1中间隔一个.,从1到0中间隔一个.,就不会画错。

5.3 从波形图反推电路连接:一个高效调试闭环

我发现很多人调试分频电路时习惯“接好线再看波形”,遇到问题就蒙圈。我更推荐“先画波形、再写代码/接线、最后对照波形验证”的三步流程:

  1. 先画出期望输出波形(用Wavedrom);
  2. 根据波形确定寄存器级数和反馈逻辑;
  3. 在仿真器里跑一遍,把仿真波形和Wavedrom波形叠在一起对比。

这样做的好处是,你能把“设计错误”和“实现错误”区分开。比如你期望5分频但仿真出来是10分频,那大概率是反馈多加了反相器;如果你期望高电平2.5拍但仿真出来高电平只有2拍,那多半是相或的合成时机不对。这种“先画图再接线”的习惯,能让你少走很多弯路。

6. 分频电路常见问题与排查技巧实录

6.1 实测踩坑记录:占空比不对、相位乱跳、复位无效

我在带学生做这个实验时,最常见的故障可以归为三类。我按出现频率排个序,并给出排查步骤:

故障一:占空比不是50%。排查顺序:先看输出波形低电平和高峰各占几拍。如果是偶数分频,检查反馈路径上是否意外多了反相器;如果是奇数分频,检查双沿采样的两个链是否确实一个用posedge一个用negedge。我曾经见过一个同学把两个always块全写成了posedge,结果两条链相位完全相同,相或后输出高电平还是2拍、低电平3拍,跟没做一样。

故障二:输出频率是预期的两倍或一半。这通常是反馈逻辑选错了点。移位寄存器分频的输出频率取决于你从哪一级引出信号以及反馈是否取反。你可以用波形图反推:在纸上画出每一级寄存器的波形,再标出反馈信号的变化规律,基本能定位问题。

故障三:复位信号无效,电路上电后状态随机。FPGA里还好说,如果是74芯片搭的电路,上电初始状态不定是正常的。解决办法是:实验前手动按一下复位键,把寄存器链置为已知初值;或者在设计上让反馈逻辑能从全0状态自恢复。注意:环形移位寄存器如果进入全0状态就永远锁死在全0了,有的同学没考虑到这一点,复位一释放电路纹丝不动,还以为芯片烧了。

6.2 一张排查速查表,照着查就行

现象可能原因快速定位方法
输出波形完全不变反馈逻辑没有取反,或寄存器初值为全0检查反馈路径和初始化值
分频比是预期的2倍反馈中多加了反相器去掉反相器再仿真
占空比明显不对称奇数分频时双沿采样合成时机不对分别查看两条链的波形,确认相差半拍后相或
输出有毛刺异步级联导致时钟歪斜累积改为所有触发器共用一个时钟源
频率漂移或抖动分频切换瞬间未预置状态,产生窄脉冲切换前对分频器预置初值
复位后电路不起振寄存器全0无法自恢复检测复位逻辑,用非全0初值

6.3 一个颠覆认知的案例:改成“共时钟”之后一切都对了

有一次我帮一个师弟调一个8分频电路,他发现输出波形总有随机毛刺,频率也不稳定。我第一反应是电源去耦不够,但加了电容没用。后来拿示波器一量,发现他把三个2分频电路级联,每一级的输出直接接到下一级的时钟输入——也就是异步级联。

这在低速下问题不大,但在几十兆赫兹时钟下,每一级D触发器的clk-to-q延迟累加起来,第三级的时钟边沿已经被“抖”得不成样子。问题的根源根本不是逻辑错误,而是时序余量不够

后来我把三级2分频改成8位移位寄存器同步分频结构,所有触发器共用一个时钟,毛刺立刻消失。这个案例给我们的启发是:分频电路的“看起来正常”和“真的可靠”之间,隔着一条叫做时序分析的鸿沟。如果你在工程里遇到在实验室怎么都复现不了的随机故障,先怀疑异步设计,这是绝大多数时序问题的来源。

6.4 给实验报告加分的几个细节

最后说点掏心窝的建议。如果你在做课程实验,想要让报告或者演示脱颖而出,可以顺手做这几件事:

  • 用示波器的“余晖模式”观察分频输出波形的抖动,对比同步结构和异步级联的差别;
  • 在Verilog仿真里加一段断言(assert),自动检查占空比是否在49%~51%之间,体现出你的工程素养;
  • 如果你用的是FPGA,尝试用Vivado或Quartus里的“时钟资源报告”看分频后信号被分配到了哪个时钟网络,顺便了解为什么门控时钟在FPGA里不推荐。

这些内容虽然不会直接改变分频电路的逻辑,但能证明你对“分频”这件事的理解不止于“画个波形图”。

我在实际项目中养成的习惯是:每个分频器设计完成后,都要额外画一个“分频切换瞬间”的时序图,专门检查切换边界有没有毛刺、占空比有没有突变。这个习惯救过我至少两次——一次是通信板卡上的可变速时钟需要动态切换,另一次是MCU外部晶振失效后切换到内部RC时钟,用的就是移位寄存器分频做的无缝切换。分频这个东西,表面上看是数字逻辑课的基础题,但真到了需要“可靠工作”的场合,每一处细节都经得起推敲才算合格。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询