2015-04-02 3 views
0

Итак, у меня есть reg[7:0] corr_Output[0:63];, который заполняется значениями в моем модуле. Как я могу найти максимальное число в этом массиве за один цикл CLK? я написал 8 битный компаратор:Как найти максимальное число в массиве verilog

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 

Но я не знаю, как я должен создать экземпляр этого модуля в моем топ-дизайна? Я думаю, что я должен использовать «для цикла» или даже написать другой модуль, который объединит мой модуль Comparator2D в форме пирамиды, но, как я понял, я не могу передать весь массив на входной порт модуля, поэтому Im немного застрял.

+0

Возможный дубликат [Найти минимальное количество чисел с использованием Verilog для реализации очереди приоритетов] (http://stackoverflow.com/questions/5785351/find-minimum- в-массив-из-чисел, используя-Verilog-для-приоритеты очереди-реализации) – Qiu

ответ

0

Вы можете сделать это, используя для/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 синтезируется так, как вы ожидаете: как пирамидальное расположение компараторов:

Circuit synthesized for greatest8bytes Для подключения массива регуляр (память) на вход этого модуля, создать провод нужного числа битов (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 
0

Не уверен, если это синтезируемого, но это хорошо, чтобы знать, что SystemVerilog имеет встроенные минимальные и максимальные функции:

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 

Альтернативно, это, вероятно, короче просто использовать этот классический и синтезируемого для петли сравнений:

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 
Смежные вопросы