我对FPGA相对较新,我正在寻找有关Verilog模块声明的现代最佳实践的一些指导。
我已经看到了两种在verilog中声明模块的方法。第一个提醒我Traditional C,例如examples on wikipedia:
module toplevel(clock,reset);
input clock;
input reset;
/* snip */
endmodule
尽管替代语法将输入/输出说明符作为参数列表的一部分,但与VHDL并不太相似,如this example中所示:
module fadder(
input a, //data in a
input b, //data in b
input cin, //carry in
output sum_out, //sum output
output c_out //carry output
);
/* snip */
endmodule
对于新编写的verilog代码,首选哪种语法?在这种情况下,“首选”是指用标准或相关材料(明确书写,或通过标准中给出的示例隐含)或用精心设计的样式指南书写的东西。问题不是要求个人偏好!
答案 0 :(得分:7)
第二个是首选。这是在Verilog 2001中引入的。这通常称为" ANSI-style"。
当我教Verilog时我会教两种语言,但建议使用ANSI样式的所有新代码。 (并提到我只是教第一种风格,以便学生能够理解遗留代码。)
如果你继续使用System-Verilog,你会发现有些东西只能用ANSI风格。
答案 1 :(得分:7)
第二种语法形式缩进以替换第一种语法形式。如果您查看1364-2001 Verlog LRM以及当前的1800-2012 SystemVerilog LRM,您会注意到模块声明的所有示例都使用第二种形式。第一种形式仅用于遗产,但不幸的是,教科书和课程材料的转换时间比预期的要长。
这种较新(或ANSI样式)语法的主要优点是您只需在一个地方声明您的端口名称。使用较旧的语法,您必须声明端口名称最多三次;一次用于位置排序,另一次用于端口方向,并且如果端口需要不是电线,则第三次声明其数据类型。
答案 2 :(得分:2)
第二种模式是首选,但有时您可能想要使用第一种模式。这是因为要对参数进行大量复杂计算以获得正确的端口宽度。以下只是一个小例子。是的,您可以使用表达式替换localparam,但这可能会使您的代码无法读取 我认为这是(系统)Verilog的遗漏之一,你不能在#(参数..定义。)之后使用local_param。
module example
#(parameter
L2DEPTH = 8,
OFFSET = 2
)
(siga,sigb,sigc,sig_out);
localparam DEPTH = 1<<L2DEPTH;
localparan TOP = DEPTH+OFFSET;
localparam BOT = DEPTH-OFFSET;
localparam DBLDEPTH = 2<<L2DEPTH;;
input [ L2DEPT-1:0] siga;
input [ TOP-1:0] sigb;
input [ BOT-1:0] sigc;
output [DBLDEPTH-1:0] sig_out;