加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

从电路到Verilog | Verilog不难学,聊聊时序逻辑那些事儿

2016/07/26
51
  • 1评论
阅读需 53 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

施主们辛苦了,学习语言一贯是一个苦差事。学 Verilog 还算好的,到底还是人工语言,有规律,还有《数字电子技术》这门课垫底(没学好这门功课的同学 ---- 学好与否,与您老的考试成绩无关 ---- 赶快回去找本教材好好看看)。如果是学习自然语言,那就更麻烦了。除了记忆还是记忆,这就是学习的规律,没有捷径的。


前面讲解了组合逻辑的事情,从今天起老衲来说说时序逻辑的端倪。


数字电路理论中,时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入形成的状态有关。 这跟组合逻辑电路相反,组合逻辑的输出只会跟目前的输入成一种函数关系。 换句话说,时序逻辑拥有储存器件(内存)来存储信息,而组合逻辑则没有。换句话说,是否存在存储器件是判断一个电路是否是时序逻辑电路的关键。


时序逻辑按照其中信号变化的时机,又分为同步时序和异步时序两种。


同步电路是一种由定时器产生的时钟信号驱动的电路。在一个同步电路中,它的各个期间中,逻辑信号的每一个变化都是同时的。所有信号变化都服从一个特别的同步信号,称为“时钟”。不管逻辑的规模有多大,都假设对于时钟信号而言,其他逻辑部分的变化的时延是微小的。所以,整个电路的行为 -- 无论任何一个信号—都可以在任何速度上精确地被预见。在实际电路中,时钟源到达各个触发器的网线长度不同,因此需要使用时钟缓存单元来尽量降低时钟偏移的影响。


异步电路逻辑更加体现逻辑的本质,但是由于它的弹性关系,其也是设计上困难度最高的。 最基本的储存组件是锁存器。 锁存器可以在任何时间改变它的状态,依照其他的锁存器信号的变动,他们新的状态就会被产生出来。 异步电路的复杂度随着逻辑级数的增加,而复杂性也快速的增加,因此他们大部分仅仅使用在小的应用。


在一般的设计中,会采用同步电路进行设计。这是方便分析和设计的要求,一般设计人员的大脑只能把握这样的范围了。在自己可以控制的范围内设计,这是一个行之有效的策略。


很多情况下,目前大规模的数字电路系统里面,对应不同功能部分,可能存在多个时钟。但是,每一个部分一般由一个时钟驱动,这个范围内可以视为同步电路。但是,因为不同时钟的频率与相位的差别,不同部分之间的信号有无法满足“逻辑信号的每一个变化都是同时”的要求。这是一种特殊的,但是常用的异步电路逻辑。对于这种电路后文书将会详细介绍,但是这种电路的分析过程倒是更类似于同步逻辑。


1. 时钟启动,节拍控制
在时序电路里面,再强调时钟的作用也不为过的。一般而言,在一个系统里面只会采用一种类型的器件。这样设计起来简单,而且不会存在不能实现的情况。最常用的器件呢,就算是 D 触发器了。这个器件使用起来,类似于对于信号的采样,最简单不过。
D 触发器的电气符号里面,一般常用的有三组输入信号:数据输入 D、复位 / 初值输入 S 和 R 以及时钟信号 CLK。忽略掉复位 / 初值输入 S 和 R 的影响,D 触发器的真值表如表 1。其中,Qnext 为下一个有效时钟沿的 Q 的值。从信号处理的角度,可以将 D 触发器理解为在时钟有效沿对于输入采样,并且延迟一个时钟节拍输出的单元。D 触发器的时序图如图 1 所示。


表 1 D 触发器的真值表

D

CLK

Q

Qnext

0

x

0

1

x

1

x

0/1

0

0

x

0/1

1

1


图 1 D 触发器的时序图


正因为 D 触发器有延时的作用,有时候为了一些相关的数据到达时间对齐,会使用 D 触发器对一些先到达的数据的延时操作。注意,D 触发器能够完成的时延一定是时钟周期的整数倍。这个时候,工程上经常说的术语是“打 X 拍子”,X 是一个整数。这个严格来说就是延迟 X 个时钟周期的意思。打一拍子就用一个 D 触发器,打两拍子就用两个 D 触发器串联,以此类推。打多个拍子的代码实现方法,会在下一讲中介绍,这里仅仅给大伙儿建立一个概念。

 


作为一个简单的例子,老衲推荐计数器。计数器,很多人见过:大家坐飞机的时候,进门前,空姐手里拿的,见一个人“咯嗒”按一下,上面的数字加一。这个计数器,用来统计最终进入飞机的人数的,以备后用(某家就不再多说了,不能乌鸦嘴。方丈告诫我:嘴下留德,胜造七级浮屠)。这里的计数器,功能和空姐手里的差不多,只不过她那是机械的,这里的是电子的。她那里的按键,在这里是使能信号“enable”。计数器的结构如图 2 所示,其中加入了溢出保护机制。其代码如例 1,其中给出了带溢出保护和不带溢出保护的两套代码。

图 2 计数器的结构图


上图中没有给出时钟 CLK 和复位 RST 信号的处理,这是一般时序逻辑结构图的惯例。这两个信号的处理太一般了,所以被偷懒地省略了。


【例 1】计数器代码

无溢出保护

具有溢出保护

module counter

  (

    input CLK, input RST,

    input enable,

    output reg[7:0] counter,

  );

//Load other module(s)

//Definition for Variables in the module

//Logical

always @(posedge CLK, negedge RST)

begin

    if (!RST)

    //Reset

    begin

       counter <= 8'h00;

    end

    else if(enable)

    //Counter enabled

    begin

        counter <=   counter + 8'h001;

end

else

begin

end

end

endmodule

module counter

  (

    input CLK, input RST,

    input enable,

    output reg[7:0] counter,

    output reg overflow_flag

  );

//Load other module(s)

//Definition for Variables in the module

//Logical

always @(posedge CLK, negedge RST)

begin

    if (!RST)

    //Reset

    begin

       {overflow_flag, counter} <= 9'h000;

    end

    else if (overflow_flag)

    //Over flew and reset

    begin

        {overflow_flag, counter} <= 9'h000;

    end

    else if(enable)

    //Counter enabled

    begin

    {overflow_flag, counter} <= {overflow_flag, counter} + 9'h001;

end

else

begin

end

end

endmodule


不具有溢出保护的功能的计数器,在实际工程中是有问题的。就按例子中 8 比特宽度的计数宽度为例,其最大计数值是 255。如果来了 256 个乘客,没有溢出保护的代码会显示计数值为 0,这显然会带来误解。


还有代码中利用了组合操作“{ }”来简化的书写,也请读者注意这个技巧。

 


2. 循环串接,链状传递
最简单的 D 触发器组成的电路是什么?那一定是只有一个 D 触发器的、延迟一个时钟节拍的电路了。这个老和尚上一讲已经介绍了,现在贫道在深入一步。“稍稍难一点的电路是什么呢?”参考图 3.1 里面的一般化的数字逻辑系统架构,去掉各种组合逻辑之后,就是一个非常单调的、也是很简单的 D 触发器链了。聪明!这就是这一节给大家介绍的第一种千层面:只有面。


这样的一个 D 触发器链,在信号处理上也叫作延时链,结构如图 3 所示。


图 3 延时链的结构


大家会发现只是 4 个 D 触发器的例子,代码已经很长了。那么如果是很多 D 触发器呢,例如 16 个 D 触发器或者 32 个 D 触发器,那不就成了累傻孩子的活计了吗?这里就要介绍唯一可以被综合成电路的循环了:常数循环次数的 for 循环。


关键词 for 的一般形式是:
for (variable = start_value; end_condition; circle_express)
begin
    operations
end


其中,variable 是一个变量名;start_vlue 是变量的初始值;end_condition 是循环的条件;circle_expree 是每个循环的步进操作;operations 是每次循环的操作。要想这个循环能被综合,for 的循环次数必须确定,。捎带说明一下,最常见的是第一行的形式。


例 2 里面给出了 4 级触发器链用 for 实现的代码。只要改变里面的常数,就是 1024 级 D 触发器链也不难实现。


【例 2】4 级 D 触发器链的 for 实现
module DFF_link_4_for
  (
    input CLK, input RST,
    input input_data,
    output output_data
  );
 
//Load other module(s)

//Definition for Variables in the module
reg dff[3:0];
integer loop;

//Logical
assign output_data = dff[3];

always @(posedge CLK, negedge RST)
begin
    if (!RST)
    //Reset
    begin
       for (loop = 0; loop <= 3; loop = loop + 1)
       begin
        dff[loop] <= 1'b0;
       end
    end
    else
    begin
    dff[0]<= input_data;
    for (loop = 1; loop <= 3; loop = loop + 1)
    begin
        dff[loop] <= dff[loop - 1];
     end
    end
end

endmodule


看到这里,很多人会把 Verilog 里面的 for 和其他程序语言里面的 for 混淆掉。这是一个十分严重的错误。循环变量在电路的哪里体现呢?任凭您老“眼睛瞪的像铜铃”,也找不到半分 loop 的影子吧?实话告诉您,这个循环变量是在综合里面起作用的,告诉综合软件要重复几遍 for 里面的操作。


如果大伙儿觉得一串 D 触发器只能做个时延玩玩,那就错了。这里贫道给诸位一个例子:不用 RAM 来存储一组数据。当然了,这个存储也是有代价的。数据不能像 RAM 一样随机读写,只能按照一定的时序读取。

 


3. 各取所长,分工合作
完成一个组合逻辑的操作,会有时延吗?这里的时延是指从输入信号稳定到获得正确结果的时间间隔。对于行为仿真,宗师和党魁说的没错,还真是没有时延的。但是到了时序仿真这里,就老母鸡变鸭了,结果里面明明白白地出现了时延。有时延倒是叫一般人感觉靠谱一点:天下没有免费的午餐。这个时延包含两个部分,也就是前文书说的可以优化的两个部分:降低布局布线造成的时延(DW)或者降低组合逻辑的时延(DC)。叫大伙儿建立一个概念:做任何事情都是要代价的,这才是天道。


回忆一下数电课程里面介绍过的 4 比特加法器链。假设:每个 1 比特的加法环节需要的处理时间是 5 ns(当然,实际电路如果这么慢,估计老夫敲一个字母计算机都要等上一分钟来处理了。这个虽然不符合实际,但是计算方便啊。大伙儿就别抬杠了。)。那么,4 个 1 比特加法器环节,一个 4 比特加法器的处理时间应该是 20 ns 了。换句话说,在 20 ns 里面如果输入输出有变化,那么结果肯定有问题。再换句话说,这个 4 比特加法器允许输入数据的变化周期大于 20 ns,对应最高的数据变化频率为 50 MHz。注意这里还都是组合逻辑,不存在时钟和时钟频率的概念。


如何能够加快数据变化的频率呢?


首先,“偷工减料”是不可取的。这位说:4 比特加法器是 50 MHz,那么 2 比特加法器就提高到 100 MHz 了。话是没错,但是这个比特位宽的减少,却不是您老说了算的。这个是一对算法什么的工程师计算、仿真的结果,减少了系统性能肯定受影响。


其次,“忍经”在这里唱不得。这位又说了:50 MHz 也不慢了,忍了吧。这话也没错,但是系统的数据输入速度,是依赖于外部要求的,也不能变。


最后,依赖于模块结构的变化以及时序控制的引入,可以解决这个问题。现在我们就开始这个过程。这里会很详细的介绍设计过程,啰嗦是啰嗦了一点,但是利于大伙儿把握和以后举一反三。忍了吧!


忽略全加器半加器的区别,图里面一共有四个一样的 1 比特加法单元。一个简单、实用的想法是把这些加法器都隔离开,这样每次运算的时间就是 5 ns 了。那么自然而然的问题来了:用什么器件来隔离呢?又是一个简单、实用的想法:D 触发器。这个就是基本的思路了。这就是所谓流水线的思想了。


To be continued!


后面内容更加精彩,大伙儿明晚早来占位!

与非网原创内容,谢绝转载!

系列汇总:

之一:温故而知新:从电路里来,到 Verilog 里去!

之二:Verilog 编程无法一蹴而就,语言层次讲究“名正则言顺”

之三:数字逻辑不容小窥,电路门一统江湖

之四:Verilog 语言:还真的是人格分裂的语言

相关推荐

电子产业图谱

本名:吴涛,通信专业博士,毕业后十多年从事无线通讯产品的研发工作。了解W-CDMA、TDS-CDMA和LTE的标准协议、接收机算法以及系统架构和开发。从事过关于W-CDMA的FPGA IP core设计工作,也完成过W-CDMA和TDS-CDMA的接收机理论研究和链路仿真工作。综合上面的工作,最终选择了无线通讯的系统设计和标准设计工作。目前拥有100多个已授权的发明专利,是某通讯行业标准文件的第一作者,亦有专利思想被写入3GPP协议。已出版FPGA设计专业著作《IP核芯志-数字逻辑设计思想》和《Verilog传奇-从电路出发的HDL代码设计》。