写点什么

同步计数器设计与建模

作者:timerring
  • 2023-02-06
    甘肃
  • 本文字数:2833 字

    阅读完需:约 9 分钟

⭐本专栏针对 FPGA 进行入门学习,从数电中常见的逻辑代数讲起,结合 Verilog HDL 语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机 FSM 进行剖析与建模。

🔥文章和代码已归档至【Github 仓库:hardware-tutorial】,需要的朋友们自取。或者关注公众号【AIShareLab】,回复 FPGA 也可获取。

概 述

(1) 计数器的逻辑功能


计数器的基本功能是对输入时钟脉冲进行计数。它也可用于分频、定时、产生节拍脉冲和脉冲序列及进行数字运算等。


(2) 计数器的分类


按脉冲输入方式,分为同步和异步计数器


按进位体制,分为二进制、十进制和任意进制计数器


按逻辑功能,分为加法、减法和可逆计数器



计数器运行时,依次遍历规定的各状态后完成一次循环,它所经过的状态总数称为计数器的“模”(Modulo),通常用 M 表示。

同步计数器的设计

例 用 D 触发器和逻辑门设计一个同步六进制计数器。要求有一个控制信号 U,


  • 当 U=1 时,计数次序为递增计数 0,1,2,3,4,5,0,1,2,…;

  • 当 U=0 时,计数次序为递减计数 5,4,3,2,1,0,5,4,3,…。


另外,当递增计数到最大值 5 时,要求输出一个高电平 CO=1;当递减计数到最小值 0 时,也要求输出一个高电平 BO=1。


解:(1) 分析设计要求,画出总体框图。


根据要求,计数器共有 6 个状态,我们要用 D 触发器来表示或区分出这 6 个状态,需要多少个 D 触发器才够呢?由于 3 个 D 触发器能够存储 3 位二进制数,而 3 位 2 进制数能表示 23=8 个状态,即 000,001,010,011,100,101,110,111,所以只需要 3 个触发器就能表示 6 个状态。


总体电路框图如下:



左半部分是 3 个 D 触发器,用于记录计数器的当前状态。右半部分是组合逻辑,生成下一个状态信号并产生输出信号。由于下一个状态信号与触发器的 D 端相连接,因此,该信号也被称为触发器的激励信号。


(2) 画出状态转换图



(3)列出转换表



(4)确定下一个状态的逻辑表达式



\begin{array}{l}N S[0]=\overline{Q[1]} \cdot \overline{Q[0]}+\overline{Q[2]} \cdot \overline{Q[0]} \N S[1]=\bar{U} \cdot \overline{Q[2]} \cdot \overline{Q[1]} \cdot Q[0]+\bar{U} \cdot \overline{Q[2]} \cdot Q[1] \cdot \overline{Q[0]}+U \cdot \overline{Q[2]} \cdot Q[1] \cdot Q[0]+U \cdot Q[1] \cdot \overline{Q[1]} \cdot \overline{Q[0]} \N S[2]=\bar{U} \cdot \overline{Q[2]} \cdot Q[1] \cdot Q[0]+\bar{U} \cdot Q[2] \cdot \overline{Q[1]} \cdot \overline{Q[0]}+U \cdot \overline{Q[2]} \cdot \overline{Q[1]} \cdot \overline{Q[0]}+U \cdot Q[2] \cdot \overline{Q[1]} \cdot Q[0] \\end{array}


同理, 得到



(5) 画出逻辑图


同步计数器的 Verilog HDL 建模

例 试用 Verilog HDL 对图所示电路建模


(1)设计块:


module Counter6 (CP,CLR_,U,Q,CO,BO);   input CP, CLR_, U;     output reg [2:0] Q;     //Data output   output CO,BO; assign CO = U  & (Q == 3'd5); assign  BO = ~U & (Q == 3'd0) & (CLR_== 1 ' b1); always @ (posedge CP or negedge CLR_)   if (~CLR_) Q <= 3'b000; //asynchronous clear   else if (U==1)          //U=1,Up Counter         Q <= (Q + 1'b1)%6;    else if (Q == 3'b000)         Q <= 3'd5;    else                    //U=0,Down Counter         Q <= (Q - 1'b1)%6;endmodule
复制代码


(2)激励块:给输入变量(CLR_、CLK 和 U)赋值,产生激励信号。


module Test_Counter6 ;    reg  U;           //Up/Down inputs          reg  CLK, CLR_;   //Clock and Reset    wire  CO,BO;      //output      wire [2:0]  Q;    //Register output
Counter6 U0(CLK,CLR_,U,Q,CO,BO); //实例引用设计块 initial begin // CLR_ CLR_ = 1'b0; CLR_ = #10 1'b1; #360 $stop; end always begin // CLK CLK = 1'b0; CLK = #10 1'b1; #10; end initial begin //U U = 1'b0; #190; U = 1'b1; end endmodule
复制代码


(3)仿真结果:


六进制计数器的仿真波形



例 试用 Verilog HDL 描述一个带有异步置零和具有使能功能的同步十进制递增计数器。


//Non-Binary counter with ENable module M10_counter (EN,CP,CLR_,Q);    input EN,CP,CLR_;   output reg [3:0] Q;      //Data outputalways @(posedge CP or negedge CLR_)  if (!CLR_)                //异步清零            Q <= 4'b0000;   else if (EN) begin        if (Q >= 4'b1001)             Q <= 4'b0000;   //出错处理       else Q <= Q + 1'b1;  //递增计数       end    else             Q <= Q;         //保持计数值不变endmodule
复制代码


例:请描述具有异步清零、同步置数的计数器,并要求具有可逆计数和保持的功能。


module cntr(q, aclr, clk, func, d);input aclr, clk;input [7:0] d;//Controls the functionality input [1:0] func; output [7:0] q;reg [7:0] q;always @(posedge clk or posedge aclr) begin  if (aclr)   q <= 8'h00;  else  case (func)     2'b00: q <= d; // Loads the counter     2'b01: q <= q + 1; // Counts up     2'b10: q <= q - 1; // Counts down     2'b11: q <= q;   endcaseendendmodule
复制代码


例:假设有一个 50 MHz 时钟信号源,试用 Verilog HDL 设计一个分频电路,以产生 1Hz 的秒脉冲输出,要求输出信号的占空比为 50%。


解:设计一个模数为的二进制递增计数器,其计数范围是 0~24999999,每当计数器计到最大值时,输出信号翻转一次,即可产生 1Hz 的秒脉冲。


module Divider50MHz(CR,CLK_50M, CLK_1HzOut);  input  CR,CLK_50M;   output reg CLK_1HzOut;     reg [24:0] Count_DIV; //内部节点parameter CLK_Freq = 50000000;parameter OUT_Freq = 1;always @(posedge CLK_50M or negedge CR)  beginif(!CR)  begin       CLK_1HzOut <= 0;       Count_DIV     <= 0;       endelse  beginif( Count_DIV < (CLK_Freq/(2*OUT_Freq-1)) )            Count_DIV <= Count_DIV+1'b1;   else begin   Count_DIV     <=  0;      CLK_1HzOut  <=  ~CLK_1HzOut;          end endendendmodule 
复制代码


产生 1Hz 的秒脉冲输出分频电路


always @(posedge CLK_50M or negedge CR) begin  if(!CR)  begin               CLK_1HzOut <= 0;                    Count_DIV     <= 0;      end  else  begin           if( Count_DIV < (CLK_Freq/2*OUT_Freq-1) )                     Count_DIV <= Count_DIV+1'b1;             else begin                     Count_DIV      <=  0;                           CLK_1HzOut  <=  ~CLK_1HzOut;                    end           endendendmodule 
复制代码




欢迎关注公众号【AIShareLab】,一起交流更多相关知识,前沿算法,Paper 解读,项目源码,面经总结。

发布于: 刚刚阅读数: 3
用户头像

timerring

关注

公众号【AIShareLab】 2022-07-14 加入

公众号【AIShareLab】

评论

发布
暂无评论
同步计数器设计与建模_FPGA_timerring_InfoQ写作社区