在verilog中注册和重置卷积输出

在verilog中注册和重置卷积输出,verilog,reset,convolution,cpu-registers,Verilog,Reset,Convolution,Cpu Registers,所以我有一个做卷积的模块,它接受一个数据输入和一个滤波器输入,其中输入是9个数字的数组,clk的每个posedge,这两个输入被相乘,然后累加,也就是说,我把每一个新的乘法积保存到一个寄存器中。在每9次迭代之后,我必须保存结果并重置它,但我必须在一个时钟周期内完成,因为我的新数据将在下一个posedge上出现。因此,我面临的问题是如何不保存数据,并在不丢失数据的情况下重置输出?如果你有任何建议,请帮忙。还需要提到的是,我的conv_模块是一个子模块,我将在顶层模块中实例化它,因此我必须访问upt

所以我有一个做卷积的模块,它接受一个数据输入和一个滤波器输入,其中输入是9个数字的数组,clk的每个posedge,这两个输入被相乘,然后累加,也就是说,我把每一个新的乘法积保存到一个寄存器中。在每9次迭代之后,我必须保存结果并重置它,但我必须在一个时钟周期内完成,因为我的新数据将在下一个posedge上出现。因此,我面临的问题是如何不保存数据,并在不丢失数据的情况下重置输出?如果你有任何建议,请帮忙。还需要提到的是,我的conv_模块是一个子模块,我将在顶层模块中实例化它,因此我必须访问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
模块多功能转换(输入时钟,
输入rst,
输入符号为[4:0]a,
输入符号为[2:0]b,
输出注册表已签出[7:0]
);
电文签名[7:0]mult;
注册签名[7:0]和;
reg[3:0]计数器;
注册你写;
reg[7:0]在顶部;
赋值mult={3{a[4]},a}*{{5{b[2]},b};
始终@(posedge clk或posedge rst)
开始
如果(rst)
开始

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

  • 你在两个地方写出
    。这是行不通的
  • 您使用%9。无法映射到硬件上的
  • 你有一个sel信号,它以某种方式控制你的总和
  • 除此之外,我知道你想把所有的记忆都带出来

    你的代码,因为它需要彻底重写。 但你最大的问题是,你肯定不能让记忆出来。无论您想做什么样的后处理,您都有两种选择:

  • 处理显示的输出数据
  • 将模块外部的数据存储在内存中,并让另一个进程读取该内存
  • 我认为只有(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 
    
    始终@(posedge clk或posedge rts)
    开始
    如果(rst)
    开始
    
    counter Hi@Oldfart,感谢您再次帮助我并提供代码修复建议)。但是,我有两个问题:1.所以我检查了你的代码好几次,我看不到你分配out进行求和的行,以及out重置为0的行。另一件事是,我不理解在这里使用do_write信号。在我的代码中,输出需要每9个周期注册一次In out,然后在顶部模块上,我将该值分配给另一个reg,例如out_top。我在问题中编辑了我的代码,在这里我使用了您提供的部分内容,并添加了我需要实现的逻辑。我编写了tb并测试了模拟,但out_top的值始终指定为0,因为它指的是第9个周期后out的值。。我仍然不知道如何解决这个问题。我同意您提出的第一个解决方案“按外观处理输出数据”最适合我,我想在这一点上我不想使用address。顺便说一句,select信号用于控制要添加到sum中的内容,因为在第一次迭代时,sum是x,这就是为什么我需要在其中存储0。Idk为什么我没有想到像您那样在“rst”状态下直接将“0”赋值给求和,所以也谢谢您。