所以,我有一个reg[7:0] corr_Output[0:63];
,它在我的模块中填充了值。如何在一个CLK周期内找到此阵列中的最大数量?
我写了一个8位比较器:
module Comparator2D(
input [7:0] X1,
input [7:0] indexX1,
input [7:0] X2,
input [7:0] indexX2,
output [7:0] Y,
output [7:0] indexY
);
always begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
但是我不知道如何在我的顶级设计中实例化这个模块?我想我应该使用" for loop",或者甚至编写另一个模块,它将以金字塔形式连接我的Comparator2D模块,但是我发现我不能将整个数组传递给模块的输入端口,所以我有点陷阱..
答案 0 :(得分:0)
你可以使用for / generate来实现,就像在这个代码示例中一样,我可以一次比较8个字节。
关键是我不能将内存作为输入(寄存器数组)传递,但我可以传递一个包含当前内存值的位数组。
// This is just your compare module.
module C2D (
input wire [7:0] X1,
input wire [7:0] indexX1,
input wire [7:0] X2,
input wire [7:0] indexX2,
output reg [7:0] Y,
output reg [7:0] indexY
);
always @* begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
// Compare 8 bytes at a time
module greatest8bytes (
input wire [63:0] array, // 8 byte array
output wire [7:0] indexG,
output wire [7:0] valueG
);
wire [7:0] value_l1[0:3];
wire [7:0] index_l1[0:3];
genvar i;
generate
for (i=0;i<8;i=i+2) begin :gen_comps_l1
C2D cl1 (array[i*8+7:i*8],
i,
array[(i+1)*8+7:(i+1)*8],
(i+1),
value_l1[i/2],
index_l1[i/2]
);
end
endgenerate
wire [7:0] value_l2[0:1];
wire [7:0] index_l2[0:1];
generate
for (i=0;i<4;i=i+2) begin :gen_comps_l2
C2D cl2 (value_l1[i],
index_l1[i],
value_l1[i+1],
index_l1[i+1],
value_l2[i/2],
index_l2[i/2]
);
end
endgenerate
wire [7:0] value_l3[0:0];
wire [7:0] index_l3[0:0];
generate
for (i=0;i<2;i=i+2) begin :gen_comps_l3
C2D cl3 (value_l2[i],
index_l2[i],
value_l2[i+1],
index_l2[i+1],
value_l3[i/2],
index_l3[i/2]
);
end
endgenerate
assign indexG = index_l3[0];
assign valueG = value_l3[0];
endmodule
greatest8bytes
模块以您期望的方式合成:作为比较器的金字塔式排列:
要将regs数组(内存)连接到此模块的输入,请创建所需位数的连线(在此示例中为64)并连接所有内存元素,如此示例模块中所示:
module findgreatest (
input wire clk,
input wire [2:0] addr,
input wire [7:0] data,
input wire we,
output wire [2:0] indexG,
output wire [7:0] valueG
);
reg [7:0] memory[0:7]; // 8 bytes
// To load data from the outside so the synthesizer won't throw away memory
always @(posedge clk) begin
if (we)
memory[addr] <= data;
end
wire [63:0] array = {memory[7],memory[6],memory[5],memory[4],
memory[3],memory[2],memory[1],memory[0]};
greatest8bytes compar (array, indexG, valueG);
endmodule
答案 1 :(得分:0)
不确定这是否是可综合的,但很高兴知道SystemVerilog内置了min和max函数:
module maximum ();
reg[7:0] corr_Output[0:63] = '{0:8'd112, 2:8'd250, 3:8'd37, 4:8'd15, default:8'd25};
reg[7:0] max_i[$];
reg[7:0] min_i[$];
initial begin
max_i = corr_Output.max;
min_i = corr_Output.min;
$display ("max=%d, min=%d", max_i[0], min_i[0]);
end
endmodule
输出:
# max=250, min= 15
或者,使用这个经典且可综合的for循环比较可能更短:
always_comb begin
max = corr_Output[0];
for (c = 0; c <= 63; c++)
begin
if (corr_Output[c] > max)
begin
max = array[c];
index = c;
end
end