本文记录一个常用的verilog模块:多路选择器 的代码。
设计要求:通道数在综合前可变、使用独热码选择、可被quartus综合。
独热码 可变长的多路选择器:
sel:独热码选择输入。
in: 输入,可以是二维的。
out:输出。
reg [N-1:0]sel;
reg [7:0]out;
reg [7:0]in[N-1:0];
integer i;
always@(*)begin
out='d0;
for ( i = 0;i < N; i=i+1 )begin:v
if(sel[i])
out= in[i];
end
end
verilog的端口不能是二维的,例如定义成output [7:0]a[7:0]是非法的。可以用以下宏将1维端口改写成2维,或2维改1维。例如将output [16:0]a;连接成[7:0]a_2D[0:1],a_2D[0]对应a的低8位,a_2D[1]对应a的高8位;
// define NEW_ARRAY_PACK_UNPACK frist
`define NEW_ARRAY_PACK_UNPACK genvar pk_idx; genvar unpk_idx;
// pack 2D-array to 1D-array
`define PACK_ARRAY(PK_WIDTH,PK_LEN,PK_SRC,PK_DEST,name) \
generate \
for (pk_idx=0; pk_idx<(PK_LEN); pk_idx=pk_idx+1) \
begin:name \
assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; \
end \
endgenerate
// unpack 1D-array to 2D-array
`define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC,name) \
generate \
for (unpk_idx=0; unpk_idx<(PK_LEN); unpk_idx=unpk_idx+1) \
begin:name \
assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; \
end \
endgenerate
wire [7:0] a_2D [0:1];
`UNPACK_ARRAY(8,2,a_2D ,a,name)
网友评论