Как определить несколько модулей, совместно использующих одну и ту же шину данных в SystemVerilog

#verilog #system-verilog

#verilog #system-verilog

Вопрос:

Я пытаюсь понять, как должны быть определены контакты в SystemVerilog.

У меня есть:

  • общий dataBus
  • ramController модуль, который может отправлять или получать данные на своих ioData выводах.
  • модуль верхнего уровня, который может записывать в ramController (например, подготовить буфер отображения)
  • a vgaController , который в основном получает данные из ramController , но также имеет командный режим, который позволяет настраивать его с использованием данных на dataBus

ioData Контакты в ramController являются двунаправленными, но также должны быть в трех состояниях, чтобы 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;
  

Возможно, я делаю это совершенно неправильно. Может кто-нибудь, пожалуйста, помочь мне в определении системы, содержащей несколько модулей, которые используют одну и ту же шину.

Ответ №1:

Трудно сказать, правильно вы это сделали или нет, без воспроизводимого примера. Однако некоторые из ваших утверждений в основном верны. Я предполагаю, что ваш dataBus такой же, как и ваш ioData на уровне контроллера. В этом случае, если оба контроллера созданы в «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;
  

Комментарии:

1. Спасибо @Serge. Я постараюсь закрыть свой проект и, возможно, обновить свой вопрос. Я получаю «Top», который должен указывать на вывод уровня, но сейчас не управляет <ничего>». Трудно найти время, чтобы сосредоточиться на этом и вне работы:-( Я определенно предпочитаю определение tri — это намного понятнее.