verilog - 如何在 SystemVerilog 中定义共享同一数据总线的多个模块

标签 verilog system-verilog

我正在尝试了解在 SystemVerilog 中应如何定义引脚。

我有:

  • 一个普通的dataBus
  • 一个 ramController 模块,可以在其 ioData 引脚上发送或接收数据。
  • 一个可以写入ramController的顶级模块(例如准备一个显示缓冲区)
  • 一个 vgaController,主要从 ramController 接收数据,但也有一个命令模式,允许使用 dataBus 上的数据对其进行配置

ramController 中的 ioData 引脚是双向的,但也需要是三态的,以便 ramController 可以“关闭”总线”,当 dataBus 被用来向 vgaController

发送命令时
module RAMController(
    inout wire[15 : 0 ] ioData,
    ..
);
..
    logic [15 : 0 ] ioDataCopy;
    assign ioData = ( chipSelect ) ? ioDataCopy : 16'hzzzzzzzzzzzzzzzz;

即使 vgaController 从不写入数据总线,它的引脚是否需要 inout 才能输入或 HiZ?

module VGAController(
    inout  wire  [15 : 0 ] iData;
);
..
logic [15 : 0 ] iDataCopy    = 0;
assign iData = ( chipSelect ) ? iDataCopy : 16'bzzzzzzzzzzzzzzzz;

dataBus 只是顶层模块中的一组连线值吗?

module Top(
..
);
..
wire   [15 : 0 ] dataBus;

我可能完全错了。有人可以帮我定义一个包含共享同一总线的多个模块的系统吗?

最佳答案

如果没有可重现的例子,很难说你做的是对还是错。但是,您的某些断言基本上是正确的。我假设您的 dataBus 与 Controller 级别的 ioData 相同。在这种情况下,如果两个 Controller 都在“top”中实例化并正确连接,那么您应该已经准备就绪。您必须确保总线始终只有一个驱动程序,以便“chipSelect”防止总线的多个驱动。

因此,这是一个演示上述内容的示例。

module Top();
  wire   [15 : 0 ] dataBus;
  logic[1:0] select;
  
  RAMController rc(.ioData(dataBus), .chipSelect(select == 1 ? 1 : 0));
  VGAController vc(.ioData(dataBus), .chipSelect(select == 2 ? 1 : 0));
  
  always @*
    $display("%0t select: %b, data: %b", $time, select, dataBus);
  
  initial begin
    select = 0;
    #1 select = 1;
    #1 select = 0;
    #1 select = 2;
    #1 select = 0;
    #1 $finish;
  end
  
endmodule

module RAMController(
    inout wire[15 : 0 ] ioData,
    input logic chipSelect 
    //...
);
  logic [15 : 0 ] ioDataCopy = 1;
  assign ioData = ( chipSelect ) ? ioDataCopy : 'z;
endmodule

module VGAController(
    inout wire[15 : 0 ] ioData,
    input logic chipSelect 
    //...
);
  logic [15 : 0 ] ioDataCopy = 2;
  assign ioData = ( chipSelect ) ? ioDataCopy : 'z;
endmodule

结果:

0 select: 00, data: xxxxxxxxxxxxxxxx
0 select: 00, data: zzzzzzzzzzzzzzzz
1 select: 01, data: zzzzzzzzzzzzzzzz
1 select: 01, data: 0000000000000001
2 select: 00, data: 0000000000000001
2 select: 00, data: zzzzzzzzzzzzzzzz
3 select: 10, data: zzzzzzzzzzzzzzzz
3 select: 10, data: 0000000000000010
4 select: 00, data: 0000000000000010
4 select: 00, data: zzzzzzzzzzzzzzzz

为了更加详细,您可以使用 tri 定义而不是 wire。它们之间没有区别,但是使代码更具可读性,恕我直言。

tri [15:0] dataBus;
...
tri [15:0] ioData;

关于verilog - 如何在 SystemVerilog 中定义共享同一数据总线的多个模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64311746/

相关文章:

verilog - Verilog、SystemVerilog 的 Doxygen 替代品?

case - System Verilog - case with or

system-verilog - System Verilog wait() 语句等待的最短时间/周期长度是多少?

system-verilog - 宽度可配置时如何编写脉冲宽度systemverilog断言

system-verilog - 连接分层模块 : struct vs interface in SystemVerilog

image - 将图像从 PC 读取到 FPGA 并返回

Verilog 分块分配

floating-point - 系统 Verilog 中的浮点除法

verilog - 什么是在编译时抛出错误的 LINT/综合安全语句?

system-verilog - 接口(interface)的类继承特性