标准很重要
作业过的朋友必定知道,公司里是很着重标准的,特别是关于大的规划(不管软件仍是硬件),不依照标准走几乎是不行完成的。逻辑规划也是这样:假如不按标准做的话,过一个月后调试时发现有错,回头再看自己写的代码,估量许多信号功用都忘了,更不要说检错了;假如一个项目做了一半一个人走了,接班的估量得从头开始规划;假如需要在本来的版别基础上添加新功用,很可能也得从头来过,很难做到规划的可重用性。
在逻辑方面,我觉得比较重要的标准有这些:
1.规划有必要文档化。要将规划思路,具体完成等写入文档,然后经过严厉评定通往后才干进行下一步的作业。这样做乍看起来很花时刻,可是从整个项目进程来看,肯定要比一上来就写代码要节省时刻,且这种做法能够使项目处于可控、可完成的状况。
2.代码标准。
a.规划要参数化。比方一开始的规划时钟周期是30ns,复位周期是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.信号命名要标准化。
1) 信号名一概小写,参数用大写。
2) 关于低电平有用的信号结束要用_n符号,如rst_n。
3) 端口信号摆放要一致,一个信号只占一行,最好按输入输出及从哪个模块来到哪个模块去的联系摆放,这样在后期仿真验证找错时后 便利许多。如:
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
…
);
4) 一个模块尽量只用一个时钟,这儿的一个模块是指一个module或者是一个entity。在多时钟域的规划中涉及到跨时钟域的规划中最好有专门一个模块做时钟域的阻隔。这样做能够让归纳器归纳出更优的成果。
5) 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,制止呈现任何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。理由同上。
6) 在FPGA的规划上制止用纯组合逻辑发生latch,带D触发器的latch的是答应的,比方装备寄存器便是这种类型。
7) 一般来说,进入FPGA的信号有必要先同步,以进步体系作业频率(板级)。
8)一切模块的输出都要寄存器化,以进步作业频率,这对规划做到时序收敛也是极有优点的。
9) 除非是低功耗规划,不然不要用门控时钟–这会添加规划的不稳定性,在要用到门控时钟的当地,也要将门控信号用时钟的下降沿 打一拍再输出与时钟相与。
clk_gate_en ——– —-
—————–|D Q |——————| \ gate_clk
_out
| | ———| )——–
-
——o|> | | | /
clk | ——– | —-
————————————
10)制止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方法,不然这种时钟满天飞的方法对规划的可靠性极为晦气,也大大添加了静态时序剖析的复杂性。如FPGA的输入时钟是25M的,现在体系内部要经过RS232与PC通讯,要以rs232_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