2017-09-01 52 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

相关问题