verilog 模块声明的首选语法
Prefered syntax for verilog module declaration
我对 FPGA 比较陌生,我正在寻找有关 Verilog 中模块声明的现代最佳实践的一些指导。
我见过两种在 verilog 中声明模块的方法。第一个让我想起 Traditional C, such as the examples on wikipedia:
module toplevel(clock,reset);
input clock;
input reset;
/* snip */
endmodule
而替代语法将 input/output 说明符作为参数列表的一部分,与 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代码,首选哪种语法?在这种情况下,"Preferred" 表示以标准或相关 material 编写的内容(明确编写,或通过标准中给出的示例隐式编写),或以备受推崇的风格指南编写。问题不是问个人喜好!
第二种优先。这是在 Verilog 2001 中引入的。这通常称为 "ANSI-style"。
当我教授 Verilog 时,我同时教授两者,但建议所有新代码使用 ANSI 风格。 (并提到我只教授第一种风格,以便学生能够理解遗留代码。)
如果你继续学习 System-Verilog,你会发现有些东西无论如何只能用 ANSI 风格工作。
缩进第二种语法形式以替换第一种语法形式。如果您查看 1364-2001 Verlog LRM,以及当前的 1800-2012 SystemVerilog LRM,您会注意到所有模块声明示例都使用第二种形式。第一种形式仅供遗留,但不幸的是,教科书和课程 material 切换所需的时间比预期的要长。
这种更新的(或 ANSI 风格的)语法的主要好处是您只需在一个地方声明您的端口名称。使用旧语法,您最多必须声明一个端口名称 3 次;一次用于位置排序,另一次用于端口方向,如果端口需要是电线以外的其他东西,则第三次声明其数据类型。
首选第二种模式,但有时您可能想使用第一种模式。这是如果您需要对参数进行大量复杂计算以获得正确的端口宽度。下面只是一个小的人工例子。是的,您可以用它们的表达式替换 localparam,但这可能会使您的代码不可读。
我认为这是(系统)Verilog 的遗漏之一,你不能在 #(parameter.. definition.
之后使用 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;
我对 FPGA 比较陌生,我正在寻找有关 Verilog 中模块声明的现代最佳实践的一些指导。
我见过两种在 verilog 中声明模块的方法。第一个让我想起 Traditional C, such as the examples on wikipedia:
module toplevel(clock,reset);
input clock;
input reset;
/* snip */
endmodule
而替代语法将 input/output 说明符作为参数列表的一部分,与 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代码,首选哪种语法?在这种情况下,"Preferred" 表示以标准或相关 material 编写的内容(明确编写,或通过标准中给出的示例隐式编写),或以备受推崇的风格指南编写。问题不是问个人喜好!
第二种优先。这是在 Verilog 2001 中引入的。这通常称为 "ANSI-style"。
当我教授 Verilog 时,我同时教授两者,但建议所有新代码使用 ANSI 风格。 (并提到我只教授第一种风格,以便学生能够理解遗留代码。)
如果你继续学习 System-Verilog,你会发现有些东西无论如何只能用 ANSI 风格工作。
缩进第二种语法形式以替换第一种语法形式。如果您查看 1364-2001 Verlog LRM,以及当前的 1800-2012 SystemVerilog LRM,您会注意到所有模块声明示例都使用第二种形式。第一种形式仅供遗留,但不幸的是,教科书和课程 material 切换所需的时间比预期的要长。
这种更新的(或 ANSI 风格的)语法的主要好处是您只需在一个地方声明您的端口名称。使用旧语法,您最多必须声明一个端口名称 3 次;一次用于位置排序,另一次用于端口方向,如果端口需要是电线以外的其他东西,则第三次声明其数据类型。
首选第二种模式,但有时您可能想使用第一种模式。这是如果您需要对参数进行大量复杂计算以获得正确的端口宽度。下面只是一个小的人工例子。是的,您可以用它们的表达式替换 localparam,但这可能会使您的代码不可读。
我认为这是(系统)Verilog 的遗漏之一,你不能在 #(parameter.. definition.
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;