品古典家具网站模板,设计做网站哪家公司好,石家庄进入应急状态,网站快速排名verilog编程规范 文章目录 verilog编程规范前言一、代码划分二、verilog编码ABCDEFG 前言
高内聚#xff0c;低耦合#xff0c;干净清爽的代码 一、代码划分
高内聚#xff1a;
一个功能一个模块干净的接口提取公共的代码
低耦合#xff1a;
模块之间低耦合尽量用少量…verilog编程规范 文章目录 verilog编程规范前言一、代码划分二、verilog编码ABCDEFG 前言
高内聚低耦合干净清爽的代码 一、代码划分
高内聚
一个功能一个模块干净的接口提取公共的代码
低耦合
模块之间低耦合尽量用少量的线连接
模块划分关键路径逻辑和非关键路径逻辑放在不同的模块。方便对关键路径做速度优化非关键路径做面积优化
二、verilog编码
A
设计文档和应用文档一个模块一个文件并命名相同顶层模块只包模块之间的连线
B
避免门级电路变得不可移植避免三态门而使用多路选择电路避免latch
C
保证时钟和复位不出现gilch竞争冒险产生的毛刺。尽量使用同步复位单个模块的reg使用同步复位小心使用门控时钟一般在低功耗设计中是用门控时钟容易产生毛刺。如果要使用门控尽量借助综合工具自动插入门控时钟。如果是手动门控信号要从reg中给出避免glitch避免使用模块内部产生的使用用PLL或者mmCM一个模块中只使用一个时钟避免多周期路径和假路径多周期路径就是一个寄存器输出到另一个寄存器输入的路径不能再一个时钟周期完成要写可测试性设计DFT写功能时就要考虑ATPG和BIST要添加各种测试逻辑和bypass逻辑一个模块中只用一个时钟沿。如果需要两个则分开模块或者将该时钟进行取反后输入取反后的使用IBUFG跨时钟处理要同步的信号从reg中出来。要同步的信号至少锁存两个clk。对cnt同步要用格雷码 关于跨时钟处理有以下代码可以比较:
100MHz时钟域下有一个单周期的脉冲如何将其转换到80MHz时钟域下的单周期脉冲。 使用电平同步将100MHZ的信号扩展然后使用边沿检测。但是下面代码存在问题。
module test( input
i_clk1, //100MHz
input i_clk2, //80MHz
input i_pulse,
output o_new_pulse);
reg r1_pulse;
reg r2_pulse;
wire w_pulse;
always (posedge i_clk1) //100Mbegin r1_pulse i_pulse ; r2_pulse r1_pulse;
end
assign w_pulse r1_pulse | r2_pulse;
reg r1_new_pulse;
reg r2_new_pulse;
reg r3_new_pulse;
wire w_new_pulse;
always (posedge i_clk2) //80Mbegin
r1_new_pulse w_pulse;
r2_new_pulse r1_new_pulse;
r3_new_pulse r2_new_pulse;
end
assign o_new_pulse ~r3_new_pulse r2_new_pulse;
endmodule问题代码在这里assign w_pulse r1_pulse | r2_pulse; 两个寄存器之间是有延迟的通过把脉冲变成电平信号如果出现上图的情况会导致电平信号又断点。在80MHZ的时钟周期的采样可能或漏。处理方式如下面说的“要同步的信号从reg中出来”。即先在当前时钟域下先展宽之后在从reg中输出出来给别人用这样就避免使用组合逻辑了。 因此代码修改如下
always (posedge i_clk1) //100Mbegin r1_pulse i_pulse ; r2_pulse r1_pulse; w_pulse r1_pulse | r2_pulse;end
reg r1_new_pulse;
reg r2_new_pulse;
reg r3_new_pulse;
wire w_new_pulse;
always (posedge i_clk2) //80Mbegin
r1_new_pulse w_pulse;
r2_new_pulse r1_new_pulse;
r3_new_pulse r2_new_pulse;end小结 会议竞争和冒险的原理可以发现assign B a b; 这如果a和b因为布线延迟的原因那么该组合逻辑就可能产生毛刺。在写组合逻辑的时候也尽量去考虑布线的延迟问题是否产生的毛刺会给设计带来影响。 参阅文章 竞争和冒险 D
用always(*)注意阻塞赋值和非阻塞赋值的场合1.不要混用。2.组合逻辑always()用锁存逻辑always()用.3.时钟逻辑用使用三段式状态机且组合逻辑的转态跳转要用defaultcase比if的时序好case无优先级。if有优先级。if语句书写嵌套要用begin
if(a 1) beginif(c 1)...else...end
else...E
模块的输入先reg再使用。模块的输出先reg再输出。使得输入的时序输出强度和延迟好预测。这样可以获得更好的时序 如代码:
module ins(input i_clk,input i_rst,input i_data,output o_vld
);
reg ri_data;
reg ro_vld;assign o_vld ro_vld;always(posedge i_clk)ri_data i_data;always(posedge i_clk)ro_vld 1b1;
endmodule不要驱动input保证所有output被驱动如果没有使用则用assign 输出为0或者1要声明所有信号反之会被综合为1bitreg只能在一个always中赋值在写验证代码时不要用内部信号用点操作符有时候会有问题因为内部信号在综合为网表之后就不见了在使用ila抓数时使用点操作符去索引内部信号可能会报错综合时被优化掉了名字。设计代码时不要使用force release initial forever !等
F
不要在include中写目录名字写工层的相对路径否则移植很麻烦使用vh头文件
G
使用简洁的代码书写
c[3:0] b[3:0] d[3:0];
改写为
cbd;// 没必要不用begin end
always(posedge i_cllk)if(a 1b1) ro_data 1b1;else ro_data 1b0;
模块端口按照功能划分如果用 i_输出用 o_inout用io_wire用w_reg用r_打拍用r_data_d1关于注释注释的核心就是把代码删除了看注释还能明白其功能。1.模块开头的注释实现功能和关键特性。2.代码中的注释简明扼要。3.删除陈旧的代码和注释使用参数化parameter