1、使用verilog进行RTL设计一般可归纳为3种基本的描述方式:
(1)数据流描述:采用assign连续赋值语句
(2)行为描述:使用always语句或initial语句块的过程赋值语句
(3)结构化描述:实例化已有的功能模块或原语,即平常所说的元件例化和IP core.
过程赋值语句包括非阻塞过程赋值、阻塞过程赋值和 连续过程赋值。
2、RTL级设计时需注意的问题
(1)凡是在always或initial语句中赋值的变量,一定是reg类型变量;凡是在assign语句中赋值的变量,一定是wire类型变量、
(2)定义存储器:reg[3:0] MEMAORY[0:7];地址为0~7,每个存储单元都是4bit;
(3)由于硬件是并行工作的,在Verilog语言的module中,所有描述语句(包括连续辅助语句assign、行为语句块always和initial语句块以及模块实例化)都是并发执行的。
(4)使用完备的if...else语句,使用个条件完备的case语句并设置default操作。以防止产生锁存器latch,因为锁存器对毛刺敏感
(5)
严禁设计组合逻辑反馈环路,它最容易引起振荡、毛刺、时序违规等问题。
(6)不要在两个或两个以上的语句块(always或initial)中对同一个信号赋值
3、阻塞赋值与非阻塞赋值
(1)阻塞赋值的操作符号为“=”。它的含义是在计算等式右侧表达式值及完成其赋值时不 会被其他的 verilog 语句打断,就是说,在当前赋值没有完成之前,它阻塞了其他 verilog 语句的执行。
(2) 非阻塞赋值的操作符为“<=”。它的含义是子啊赋值操作时刻开始计算等式右边,赋值操作时刻结束时更新等式左边。在这器件,可以执行其他Verilog语句,也不阻塞其他Verilog语句的执行。
在实际使用中,应该遵循的原则是:
(1)在时序逻辑中,使用非阻塞赋值
(2)在组合逻辑中,使用阻塞赋值
(3)在同一个always块中,不要混合使用阻塞赋值和非阻塞赋值
(4)在同一个always块中,如果既有组合逻辑又有时序逻辑,使用非阻塞赋值
(5)
always模块的敏感表为电平敏感信号时,使用阻塞赋值
(6)
不要使用#0时延进行赋值
(7)不要在阻塞赋值中使用时延语句
(8)在行为级描述中,如语句间是
顺序执行的关系,使用阻塞赋值
4、哪些是不可综合的代码
(1)对于一些抽象的行为描述代码是不可综合的。延迟语句(如:
#delay)、初始化语句
initial以及等待语句
wait。
(2)对于一些抽象的运算代码也是不可综合的。
(3)对于不定次数的循环运算是不可综合的。
5、面积和速度是FPGA设计的两个标准。
“面积”是指一个设计所消耗FPGA的逻辑资源数量,“速度”指设计在芯片上稳定运行所能达到的最高频率。
优化RTL代码追求的最终目标是面积或速度,或者是两者的平衡。
6、Pipelining技术
即
流水线时序优化方法,其本质是调整一个较大的组合逻辑路径中寄存器位置,
用寄存器合理分割改组合逻辑路径,从而降低路径Clock-To-Output 和Setup等时间参数的要求,达到提高设计频率的目的。
7、模块复用与资源共享
模块复用与资源共享的目的在于节约FPGA的逻辑资源,即节约面积。
8、逻辑复制时一种通过增加面积而改善时序条件的优化手段。逻辑复制最常用的场合是调整信号的扇出。
9、状态机的设计
推荐采用两段写法(2个always模块)或三段写法(3个always模块)。
两段写法的核心思想是,一个always模块采用同步时序描述状态转移;另一个always模块采用组合逻辑方式判断转台转移条件,描述状态转移规律。其结构如下:
三段式写法的核心思想是,一个always模块采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件,描述状态转移规律,第三个always模块使用同步时序电路描述每个状态的输出。
状态机设计的其他技巧和准则:
(1)状态机的编码最好使用one-hot(独热码)
(2)一个玩呗的状态机应该具备初始化状态和默认状态
(3)状态机的编码可以用parameter定义,不推荐使用define宏定义
(4)时序逻辑always米快使用非阻塞赋值"<=",组合逻辑模块使用阻塞赋值“=”
(5)使用玩呗的if...else语句和case 语句
(6)case语句需具备full_case和parallel_case属性。full_case定义了所有可能的输入模式,parallel_case定义了case项是不重复的。
10、分析状态机的工具:synplify pro。
11、testbench包括两部分:一时激励,而是被验证设计的元件例化。