регистрация и сброс вывода свертки в Verilog - PullRequest
0 голосов
/ 11 мая 2018

поэтому у меня есть модуль, который выполняет свертку, он принимает входные данные и входные данные фильтра, где входные данные представляют собой массив из 9 чисел, каждый шаг clk эти два входа умножаются, а затем суммируются, т.е. я сохраняю каждыйновый продукт умножения в регистр.после каждых 9 итераций я должен сохранять результат и сбрасывать его, но я должен делать это за один такт, поскольку мои новые данные поступают на следующей стадии.Итак, проблема, с которой я сталкиваюсь, заключается в том, как не сохранять данные и сбрасывать их без потери данных?Пожалуйста, помогите, если у вас есть какие-либо предложения.Также необходимо упомянуть, что мой conv_module является субмодулем, и я буду создавать его экземпляр в верхнем модуле, поэтому я должен получить доступ ко всем входам и выходам из uptop.

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

module mult_conv( input clk,
              input rst,
                     input signed [4:0] a,
                     input signed[2:0] b,
                     output reg signed[7:0] out
                         );

wire signed [7:0] mult;
reg signed [7:0] sum;

reg [3:0] counter;
reg do_write;
reg [7:0] out_top;

assign mult = {{3{a[4]}},a} * {{5{b[2]}},b};


always @(posedge clk or posedge rst)
begin
   if (rst)
   begin
      counter  <= 4'h0;
      addr     <= 'h0;
      sum      <= 0;
      do_write <= 1'b0;
   end // rst
   else
   begin
      if (counter == 4'h8)
      begin // we have gathered 9 samples
         counter <= 4'h0;
         // start again so ignore old sum
         sum <= mult;
            out <= sum;
            out_top <= out;
      end
      else
      begin
         counter <= counter  + 4'h1;
         // Add results
         sum <= sum + mult;
            out <= 0;
            out_top <= out_top;
      end
      // Write signal has to be set one cycle early
      do_write = (counter==4'h7);
   end // clocked
end // always


        endmodule

1 Ответ

0 голосов
/ 11 мая 2018

В этом коде множество ошибок.
Кроме того, у вас есть 3-мегабитная память, из которой вы используете только 1 в 9 местах.

  1. Вы пишете out в двух местах. Это не работает.
  2. Вы используете% 9. Это не может быть отображено на оборудование.
  3. У вас есть сигнал sel, который каким-то образом контролирует вашу сумму.

Кроме того, я понимаю, что вы хотите вывести всю память из памяти.

Ваш код, потому что его нужно кардинально переписать. Но ваша самая большая проблема в том, что вы определенно не можете заставить память всплыть. Что бы вы ни делали после постобработки, у вас есть два варианта:

  1. Обработка выходных данных в том виде, в котором они отображаются.
  2. Сохраните данные вне модуля в памяти и попросите другой процесс прочитать эту память.

Я думаю, что только (1) является правильным способом, потому что ваш сигнал может иметь бесконечную длину.

Что касается исправления этого кода:

  • Заменить% 9 на счетчик, чтобы считать от 0 до 8.
  • Обработка в синхронизированной секции. Смотри ниже
  • Переместите сюда логику генерации addr и sel. Держите все это вместе.

Ниже приведен основной код того, как сделать свертку из 9 последовательностей. Я должен игнорировать «sel», так как понятия не имею о сроках. Я также добавил генерацию адреса и сигнал записи, чтобы результат можно было сохранить во внешней памяти. Но я все еще думаю, что вы должны обработать результат на лету.

always @(posedge clk or posedge rts)
begin
   if (rst)
   begin
      counter  <= 4'h0;
      addr     <= 'h0;
      sum      <= 0;
      do_write <= 1'b0;
   end // rst
   else
   begin
      if (counter == 4'h8)
      begin // we have gathered 9 samples
         counter <= 4'h0;
         addr <= addr  + 1;
         // start again so ignore old sum
         sum <= mult;
      end
      else
      begin
         counter <= counter  + 4'h1;
         // Add results
         sum <= sum + mult;             
      end

      // Write signal has to be set one cycle early
      do_write = (counter==4'h7);
   end // clocked
end // always 

(код выше был введен на лету, может содержать синтаксис, опечатку и другие ошибки !!)

Как видите, хитрость заключается в том, чтобы узнать, когда добавить старый результат или когда игнорировать старую сумму и начать заново.

(на это я трачу около 3/4 часа, поэтому по моему обычному тарифу вы должны будете заплатить мне $ 93,75 :-)


Я предоставил основной код, чтобы вы могли разобраться со спецификой. Я ничего не делал с тобой, но оставил это тебе.
do_write и addr, где для возможной памяти, чтобы забрать результат. Без памяти вы можете удалить addr, но do_write должен сообщить вам, когда будет доступен новый результат свертки, и в этом случае вы можете присвоить ему другое имя. например 'Sum_valid'.

...