在设计FPGA时,大多数采用Verilog HDL或者VHDL语言进行设计(本文重点以verilog来做介绍)。设计的电路都是利用FPGA内部的LUT和触发器等效出来的电路。

数字逻辑电路分为组合逻辑电路和时序逻辑电路。时序逻辑电路是由组合逻辑电路和时序逻辑器件构成(触发器),即数字逻辑电路是由组合逻辑和时序逻辑器件构成。所以FPGA的最小单元往往是由LUT(等效为组合逻辑)和触发器构成。

在进行FPGA设计时,应该采用组合逻辑设计还是时序逻辑?这个问题是很多初学者不可避免的一个问题。

设计两个无符号的8bit数据相加的电路。

组合逻辑设计代码:

module adder_8bit (

input   wire        [7:0]   dataa,

input   wire        [7:0]   datab,

output  wire        [8:0]   datas

);

assign datas = dataa + datab;

endmodule

对应的电路为:

时序逻辑对应代码为:

module adder_8bit (

input   wire                clk,

input   wire                rst_n,

input   wire        [7:0]   dataa,

input   wire        [7:0]   datab,

output  reg         [8:0]   datas

);

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

datas <= 9'd0;

else

datas <= dataa + datab;

end

endmodule

对应的电路为:

可以思考一下,这个两种设计方法都没有任何错误。那么在设计时应该用哪一种呢?

在设计时,有没有什么规定必须要用组合逻辑或者时序逻辑?例如:在verilog中,在always中被赋值了就必须是reg类型,assign赋值了就必须是wire类型。很遗憾的是,目前没有任何的规定。

下面几点笔者平时自己做设计的经验,在这里分享一下:

一、   带有反馈的必须用时序逻辑

何为带有有反馈?即输出结果拉回到输入。

自加一计数器。

代码为:

//  assign cnt  = cnt + 1'b1;

always @ (*) begin

cnt = cnt + 1'b1;

end

对应的电路为

这种电路在工作时,就会出现无限反馈,不受任何控制,一般情况下,我们认为结果没有任何意义。

和上面的情况类似的还有取反。

assign flag = ~flag;

类似情况还有很多就不在一一列举。

上述说的情况都是直接带有反馈,下面说明间接反馈。

代码为:

assign k = cnt * 2;

always @ (*) begin

cnt = k + 1'b1;

end

从代码上来看,没有什么明确反馈,下面看实际对应的电路

从实际的电路上来看,一旦运行起来,还是会出现无限反馈,不受任何控制。

还有一种情况是带有控制的反馈。

设计代码为:

always @ (flag) begin

if (flag == 1'b1)

cnt = cnt + 1'b1;

else

cnt = cnt;

end

这个电路可以等效为

在flag等于1期间,此电路依然会无限制的反馈,无法确定在此期间进行了多少次反馈。

从代码的角度理解是flag变化一次,加一次。可是对应于电路后,和预想的是不相同的。

说了这么多的这么多不对的情况,下面考虑正确的情况

设计代码为:

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

cnt <= 4'd0;

else

cnt <= cnt + 1'b1;

end

在上述的电路中,clk每来一个上升沿,cnt的数值增加一。可以用作计时使用。

利用寄存器将反馈路径切换即可。此时的反馈是可控制,并且此时的结果就有了意义。

其他的反馈中,加入寄存器即可。而加入寄存器后,就变为时序逻辑。

二、  根据时序对齐关系进行选择

在很多的设计时,没有反馈,那么应该如何选择呢?

举例说明:输入一个八位的数据(idata),然后将此八位数据进行平方后,扩大2倍,作为输出。要求输出结果(result)时,将原数据同步输出(odata),即数据和结果在时序上是对齐的。

设计代码为:

assign odata = idata;

assign result = 2 * (idata * idata);

这种设计方法是可以的,因为都采用组合逻辑设计,odata和result都是和idata同步的,只有逻辑上的延迟,没有任何时钟的延迟。

另外一种设计代码为:

assign odata = idata;

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

odata <= 17'd0;

else

result <= 2 * (idata * idata);

end

这种设计方法为错误,odata的输出是和idata同步的,而result的输出将会比idata晚一拍,最终导致result要比odata晚一拍,此时结果为不同步,设计错误。

修改方案为:将result的寄存器去掉,修改为组合逻辑,那就是第一种设计方案。第二种为将odata也进行时序逻辑输出,那么此时odata也将会比idata延迟一拍,最终结果为result和odata同步输出。

三、  根据运行速度进行选择

在数字逻辑电路中,中间某一部分为组合逻辑,两侧的输入或者输出也会对延迟或者输入的数据速率有一定的要求

组合逻辑1越复杂延迟越大,而导致的结果就是clk的时钟速率只能降低,进而导致设计结果失败。

当组合逻辑1无法进行优化时,还想要达到自己想要的速度时,我们可以进行逻辑拆分,增加数据的输出潜伏期,增加数据的运行速度。

将组合逻辑1的功能拆分为组合逻辑A和组合逻辑B,此时,输入的数据得到结果虽然会多延迟一拍,但是数据的流速会变快。

那么这个和选用组合逻辑和时序逻辑有什么关系呢?

举例说明:目前要设计模块A,不涉及反馈,不涉及时序对齐等,可以采取组合逻辑设计也可以采用时序逻辑设计。

模块A的输出连接到模块B,经过一些变换(组合逻辑N)连接到某个寄存器K上。如果模块A采用组合逻辑,那么模块A的组合逻辑和模块B到达寄存器K之前的组合逻辑N会合并到一起。那么此时组合逻辑的延迟就会变得很大,导致整体设计的时钟速率上不去。

当运行速率比较快时,建议对于复杂的组合逻辑进行拆分,有利于时序分析的通过。

在上述的三个规则中,第一个和第二个用的是最多的,第三个在设计时,有时不一定能够注意到,当出现时序违例时,知道拆分能够解决问题就可以。

设计者:郝旭帅         QQ:746833924     QQ交流群: 173560979

在FPGA中何时用组合逻辑或时序逻辑的更多相关文章

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

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

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

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

  3. 【转】关于FPGA中建立时间和保持时间的探讨

      时钟是整个电路最重要.最特殊的信号,系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错:因而明确FPGA设计中决定系统时钟的因素,尽 ...

  4. sv时序组合和时序逻辑

    input a; input b; input c; reg d; wire e; reg f; // 时序逻辑,有寄存器 always@(posedge clk)begin 'b1)begin d ...

  5. FPGA中改善时序性能的方法_advanced FPGA design

    本文内容摘自<advanced FPGA design>对应中文版是 <高级FPGA设计,结构,实现,和优化>第一章中的内容 FPGA中改善时序,我相信也是大家最关心的话题之一 ...

  6. FPGA时序逻辑中常见的几类延时与时间(五)

    FPGA逻辑代码重要的是理解其中的时序逻辑,延时与各种时间的记忆也是一件头疼的事,这里把我最近看到的比较简单的几类总结起来,共同学习.    一.平均传输延时 平均传输延时 二.开启时间与关闭时间 开 ...

  7. FPGA中的delay与latency

    delay和latency都有延迟的意义,在FPGA中二者又有具体的区别. latency出现在时序逻辑电路中,表示数据从输入到输出有效经过的时间,通常以时钟周期为单位. delay出现在组合逻辑电路 ...

  8. FPGA中的时序分析(四)

    常用约束语句说明 关于Fmax      上述是实现Fmax的计算公式,clock skew delay的计算如下图, 就是两个时钟的差值.到头来,影响Fmax的值的大小就是组合逻辑,而Fmax是针对 ...

  9. 【转载】FPGA 中的latch 锁存器

    以下这篇文章讲述了锁存器的一些概念和注意事项.原文标题及链接: FPGA 中的latch 锁存器 - 快乐至永远上的博客 - 与非博客 - 与网 http://www.eefocus.com/liuy ...

  10. FPGA中的时序分析(一)

    谈及此部分,多多少少有一定的难度,笔者写下这篇文章,差不多是在学习FPGA一年之后的成果,尽管当时也是看过类似的文章,但是都没有引起笔者注意,笔者现在再对此知识进行梳理,也发现了有很多不少的收获.笔者 ...

随机推荐

  1. C# PaddleOCR 车牌识别

    效果 车牌识别测试地址 http://47.108.88.211/manual/VehPlateTest.html 通用OCR识别测试地址 http://47.108.88.211/manual/OC ...

  2. nginx location块

    location块在server块中使用,它的作用是根据客户端请求URL去定位不同的应用. 匹配格式 作用 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ...

  3. ResNet-RS:谷歌领衔调优ResNet,性能全面超越EfficientNet系列 | 2021 arxiv

    论文重新审视了ResNet的结构.训练方法以及缩放策略,提出了性能全面超越EfficientNet的ResNet-RS系列.从实验效果来看性能提升挺高的,值得参考   来源:晓飞的算法工程笔记 公众号 ...

  4. apue 文章集锦

    与 apue 相关的一系列文章比较庞杂,按原书目录整理了一下,形成目录,方便系统性阅读. 另外这些文章是在我快读完的时候开始写的,之前的一些章节还多有遗漏,后面慢慢补上. chapter 1: UNI ...

  5. CC2530 中的ZigBee协议栈

    CC2530 中的ZigBee协议栈 1.何为协议栈 ZigBee协议栈将各个层的协议集合在一起,并以函数的形式实现,并且向用户提供接口,用户能够直接调用. 它本身就为一个工程. 2. 如何使用 开始 ...

  6. C++ 自动计时

    #include<iostream> #include<chrono> struct Timer { std::chrono::time_point<std::chron ...

  7. 详解数仓对象设计中序列SEQUENCE原理与应用

    本文分享自华为云社区<GaussDB(DWS)对象设计之序列SEQUENCE原理与使用方法介绍>,作者:VV一笑. 1. 前言 适用版本:8.2.1及以上版本 序列SEQUENCE用来生成 ...

  8. 2024年:如何根据项目具体情况选择合适的CSS技术栈

    2024年:如何根据项目具体情况选择合适的CSS技术栈 (请注意,这是一篇主观且充满个人技术偏好的文章) 方案一: antd/element ui/类似竞品 适合情形: 项目没有设计师 or 大部分人 ...

  9. cloudflare认识2(picgo结合使用)

    参考:https://zhuanlan.zhihu.com/p/658058503 https://blog.csdn.net/CCCChris001122/article/details/13585 ...

  10. #整体二分 or 主席树#洛谷 7424 [THUPC2017] 天天爱射击

    题目 给定\(n\)条线段\(x_i,y_i,k_i\)和\(m\)个点(点有顺序), 对于每个点,问有多少条线段是第\(k_i\)次被该点经过. 分析(主席树) 将点按坐标排序建主席树那么就是一道静 ...