在Verilog中避免代码重复
我发现这种情况在Verilog代码中经常发生:在Verilog中避免代码重复,verilog,Verilog,我发现这种情况在Verilog代码中经常发生: wire my_module_output_1; wire my_module_output_2; wire my_module_output_3; ... MyModule my_module( .output_1(my_module_output_1), .output_2(my_module_output_2), .output_3(my_module_output_3), ... ); MyOtherMo
wire my_module_output_1;
wire my_module_output_2;
wire my_module_output_3;
...
MyModule my_module(
.output_1(my_module_output_1),
.output_2(my_module_output_2),
.output_3(my_module_output_3),
...
);
MyOtherModule my_other_module(
.input_1(my_module_output_1),
.input_2(my_module_output_2),
.input_3(my_module_output_3),
...
);
我希望我能做的是:
MyModule my_module();
MyOtherModule my_other_module(
.input_1(my_module.output_1),
.input_2(my_module.output_2),
.input_3(my_module.output_3),
...
);
有没有这样的方法让我达到同样的效果,也就是说,每次我需要某个模块的输出时,我都不必一遍又一遍地重复自己的操作?人们还没有到处使用Verilog AUTOs吗 特别要注意有关自动安装的部分。这并不能解决你所有的问题,但是明智地使用AUTOs可以减少生成结构化Verilog的繁琐工作
不要介意它是一个Emacs节点。我自己也是一个vim人,但当我需要更新我的汽车时,我只是通过emacs加载这个模式,将我的缓冲区传输到emacs。人们还没有到处使用Verilog汽车吗 特别要注意有关自动安装的部分。这并不能解决你所有的问题,但是明智地使用AUTOs可以减少生成结构化Verilog的繁琐工作
不要介意它是一个Emacs节点。我自己也是一名vim人员,但当我需要更新汽车时,我只需通过emacs加载此模式即可使用缓冲区。以下是一些减少重复次数的方法 起点 下面是一个连接两个子模块的简单示例。正如你在问题中提到的,将它们缝合在一起需要大量的重复
module source(output A, output B);
assign A = 0;
assign B = 1;
endmodule
module sink(input A, input B);
initial begin
#1 $display("A=%0d B=%0d", A, B);
end
endmodule
module top();
wire A;
wire B;
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
使用隐式导线 Verilog允许隐式声明导线。因此,如下所示,您不需要将
A
和B
声明为导线。如果它们出现在端口映射中,它们将被隐式声明。唯一的问题是它们总是声明为单位导线/网络。因此,虽然这对单位信号很好,但对于总线,互连仍然需要明确声明
// Verilog, implicit wires
module top();
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
使用Verilog模式AUTOs 可以极大地减少将模块缝合在一起所需的键入量。下面是上面使用AUTOs的示例 展开汽车前:
// Verilog, explicit connections using AUTOs
module top();
/*AUTOWIRE*/
source the_source (/*AUTOINST*/);
sink the_sink (/*AUTOINST*/);
endmodule
// Verilog, explicit using AUTOs
module top();
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire A; // From the_source of source.v
wire B; // From the_source of source.v
// End of automatics
source the_source (/*AUTOINST*/
// Outputs
.A (A),
.B (B));
sink the_sink (/*AUTOINST*/
// Inputs
.A (A),
.B (B));
endmodule
展开汽车后:
// Verilog, explicit connections using AUTOs
module top();
/*AUTOWIRE*/
source the_source (/*AUTOINST*/);
sink the_sink (/*AUTOINST*/);
endmodule
// Verilog, explicit using AUTOs
module top();
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire A; // From the_source of source.v
wire B; // From the_source of source.v
// End of automatics
source the_source (/*AUTOINST*/
// Outputs
.A (A),
.B (B));
sink the_sink (/*AUTOINST*/
// Inputs
.A (A),
.B (B));
endmodule
正如Brian在他的回答中指出的,您不需要使用emacs来使用Verilog模式。我还使用Vim和从Vim中启用Verilog模式
SystemVerilog选项 如果可以使用SystemVerilog,则可以使用点星表示法按名称连接端口。这非常方便,但是您仍然需要声明对等模块之间互连的导线
// SystemVerilog, dot-star notation
module top();
wire A;
wire B;
source the_source(.*);
sink the_sink(.*);
endmodule
下面是一些可以用来减少重复次数的方法 起点 下面是一个连接两个子模块的简单示例。正如你在问题中提到的,将它们缝合在一起需要大量的重复
module source(output A, output B);
assign A = 0;
assign B = 1;
endmodule
module sink(input A, input B);
initial begin
#1 $display("A=%0d B=%0d", A, B);
end
endmodule
module top();
wire A;
wire B;
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
使用隐式导线 Verilog允许隐式声明导线。因此,如下所示,您不需要将
A
和B
声明为导线。如果它们出现在端口映射中,它们将被隐式声明。唯一的问题是它们总是声明为单位导线/网络。因此,虽然这对单位信号很好,但对于总线,互连仍然需要明确声明
// Verilog, implicit wires
module top();
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
使用Verilog模式AUTOs 可以极大地减少将模块缝合在一起所需的键入量。下面是上面使用AUTOs的示例 展开汽车前:
// Verilog, explicit connections using AUTOs
module top();
/*AUTOWIRE*/
source the_source (/*AUTOINST*/);
sink the_sink (/*AUTOINST*/);
endmodule
// Verilog, explicit using AUTOs
module top();
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire A; // From the_source of source.v
wire B; // From the_source of source.v
// End of automatics
source the_source (/*AUTOINST*/
// Outputs
.A (A),
.B (B));
sink the_sink (/*AUTOINST*/
// Inputs
.A (A),
.B (B));
endmodule
展开汽车后:
// Verilog, explicit connections using AUTOs
module top();
/*AUTOWIRE*/
source the_source (/*AUTOINST*/);
sink the_sink (/*AUTOINST*/);
endmodule
// Verilog, explicit using AUTOs
module top();
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire A; // From the_source of source.v
wire B; // From the_source of source.v
// End of automatics
source the_source (/*AUTOINST*/
// Outputs
.A (A),
.B (B));
sink the_sink (/*AUTOINST*/
// Inputs
.A (A),
.B (B));
endmodule
正如Brian在他的回答中指出的,您不需要使用emacs来使用Verilog模式。我还使用Vim和从Vim中启用Verilog模式
SystemVerilog选项 如果可以使用SystemVerilog,则可以使用点星表示法按名称连接端口。这非常方便,但是您仍然需要声明对等模块之间互连的导线
// SystemVerilog, dot-star notation
module top();
wire A;
wire B;
source the_source(.*);
sink the_sink(.*);
endmodule
我不太清楚这个例子,你为什么不直接将“其他线路”连接到输出端口以获得相同的结果:
。output\u 1(其他线路)
@Tim:对不起,让我更改一下这个例子。。。关键是,这并不总是可能做到的,例如,如果不是some_other_wire_1
,而是另一个模块的输入,或者如果您需要在always
块内,等等。@Tim:Fixed,这更有意义吗?是的,这样更好。对你来说不幸的是,我认为这样的事情不存在。verilog标准确实支持分层引用,允许您在没有现有端口的情况下直接连接到模块内部的导线,但我相信大多数合成器不支持它,作为一种编码样式,我认为它通常不受欢迎。这是用于合成的吗?您的第二个示例是有效的代码。我不确定我是否完全理解该示例,您是否有理由不直接将“其他一些线路”连接到输出端口以获得相同的结果:。输出线路1(其他一些线路)
@Tim:对不起,让我更改示例。。。关键是,这并不总是可能做到的,例如,如果不是some_other_wire_1
,而是另一个模块的输入,或者如果您需要在always
块内,等等。@Tim:Fixed,这更有意义吗?是的,这样更好。对你来说不幸的是,我认为这样的事情不存在。verilog标准确实支持分层引用,允许您在没有现有端口的情况下直接连接到模块内部的导线,但我相信大多数合成器不支持它,作为一种编码样式,我认为它通常不受欢迎。这是用于合成的吗?您的第二个示例是有效代码。啊,我不使用emacs+1尽管如此。啊,我不使用emacs+1尽管如此。