Verilog目前并不支持数组型端口,这不利于一些信号的管理(仅有System Veilog允许这样定义)
module example(
input clk,
...
...
output [7:0] array [15:0] //Verilog-2001不支持这样的端口定义
);
...
endmodule 一般情况下我们选择将数组合并为一个大位宽信号进行输出
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则无要求
`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型
`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
*/
总结:
在实际使用时可以将上述两个宏函数定义放入单独的头文件中,需要管理数组型端口时直接引用头文件,调用宏函数即可。
此方法并不会对综合结果产生负面影响。