当前位置:首页 > 龙芯公司IC芯片编写规则
R 7.5 使输入输出时钟无脉冲干扰
使用输入输出时钟的地方在时钟时间不能存在任何脉冲干扰。
原因:尽管输入输出时钟导致功率消耗,脉冲干扰会发生在时钟信号中,这是由于时钟使信号在时钟敏感延设置或保持,从而导致错误操作。 例外:异步接口,但时间必须严格定义。
G 7.6 无脉冲干扰信号直接作用于各信号 推荐使用内部产生的信号直接作用以避免干扰。 原因:直接作用信号中的脉冲干扰将导致错误操作。
R 7.7 功率下降信号的已知状态
一个由功率供应可能下降的电源驱动的输入端必须或者是关于不敏感电平的逻辑门,是用于非门或同或门,或者由库文件提供。输入必须可控,当电源信号的功率下降时,输入仍然在一致的状态。
G 7.8 初始化控制存储器
推荐在适当的时候,所有的锁存器和寄存器可以被控制置位和复位。见G 9.9.
原因:对于没有复位的存储器,仿真结果可能取决于仿真器,不同的仿真器会出现不同的初始值。(如“0” oR“X”)
G 7.10 避免组合反馈回路 组合反馈回路不能使用。
原因:不能与循环仿真器和形式化验证(formal verification)工具兼容。
G 7.9 使用同步设计规则
推荐在任何可能的情况下遵守同步设计规则。无法避免时才可使用异步设计电路。 原因:目前还没有完全支持异步设计的设计工具。
例外:不需要综合的行为模块(如,总线功能模块,总线监视器和行为级模型)可以使用异步设计。
8 编码方法概要
R 8.1 表达式在一定情况下必须是1比特
以下结构中的情况必须是一个占1比特的表达式: ? if(condition) ? while(condition)
? for(initial_assignment; condition; step_assignment) ? @(posedge condition oR...) ? @(negedge condition oR...) 原因:避免非标准仿真器行为。
例子:当被称作敏感总线(bus_is_active)的多比特值信号值不是0时,就设值为1。 a) if (bus) bus_is_active = 1;
25
在这个例子中,总线是一个多比特值,与规则相悖。 b) if (bus > 0) bus_is_active = 1;
这种情况下的结果1比特表达式,按照规则,直观上很容易阅读。
R 8.2 按一致的总线比特值排序
当描述多比特总线时,必须坚持按照一致的总线比特值排序。 原因:提高可读性和减少总线间的无意的次序颠倒。
例外:内部使用一定协议的VC块,在VC块边界却与其他别的协议相接。
R 8.3 不能将x赋给信号
信号值不能赋为x,已知的合法信号值必须赋给所有信号。 原因:避免x沿着电路传输。 例外:Testbenches.
R 8.4 reg型不能在两个always块中赋值
reg型不能在两个分离的always块中赋值 原因:避免内部总线和仿真器依赖执行顺序。 例外:行为级代码。
G 8.5 在宏文本上使用参量做常量
推荐在指示详细说明的常量的宏定义中使用参量
原因:定义宏文本的范围是全局量除非明确的没有定义。这会导致编辑次序的依赖和SoC层的冲突。
例外:全局常量
R 8.6 参量不可修改
参量在仿真时不能被修改或者覆盖,甚至在第一次仿真时前也不能
原因:IEEE Verilog标准禁止这种做法,仿真器可能针对这种情况产生不同的结果。 例外:参量可以在编辑时被修改或覆盖
R 8.7 宏文本不能重复定义
宏文本不能被重复定义为不同的值,这适用于局部和全局定义的宏 原因:避免无意中重复定义宏
G 8.8 保持常量间的关系
如果一个常量由另一个常量的值决定,推荐在定义时指明依赖关系。在宏文本定义算法或逻辑表达式的地方,要附上括号。
原因:增强适应性,因为代码改写所需要的工作量减少。 例子:preferred: `define DATA_WORD 8
`define DATA_LONG(4 * ‘DATA_WORD)
versus: `define DATA_WORD 8
`define DATA_LONG32
R 8.9 使用参量做状态编码
26
在编码明确的状态机中,必须使用列举参量来给不同的状态编码
原因:使不同状态机的执行retargeting,例如,从1-hot码到gray码的转换。用形象的命名提高可读性,
并为状态改变提供一个单一的点。 例子:
parameteR[1:0] // synthesis enum state_info RESET_STATE = 2’b00, TX_STATE = 2’b01, RX_STATE = 2’b10, ILLEGAL_STATE = 2’b11;
G 8.10 `define 和‘undef的用法
如果在设计代码中使用`define声明语句,宏的名字应该没有被同一模块的‘undef定义(见 R 3.15).
原因:因为`define没有范围,所以他们必须与已有代码保持联系,在源代码中维持名字的联系,定义
宏将使重用简化。 例外:Testbenches.
R 8.11 使用可编程基地址 模块的基地址必须可编程 原因:简化改变模块内存印象图
R 8.12 用宏文本赋值给基地址
如果在Verilog代码中出现基地址,必须赋以宏文本 原因:简化改变模块内存印象图 例外:基地址在软件中已定义
R 8.13 用基地址加偏移量来作为地址
模块中内部寄存器或存储器的所有路径必须以基地址和与基地址的偏移量的形式表示 原因:使不同系统的结构retargeting
G 8.14 用宏文本来表示寄存器域的位置和值
推荐使用宏文本来表示寄存器域的位置和值而能用数字常量。这个域可以是一个或多个比特,或者是整个寄存器
原因:提高可读性和可维护性,减少使用错误比特和错误值的机会 例子: `define CNT_WHAT cnt_ctrl[7:5] // What to count
parameteRCNT_ADDR= 2`b00 // count address matches parameteRCNT_DATA = 2`b01 // count data matches always @(`CNT_WHAT) case (`CNT_WHAT)
`CNT_ADDR: cnt_in = cnt_addR; `CNT_DATA: cnt_in = cnt_data ; endcase // (`CNT_WHAT) always @(posedge clk) if (cnt_in) begin
27
counteR<= counteR+ 8'b1 ;
if (`CNT_WHAT == `CNT_ADDR) addr_flaG<= 1; end // if (cnt_in)
G 8.15 使用宏文本来定义信号层次的路径
一般使用的信号层次的路径应该用宏文本详细说明,层次性信号的路径在设计成可综合的代码中不允许存在。
原因:使新环境的重测简化
例子: `define XXX_TESTBENCH si
`define XXX_TOP_SCOPE ‘TESTBENCH.xxx // xxx is the top-level module `define XXX_YYY_SCOPE ‘XXX_TOP_SCOPE.yyy // yyy is a submodule of xxx
R 8.16 限制`ifdef超过三个的嵌套 `ifdef的嵌套不能超过三个 原因:使代码更容易理解
R 8.17 不允许使用宏模块 宏模块结构不能使用
原因:仿真结果可能依赖于仿真器。不同的仿真器处理宏模块结果不同
R 8.18 必须匹配操作数的大小 表达式不能私自扩大或缩小它的大小
原因:对于不同的操作数大小,操作数没有明确定义,但却取决于Verilog处理数据大小的不用。Verilog允许这样是因为它不是高级语言。 例子: The followinGshould all be avoided:
wire [63:0] some_signal; wire [7:0] other_signal; some_signal <= 1;
some_signal <= other_signal; x = some_signal && other_signal;
例外:由于整型变量没有直接的硬件目的(intent)所以对它们不适用
R 8.19 使用在实例化模块中涉及到的明确端口
模块实例化时必须使用模块中涉及到的明确端口,而不能使用周围的端口
原因:模块实例化将明确的表示出端口之间的连接,在实例层上不会出现额外的逻辑,这将提高可读性和适应性
例子:block block_1(
.signal_a(signal_a), .signal_n(signal_n) );
R 8.20 矢量端口声明和线网/变量声明的分类必须一致 矢量端口声明的分类和线网/变量声明的分类必须相同
原因:由于IEEE Verilog标准禁止,仿真器可能处理不同的情况会有不同的结果,它将提高代码
28
共分享92篇相关文档