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) 非阻塞赋值的操作符为“<> 在实际使用中,应该遵循的原则是: (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包括两部分:一时激励,而是被验证设计的元件例化。 |
|