首页 > 解决方案 > 在verilog中注册和重置卷积输出

问题描述

所以我有一个进行卷积的模块,它需要一个数据输入和一个过滤器输入,其中输入是 9 个数字的数组,这两个输入的 clk 的每个位姿都被相乘然后累加,即我保存每个新的乘积入一个寄存器。在每 9 次迭代后,我必须保存结果并重置它,但我必须在一个时钟周期内完成,因为我的新数据即将到来。所以我面临的问题是如何不保存数据并在不丢失数据的情况下重置输出?如果您有任何建议,请提供帮助。还需要提到的是,我的 conv_module 是一个子模块,我将在顶层模块中实例化它,所以我必须从顶层访问所有输入和输出。

这是我到目前为止编写的代码,但它不能按我想要的方式工作,因为我无法从顶部模块中点击输出数字数组。

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

标签: verilogresetconvolutioncpu-registers

解决方案


该代码中有大量错误。
除此之外,您还有一个 3Mega 位内存,您只能使用 9 个位置中的 1 个。

  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 where 一个可能的内存来获取结果。如果没有内存,您可以删除 addr 但 do_write 应该会告诉您何时有新的卷积结果可用,在这种情况下您可能需要给它一个不同的名称。例如“sum_valid”。


推荐阅读