2015-02-27 7 views
1

Im пытается построить модуль скользящей средней. Он должен использовать количество значений для использования в качестве параметра.Verilog: сумма над регистром

Как получить сумму всех n tmp -регистров с использованием for - или gernerate -block в течение одного такта-цирка?

reg [WORDLEN - 1:0] tmp [SIZE - 1:0]; 
reg [WORDLEN + SIZE/2 - 1:0] sum; 
always @(posedge clk) 
    sum <= sum(tmp) // Like <= tmp[0] + tmp[1] + ... + tmp[SIZE-1] 
+0

Этот метод снижения частота часов. Вы можете использовать ввод «reset» для сброса 'sum', после чего операция может быть завершена после некоторых нарастающих фронтов часов. В каждом часе просто добавьте один элемент 'tmp' с' sum'. (Вы можете использовать счетчик для подсчета необходимых циклов для работы) – Amir

ответ

1

Петли, подобные этому, как правило, легче понять, если вы сначала разобьете синхронные и комбинаторные части. Сначала у нас есть комбинаторный цикл, который разворачивается к настраиваемому числу добавлений. Затем введем триггер на результат.

integer i; 
reg [WORDLEN + SIZE/2 - 1:0] sum_comb; 
always @* begin 
    sum_comb = 'd0; 
    for(i=0; i< SIZE; i=i+1) begin 
    sum_comb = sum_comb + tmp[i]; 
    end 
end 

always @(posedge clk) begin 
    sum <= sum_comb; 
end 
+0

И если вы хотите получить более компактный, вы можете использовать 'sum_comb + = tmp [i];' – nguthrie

+0

Я завершил этот код и смог получить правильный результат в Modelsim, но когда я синтезировал его на ISE (Xilinx Synthesis Tool), технологическая схема была черным ящиком. Вы уверены, что код синтезирован для конкретного оборудования? – Amir

+0

@Amir Я часто синтезирую код, как это, без проблем. Глядя на sum_comb, вы можете видеть, что это просто количество сумматоров параллельно. Большинство инструментов должны уметь видеть это и делать разумные вещи. – Morgan

0

Если вы используете SystemVerilog, вы можете просто написать:

always @(posedge clk) 
    sum <= tmp.sum; 

Ниже приведен полный пример кода:

module test; 
    parameter WORDLEN = 8; 
    parameter SIZE = 4; 
    reg [WORDLEN - 1:0] tmp [SIZE - 1:0]; 
    reg [WORDLEN + SIZE/2 - 1:0] sum; 
    logic clk = 0; 

    initial begin 
     tmp = '{ '{1}, '{4}, '{6}, '{7}}; 
     forever begin 
     clk = ~clk; 
     #10; 
     tmp [0] = tmp[0] + 1; //Increment tmp[0] twice during each clock for testing 
     end 
    end 

    always @(posedge clk) begin 
    sum <= tmp.sum ; 
    $display ("sum(tmp) = sum(%p) = %d", tmp, sum) ; 
    end 
endmodule 

выход:

# sum(tmp) = sum('{1, 4, 6, 7}) = 18 
# sum(tmp) = sum('{1, 4, 6, 9}) = 20 
# sum(tmp) = sum('{1, 4, 6, 11}) = 22 
# sum(tmp) = sum('{1, 4, 6, 13}) = 24 
# sum(tmp) = sum('{1, 4, 6, 15}) = 26 
# sum(tmp) = sum('{1, 4, 6, 17}) = 28 
Смежные вопросы