Verilog矢量包装/拆包宏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog矢量包装/拆包宏相关的知识,希望对你有一定的参考价值。

我目前正在努力解决verilog模块只接受一维打包向量作为输入/输出的问题。例如:

wire [bitWidth-1:0] data;

我想要做的是输入一维打包的二维向量(想想数字数组)。例如:

wire [bitWidth-1:0] data [0:numData-1];

我目前有几个方便的宏,它们使二维矢量变平并且不展平一维矢量。他们是:

`define PACK_ARRAY(PK_WIDTH,PK_LEN,PK_SRC,PK_DEST) 
genvar pk_idx; 
generate 
    for (pk_idx=0; pk_idx<(PK_LEN); pk_idx=pk_idx+1) begin : packLoop 
        assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; 
    end 
endgenerate

`define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC) 
genvar unpk_idx; 
generate 
    for (unpk_idx=0; unpk_idx<(PK_LEN); unpk_idx=unpk_idx+1) begin : unpackLoop 
        assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; 
    end 
endgenerate

如果我只使用它们来处理我正在使用的模块的一个输出和一个输入,这些工作很有用。问题是如果我在给定模块中多次使用这些宏中的任何一个,则会发生以下错误:

1)genvars已经宣布。 2)已经使用了循环标签。

我可以通过不在宏中声明并在其他地方声明它来解决genvar问题,但我无法弄清楚如何解决循环标签问题并且仍然能够使用宏来保持干净的代码。

任何建议(除了'切换到系统verilog':P)都是受欢迎的!谢谢。

答案

对于纯verilog解决方案,您需要再为genvar标识符提供一个参数。示例(注意:为简单起见,用((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)替换(PK_WIDTH)*unpk_idx +: PK_WIDTH,请参阅herehere):

`define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC,UNPK_IDX) 
genvar UNPK_IDX; 
generate 
  for (UNPK_IDX=0; UNPK_IDX<(PK_LEN); UNPK_IDX=UNPK_IDX+1) begin //: unpackLoop <-- remove label
    assign PK_DEST[UNPK_IDX][((PK_WIDTH)-1):0] = PK_SRC[(PK_WIDTH)*unpk_idx +: PK_WIDTH]; 
  end 
endgenerate

如果SystemVerilog是使用流操作符的选项,则有一个更简单的解决方案。请参阅IEEE Std 1800-2012§11.4.14流媒体运营商(打包/解包)。例:

// packing
assign packed_array = {>>{unpacked_array}};
// unpacking
assign unpacked_array = {<<PK_WIDTH{packed_array}};

以上是关于Verilog矢量包装/拆包宏的主要内容,如果未能解决你的问题,请参考以下文章

text ch139一览解构-AKA包装和-拆包/ ch139.ipynb

Android 矢量资产:dp 测量是不是只对“包装内容”重要?

php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用

如何组合绑定片段而不将它们包装在 XML 文字中

如何包装所有片段(不在里面)or) with?

Verilog学习笔记基本语法篇········ 生成块