FPGA代码设计规范整理

时间:2021-08-06 00:38:41

1、设计中的FIFO、状态机接口需要有异常恢复状态和状态上报机制,格雷码电路防止被综合电路优化掉。

a)自行设计的格雷码FIFO(一般用于连续数据流跨时钟域)用Synplify综合时,为了防止被优化需要添加综合引导语句:“synthesis_syn_preserve = 1”;

b)各种综合工具均有状态机安全模式,综合时候建议打开。

2、电路中所以寄存器、状态机、计数器、FIFO在单板上电复位时以及使用前必须处于一个已知状态。

a)对电路中的寄存器、状态机、计数器、FIFO必须进行异步复位(不依赖于任何时钟的复位);

b)电路中的状态机、计数器在应用的时候不能完全依赖于异步复位时的状态,对于重要的状态机或计数器,必须还有周期检测或同步并对它进行复位/置数机制,保证可靠工作。

3、跨时钟域以及异步信号必须同步化处理(使用的QuartusII中的Design Assistant或者专业的nlint、spyglass等工具完成代码检查),这条是用FPGA进行数字电路设计的最核心最基本的思想和方法。

a)尽可能在整个设计中只用一个主时钟,同时只用一个时钟沿,主时钟走全局时钟网络;

b)推荐所有输入输出信号均通过寄存器寄存,寄存器接口当作异步接口考虑;

c)当全部电路不能用同步电路思想设计时,即需要用多个时钟来实现,则可以将全部电路分成若干个局部同步电路(尽可能以同一个时钟为一个模块),局部同步电路之间的接口当作异步接口考虑;

d)电路的实际最高工作频率不应大于理论最高工作频率,要留有一定设计余量,保证芯片可靠工作;

e)电路中所有寄存器、状态机在单板上电复位时应处在一个已知状态;

f)对于设计中的异步电路,要给出不能转换为同步设计的原因,并对该部分异步电路的工作可靠性(如时钟等信号是否有毛刺,建立保持时间是否满足要求等)做出分析判断,并提供分析报告;

e)关于全局时钟的约束,能上全局的全部上全局,不能上全局的建议通过区域时钟约束、逻辑锁定、增量编译等保证性能;

h)依靠QuartusII中的Design Assistant或者专业的nlint/spyglass工具检查跨时钟域代码处理部分。

4、电路中不能出现门控时钟和行波时钟。

a)门控时钟的使用主要是通过关断时钟来达到降低功耗的目的,但是使用不当容易使得时钟出现毛刺,给设计带来灾难性风险。如果降功耗必要的话,推荐使用厂家自带的时钟控制的IP Core,例如ALTCLKCTRL;

b)行波时钟是指寄存器输出的数据又作为下一个寄存器的时钟使用。行波时钟是一个非常危险的设计,由于寄存器有Tco,它会使时钟沿变缓,延时加大,多级级联的时候情况更加恶劣,出问题是必然的!行波时钟设计实际上是一种异步设计,大部分综合布线工具都不会对行波时钟设计进行setup/hold时序分析检查,设计无法保证正确性!

设计中完全没有必要使用行波时钟,可以用寄存器输出做同步使能用,与行波时钟设计意图完全一致。

5、需要综合的RTL源代码中不允许出现“*  /  %”这三个运算符。

a)目前大部分综合工具对以上三种运算支持的不好,而且非常浪费LE资源,还不能保证正确性和稳定性。可行的替代方案如下:

“*”通过例化IP Core或者“移位运算+加法”来实现;

“/”通过“移位运算+加法”来近似逼近实现,例如:1/30 = 1/32 + 1/512 + 1/8192;

“%”通过自己手动计算得到;

以上运算在非综合的RTL的代码中使用不受此限制。

6、条件语句必须赋值完全,即:if语句后必须有配对else语句,case、casez、casex语句中必须有default语句。

a)如果if没有配对的else,case/casez/casex中没有对应的default语句的话,之后reg型数据会保持原来的值。这个在时序逻辑中可能没有太大的问题(如果设计者本意就是要保持的话),但在组合逻辑中会生成一个锁存器,锁存器逻辑往往不是设计者的意图而导致灾难性的后果。

为了避免不经意的犯错,建议养成良好的编码习惯:if语句一定要有配对的else,case/casez/casex中一定要有对应的default语句,即使要保持原来的值也要显示声明(else ;或者default ;)

7、使用器件的专用引脚和专用资源实现电路功能,这些包括全局时钟、复位管脚、全局输出允许管脚等,内部全局时钟网络等。

专用管脚和专用资源一定要优先使用,使用的好会事半功倍。如果不用器件提供的专用管脚或资源,有时导致稳定性和可靠性不高甚至是设计失败。

8、逻辑未使用的但又硬件连线的管脚,逻辑必须显示声明并处理。所有有硬件连线的管脚必须在顶层代码中显示声明(包括暂时没有使用的),不允许放任不管。

a)对于有硬件连线的输入信号(包括三态的输入方向),建议输入到CPU接口作为只读寄存器(如果没有CPU接口可以将该信号做成一些等效冗余逻辑加到其他逻辑中去),这样既可以消除Warning,又可以避免布线工具随便布线(把输出信号放到输入管脚)导致外部信号冲突;

b)对于有硬件连线的输出信号(包括三态的输出方向),对于暂时没有使用的一定与硬件人员确定其默认值,避免对外信号(包括电阻上下拉)的干扰。

9、修改接口文档需要同对应项目组人员确认。

a)与硬件相关的方面涉及输入文件有qsf和sdc,内容包括但不限于电平标准、电流强度、管脚位置、输入输出方向、上下拉等等;

b)与软件相关的方面涉及方案协同实现文档和寄存器接口文档,包括寄存器操作地址、操作顺序等等。