1、第 1 页 共 28 页Verilog 编码规范(仅供内部使用)拟制 : xxx 日期: xxx审核 : 审核者 日期: yyyy-mm-dd批准 : 批准者 日期: yyyy-mm-dd版权所有 侵权必究第 2 页 共 28 页修订记录修订日期 修订版本 描述 修订者第 3 页 共 28 页目录1 命名规范 .62 代码编写规范 .82.1 版面 .82.2 编写代码规范 .83 电路设计规则 .173.1 时钟 .173.2 复位 .173.3 避免 LATCH 183.4 避免组合反馈 .183.5 赋值语句 .183.6 case 语句和 if-then-else 语句 .193.7
2、状态机 .193.8 异步逻辑 .214 模块划分 .215 提高可移植性的编码风格 .215.1 采用参数化设计 .215.2 采用独立于工具平台和工艺库的设计 .225.3 尽量使用已经得到验证的 IP 226 其他一些设计建议 .237 附件 .258 参考文档: .30第 4 页 共 28 页第 5 页 共 28 页基本原则:简单,一致,可重用。 简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。 一致指尽量保持代码风格一致,尽量保持命名一致。 可重用指有成熟的 IP 尽量使用 IP,设计的代码要尽量可重用。第 6 页 共 28 页1 命名规范给信号
3、命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。简单点,几十个字母长的名字,打字的和看字的都累。 大小写规则:只有 parameter,define 和 module 名称才能享受大写。 Module 名应与文件名保持一致(文件名是小写) ,假如不想在设计后面遇到麻烦的话。 不要尝试使用任何保留字,因为他们已经被保留了。 不要重复使用同
4、样的名字去命名不同的数据。 (建议)对 module 名加 ”_LVx”的后缀,增强 module 名称的结构层次含义如:设计顶层为 TOP LEVEL,即 LEVEL1,命名为 QTRxxxx_LV1;时钟模块,IO_PAD,CORE,为 LEVEL2,命名为 CLK_PROC_LV2 等等;CORE 内子模块为 LEVEL3,然后以此类推。 对于来自同一驱动源的所有时钟信号使用相同的名字。 对于低电平有效的信号,应该以_n 结尾。 模块间相连端口名称要一致。 (建议)使用下表所列的命名缩写方式。全称 名称clock Clkreset rstclear clraddress addrdata
5、_in dindata_out doutinterrupt request intread enable rdenwrite enable wrencount cnt第 7 页 共 28 页全称 名称request reqcontrol ctrlarbiter arbpointer ptrsegment segmemory memregister reg (建议)使用下列后缀命名方式全称 添加后缀active low _nenable _enselect _selflag _flgdelay _dly 信号命名的两个词之间用下划线间隔,如 ram_addr,cnt_ctrl 等等 信号命名尽量
6、不要使用孤立的、小写的英文字母 L第 8 页 共 28 页2 代码编写规范2.1 版面 语句独立成行,增加可读性和可维护性。 行的长度保持每行小于或等于 72 个字符。因为有的终端或打印机每行不能超过 80 个字符。规定 72 个字符是为了留出边空,提高可读性。还有一个原因是为象 vi 这样的编辑器留有显示行号的地方。用回车来分割超过 72 个字符的行,并且在下一行用缩进来表示该行是前一行的继续。 缩进。用缩进来提高续行和嵌套循环的可读性。缩进采用 4 个空格。避免使用 TAB 键。不同的编辑器或用户环境使得 TAB 的位置差别很大,造成缩进的混乱。有一些工具可以将 TAB 替换成空格。 (建
7、议)使用注释使用注释来解释端口、信号、信号组、always 块、函数等。注释应该放在它所描述的代码的附近。注释应该简明扼要,并足够说明问题。避免注释杂乱。显而易见的功能不用加注释。注释关键是说明设计意图。2.2 编写代码规范 在源文件中要有文件头在源文件、script 文件的开始应包含一个文件头。文件头至少应包含下列信息:文件名、作者、模块的功能描述和关键特征的列表、文件产生的日期、更改记录(日期、更改者、更改的内容) 。 (参见代码模板 sample.v) 模块名称用大写,例如:module MEM_CTRL。 端口声明时每行声明一个端口,并有注释(最好在同一行) ,也可对同一类型的一组端口
8、加注释。对于时钟,复位以及其他控制信号,需要注释有效工作沿或者有效工作值 建议用下述顺序声明端口。/INPUTsclocks , / posedge activeresets , / active highenables , / active highother control signals ,Data and address lines ,第 9 页 共 28 页/OUTPUTsclocks ,resets ,enables ,other control signals ,data 在输入和输出两类端口之间留一个空行来提高可读性。如上例所示。 端口列表之后,使用 parameter 定义内
9、部信号宽度以及其他参数化设置。 IO 信号申明和内部信号申明要单独成行,参考 sample.v 文件 使用简单的语句,一般使用 if else和 case 就能满足大部分需求,不要使用复杂的语句 常量(1)一位的控制信号采用二进制表达方式,如 1b0;(2)常数位宽不可缺省;如:Bad: if (rst_n = 0) temp = mem33; /temp gets data at addr 333_bit_reg = temp8:6; /get three bits of addr 33 运算符及表达式(1)表达式第 10 页 共 28 页(a)用括号来表示执行的优先级,尽管操作符本身有优先
10、顺序,但用括号表示优先级对读者更清晰,更有意义如:Bad: A + B ? C : D;Good: (A + B) ? C : D;(b)适当使用括号适当使用括号可以控制生成的电路结构,如 Z = A + B + C + D,综合结果可能为三级加法器,而变换为 Z = (A + B) + (C + D),综合结果则可能为两级加法器;(c)注意资源共享需要资源共享的部分一定要放在同一个模块的同一个 always 语句中,不同模块不同 always 语句之间的代码不能实现资源共享。如:always (.)if (.)d0 = A + B;else d0 = C + D;中,DC 可能只会生成一个加
11、法器。条件算子中不存在资源共享如:z = (cond1b1)? (a+b) : (c+d);必须使用两个加法器;而等效的条件 if-else 语句可以资源共享,如:if (cond=1b1)z = (a+b);elsez = (c+d);只要加法器的输入端复用,就可以实现加法器的共享,使用一个加法器实现。(d)尽量采用公共子表达式如 :x=a+b+cy=d+a+b改为:z=a+bx=z+cy=d+z(2)算符第 11 页 共 28 页(a)条件运算符r1 = gate? r2 : r3;避免使用条件嵌套:r1 = (aa = 0)? (bb = 0)? r2 : r3) : r4; orr1
12、= aa,bb = 0? r2:aa,bb = 0? r3:aa,bb = 0? R4:r4;(b)逻辑操作符在 if(),while(),()?A:B 之类的表达式中,括号中的表达式应该是一个逻辑表达式,相应的操作符应该用逻辑操作符。如:wire x,A,B;(x) ? A:B 与 (x = 1b1) ? A:BIf(AGood: addr(a,b,c); c=d(2)BLOCK 赋值和 NON-BLOCK 赋值的使用(a)组合逻辑采用 BLOCK 赋值(=)如:always (dat)i_dat = dat;(b)非组合逻辑(主要是寄存器)采用 NON-BLOCK 赋值并加 delay 以
13、保证前仿真和后仿真的一致如:always (posedeg clk)q = #DEL d;第 12 页 共 28 页(3)在同一块语句中不允许同时出现阻塞赋值和非阻塞赋值 条件语句(1)IF 语句(a)向量比较时,比较的向量长度要相等,同样向量和常量比较时长度也要求匹配,长度不同时要求进行显式位扩展(verilog 对位数小的向量做 0 扩展以使它们的长度相匹配,该扩展是隐式的)如:reg 7:0 abc;reg 3:0 def;.if (abc = 4b0,def) begin.if (abc = 8h0) begin(b)不要采用 if 表达式的简写形式例如:if (variable) 等
14、同于 if (variable != 0)if (!variable) 等同于 if (variable = 0)但后者才合乎规范(c)每个 if 都应该有一个 else 与之相对应,如果条件为假时不进行任何操作,则用一条空语句 else;避免产生 latch(d)if.else if.else if.else 的代码书写格式如下,要注意优先级if (.) beginendelse beginif (.)else (.)if (.)else (.)end第 13 页 共 28 页(d)如果变量在 if-else 语句中非完全赋值,则应给变量一个缺省值如:if (a = b) beginv1 =
15、 2b01;v2 = 2b10; /v3 is not assigned endelse if (a = c) beginv2 = 2b10;v3 = 2b11; /v1 is not assigned endelse /default 赋值beginv1 = 2b00;v2 = 2b00;v3 = 2b00;end(2)CASE 语句(a)所有的 case 语句都应该有一个 default 语句,避免产生 Latch(b) (建议)不要使用 casex、casez 语句,综合工具不支持 循环语句(1)forever 语句(2)repeat 语句(3)while 语句(4)for 语句在可以用
16、其它语句描述电路时,建议不要采用循环语句来描述。 initial 语句不要在 RTL 代码中出现 initial 块综合会将 initial 块忽略,使前仿真和后仿真不一致initial begin第 14 页 共 28 页end always 语句(1)在使用 always 生成组合逻辑时,敏感表要列全,敏感表中也不能包含没有用到的变量。Rule:Combinational sensitivity lists should include1)Any signal on right hand side of assignment2)Any signal in if or case expres
17、sionFor example:module sense_list_ex(b,c,d);/PARAMETER/INPUTSinput b;input c;input d;/OUTPUTS/INOUTS/SIGNAL DECLARATIONSwire b;wire c;wire d;reg a;/ASSIGN STATEMENTS第 15 页 共 28 页/MAIN CODE always (b or c or d)if (b1b1) a = c elseif (c=1b1) a = d;endmodule /SENSE_LIST_EX(2)对带异步清零端的寄存器的定义模板always (pos
18、edge clk_main or negedge rst_n)if (rst_n = 1b0) /此处统一采用 rst_n = 1b0 形式而不采用(! rst_n)begin /形式,对相关寄存器清 0(采用 # u_dly= 赋值)endelse begin/对相关寄存器赋值(采用 # u_dly= 赋值)end采用时钟上升沿触发。 有限状态机(FSM)(1)组合逻辑和时序逻辑分开描述;/ PART 1: COMBINATERIAL LOGIC FOR NEXT STATEalways (cur_state or full_new_fr or full or have_space)begi
19、n: OVC_FSM_NXT_ST case (cur_state)STDBY: beginif (full_new_fr = 1b1)nxt_state = W_BLOCK;else if (full = 1b1)nxt_state = W_DSCD;elsenxt_state = cur_state;end第 16 页 共 28 页W_BLOCK: beginif (have_space = 1b1)nxt_state = STDBY;elsenxt_state = cur_state;endW_DSCD: beginif (have_space = 1b1)nxt_state = STD
20、BY;else nxt_state = W_BLOCK;enddefault: nxt_state = STDBY;endcaseend / OVC_FSM_NXT_ST/ PART 2: SEQUENTIAL LOGIC FOR CURRENT STATEalways (posedge clk or RST_EDGE reset)begin: OVC_FSM_ST_TRANS if(reset = RST_VALUE)cur_state = DLY W_BLOCK;elsecur_state = DLY nxt_state;end / OVC_FSM_ST_TRANS3 电路设计规则3.1
21、时钟 (建议)简单的时钟结构易于理解、分析和维护,而且容易产生好的综合结果。最好是能够有单一的全局时钟,所有寄存器都在上升沿触发。 所有子模块内部使用单一时钟单一时钟沿,如条件不满足时,必须注明原因,并提出对综合以及布线的要求。 设计中包含内部产生的时钟时,必须将所有需要的时钟在一个单独的模块中生成。 如果不得不用混合的时钟沿,在综合和时序分析时确保能满足时钟精度最差情况下的占空比。同时确保把假定的占空比写入用户手册。第 17 页 共 28 页在多数设计中,占空比是时钟树的函数,而时钟树的插入通常又依赖于具体的工艺。使用 Core 的芯片设计者必须检查实际的占空比能够满足 Core 的要求,也
22、应该了解怎样改变综合和时序分析的策略以使得 Core 能够满足实际的条件。 (建议)多数基于扫描链的测试方法要求对上升沿和下降沿触发的寄存器分开处理。如果必须使用大量的上升沿和下降沿触发的寄存器,将上升沿和下降沿触发的寄存器分到不同的模块中是很有用的。这样容易确定下降沿触发的寄存器,并可将它们放到不同的扫描链中。 (建议)避免在 RTL 级手工实例化时钟 Buffer。时钟 Buffer 通常是在综合以后在物理设计时插入的。在可综合的 RTL 代码中,时钟网络通常被认为是理想的网络,没有延时。在布局布线时,时钟树插入工具插入适当的结构,尽可能的接近理想的、平衡的时钟配布网络。一个例外情况是在顶
23、层模块中可以插入厂家提供的伪时钟 Buffer,用于指明时钟树的源头和时钟树的参数。 (建议)避免在 RTL 级使用门控时钟或内部产生的时钟信号。门控时钟电路依赖于具体的工艺和时序。门控时钟不正确的时序可能导致假的时钟信号和误操作。不同局部时钟 SKEW 还会导致保持时间冲突( violation) 。门控时钟还会降低电路的可测性,也使得综合的约束变得困难。多数低功耗的电路需要门控时钟,但它们不应该出现在 RTL 级的编码中,象Power Compiler 这类工具可以自动去做。如果设计中必须使用门控时钟、内部产生的时钟或复位信号,应该让产生这些信号的电路位于设计顶层的一个独立的模块中。它将违
24、反编码规范的地方限制在一个小的范围内,有利于对这些产生电路开发特殊的测试策略。对于其他模块将可采用标准的时序分析和扫描链插入技术。3.2 复位 (建议)确保所有寄存器只被简单的复位信号所控制。最好的情况是,复位信号是 1bit 寄存器的输出。因为组合逻辑的输出会带有毛刺,对于异步复位电路,则会引起触发器的异常。 (建议)尽可能避免内部产生的条件复位信号。通常模块内所有寄存器应在同一时间内被复位。这种方式使得分析和设计更加简单和容易。 (建议)如果需要条件复位,设置一个单独的复位信号,并且将产生逻辑隔离于一个单独的模块。这种方式可使代码更易读,并易于综合出好的结果。 如果需要内部产生异步复位信号
25、,必须保证所产生的异步复位信号没有毛刺,最好的办法是保证异步复位信号最后为 1bit 触发器的输出,例如当计数器达到一个预设值时,产生异步复位信号:bad: wire reset; assign reset = (count=value);better: reg reset;always (posedge clk)第 18 页 共 28 页reset = (count=value);3.3 避免 LATCH描述组合逻辑的 always 块中,如果 if 语句缺乏 else 子句、 case 语句中各个条件所处理的变量不同都会在综合时推断出 LATCH。使用下述方法可避免 LATCH: 对所有的
26、输入条件都给出输出。 保证 always 块敏感列表完备。敏感列表应包括:if(),case()中的条件信号;所有 always 块中位于赋值语句右边的信号;当信号为多 bit 向量时,应包括向量的所有 bit 而不是部分。 在最终优先级的分支上使用 else 子句,而不用 elsif。 所有的 Case 应该有一个 default case。 避免使用 LATCH,除非能清楚地分析相关电路的时序以及毛刺带来的影响3.4 避免组合反馈 在设计中避免组合反馈电路。这种电路违背了同步设计原则,难以控制其行为,对仿真、调试和 DFT 都极其不利。3.5 赋值语句 在写可综合的代码时,在时序逻辑的 a
27、lways 语句块中总是使用非阻塞赋值。否则 RTL 级的仿真会和门级仿真的结果不一致。 在组合逻辑的 always 语句块中使用阻塞赋值。 同一个触发器不能在多个 always 块中被赋值。3.6 case 语句和 if-else 语句 (建议)如果不需要有优先级的编码结构,建议使用 case 语句而不要使用 if-else语句。对于基于 cycle 的仿真器,case 语句的仿真速度要比 if 语句的仿真速度快。对于大的多选器,case 语句也比条件赋值语句的仿真速度快。对于综合工具,case 语句也往往能产生出时序和面积更优化的电路。 (建议)对于条件分支为独热编码的 case 语句,建
28、议采用下列语句,对于综合工具能产生较优化的电路case(1b1)condition1 : statement ;第 19 页 共 28 页condition2 : statement ;default : statement;endcase3.7 状态机 将状态机的描述分成两个 always 块,一个用来描述组合逻辑,一个用来描述时序逻辑。 (建议)用参数语句来定义状态向量。 (建议)将状态机的逻辑和非状态机的逻辑分成不同的模块,以便于综合工具对状态机进行单独优化。 必须使用 default 条件为状态机指定一个默认的状态,防止状态机进入死锁状态。 FSM 提供防死锁机制,以防止限死在某个状态
29、,特别是在异常情况下。 在 FSM 逻辑比较复杂的时候,建议使用独热编码方式,以提高时序。/ PART 1: COMBINATERIAL LOGIC FOR NEXT STATEalways (cur_state or full_new_fr or full or have_space)begin: OVC_FSM_NXT_ST case (cur_state)STDBY: beginif (full_new_fr = 1b1)nxt_state = W_BLOCK;else if (full = 1b1)nxt_state = W_DSCD;elsenxt_state = cur_state
30、;endW_BLOCK: beginif (have_space = 1b1)nxt_state = STDBY;elsenxt_state = cur_state;endW_DSCD: beginif (have_space = 1b1)nxt_state = STDBY;else 第 20 页 共 28 页nxt_state = W_BLOCK;enddefault: nxt_state = STDBY;endcaseend / OVC_FSM_NXT_ST/ PART 2: SEQUENTIAL LOGIC FOR CURRENT STATEalways (posedge clk or
31、RST_EDGE reset)begin: OVC_FSM_ST_TRANS if(reset = RST_VALUE)cur_state = DLY W_BLOCK;elsecur_state = DLY nxt_state;end / OVC_FSM_ST_TRANS 状态机输出异步控制信号时,必须采用下列结构 DQQSETCLRDQQSETCLRstateregitroutptregisterclk combinatoriallogicinputs outpts3.8 异步逻辑 (建议)避免使用异步逻辑。异步逻辑难于设计和验证,并会降低设计的可移植性。 (建议)如果在设计中使用异步逻辑,
32、将异步逻辑和同步逻辑分成不同的模块。这使得代码检查更加容易(异步逻辑通常需要仔细的检查和功能及时序上的验证)。 异步信号必须使用两级触发器同步之后使用。如下图所示第 21 页 共 28 页DQQSETCLRDQQSETCLRcombinatoriallogicclk1 clk2DQQSETCLR to iner logic4 模块划分 (建议)对设计层次中的每一个模块,锁存模块的所有输出信号。这样做可以简化处理过程,它使得输出的驱动强度和输入延时都可预期。输出驱动强度是触发器的平均驱动强度。 (建议)保持相关的组合逻辑在同一个模块中。这有利于综合工具对逻辑的优化,也有利于时序预算和快速仿真。
33、(建议)对不同设计目标的电路分成不同的模块将含有关键路径的逻辑和非关键路径的逻辑分成不同的模块,以便综合工具对关键路径采用速度优化,对非关键路径采用面积优化。 (建议)确保只有在顶层模块中才包括 I/O PAD。顶层模块中还包括一个中层模块,该模块中包含 JTAG 模块、时钟产生电路、 CORE 逻辑。这个要求不是强制性的,但这样做易于集成测试逻辑、PAD 和功能逻辑。 (建议)避免在顶层模块中出现 Glue logic。5 提高可移植性的编码风格5.1 采用参数化设计 (建议)不要直接使用数字在设计中不要直接使用数字(Hard-Coded Numeric Value) 。 作为例外,可以使用
34、 0 和 1(但不要组合使用,如 1001) 。例如:差的编码风格:wire 7:0my_in_bus;reg 7:0my_out_bus;好的编码风格:Define MY_BUS_SIZE 8wire MY_BUS_SIZE-1:0 my_in_bus;reg MY_BUS_SIZE-1:0 my_out_bus;第 22 页 共 28 页另一种较好的编码风格,有利于 IP 封装:parameter BUS_SIZE = 8 ;wire BUS_SIZE-1:0 my_in_bus ;reg BUS_SIZE-1:0 my_out_bus (建议)将一个设计的所有的define 语句集中到一
35、个单独的文件。5.2 采用独立于工具平台和工艺库的设计 (建议)避免嵌入式的 EDA 工具的命令。不要在源代码中使用嵌入式的 EDA 工具命令。因为其他的 EDA 工具并不一定认得这些隐含的命令,导致差的或错误的结果,降低代码的可移植性。即使是使用 Design Compiler,当综合策略改变是,嵌在源代码中的综合命令也不如单独的 script 文件中的综合命令容易修改。例如:1: /synopsys async_set_reset “reset”2: always (posedge clk or posedge reset)诸如第一行之类的工具命令最好不要使用。这个规则有一个例外就是编译开
36、关的打开和关闭可以嵌入到代码中。例如:/synopsys translate_off/synopsys translate_on (建议)使用独立于工艺的库。 (建议)在设计中避免实例化(instantiate )门,门级设计难于理解、维护和重用。如果使用的特定工艺的门,设计将变得不可移植。如果必须使用特定工艺的门,建议将它们放于单独得模块,这样在移植时易于更改。 5.3 尽量使用已经得到验证的 IP(1)对于通用的接口和常用的模块,尽量使用已经得到验证的 IP(2)尽量对自己设计的模块采用参数化设计,在得到充分验证之后,能被其他项目当作 IP 使用,提高其他设计的可靠性,缩短设计周期。bad
37、: module add (a,b,c);input 7:0 a,b;output 7:0 c ;better: module add (a,b,c);parameter WIDTH = 8 ;input WIDTH-1:0 a,b ;output WIDTH-1:0 c;第 23 页 共 28 页6 其他一些设计建议 整个项目组都使用一致的信号命名规则。 尽量避免使用复杂的运算符,如*, /, %。特别是/, %,大部分综合器的支持是非常有限的(只支持常量) 。 提供方便调试的功能:比如增加可读的标志寄存器、统计计数、FIFO 的状态寄存器等等。 在地址空间允许的范围内,尽量使内部关键触发器
38、能够通过 CPU 接口被 CPU 访问和控制,如计数器,移位寄存器,状态机寄存器等等Bad: reg7:0 cnt ;Always (posedge clk or posedge rst)If (rst=1b1)cnt = 0 ;Else if (cnt_en=1b1)cnt = cnt +_1 ;better: reg7:0 cnt;always (posedge clk or posedge rst)if (rst=1b1)cnt = 0 ;else if (cnt_en | test_cnt_en)cnt = cnt + 1 ; 尽量避免使用异步 FIFO,采用将速度较慢侧的读或者写使能
39、信号同步到速度较快侧,然后使用同步 FIFO 实现。 对于 FPGA 设计,适当限制组合逻辑的输入信号数目(4 个以下最好) 。在一个logic block 中 fan-in 数目是固定的;组合逻辑如果需要跨越 Logic block,则延迟会大大增加。这对提高 Timing 很有用。 对于 FPGA 设计,一般情况先使用块 RAM,在块 RAM 资源不够的情况下才使用分散 RAM,而且分散 RAM 的接口时序最好与块 RAM 的时序一致,便于随时调整 RAM 的使用状况。 逻辑级数过多的功能块,使用寄存器隔离,提高设计的综合时的时钟频率。 不要使用位宽过大的计数器,建议将位宽超过 8 的计数
40、器打散成多个不超过 8bit宽度的计数器。计数器要求可被 CPU 直接访问,并且每个打散后的小计数器都有 CPU 可控的计数使能信号。第 24 页 共 28 页Bad: reg31:0 cnt ;Always (posedge clk or posedge rst)If (rst=1b1)cnt = 0 ;Else if (cnt_en=1b1)cnt = cnt +_1 ;better: reg7:0 cnt0,cnt1,cnt2,cnt3;wire cnt0_en,cnt1_en,cnt2_en,cnt3_en ;assign cnt0_en = cnt_en | test_cnt_en
41、;assign cnt1_en = (always (posedge clk or posedge rst)if (rst=1b1)cnt0 = 0 ;else if (cnt0_en=1b1)cnt0 = cnt0 + 1 ; 尽可能地使用 FPGA 工具能提供的 Cores。例如 ALTERA/Xilinx 的 FPGA 内嵌的 DSP 可以用于实现比较复杂的数学计算公式、算法,而且不占用原有的 LUT资源。 养成良好的习惯:每个模块代码完成之后单独综合,或者几个子模块合成一个功能相对完整的模块时综合一次,把相应的 warnning 或者 latch 去掉,不能去除的 warning 需要
42、全部加以说明,并以文档方式记录。7 附件1. Verilog 编码文档模板:sample.v/*/ Company : UTStarcom/ Copyright(c) 2003, UTStarcom Telecom Co., Ltd./ All rights reserved第 25 页 共 28 页/ Project Name : / Filename : xxx.v/ Designer : your name/ Email : Date : / Version : 1.0/ MODULE Name : XXXXX/ Description : -. / / Called by : XXX
43、X/ - / Modification History/ $Log: sample.v,v $/ Revision 1.2 2007/12/29 03:17:59 hz05145/ tab2space/ Revision 1.1 2007/06/05 03:57:49 hz05145/ xx_yy changed to mmxnn/ Revision 1.1 2005/09/20 02:57:07 hz05145/ no message/ intial/*/ */ INCLUDES/ * include “defines.v“/ * / MODULE DEFINTION / * module
44、SAMPLE(/INPUTSrst, clk77m_sys,第 26 页 共 28 页mode_choose, /0 choose SDH mode frame;1 means SONET mode frame.cpu_cs, cpu_addr, cpu_datain, cpu_rd, cpu_we, ./OUTPUTScpu_dataout, cpu_int, . );/ */ INPUTS / *input rst;input clk77m_sys;input mode_choose;input cpu_cs;input 7:0 cpu_addr;input 15:0 cpu_datain
45、;input cpu_rd;input cpu_we;/ */ OUTPUTS/ *output 15:0 cpu_dataout;output cpu_int;wire 15:0 cpu_dataout;wire cpu_int;/ */ INTERNAL SIGNALS/ *第 27 页 共 28 页wire dout_tmp;reg fifo_wen;/ */ PARAMETERS/ *parameter RST_STATE = 3b000;/ */ CODE/ *always (posedge clk77m_sys or RST_EDGE rst)begin : FIFO_W_SIG if(rst = RST_VALUE)beginfifo_wen = 1b0;endelse beginfifo_wen = fifo_wen_tmp;endend/FIFO_W_SIG/ */ SUBMODULE INSTANTIATION/ *WRAP_SRAM16x