前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDLBits:在线学习 Verilog (十七 · Problem 80-84)

HDLBits:在线学习 Verilog (十七 · Problem 80-84)

作者头像
数字积木
发布2021-04-15 11:48:20
5380
发布2021-04-15 11:48:20
举报
文章被收录于专栏:数字积木数字积木

本系列内容来自于知乎专栏,链接如下:https://zhuanlan.zhihu.com/c_1131528588117385216 本系列文章将和读者一起巡礼数字逻辑在线学习网站 HDLBits 的教程与习题,并附上解答和一些作者个人的理解,相信无论是想 7 分钟精通 Verilog,还是对 Verilog 和数电知识查漏补缺的同学,都能从中有所收获。

Problem 80 : D flip-flop (Dff)

接下来的题目是属于触发器,锁存器的专题。我们会从用 Verilog 实现基础 D 触发器开始,学习触发器这一数字电路中最重要的电路之一。

D 触发器是一个电路,存储 1bit 数据,并定期地根据触发器的输入(d)更新这 1 bit 数据,更新通常发生在时钟上升沿(clk)。存储的数据会通过输出管脚(q)输出。

t1时刻: d -> 0

t2时刻: clk->1 上升沿到来,触发器存储的数据变成 0,输出 q 保持为存储的值:0,直到下一个时钟上升沿到来。

t3时刻: d -> 1(d:我变了),q 仍保持 0 不动摇(时钟沿还没来呢)

t4时刻: clk->1 上升沿到来,q->1(q:时钟沿来了,我该变身了)

绝大多数时候,我们不会在 Verilog 代码中显示例化一个触发器(作者没这么做过,但应该是可以做的),我们在时钟敏感的 always 块中的语句一般都会被综合工具转换为相应的触发器。

D 触发器可以认为是一个触发器和一段最简单的组合逻辑块(blob :想表达逻辑块的时候用我,别用 block)的组合。其中组合逻辑块仅仅是一段 wire。(q 直接输出了触发器的存储值)

牛刀小试

造个 D 触发器吧。

解答与分析

代码语言:javascript
复制
module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//

    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments
    always@(posedge clk) begin
        q <= d;
    end
endmodule

在每个时钟上升沿,输出 q 的值变为输入 d 的值。我们在 always 块中的语句就会被综合工具转换为触发器。这里使用 clk,q,d 对应于触发器的三个端口,反应了转换的对应关系。

上图是触发器在 ISE 中的综合结果,fd 是多种触发器中的基础款,我们会在后续的题目中认识更多款式。

Problem 81 : D flip-flops (Dff8)

牛刀小试

本题需要你实现 8 个 D 触发器。

解答与分析

代码语言:javascript
复制
module top_module (
    input clk,
    input [7:0] d,
    output [7:0] q
);
    always@(posedge clk) begin
    	q <= d;
    end
endmodule

实现 8 个 D 触发器,听上去好像很累的样子,实则 Verilog 语言的抽象帮助我们省去不少麻烦。输入 a,b 的位宽变为 8 位,但 always 块中的语句与上一题完全相同。

综合工具根据位宽,综合出了 8 个 D 触发器。一般没有八位触发器的说法。这里反映了综合工具能分析代码,生成相应的触发器电路,其实综合器还能将复杂得多的语句转为相应的电路。

Problem 82 : DFF with reset (Dff8r)

牛刀小试

在上题的 8 个 D 触发器基础上,这题我们要给触发器配上同步复位端口。

什么同步复位?当时钟上升沿到来时,如果同步复位端有效(本题中复位高电平有效,即 reset),那么任凭你触发器此前输出或者输入的是 0,是 1,输出一律变为 0。

复位电路对于那些经常需要恢复到初始状态的电路是必要的,复位相较于断电重新加载程序恢复到初始状态的速度要快得多。但也有一些电路则不需要复位设计。(作者也是有所耳闻那些不需要复位的电路,平常自己还是会加上复位电路)

解答与分析

代码语言:javascript
复制
module top_module (
    input clk,
    input [7:0] d,
    output [7:0] q
);
    always@(posedge clk) begin
        if(reset)
            q <= 8'b0;
        else
    	    q <= d;
    end
endmodule

从语法的角度来说,reset 实现就是加一个 if 语句判断 reset 是否有效,有效就将输出 q 置为 0 。

但从电路的角度来说,电路的角度往往更加重要,是使用一个带有复位端的 D 触发器 fdr,另一种 D 触发器单元。

Problem 83 : DFF with reset value (Dff8p)

牛刀小试

与上题的不同点在于,复位后的值不再是 0 (那么即为 1,对于 1bit 来说也没别的选择了),另外触发器的触发事件从时钟上升沿变成了时钟下降沿,这些在语法都没什么好提的。

解答与分析

代码语言:javascript
复制
module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output [7:0] q
);
    always@(negedge clk) begin
        if(reset)
            q <= 8'h34;
        else
    	    q <= d;
    end
endmodule

从电路的角度来说,时钟下降沿触发,如果仍要使用上升沿触发的触发器,则通过将输入触发器的时钟取反实现。

复位后的值为 1,那么通常我们可以管这种复位为置位,在电路中使用 fds ,带有置位端 s 的触发器实现。

Problem 84 : DFF with asynchronous reset (Dff8ar)

牛刀小试

本题中的触发器引入了异步复位。当异步复位端有效时,触发器的输出复位为 0 。

对于上上题中引入的同步复位来说,存在一个问题。

我们假设一个工作时钟为 1Hz 的系统,比如你的床头闹钟,你按下隆隆叫的闹钟时,就好比按下了闹钟的同步复位键。那么当你清晨 6:30:00 的闹钟响起,不想起床的你拍下闹钟,最糟糕的情况下,闹钟还会再响接近一秒,因为你刚好错过了一个时钟上升沿,真是糟糕,这真是太可怕了!

对于同步复位系统来说,当同步复位事件发生时,等到下一个时钟上升沿才会得到响应,响应的速度比较慢。

与之相对的异步复位的响应就很快,因为在异步复位有效的时刻,复位响应就会发生,好像戳破气球一般。

解答与分析

代码语言:javascript
复制
module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output [7:0] q
);
    always@(posedge clk or posedge areset) begin
        if(areset)
            q <= 8'b0;
        else
    	    q <= d;
    end
endmodule

多次重复,之后仍然会提及:语法的实现很简单。将异步复位加入 always 块的敏感列表当中,在电路上则又出现了一位新的小伙伴( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ:fdc,它有一个异步复位端 CLR。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数字积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档