Как использовать генератор на блок с интерфейсами SV - PullRequest
0 голосов
/ 15 сентября 2018

Мне нужно использовать цикл создания цикла для репликации нескольких экземпляров модуля, в которых есть интерфейсы, и я столкнулся с проблемой разработки.Я попытаюсь показать проблему с этим примером.Я объявил простой интерфейс, а затем я создал иерархический дизайн ниже, с верхним модулем, следующим за интерфейсом и затем снижающимся.Когда я запускаю этот дизайн с помощью ncverilog, я получаю следующую ошибку:

.write (test_intf.w), |ncelab: * E, CUIOAI (./test_generate_interface.sv,105|21): недопустимое подключение порта интерфейса через экземпляр создания или массива (test_wrap.genblk1 [0] .test.test_intf.w).test_intf.w написать, |ncelab: * E, CUIMBC (./test_generate_interface.sv,116|18): должно быть подключено объявление порта интерфейса (test_wrap.genblk1 [0] .test.test_intf_top.write_read)..read (test_intf.r)

Начальный код ----------------

interface test_intf
    #(parameter W = 32)
();

logic [(W-1):0] wdata;
logic [(W-1):0] rdata;
logic read;
logic write;

modport w
(
  input write,
  input wdata
);


modport r
(
  input read,
  output rdata
);

endinterface

module test_wrap
#(
  parameter NUM = 5,
  parameter W   = 32
  )
(
 input clk,
 input rst,
 input [(NUM-1):0] [(W-1):0]  wdata,
 input [(NUM-1):0]            write,
 input [(NUM-1):0]            read,
 output [(NUM-1):0] [(W-1):0] rdata
 );

 genvar v;

  generate
   for (v = 0; v < NUM; v++)
     test
     #(.W(W))
     test
     (
      .clk(clk),
      .rst(rst),
      .read(read [v]),
      .write(write [v]),
      .wdata(wdata [v]),
      .rdata(rdata [v])
     );

  endgenerate
 endmodule

module test
#(parameter W = 32)
(
 input            clk,
 input            rst,
 input            read,
 input            write,
 input  [(W-1):0] wdata,
 output [(W-1):0] rdata
 );

test_intf 
#(.W(W))
test_intf
();

assign test_intf.write  = write;
assign test_intf.wdata  = wdata;
assign test_intf.read   = read;
assign rdata  = test_intf.rdata;

test_intf_top
#(.W (W)) 
test_intf_top
(
 .clk  (clk),
 .rst  (rst),
 .test_intf(test_intf)
 );

endmodule

module test_intf_top
#(parameter W = 32)
(
 input clk,
 input rst,
 test_intf test_intf
 );


 write_read
  #(.W(W))
  write_read
  (
   .clk (clk),
   .rst(rst),
   .write (test_intf.w),
   .read (test_intf.r)
  );

 endmodule

 module write_read
 #(parameter W = 32)
 (
  input clk, 
  input rst,
  test_intf.w write,
  test_intf.r read
  );

reg [(W-1):0] counter;

always_ff @(posedge clk or negedge rst)
  if (~rst)
    begin
      counter <= '0;
    end
  else
    begin
      if (write.write)
        counter <= write.wdata;
      else if (read.read)
        read.rdata <= counter;
      else
        counter <= counter + 1;
    end
endmodule

1 Ответ

0 голосов
/ 19 сентября 2018

Я мог бы повторить вашу проблему на EDAplayground с различными симуляторами. Вы назвали свой экземпляр интерфейса так же, как имя объявления, и это сбивает с толку симулятор. В частности, симулятор видит любое использование test_intf.w, а test_intf.r ссылается на modeport int в определении определения test_intf; не экземпляр с тем же именем, которое вы намеревались.

Рекомендуется, чтобы имена были уникальными. Изменяя имена экземпляров, я смог заставить его скомпилировать и запустить без ошибок.

//...

module test_wrap
#(
  parameter NUM = 5,
  parameter W   = 32
  )
(
 input clk,
 input rst,
 input [(NUM-1):0] [(W-1):0]  wdata,
 input [(NUM-1):0]            write,
 input [(NUM-1):0]            read,
 output [(NUM-1):0] [(W-1):0] rdata
 );

 genvar v;

  generate
   for (v = 0; v < NUM; v++)
     test
     #(.W(W))
     test_inst // rename instname test to test_inst
     (
      .clk(clk),
      .rst(rst),
      .read(read [v]),
      .write(write [v]),
      .wdata(wdata [v]),
      .rdata(rdata [v])
     );

  endgenerate
endmodule

module test
#(parameter W = 32)
(
 input            clk,
 input            rst,
 input            read,
 input            write,
 input  [(W-1):0] wdata,
 output [(W-1):0] rdata
 );

test_intf 
#(.W(W))
test_if // rename instname test_intf to test_if
();

assign test_if.write  = write; // rename instname test_intf to test_if
assign test_if.wdata  = wdata; // rename instname test_intf to test_if
assign test_if.read   = read; // rename instname test_intf to test_if
assign rdata  = test_if.rdata; // rename instname test_intf to test_if

test_intf_top
#(.W (W)) 
test_if_top // rename instname test_intf_top to test_if_top
(
 .clk  (clk),
 .rst  (rst),
 .test_if(test_if) // rename portname/instname test_intf to test_if
 );

endmodule

module test_intf_top
#(parameter W = 32)
(
 input clk,
 input rst,
 test_intf test_if // rename portname/instname test_intf to test_if
 );


 write_read
  #(.W(W))
  write_read
  (
   .clk (clk),
   .rst(rst),
   .write (test_if.w), // rename instname test_intf to test_if
   .read (test_if.r) // rename instname test_intf to test_if
  );

 endmodule

 // ...
...