草庐IT

SystemVerilog-时序逻辑建模(4)同步和异步复位

碎碎思 2023-04-18 原文

Part1数字硬件建模SystemVerilog-时序逻辑建模(4)同步和异步复位

数字门级电路可分为两大类:组合逻辑和时序逻辑。锁存器是组合逻辑和时序逻辑的一个交叉点,在后面会作为单独的主题处理。

组合逻辑描述了门级电路,其中逻辑块的输出直接反映到该块的输入值的组合,例如,双输入AND门的输出是两个输入的逻辑与。如果输入值发生变化,输出值将反映这一变化,组合逻辑的RTL模型需要反映这种门级行为,这意味着逻辑块的输出必须始终反映该逻辑块当前输入值的组合。

SystemVerilog有三种在可综合RTL级别表示组合逻辑的方法:连续赋值语句、always程序块和函数。接下来几篇文章将探讨每种编码风格,并推荐最佳实践编码风格。

Part2同步和异步复位

在实现层面上,实际的触发器可以是不可复位的(没有复位输入),也可以有一个复位输入控制。复位控制可以与时钟同步或异步,也可以是高电平或低电平控制。一些触发器设备也有一个置位(有时称为预置)输入。每种类型的触发器都有其优点和缺点。这些工程上的权衡不在本文讨论的范围内,本文的重点是反映这些实现特点的RTL建模风格。

注意事项
特定的目标ASIC或FPGA器件基本只支持一种类型的复位。

ASIC和FPGA在设备使用的复位类型上可能有所不同,这可能会影响RTL的建模风格。特别是FPGA器件,通常只有一种复位类型的触发器(也许是同步的、高电平的)。相反,许多ASIC器件和一些FPGA器件都有同步和异步触发器可用。同样地,一些器件只有复位输入的触发器,而其他器件也有置位和复位输入的触发器。

最佳实践指南8-5
使用首选的复位类型编写RTL模型,并让综合编译器将复位功能映射到目标ASIC或FPGA支持的复位类型。只有在有必要的情况下,才编写RTL模型,以使用特定目标ASIC或FPGA使用的相同类型的复位,从而实现该特定器件的最优速度和面积。

许多RTL设计工程师,都是用一种预设的风格或复位来建模,而不关心目标器件支持什么。综合编译器可以将RTL模型中的任何类型的复位映射到目标ASIC和FPGA器件中可用的任何类型的复位。例如,如果RTL模型使用主动低电平复位,而目标器件只有主动高电平复位的触发器,那么综合编译器将添加额外的门级逻辑来转换RTL模型中使用的复位。如果RTL模型使用同步复位,而目标器件只有异步复位的触发器,那么综合编译器将在异步触发器的外部添加额外的门级逻辑,使其与时钟同步复位。FPGA有充足的速度和容量。可以得到一个功能齐全的设计,而不必担心综合过程是否必须添加一些额外的逻辑,以将RTL风格的复位映射到目标器件的触发器类型。

Part3不可复位的RTL触发器模型

一个没有复位输入的触发器只能通过数据输入和时钟来控制。RTL模型在每次程序触发时将数据输入转移到触发器的输出。没有任何if-else条件可能会指定数据输入以外的值。一个不可复位的触发器的RTL模型的例子是:

always_ff @(posedge clk) q <= d;

当综合在一个特定的ASIC或FPGA目标中实现这个RTL功能时,将选择该设备库中可用的触发器类型。这可能是一个没有复位或置位输入的触发器,一个只有一个复位输入的触发器或一个置位和复位输入都被关断的触发器。

Part4同步复位RTL触发器模型

一个同步复位的触发器有一个复位输入,但该输入只有在时钟输入被触发时才被采样。RTL模型包含一个if条件,当复位激活时分配一个值,或者当复位不激活时分支到else语句。复位信号不是always程序的灵敏度列表的一部分。灵敏度列表只包含触发触发器的时钟沿。因此,always过程中的编程语句只在时钟触发发生时被评估。

下面的例子说明了一个具有主动低电平同步复位的触发器。

always_ff @(po sedge clk)
if (!rstN) q <= '0; // 同步有源低电平复位
else q <= d;

当综合将这个RTL功能映射到一个特定的FPGA目标时,如果有同步复位的触发器,将选择一个触发器。如果目标器件有高电平触发器,综合将为rstN信号添加一个反相器。如果目标器件中没有同步复位的触发器,同步复位信号将与触发器的数据输入相加。任何时候复位都是有效的,一个0将被输入到触发器的时钟中,这就提供了一个与时钟同步的复位功能。如果目标设备的触发器也有异步复位或置位输入,它们将被绑在一起,处于非活动状态。

图8-8显示了针对通用触发器的综合结果,该器件具有同步复位触发器,即Xilinx Virtex®  -7   FPGA。触发器的复位是高电平有效,所以rstN输入是反相的。

图 8-7: 综合结果。异步复位DFF映射到Xilinx Virtex® -7 FPGA中

图8-8显示了将相同的通用触发器定位到没有同步复位触发器的设备上的结果,即Xilinx CoolRunner™-11 CPLD。该触发器的异步高电平有效CLR和PRE输入没有被使用。

图8-8:综合结果。映射到Xilinx CoolRunner™-11 CPLD的异步复位

Part5异步复位RTL触发器模型

一个具有异步复位的触发器有一个复位控制输入,在复位生效的那一刻将改变触发器的状态,与时钟无关。RTL模型的灵敏度列表包含了触发触发器的时钟边沿和复位信号的边沿。因为复位的边沿在敏感度列表中,所以只要复位有效,always程序就会触发,而不需要等待时钟输入的变化。RTL模型包含一个if条件,当复位激活时分配一个值,或者当复位不激活时分支到else语句。

下面的例子模拟了一个具有主动低电平异步复位的触发器。

always_ff @ ( posedgeclk or negedge rstN)
if (!rstN) q <= '0; // 主动低电平异步复位
else q <= d;

忽略异步复位的尾部边沿。always程序的一个综合要求是,如果posedge或negedge被用于敏感度列表中的一个信号,那么必须为这个列表中的所有信号指定一个边沿。下面的代码片断是不能综合的,因为rstN没有用posedge或negedge限定。

always @(posedge clk or rstN) // incorrect sensitivity 
if (!rstN) q <='0; // Asynchronous active-low reset 
else q <= d;

正确的行为还要求只有异步复位的边沿被列在always程序的敏感度列表中。敏感度列表决定了always程序中的编程语句何时被执行。对于异步复位,敏感度列表需要在复位激活时触发,以便立即复位触发器。然而,如果always程序也在复位回到非活动状态时触发,那么复位活动的if测试将评估为假,else分支将被执行。在没有时钟边沿的情况下,看起来就像发生了一个时钟事件。图8-9显示了一个波形,说明了上述代码片段的不正确的仿真行为。

图8-9:不正确建模的异步复位结果的波形

仿真和综合都要求在敏感列表中只包括异步复位的边沿--仿真要求这样做以获得正确的异步复位行为,而综合则在语法上要求这样。SystemVerilog的语法并没有强制执行这个限制。

这是一种RTL编码风格,设计人员必须遵循。Lint检查器可以检查这个编码风格是否被遵循。

| 最佳实践指南8-6 | | :--------- | :--: | -----------: | | 在使用高电平或低电平复位时要保持一致。对高电平和低电平控制信号使用一致的命名规则。 |

虽然可以使用高电平或低电平复位,但项目中的所有RTL模型应该是一致的。

混合的复位极性会导致代码难以理解、维护和重用。

本文采用的惯例是在有低电平信号的名称后面加上一个大写的"N"。另一个常见的惯例是在有源低电平信号名称后面加上"_n"。

Part6异步置位-复位触发器

一些触发器同时具有复位和置位控制输入。一个if-else-if决策系列被用来模拟这种行为,如下面的例子。

一个if-else-if语句将优先考虑被测试的第一个输入。在上面的例子中,如果两者同时激活,那么复位就会优先于置位输入。

注意事项
在RTL模型中给予置位或复位输入的优先权应与特定的目标ASIC或FPGA器件相匹配。有些器件优先考虑复位输入,而其他器件则优先考虑置位输入。
最佳实践指南8-7
为了达到最佳的综合结果质量(QoR),对RTL触发器进行建模,只需要一个复位输入或一个置位输入。如果设计的功能需要,只对置位/复位触发器进行建模。

如果需要一个置位/复位的触发器行为,请为置位和复位编写RTL模型的优先级,以匹配设计将在其中实现的特定目标器件的优先级。 由于并不是所有的目标器件都有相同的置位/复位优先级,因此很难编写置位/复位触发器RTL模型,就很难为所有目标器件进行最佳综合。如果目标器件没有与RTL模型具有相同优先级的置位/复位触发器,综合编译器可以在触发器之外添加额外的逻辑,使其与RTL模型相匹配。然而,这种额外的逻辑可能会影响器件的时序,并且在从复位状态出来时,会引起与设计中其他部分的竞争条件。

置位/复位触发器对这些输入也有更严格的建立和保持时间,而触发器只有一个置位或复位输入,但没有两个。即使RTL模型中置位和复位的优先级与目标器件的优先级一致,设计人员也需要注意设计是否能满足这些建立和保持时间要求。

置位/复位触发器的仿真故障。上面显示的置位-复位触发器RTL模型的例子在功能上是正确的,并且可以正确地进行综合。但是,这段代码有一个潜在的仿真故障。如果setN和rstN的控制输入同时有效,然后rstN变得无效,就会出现这种故障。在这个例子中,rstN具有优先权,并且触发器正确复位。当rstN输入变得不活跃,setN输入应该接管,并且触发器应该切换到其置位状态。仿真中的故障是,RTL模型只对rstN的前边沿敏感--这  是  综合编译器的要求--而对rstN的前后边沿不敏感。当rstN变得不活跃时,敏感度列表将不会触发,因此错过了置位触发器,即使setN仍然活跃。这个故障只持续到时钟的下一个正边沿,它将触发always程序,并导致该程序被重新评估。

防止这种仿真故障的办法是将复位的后边沿添加到灵敏度列表中。然而,仅仅增加复位的后边沿会导致前面描述的同样问题,即复位的后边沿可以作为一个时钟。因此,复位输入的非活动电平需要与置位输入的活动电平相加,当该结果为真时,灵敏度列表将被触发。

为防止仿真故障,修订后的敏感度列表为:

对表达式的结果进行触发在SystemVerilog语言中是合法的,但综合编译器不允许。为了避免仿真故障,需要从综合中隐藏额外的触发。这可以通过使用综合的translate_off / translate_on pragmas来实现。综合语是以synthesis一词开头的特殊语句。仿真器会忽略这些注释,但综合编译器会对它们采取行动。下面的片段添加了translate_off /translate_on语句。

图8-12显示了综合这个置位-复位触发器代码的结果。

图8-12:一个异步置位-复位触发器的综合结果

请注意,综合编译器在通用触发器的set输入之前添加了额外的逻辑,以强制执行rstN比setN有优先权。如果目标ASIC或FPGA设备有set/reset触发器,其中reset优先于set,那么当通用触发器被映射到ASIC或FPGA时,这个附加逻辑将被删除。否则,附加逻辑将被保留,以便ASIC或FPGA实现与RTL模型相匹配。

在针对特定的ASIC或FPGA之前,综合编译器使用的通用触发器具有高电平有效的置位和复位输入。因此,综合编译器在RTL模型中对有源低电平信号添加了反相器。如果目标器件具有低电平有效的控制输入,这些反相器将被删除。

使用translate_off和translate_on综合pragmas的另一种方法是使用条件编译。大多数综合编译器都有一个预定义的SYNTHESIS宏,可以用来有条件地包括或排除综合工具所编译的代码。要排除前面例子中的不可综合的那一行,代码应该是。

有关SystemVerilog-时序逻辑建模(4)同步和异步复位的更多相关文章

  1. ruby-on-rails - 建模收藏夹 - 2

    我希望将Favorite模型添加到我的User和Link模型。业务逻辑用户可以有多个链接(即可以添加多个链接)用户可以收藏多个链接(他们自己的或其他用户的)一个链接可以被多个用户收藏,但只有一个所有者我对如何为这种关联建模以及在模型就位后如何创建用户收藏夹感到困惑?classUser 最佳答案 下面的数据模型怎么样:classUser:destroyhas_many:favorite_links,:through=>:favorites,:source=>:linkendclassLink:destroyhas_many:favor

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  6. 建模分析 | 平面2R机器人(二连杆)运动学与动力学建模(附Matlab仿真) - 2

    目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标

  7. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  8. ruby-on-rails - Ruby 和 SQL 中的重复业务逻辑 - 2

    我有一个PORO(普通旧Ruby对象)来处理一些业务逻辑。它接收一个ActiveRecord对象并对其进行分类。为了简单起见,以下面为例:classClassificatorSTATES={1=>"Positive",2=>"Neutral",3=>"Negative"}definitializer(item)@item=itemenddefnameSTATES.fetch(state_id)endprivatedefstate_idreturn1if@item.value>0return2if@item.value==0return3if@item.value但是,我还想根据这些st

  9. ruby - 了解 Ruby 中赋值和逻辑运算符的优先级 - 2

    在以下示例中,我无法理解Ruby运算符的优先级:x=1&&y=2由于&&的优先级高于=,我的理解是类似于+和*运算符:1+2*3+4解析为1+(2*3)+4它应该等于:x=(1&&y)=2但是,所有Ruby源代码(包括内部语法解析器Ripper)都将其解析为x=(1&&(y=2))为什么?编辑[08.01.2016]让我们关注一个子表达式:1&&y=2根据优先规则,我们应该尝试将其解析为:(1&&y)=2这没有意义,因为=需要特定的LHS(变量、常量、[]数组项等)。但是既然(1&&y)是一个正确的表达式,那么解析器应该如何处理呢?我试过咨询Ruby的parse.y,但它太像意大利面条

  10. ruby-on-rails - 本地 yaml key 的 i18n 同步 - 2

    类似的问题,但对于java,Keepingi18nresourcessynced如何保持i18nyamllocals的key同步?即,当将key添加到en.yml时,如何将它们添加到nb.yml或ru.yml?如果我在my_title:"atitle"旁边添加键my_label:"sometextinenglish"我想把它给我的其他本地人我指定,因为我不能做所有的翻译,它应该回到其他语言的英语例如en.ymlsomegroup:my_tile:"atitleinenglish"my_label:"sometextinenglish"othergroup:...我想发出命令,将整个键和

随机推荐