0

So, I have a reg[7:0] corr_Output[0:63]; which is filled with values in my module. How I can find maximum number in this array at one CLK cycle? I wrote a 8 bit comparator:

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

But I dont know how I should instantiate this module in my top design? I think I should use "for loop", or even write another module which will concatenate my Comparator2D module in pyramid form, but as I found I cant pass whole array to input port of module, so Im a little stuck..

1

2 Answers 2

0

You can do it by using for/generate, like in this code sample, in which I can compare 8 bytes at a time.

The key point is that I cannot pass a memory as input (an array of registers), but I can pass an array of bits that hold the current values from memory.

// 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

The greatest8bytes module is synthesized the way you expect: as a pyramid-like arrangement of comparators:

Circuit synthesized for greatest8bytes To connect an array of regs (a memory) to the input of this module, create a wire of the desired number of bits (64 in this example) and concatenate all elements of memory, like in this example module:

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
Sign up to request clarification or add additional context in comments.

Comments

0

Not sure if this is synthesizable, but it is good to know that SystemVerilog has built in min and max functions:

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

Output:

# max=250, min= 15

Alternatively, it is probably shorter to just use this classic and synthesizable for-loop of comparisons:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.