2014-01-12 2 views
3

Следующий кодИспользование параметризированный совокупный тип данных в ANSI-стиль списка модуль порта

module test #(A = 1, B = 2) (output t_my sig); 
    typedef struct { 
     logic [A-1:0] fA; 
     logic [B-1:0] fB; 
    } t_my; 
    initial $display("hello\n"); 
endmodule 

возвращает ошибку

Error-[SV-UIOT] Undefined interface or type 
test.vs, 1 
t_my, "sig" 
    The definition for the forward-referenced interface 't_my' is missing or 
    't_my' is the name of an undefined user type. 
    Check to see if the interface definition file/work library is missing or the 
    definition of the user type is missing. 

VCS Если я вместо этого сделать

typedef struct { 
    logic [A-1:0] fA; 
    logic [B-1:0] fB; 
}t_my; 

module test #(A = 1, B = 2) (output t_my sig); 
    initial $display("hello\n"); 
endmodule 

тогда я получаю

Error-[IND] Identifier not declared 
test.vs, 2 
    Identifier 'A' has not been declared yet. If this error is not expected, 
    please check if you have set `default_nettype to none. 


Error-[IND] Identifier not declared 
test.vs, 3 
    Identifier 'B' has not been declared yet. If this error is not expected, 
    please check if you have set `default_nettype to none. 

Есть ли способ сделать то, что я хочу, используя списки портов модуля стиля ANSI? Обратите внимание, что я могу сделать это без ANSI списков стиль порта следующим образом:

module test #(A = 1, B = 2) (sig); 
    typedef struct packed { 
     logic [A-1:0] fA; 
     logic [B-1:0] fB; } t_my; 

     output t_my sig; 
     initial $display("hello\n"); 
endmodule 

module top; 
    logic topsig [2:0]; 
    test test1 (.sig ({>>{topsig}})); 
endmodule 

ответ

4

Если у вас есть определенный пользователем совокупный тип в списке портов, вам нужно поместить этот тип в таком месте, где он будет совместим с сделайте соединение, то есть модуль test, и модуль над ним, который будет подключаться к этому порту. Это можно сделать двумя способами:

Пропустите тип данных вниз с более высокого уровня, используя параметр .

module test#(type T) (input T sig); 
    parameter A = $bits(sig.fA); 
    parameter B = $bits(sig.fB); 

    initial #1 $display(A,, B); 
endmodule 
module top; 
    typedef struct { 
     logic [3:0] fA; 
     logic [4:0] fB; 
    } my_t; 

    my_t s; 

    test #(my_t) t2(s); 

endmodule 

отображает

#   3   4 

или вы можете поставить тип в общем пакете. Однако для того, чтобы сделать параметризацию структуры, вам нужно обернуть тип в классе. Смотрите раздел 6.25 в 1800-2012 LRM (Это должно быть synthesiable)

package p; 
class T#(int A,B); 
    typedef struct { 
     logic [A-1:0] fA; 
     logic [B-1:0] fB; 
    } my_t; 
endclass 
endpackage : p 

module test#(int A=1, B=2) (input p::T#(A,B)::my_t sig); 
    initial #1 $displayb(sig.fA,, sig.fB); 
endmodule 

module top; 
    import p::T; 

    T#(2,3)::my_t s = '{'1, '1}; 
    test #(2,3) t(s); 

endmodule 
+0

Спасибо за ваш ответ - 2-й вариант интересен, и я сделал это к сведению на будущее. Но я не согласен с основополагающей предпосылкой, что оба модуля «top» и «test» должны знать определение «T». Я знаю это, потому что следующий код компилирует и имитирует только штраф ....... модуль test # (A = 1, B = 2) (sig); typedef struct packed { логика [A-1: 0] fA; логика [B-1: 0] fB; } t_my; выход t_my sig; начальный $ display ("hello \ n"); endmodule ----------- модуль сверху; логика topsig [2: 0]; test test1 (.sig ({>> {topsig}})); endmodule – user2400361

+0

Упакованная структура - это совсем другая история. Все интегральные типы упакованы и нет проверки типа. Правила Verilog применяются, и биты будут усечены или дополнены для установления соединений или назначений. –