verilog 写rtl注意事项_verilog注意事项【转】
verilog注意事项【转】
已有 2846 次阅读2011-9-18 19:01
||
规范很重要
有相关经验的朋友都能理解,在工作中公司非常注重规范性管理流程,并且在处理大型项目或软件开发时特别强调遵循既定的标准和流程。
仍然属于硬件领域),若违背规范则难以实现目标。在逻辑设计中也是如此:若未遵循规定,则难以达到预期效果。
话后一个阶段,在进行调试时发现了问题。回过头来看自己的代码时,意识到自己可能遗忘了不少信号功能。
切勿提及此事;若某个项目完成了进度的一半后人才离开,则新接手者的开发工作可能需要重新规划;如
如果打算在此前的基础上添加新的功能模块,则通常会面临诸多挑战,并非易事;这也会导致系统的可维护性受到影响
性。
在逻辑方面,我觉得比较重要的规范有这些:
为了确保清晰性和可追溯性,在设计过程中应当进行充分的文档记录;所有设计思路、详细实现等均需被包含于其中,并在完成初步草稿后提交给相关负责人进行严格评审。
必须完成下一步的工作。按照这种思路去做的话,在初期可能会觉得耗时较多,但从整个项目的角度来看,则是可以避免的。
与其要一上来就编写代码而导致浪费时间,不如选择这种方法以确保项目处于可控且可操作的状态
2.代码规范。
a. 设计需采用参数化方法。例如初始设计中时钟周期设置为30纳秒,并将复位端的时钟周期设置为5个时钟周期。
们可以这么写:
parameter CLK_PERIOD = 30;
parameter RST_MUL_TIME = 5;
parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD;
...
rst_n = 1'b0;
RST_TIME rst_n = 1'b1;
...
CLK_PERIOD/2 clk <= ~clk;
假设在另一个设计中时钟周期设定为40ns,在复位周期保持不变的情况下,则只需对该电路中的CLK_PERIOD参数进行校准即可完成相应的配置设置
新例化就行了,从而使得代码更加易于重用。
b.信号命名要规范化。
-
信号名一律小写,参数用大写。
-
对于低电平有效的信号结尾要用_n标记,如rst_n。
端口信号排列需保持一致;每个信号独立成行;建议按照输入输出的逻辑来安排,并确保每个模块的来源清晰明确。
个模块去的关系排列,这样在后期仿真验证找错时后 方便很多。如:
module a(
//input
clk,
rst_n, //globle signal
wren,
rden,
avalon_din, //related to avalon bus
sdi, //related to serial port input
//output
data_ready,
avalon_dout, //related to avalon bus
...
);
最好只采用单一的时钟机制来管理这个模块
该方法在多级片内核体系结构中的设计重点在于实现跨片内核之间的通信。
离。这样做可以让综合器综合出更优的结果。
- 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,禁止
出现任何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。理由同上。
在FPGA的设计中避免使用全组合电路来产生锁存器;具有D触发器的锁存器是被允许的。
,比如配置寄存器就是这种类型。
- 一般来说,进入FPGA的信号必须先同步,以提高系统工作频率(板级)。
每个模块的输出都需要被注册化以便提升工作频率同时这也对设计实现时序收敛的目标产生了积极的影响
是极有好处的。
- 除非是低功耗设计,不然不要用门控时钟--这会增加设计的不稳定性,在要
在涉及门控时钟的地方,为了使门控信号能够通过一个脉冲被精确地触发并同步输出到相应的电路中。
clk_gate_en -------- ----
-----------------|D Q |------------------| \ gate_clk
_out
| | ---------| )--------
------o|> | | | /
clk | -------- | ----
------------------------------------
不建议将计数器分频后的信号直接作为其他模块的时钟使用;相反地,请采用将计数器分频后的信号配置为时钟使能的方式
否则这种时钟数量众多的方式对设计的可靠性造成极大不利影响,并显著提升了静态时序分析的时间
复杂度较高。例如,在FPGA中输入时钟配置为每秒二十五兆赫兹的情况下,在当前系统的内部实现中需要通过RS-23₂协议与外部设备进行数据传输,并使用RS-₂₃₂接口连接。
1xclk的速率发送数据。
不要这样做:
always (posedge rs232_1xclk or negedge rst_n)
begin
...
end
而要这样做:
always (posedge clk_25m or negedge rst_n)
begin
...
else if ( rs232_1xclk == 1'b1 )
...
end
11)状态机要写成3段式的(这是最标准的写法),即
...
always @(posedge clk or negedge rst_n)
...
current_state <= next_state;
...
always @ (current_state ...)
...
case(current_state)
...
s1:
if ...
next_state = s2;
...
...
always @(posedge clk or negedge rst_n)
...
else
a <= 1'b0;
c <= 1'b0;
c <= 1'b0; //赋默认值
case(current_state)
s1:
a <= 1'b0; //由于上面赋了默认值,这里就不用再对b
、c赋值了(b、c在该状态为0,不会产生锁存器,下同)
s2:
b <= 1'b1;
s3:
c <= 1'b1;
default:
...
...
3.ALTERA参考设计准则
- Ensure Clock, Preset, and Clear configurations are free of glitch
es.
- Never use Clocks consisting of more than one level of combinatori
al logic.
- Carefully calculate setup times and hold times for multi-Clock sy
stems.
- Synchronize signals between flipflops in multi-Clock systems when
the setup and hold time requirements cannot be met.
- Ensure that Preset and Clear signals do not contAIn race conditio
ns.
-
Ensure that no other internal race conditions exist.
-
Register all glitch-sensitive outputs.
Synchronize all asynchronous inputs.
- Never rely on delay chains for pin-to-pin or internal delays.
10)Do not rely on Power-On Reset. Use a master Reset pin to clear al
l flipflops.
11)Remove any stuck states from state machines or synchronous logic.
其它方面的规范一时没有想到,想到了再写,也欢迎大家补充。
====================================================================================
时序是设计出来的
我的老板具备华为与寒武ake的技术经验背景;这些经验促使我们了解了华为技术架构以及altra的逻辑设计。
一些内容,并且我们的项目规范主要参考华为的相关规定。在这几个月的时间里
、我最大的感触源自华为的经典话语:时序并非模仿而来,并非凭空捏造。
的。
在我们公司里,每个项目都需要经过严谨的审查,仅当获得批准后方能继续开展后续工作
写作。以逻辑为例,并非一开始就直接编写代码,而是要制定总体设计方案并详细规划每一步骤
设计方案需要等到这些方案经过评审并通过后才开始进行编码工作;通常情况下这是必要的步骤。
所占的时间要远大于编码的时间。
整体方案主要围绕模块划分展开,并涵盖了一级模块与二级模块之间的接口信号及时序安排(我们规定)
完成接口信号的时间序列特征详细描绘,并探讨未来如何进行测试规划。针对这一级方案的技术架构,在确保该方案能够实现稳定运行的前提下
今后的设计中时序需收敛至一级模块(最终将进入二级模块处理)。我们正在构建。
在详细设计阶段,在某些情况下可能会对特定参数进行优化设置;但这种参数优化的最大限度是有限制的
该系统目前的设计仅限于本一级模块的影响范围,并未涉及整体架构的优化工作
未对时序进行合理规划,在实际调试过程中往往会出现某个信号通道的时间分配未能达标的情况。这种情况下,则需要最终不得不调整其他模块的时间参数以解决问题。
序也改一下,搞得人很郁闷。
在构建详细设计方案的过程中,在各个阶段我们完成了各模块的接口时序设计工作。
,各级模块内部是怎么实现的也基本上确定下来了。
因为实现了这一目标,在编码过程中因此变得高效。无论怎样做之后都能够使设计更加优化。
一直处于可控的状态,不会因为某一处的错误引起整个设计从头进行。
受版权保护者悉知
提建议请给作者发email:wangdian@tom.com
EDA论坛 版权所有,严禁拷贝! 转载请联系bbs@edacn.net
=============================================================================================
如何提高电路工作频率
从工程师的角度来看,自然追求的是电路运行频率的稳定性和可靠性;通常情况下,默认参数设置为48kHz.
运行频率(FPGA芯片的工作频率)尽可能高。我们还常常听说采用流水线的方式来提高效率。
方式可以通过增强工作频率来实现。这一方法确实是一个关键性的手段。今天我想进一步地进行分析如何提出这个方法。
高电路的工作频率。
我们先来分析下是什么影响了电路的工作频率。
我们电路的工作频率主要取决于寄存器间的信号传输延迟以及与clock skew相关的因素。
在FPGA内部时钟线路过长的情况下, clock skew非常小, 可以忽略不计; 这里为了简化处理.
单起见,我们只考虑信号的传播时延的因素。
信号的传播时延包含寄存器切换时延、走线传输时延以及通过组合逻辑产生的延迟(例如)
可能不够精确;实际上,在分析问题时并没有好的方法可选;需要提升电路的工作频率
,我们就要在这三个时延中做文章,使其尽可能的小。
为了更好地理解开关时延这一现象及其影响因素,在电路设计中这是一个重要的考量点。
我们只能通过调整线路走向以及删减复杂逻辑模块的方法来提高工作频率。
1.通过改变走线的方式减少时延。
以 Altera 的器件为例,在 Quartus 中的 timing closure floorplan 可以看到存在明确的信息。
大量条理松散的结构单元中
数量为8或10个LE。它们的走线时延关系如下:在同一个LAB中其走线时延小于其他同类或相同
行 < 不同行且不同列。
在优化过程中,在综合器的设计中施加适当约束条件时,请避免采用贪心算法,并且通常建议预留5%的安全裕量。例如,在电路设计中
当频率设置为100MHz时,在此基础上提升至105MHz并施加相应的约束条件是可行的。这会导致贪心策略的效果变差,并且显著提高系统的总体延迟。
间) 可以在布线过程中将相关的逻辑尽可能地集中一些, 从而达到减少走线时延的目的。(注:约束
不仅仅是通过优化布局布线方案来提升工作效率,并且此外还有其他的优化手段。
2.通过减少组合逻辑的减少时延。
在之前的讨论中,我们提到可以通过施加限制措施来提升工作效率;然而,在设计初期必须避免这种做法
将实现工作频率提升的美好愿景寄托于增加约束措施上,并要求我们通过合理设计来防止出现过大的组织结构
有逻辑性地设计电路后,能够使工作频率得到提升;为了增强设计的可移植性,则需要确保所有组件都经过严格测试;我们的设计更加完善和可靠.
计在移植到另一同等速度级别的芯片时还能使用。
据我们了解,在现有的FPGA设计中, 大部分采用的是基于4输入LUT的方法; 当某个输出所涉及的条件数量超过时
四输入的话就要由多个LUT级联才能完成,并由此导致一级组合逻辑延迟的产生;为了优化设计性能,在此过程中我们需要降低组件数量。
合理情况下, 也就是最少的条件数量, 通过这种方式实现级联所需的LUT数量更少, 进而减少了组的数量
合逻辑引起的时延。
在我们日常生活中所提及的流水是一种将较大的组合逻辑进行拆分,并在此处插入一阶或多阶D型触发器的技术方法
在设计电路时,在两个寄存器之间插入管致能器(从而降低寄存器之间的组合逻辑)是一种有效的方法以提升时钟频率的方式)。例如,在32位系统中使用这种方法可以使时钟频率得到显著提升
数字电路中的一个计数器存在较长进位链的问题, 这必然导致工作频率降低. 为此, 我们可以将其分割为4位及以下部分进行优化处理.
八进制数值被设置为8位长度。每当四进制(Quaternary)计数器达到十进制15时会触发八进制计数器的一次增量操作。从而完成了整个计数值转换过程。
割,也提高了工作频率。
在状态机设计过程中进行优化时
如果输入值超过4,并与其它条件共同作为状态切换判据时,则必然会提高LUT级别的数量
连接它们之后, 有助于提升组合逻辑的能力. 举个例子来说, 在一个6输入的计数器中, 我们期望当它达到111100的状态时
状态切换
去触发状态跳变,这样就将组合逻辑减少了。
前面提到的都是采用流水方式进行处理组合逻辑的情形;然而,在某些情况下我们发现这样的方法并不适用。
难去切割组合逻辑的,在这些情况下我们又该怎么做呢?
状态机就如这样一个案例,在这种情况下我们无法在状态译码的组合逻辑中增加流水
在我们的设计中包含了一个包含几十个状态的状态机,在这个状态下其状态译码逻辑相当复杂无疑。
这很可能是设计的关键路径之一。那么我们该怎么办呢?还是老方法吧?试着简化组合逻辑。
我们能够分析其状态输出结果,并对其进行重新分类处理,将其划分为若干个小类。
状态机通过根据输入条件进行判断(case语句),导致相应的小状态机被激活,并最终实现了对复杂的问题拆解为多个小的状态管理逻辑过程。
将一个较大的状态机分解成若干个小的状态机单元。按照ATA6标准,在硬盘系统中执行的各种命令通常数量在20上下波动。
每个命令都对应着多种不同的状态;如果按照单一的大规模的状态机(即一个嵌套在另一个的状态)去处理的话,则是完全不可能的
设想中我们利用case语句来对命令进行解码,并导致相应的状态机被激活
这一个模块的频率就可以跑得比较高了。
总结:提高工作频率的本质原因在于减少寄存器之间的时延问题;主要通过引入高速缓存机制来实现这一目标。
避免出现复杂的组合逻辑,并且最好能够满足四个输入条件下的10以内LUT数量级。
可以通过加约束、流水、切割状态的方法提高工作频率。
===================================================================================
做逻辑的难点在于系统结构设计和仿真验证
初到公司时 boss跟我分享了开发流程中的一些关键注意事项。具体来说,在设计逻辑体系时并不是因为 RTL 级别的硬件层面代码实现存在难度,而是整个系统的架构设计才是核心挑战所在。
在结构设计与仿真验证领域。目前国内对于综合集成设计的关注程度较高,在系统架构层面的研究工作也取得了一定进展;然而,在系统结构设计方面还存在一定的不足
在仿真验证方面目前尚且缺乏系统性的相关资料这一情况也一定程度上显示了我国当前设计水平的发展现状。
还比较低下吧。
在学校的时光中, 我们往往过于重视RTL级编码的实现, 而对仿真验证这一环节则流于表面. 其实, 这种做法可能会导致后续开发中的诸多问题
对于HDL行为描述的语法不感兴趣,并且也不愿意深入学习TestBench工具;原因是因为觉得它比较复杂。
波形图方便;对于系统结构设计更是一点都不懂了。
到了公司接触了些东西才发现完全不是这样。
其实在国外,花在仿真验证上的时间和人力大概是花在RTL级代码上的两倍,现在仿
仿真验证是百万门级芯片设计的关键路径之一。其难点主要体现在如何构建模型以达到预期效果。
确保准确去验证设计准确性(主要提升代码覆盖率),在其中提高速度也很快
重要的。
验证本质上就是如何产生足够覆盖率的激励源,并且如何进行错误检测。我认为这可能是一个有效的解决方案。
在仿真验证过程中,最为关键的是要实现自动化测试工作流程。这也是为什么我们要制定标准化的测试基准文档(TestBench)。
根本原因在于我的一个设计中每次仿真都需要耗时一个上午(相对来说规模不算大)。
然而难以实现自动化验证。当采用画波形图进行仿真时,则主要进行仿真分析时会遇到的问题是?
在算法复杂且输入呈统计分布设计的系统中可能会失效。另外,在分析时需要查看与波形图相关的结果。最后,在测试过程中需要检测该指标的值。
错率几乎为零。
那么如何实现自动化呢?由于个人能力有限,我仅能简要提及BFM(bus function)的相关内容。
ion model,总线功能模型)。
举例而言,在构建一个MAC核心时(其中主板采用PCI总线架构),我们所需的硬件配置包括一个MAC_BFM和一个PCI_BFM
即_PCI_BM(基于PCI行为模型)。MAC_BFM主要负责生成相应的以太网帧数据(作为激励源),并同步相应的时钟信号。
即_PCI_BM(基于PCI行为模型)。MAC_BFM主要负责生成相应的以太网帧数据(作为激励源),并同步相应的时钟信号。
该机制在处理过程中将长度参数和头部字段的数据设置为随机值,并同时在发送过程中将该数据复制一份至PCI_BM中;PCI_BFM
该设备的功能类似于PCI总线的行为。例如,在接收了一个正确的帧后,它会将这个帧发送到PCI总线。
发起请求,则会去响应这一请求并接收 incoming data;而 main function of PCI_BM is to send out MAC_BFM.
incoming items be compared with the received items by PCI_BFM, due to its inclusion of MAC_BFM's send information and PCI_BTM's.
获取信息时,在设计合理的前提下,系统总是能够自动且彻底地进行测试以确定设备是否正常运行。
从而实现自动检测。
据认为,在仿真验证方面华为已形成了一个优秀的优化的仿真验证体系和方法论框架,在国内范围内表现较为突出。
证平台方面,在大多数与通信相关的领域已经完成了相应的验证工作。听说他朋友提到,在当前阶段他们只需将待测设备接入该验证平台即可完成必要的验证流程。
在测试平台中,并配置好参数,就可以自动地检测被测功能的正确与否。
功能仿真完成后,在基于FPGA的设计过程中已基本实现了RTL级别代码。
在满足所有综合分析结果与功能仿真一致性条件的情况下,在综合布局布线后的静态时序报告未出现违反时间限制的情况
时序约束的问题出现后,可以直接在PC上进行排查.具体来说,在华为和中兴之间,他们负责FPGA开发工作.
时段也是不进行时序仿真的时候,并非不能这么做。原因在于进行此类仿真的工作量较大,在实际应用中可能会带来额外的时间成本与资源消耗。此外,在某些情况下选择直接观察静态序列的变化可能更为高效与便捷
报告好。
一般来说,在采用asic设计方法时仿真验证所需的时间会较长,在涉及长时间测试的情况下
通常来说,在进行钟域设计时, 我们会采用后仿的方式进行开发工作. 然而, 在开展后仿工作之前, 也会倾向于优先采用形式验证工具, 并结合相应的测试手段进行评估.
采用静态时序分层报告的方式来检查是否存在违反设计规范的地方,在做完此步骤后进行后续仿真工作
量可以小很多。
关于HDL语言的选择,在国内也存在诸多争议。有人倾向于使用VHDLOthers prefer Verilog.
这一做法并无显著价值,并非大型企业普遍采用的做法而是采用verilog进行rtl级编码因此而言
建议大家尽可能深入学习Verilog。在仿真过程中,因为Verilog在行为级建模方面的表现优于VHDL,因此通常采用Verilog进行仿真实验。
用于建立仿真模型的深度学习(DL)相对较少。但也不能单纯认为Verilog是最好的工具。实际上,在复杂的行为级建模中,Verilog展现出卓越的表现。
该方法的能力也存在局限性。例如目前该技术还无法处理数组。在处理复杂场景时需要更高水平的算法设计。
通过进行语义理解与抽象处理的语言学方法能够准确构建并描述出行为级模型。
在国际仿真领域中,在仿真实验室中使用System C和E语言较为普遍。
verilog的都算是很落后的了,国内华为的验证平台好像是用System C写。
在系统结构设计方面, 因为我所进行的设计规模较小, 缺乏相应的实践经验, 只是感觉到有必要进一步优化系统结构.
需要具备一定的计算机系统结构相关知识才行。划分的标准则分为两个层次:首先是根据功能进行区分;其次是根据其他因素进行选择。
总线结构、存储结构和处理器架构等关键组成部分,在系统化的基础上进行分类组织;这样不仅便于各组件之间的协调工作执行得更加顺利有序,并且能够使得系统的整体运行更加高效稳定
实现。我想以后会有一些心得体会与大家分享,并且不再误导大家。
