2017-09-01 34 views
0

我想編寫其中某些輸入不存在的代碼。我想創建一個包含這些參數的結構(除其他外)。我該怎麼做?我試圖使用生成,定義一個空結構(typedef struct {} empty_t)和0大小的數組(logic foo[0]),但我所有的嘗試失敗作爲語法錯誤。如何在SystemVerilog中創建一個空數據類型或條件字段

編輯:我想這樣做(簡體):

module foo(clk, data_in, opt_data_in); 
    parameter USE_OPT_IN = 1; 

    input logic clk; 
    input logic data_in; 
    input logic opt_data_in; 

    typedef struct packed { 
     logic data_in; 
     // Since it's stored in on-chip RAM I'd like it 
     // to be as small as possible 
     if (USE_OPT_IN != 0) 
      logic opt_data_in; 
    } ram_entry_t; 
    ram_entry_t my_ram[4096]; 

    always_ff @(posedge clk) begin 
     ram_entry_t new_entry; 
     new_entry.data_in = data_in; 
     if (USE_OPT_IN != 0) 
      new_entry.opt_data_in = opt_data_in; 
     my_ram[$random() % 4096] = new_entry; 
    end 
endmodule 

當然這並不編譯。

編輯2:上面是簡化的例子。有超過7個可選字段,編碼128個結構似乎不合理 - 與僅使用非結構化位字段相比。

+0

當你說'輸入'你能解釋什麼輸入? –

+0

到模塊。從外面看,他們不會連接任何東西(''Z'),因爲我不認爲我可以進行可選輸入,但是當我想要將它們實際存儲在某個地方時遇到問題。現在我正在考慮只使用一個位域並手動打包數據,但如果我可以做更多的HL,那將會很好。 –

+0

你有代碼示例嗎? – Serge

回答

0

沒有可選的端口或空數據類型。引用端口的模塊內部的代碼對任何情況都是有意義的。

有幾件事情可以做

  1. 您可以指定一個默認值,如果不連接將使用的輸入端口。
  2. 您可以參數化端口類型以使用具有不同數量字段的不同結構。同樣,模塊內的代碼必須適用於任何數據類型。這通常意味着將輸入轉換爲模塊內已知類型的輸入。
  3. 如果所有輸入類型相同,也可以使用可變大小的數組。
+0

好的。它看起來像我需要手動連接有用的字段由於外部要求。 –

0

我想唯一的建議是使用一個TYPE作爲模塊的參數,其中後者可能是一個有或沒有字段的結構。除非可以使用接口或類,否則您還需要genarate塊。這是一個簡單的方法。對於生成塊,它可能還需要另一個OPT參數。對不起,我沒有嘗試編譯它。

module foo#(parameter type TYPE = int, parameter bit OPT = 1) 
     (clk, data_in, opt_data_in); 
    input logic clk; 
    input logic data_in; 
    input logic out_data_in; 

    TYPE my_ram[4096]; 

    if (OPT) begin 
    always_ff @(posedge clk) begin 
     TYPE new_entry; 
     new_entry.data_in <= data_in; 
     new_entry.opt_data_in <= opt_data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 
    else begin 
    always_ff @(posedge clk) begin 
     TYPE new_entry; 
     new_entry.data_in <= data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 

    end 
endmodule 

現在你可以實例與你不同類型的模塊:

typedef struct packed { 
    logic data_in;  
    logic opt_data_in; 
} ram_entry_full_t; 
typedef struct packed { 
    logic data_in;  
} ram_entry_short_t; 

foo#(ram_entry_full_t, 1) foo_full(..); 
foo#(ram_entry_short_t, 0) foo_short(..); 
+0

問題是這很快就變得不合理。如果我有7個字段,這是我需要實現的128個結構。在這一點上更容易做到: 'function int get_size(); return 1 + USE_OPT_IN endfunction function logic get_data_opt_offset(); return 0; endfunction 函數邏輯get_data_offset(); return get_data_opt_offset()+ USE_OPT_IN; endfunction ... typedef logic [get_size() - 1]條目; ' –

+0

對於get_size,您可以使用'$ bits()'代替。 – Serge

0

我會建立在@Serge答案。如果你想使你的RAM條目類型外部模塊,並使用它們作爲參數,你可以做掉與USE_OPT_IN參數完全,因爲這是多餘的:

typedef struct packed { 
    logic data_in;  
    logic opt_data_in; 
} ram_entry_full_t; 

typedef struct packed { 
    logic data_in;  
} ram_entry_short_t; 


module foo #(parameter type TYPE = int) (clk, data_in, opt_data_in); 
    input logic clk; 
    input logic data_in; 
    input logic out_data_in; 

    TYPE my_ram[4096]; 

    if (TYPE == type(ram_entry_full_t)) begin 
    always_ff @(posedge clk) begin 
     TYPE new_entry; 
     new_entry.data_in <= data_in; 
     new_entry.opt_data_in <= opt_data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 
    end 

    else if (TYPE == type(ram_entry_short_t)) begin 
    always_ff @(posedge clk) begin 
     TYPE new_entry; 
     new_entry.data_in <= data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 
    end 

    else begin 
    $error("Unsuported type ..."); 
    end 

endmodule 

你可以更換如果/否則級聯案例使代碼稍微更具可讀性。您也可以通過提取函數來重構初始化代碼以避免重複。

您也可以使用TYPE作爲您的頂級模塊的端口,而不是data_inopt_data_in

對於第二種情況,你可以留下你的模塊簽名在你的問題,裏面做的所有的魔法:

module foo(clk, data_in, opt_data_in); 
    parameter bit USE_OPT_IN = 1; 

    input logic clk; 
    input logic data_in; 
    input logic opt_data_in; 

    typedef struct packed { 
    logic data_in;  
    logic opt_data_in; 
    } ram_entry_full_t; 

    typedef struct packed { 
    logic data_in;  
    } ram_entry_short_t; 

    if (USE_OPT_IN) begin 
    always_ff @(posedge clk) begin 
     ram_entry_full_t new_entry; 
     new_entry.data_in <= data_in; 
     new_entry.opt_data_in <= opt_data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 
    end 

    else begin 
    always_ff @(posedge clk) begin 
     ram_entry_short_t new_entry; 
     new_entry.data_in <= data_in; 
     my_ram[$random() % 4096] <= new_entry; 
    end 
    end 

endmodule 

這樣,它不可能用錯誤的參數來實例化模塊,如果你不」如果你的模塊已經在某個地方被使用,那麼就會中斷接口兼容性

+0

問題是這很快就變得不合理。如果我有7個字段,這是我需要實現的128個結構。在這一點上更容易做到: 'function int get_size(); return 1 + USE_OPT_IN endfunction function logic get_data_opt_offset(); return 0; endfunction 函數邏輯get_data_offset(); return get_data_opt_offset()+ USE_OPT_IN; endfunction ... typedef logic [get_size() - 1]條目; ' –

+0

取決於您在代碼中拍攝多少表現力。有人可能更容易開發,但更難以調試。只有你可以打電話。 –

+1

@MaciejPiechotka因爲代碼不能在第一時間合成,爲什麼不使用svtb類重載函數和繼承?那裏可能會找到更好的解決方案。 – Serge

相關問題