1、Verilog 代码风格总结供参考窗体顶端转Verilog 代码风格-供参考Description本文主要是收集一些重要的Verilog coding style。一个好的coding style可以减少错误的发生,增加电路的效能,以及较好的可读性。TextThe order of module signals一个module signal顺序如下 (由左至右):Inputclock signals(clk_*)set/reset signals(set_*, rst_*)enable/disble signals(en_*, dis_*)read/write enable signals(w
2、e_*, re_*, rw_*)control signals(i_*)address signals(i_*)data signals(i_*)Outputclock signals(o_clk_*)set/reset signals(o_set_*, o_rst_*)enable/disable signals(o_en_*, o_dis_*)control signals(o_*)address signals(o_*)data signals(o_*)In/Outcontrol signals(io_*)address signals(io_*)data signals(io_*)Na
3、ming Rule以下的namign rule为个人使用的规则。命名方式分类底线分隔型:xxx_yyy_zzz大写底线分隔型:XXX_YYY_ZZZ首字大写型:AbcDefGhi首字小写型:avcDefGhi各种元素所使用的命名文件名称:底线分隔型, Ex: xxx_yyy_zzz.vmodule名称:底线分隔型, Ex: xxx_yyy_zzzmodule instance名称:底线分隔型, Ex: xxx_yyy_zzzlocal wire名称:底线分隔型:Ex: xxx_yyy_zzzlocal reg名称:底线分隔型, Ex: xxx_yyy_zzzinput signal名称:前置i
4、_的底线分隔型, Ex: i_xxx_yyy_zzzoutput signal名称:前置o_的底线分隔型, Ex: o_xxx_yyy_zzzinput/output signal名称:前置io_的底线分隔型, Ex: io_xxx_yyy_zzz常数名称:大写底线分隔型, XXX_YYY_ZZZparameter参数名称:大写底线分隔型, Ex: XXX_YYY_ZZZblock名称:大写底线分隔型, Ex: XXX_YYY_ZZZ特殊讯号名称单一的clock signal: clk多个clock signal: clk_xxx负缘触发的clock signal: clk_n, clk_xx
5、x_n单一的reset signal: rst多个reset signal: rst_xxx负缘触发的reset signal: rst_n , rst_xxx_n单一的set signal: set多个set signals: set_xxx负缘触发的set signals: set_n, set_xxx_n致能讯号: en_xxx除能讯号: dis_xxxProcedural Assignments使用指引在撰写sequential logic时,使用nonblocking assignment。在撰写latches电路时,使用nonblocking assignment。在always
6、block中撰写conbinational logic时,使用blocking assignment。在同一个always block中同时撰写sequential及combinational logic时,一律使用nonblocking assignment。别在同一个always block中混合使用nonblocking及blocking assignment。别在两个以上的always block中对同一个变量设定数值。使用$strobe来显示由nonblocking assignment所给定的变量。不要对assignment使用#0延迟设定。在procedural assignme
7、nt中,LHS(等式的左边Left Hand Side?)一定要是reg型态。非procedural assignment一定是net的型态。常用的styleCombination logic在always block中,如果使用combination logic,应当使用blocking assignment./ All inputs used within always block should be listed in sensitive list.always (in1 or in2 or in3)begin xxx = in1 in2 & in3;endSequential logi
8、c在always block中,如果使用sequential logic,应当使用nonblocking assignment./ Synchronous reset. The rst_n is NOT in sensitive list.always (posedge clk) begin if (rst_n) begin xxx = INIT_VAL; end else begin xxx = yyy; end end/ Asynchronous reset. The rst_n IS in sensitive list.always (posedge clk or negedge rst
9、_n) begin if (rst_n) begin xxx = INIT_VAL; end else begin xxx = yyy; end endDelay的建模Combination logic建模没有delay时,使用blocking assignment(ex: a = b;)建模有惯性(inertial) delay时(即glitch不会传到后面的电路中)。使用delayed evaluation blocking assignments(#10 a = b;).建模传输(transport)delay时(即glitch也会一并传到后面的电路中)。使用delayed assign
10、ment nonblocking assignments(ex: a = #10 b;).Sequential logic建模没有delay时,使用non-blocking assignments (ex: q = d; ).建模有delay时,使用delayed assignment nonblocking assignments(ex: q = #10 d;).Finite State MachineMoore FSM: 输出与输入没有直接关系。由两个always block构成,一个是sequential block用来处理状态的变化。另一个为combinational block用来处
11、理状态与输入之间的关系。注意,在sequential block中应全部使用nonblocking assignment。在combinational block中应使用blocking assignment。在某些简单的case中,combinational block也可直接由continuous assignment来取代。下面的范例是一般简单的FSM。/ Sequential always block.always (posedge clk or posedge rst) begin if (rst) state = STATE_IDLE; else state = next; end
12、/ Combinational always block.always (state or input1 or input2 . or inputN) begin next = STATE_IDLE; outputs = OUTPUT_IDLE: case (state) STATE_IDLE: begin . / the logic to determine the next state. next = STATE_?; end STATE_?: begin . / the logic to determine the next state. next = STATE_?; outputs
13、= ?; / The output of this state. end endcase end针对simplified one-hot encoding的FSM范例:/ Sequential always block.always (posedge clk or posedge rst) begin if (rst) state = nb0; stateSTATE_DEFAULT = 1b0; else state = next; end/ Combinational always block.always (state or input1 or input2 . or inputN) be
14、gin next = nb0; outputs = OUTPUT_DEFAULT: case (1b1) / synopsys full_case parallel_case stateSTATE_DEFAULT: begin . / the logic to determine the next state. nextSTATE_? = 1b1; end stateSTATE_?: begin . / the logic to determine the next state. nextSTATE_? = 1b1; outputs = ?; / The output of this stat
15、e. end / synopsys translate_off default: $display(Bad state!); / synopsys translate_on endcase end针对simplified one-hot with zero-idle encoding的FSM:/ Sequential always block.always (posedge clk or posedge rst) begin if (rst) state = nb0; else state (c * d); 因为(a + b)及(c * d)都会是8 bit的结果。assign tmp1 =
16、a + b; / 16 bits.assign tmp2 = c * d; / 16 bits.assign o = tmp1 tmp2; / 1 bit.一. 文件命名规则 1: 每个文件中只包含一个设计单元理由: 便于修正.规则 2: 文件命名协定.理由: 便于理解设计单元constructs及文件内容.如: spooler.v / spooler模块的同步Verilog代码描述规则 3. 模拟和数字Verilog文件每个单一文件必须包含: (1)模拟(analog)Verilog(用.va文件后缀); 或(2)数字Verilog(用.v文件后缀); 或(3)清晰的模数混合Verilog(
17、用.va文件后缀).理由: 模拟的编译器也许不能操纵数字的架构; 反之亦然.二. HDL编码项目命名规则 4: 允许的字符集命名中必须包含字母, 数字或下划线A-Z, a-z, _ (见 规则5)例外: 不允许使用连续的下划线.理由: 双下划线在硬件竞争中是不工作的.规则 5: 命名的首字符命名必须以字母开头, 而不是数字或下划线 (见 规则4)理由: 以数字或下划线开头的命名, 可能会引起工具冲突.规则 6: 所有命名必须是唯一的无关项理由: 在Verilog(语法敏感)和VHDL(语法不敏感)中的设计转换中, 很可能受语法不敏感的设计风格影响.规则 7: 信号的一致性理由: 和VHDL相比
18、, Verilog和许多支持VHDL的工具都一样是语法敏感. 及时辨别信号的类型(如: 低电平有效的信号或时钟)有助于调试.规则 8: 常量, 参数和标签区块要大写理由: 提供了一种可以辨别那些在仿真中不需要经过数据转换的实体的机制.规则 9: 信号, constructs和实例化标签要小写理由: 从在仿真中数据不变化的实体中区别信号和constructs, 以及在设计中保持一致的视觉和感觉.规则 10: 有意义的信号和变量名称小写的名称必须包含信号和变量的意图.理由: 描述是什么, 而不是怎样去做, 有助于理解设计.如: data_bus, set_priority规则 11: 有意义的常量
19、名称常量名称一定要描述常量的意图. 根据意图可以很明显地看出常量的类型, 及不是端口的名称. 常量需大写.理由: 有意义的名称对于常量来说, 非常重要.如: 好的名称: SBUS_DATA_BITS, MEMORY_WIDTH, CLK_PERIOD如: 差的名称: ADDRESS_SIZE 并不明晰, 当它指的是数的位宽或地址空间的长度规则 12: 有意义的construct名称construct的名称如functions, modules, tasks等,必须根据它们要做什么而不是怎么样去做来命名. construct名称必须小写.理由: 描述是什么, 而不是怎样去做, 有助于理解设计.规则 13: 有意义的实例化标签实例化标签要根据construct指定的要实现什么, 而不是怎样去做来命名.理由: 描述是什么, 而不是怎样去做, 有助于理解设计.如: addr_decode, bit_stuff, sbus_if规则 14: 用下划线分隔包含许多单词的名称理由: 增加可读性如: ram_addr规则 15:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1