[Verilog HDL笔记] 数组型端口管理方法
擺爛王091
2021年04月12日 11:36

Verilog目前并不支持数组型端口,这不利于一些信号的管理(仅有System Veilog允许这样定义)

代码块
clike
自动换行
复制代码
module example(
  input				clk,
  ...
  ...
  output	[7:0]	array	[15:0]  //Verilog-2001不支持这样的端口定义
 );

...
 
 endmodule
复制成功

一般情况下我们选择将数组合并为一个大位宽信号进行输出

代码块
clike
自动换行
复制代码
module example(
  input		wire				clk,
  ...
  ...
  output	wire	[8*16-1 : 0]	array_pack
 );

reg		[7 : 0]	array	[15 : 0];

genvar i;
generate
	for(i=0;i<15;i=i+1) begin : pack
   		assign array_pack[8*i+7 : 8*i] = array[i];
   end
endgenerate

endmodule
复制成功

类似的,我们也可以将一个大位宽输入信号拆分为数组,这里不再赘述

不难想到,我们可以定义一个用于pack/unpack的宏函数,以方便的进行数组的打包与拆分


PACK_ARRAY(数组宽度,数组深度,被打包数组,打包输出信号)

        注意打包输出信号PK_DEST必须是wire型,被打包信号PK_SRC则无要求

代码块
clike
自动换行
复制代码
`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
		assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; 
   end 
endgenerate

/*
使用例
module example(
  input		wire				clk,
  ...
  ...
  output	wire	[8*16-1 : 0]	array_pack
 );

reg		[7 : 0]	array	[15 : 0];

`PACK_ARRAY(8,16,array,array_pack)

endmodule
*/
复制成功


UNPACK_ARRAY(数组宽度,数组深度,拆分输出数组,被拆分信号)

    注意拆分输出数组PK_DEST必须为wire型

代码块
clike
自动换行
复制代码
`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
		assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; 
	end 
endgenerate

/*
使用例
module example(
  input		wire				clk,
  ...
  ...
  input		wire	[8*16-1 : 0]	array_pack
 );

wire	[7 : 0]	array	[15 : 0];

`UNPACK_ARRAY(8,16,array,array_pack)

endmodule
*/
复制成功

总结:

    在实际使用时可以将上述两个宏函数定义放入单独的头文件中,需要管理数组型端口时直接引用头文件,调用宏函数即可。

    此方法并不会对综合结果产生负面影响。