Verilog:如何实例化模块 [英] Verilog: How to instantiate a module

查看:60
本文介绍了Verilog:如何实例化模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个 Verilog 模块top"和一个 verilog 模块subcomponent",我如何在 top 中实例化子组件?

If I have a Verilog module 'top' and a verilog module 'subcomponent' how do I instantiate subcomponent in top?

顶部:

module top(
   input        clk,
   input        rst_n,
   input        enable,
   input  [9:0] data_rx_1,
   input  [9:0] data_rx_2,
   output [9:0] data_tx_2
);

子组件:

module subcomponent(
   input        clk,
   input        rst_n,
   input  [9:0] data_rx,
   output [9:0] data_tx
);

注意
这是一个经常出现的通用问题,它遵循 self-answer 格式.鼓励添加答案和更新.

Note
This was written as a generic question that keeps cropping up now and again, it is following the self-answer format. Addition answers and updates are encouraged.

推荐答案

SystemVerilog IEEE Std 1800-2012.

最简单的方法是在 top 的主要部分进行实例化,创建一个命名实例并按顺序连接端口:

The simplest way is to instantiate in the main section of top, creating a named instance and wiring the ports up in order:

module top(
   input        clk,
   input        rst_n,
   input        enable,
   input  [9:0] data_rx_1,
   input  [9:0] data_rx_2,
   output [9:0] data_tx_2
);

subcomponent subcomponent_instance_name (
  clk, rst_n, data_rx_1, data_tx ); 

endmodule

这在 SystemVerilog IEEE Std 1800-2012 的第 23.3.2.1 节中有描述.

这有一些缺点,尤其是在子组件代码的端口顺序方面.此处的简单重构可能会破坏连接或改变行为.例如,如果其他人出于某种原因修复了错误并重新排序端口,则切换时钟和重置顺序.您的编译器不会出现连接问题,但不会按预期工作.

This has a few draw backs especially regarding the port order of the subcomponent code. simple refactoring here can break connectivity or change behaviour. for example if some one else fixs a bug and reorders the ports for some reason, switching the clk and reset order. There will be no connectivity issue from your compiler but will not work as intended.

module subcomponent(
  input        rst_n,       
  input        clk,
  ...

因此建议使用命名端口进行连接,这也有助于跟踪代码中电线的连接性.

It is therefore recommended to connect using named ports, this also helps tracing connectivity of wires in the code.

module top(
   input        clk,
   input        rst_n,
   input        enable,
   input  [9:0] data_rx_1,
   input  [9:0] data_rx_2,
   output [9:0] data_tx_2
);

subcomponent subcomponent_instance_name (
  .clk(clk), .rst_n(rst_n), .data_rx(data_rx_1), .data_tx(data_tx) ); 

endmodule

这在 SystemVerilog IEEE Std 1800-2012 的第 23.3.2.2 节中有描述.

为每个端口指定一行并正确缩进可提高可读性和代码质量.

Giving each port its own line and indenting correctly adds to the readability and code quality.

subcomponent subcomponent_instance_name (
  .clk      ( clk       ), // input
  .rst_n    ( rst_n     ), // input
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

到目前为止,所有已建立的连接都重用了到子模块的输入和输出,并且没有创建连接线.如果我们将输出从一个组件带到另一个组件会发生什么:

So far all the connections that have been made have reused inputs and output to the sub module and no connectivity wires have been created. What happens if we are to take outputs from one component to another:

clk_gen( 
  .clk      ( clk_sub   ), // output
  .en       ( enable    )  // input

subcomponent subcomponent_instance_name (
  .clk      ( clk_sub   ), // input
  .rst_n    ( rst_n     ), // input 
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

这名义上是自动创建的 clk_sub 连线,依赖于此存在危险.默认情况下,它只会创建 1 位线.这是一个问题的例子是数据:

This nominally works as a wire for clk_sub is automatically created, there is a danger to relying on this. it will only ever create a 1 bit wire by default. An example where this is a problem would be for the data:

请注意,第二个组件的实例名称已更改

subcomponent subcomponent_instance_name (
  .clk      ( clk_sub   ), // input
  .rst_n    ( rst_n     ), // input 
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_temp )  // output [9:0]
);
subcomponent subcomponent_instance_name2 (
  .clk      ( clk_sub   ), // input
  .rst_n    ( rst_n     ), // input 
  .data_rx  ( data_temp ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

上面代码的问题是data_temp只有1位宽,会有关于端口宽度不匹配的编译警告.需要创建连接线并指定宽度.我建议明确写出所有连接线.

The issue with the above code is that data_temp is only 1 bit wide, there would be a compile warning about port width mismatch. The connectivity wire needs to be created and a width specified. I would recommend that all connectivity wires be explicitly written out.

wire [9:0] data_temp
subcomponent subcomponent_instance_name (
  .clk      ( clk_sub   ), // input
  .rst_n    ( rst_n     ), // input 
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_temp )  // output [9:0]
);
subcomponent subcomponent_instance_name2 (
  .clk      ( clk_sub   ), // input
  .rst_n    ( rst_n     ), // input 
  .data_rx  ( data_temp ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

转向 SystemVerilog 有一些技巧可以节省输入少量字符.我相信它们会阻碍代码的可读性,并且会使查找错误变得更加困难.

Moving to SystemVerilog there are a few tricks available that save typing a handful of characters. I believe that they hinder the code readability and can make it harder to find bugs.

使用不带括号的 .port 连接到同名的电线/reg.这看起来很整洁,尤其是有很多时钟和重置,但在某些级别,您可能会生成不同的时钟或重置,或者您实际上不想连接到同名的信号,而是一个修改过的信号,这可能导致接线错误肉眼不明显.

Use .port with no brackets to connect to a wire/reg of the same name. This can look neat especially with lots of clk and resets but at some levels you may generate different clocks or resets or you actually do not want to connect to the signal of the same name but a modified one and this can lead to wiring bugs that are not obvious to the eye.

module top(
   input        clk,
   input        rst_n,
   input        enable,
   input  [9:0] data_rx_1,
   input  [9:0] data_rx_2,
   output [9:0] data_tx_2
);

subcomponent subcomponent_instance_name (
  .clk,                    // input **Auto connect**
  .rst_n,                  // input **Auto connect**
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

endmodule

这在 SystemVerilog IEEE Std 1800-2012 的第 23.3.2.3 节中有描述.

我认为比上面那个更糟糕的另一个技巧是 .* 它将未提及的端口连接到同一条线的信号.我认为这在生产代码中非常危险.如果新端口名称在实例化级别中具有计数器部分,则新端口添加和丢失时并不明显,或者它们可能会意外连接,它们会自动连接并且不会生成警告.

Another trick that I think is even worse than the one above is .* which connects unmentioned ports to signals of the same wire. I consider this to be quite dangerous in production code. It is not obvious when new ports have been added and are missing or that they might accidentally get connected if the new port name had a counter part in the instancing level, they get auto connected and no warning would be generated.

subcomponent subcomponent_instance_name (
  .*,                      // **Auto connect**
  .data_rx  ( data_rx_1 ), // input  [9:0]
  .data_tx  ( data_tx   )  // output [9:0]
);

这在 SystemVerilog IEEE Std 1800-2012 的第 23.3.2.4 节中有描述.

这篇关于Verilog:如何实例化模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆