【问题标题】:Matrix reconstruction and multiplication in verilogVerilog中的矩阵重建和乘法
【发布时间】:2015-01-25 13:23:55
【问题描述】:

我正在尝试在 verilog 中将两个 16 位定点数数组相乘。我已经接收了 8 个每个定点数的 2 位流,将它们重构为二维数组并尝试相乘。我收到代码后出现的错误。我知道重建数组的方法会很慢,但我没有想法。我遇到的问题是无法将二维数组作为输入,也无法在索引中使用变量。如果有人可以帮助我理解为什么会出现这些错误或提出更好的方法来完成此任务,将不胜感激。

仅供参考,我已经标记了第 51 行....

`timescale 1ns / 1ps

module Nueron(
    input wire clk,
    input wire [2:0] sel,
    input wire signed [383:0] z_in,
    input  wire signed [383:0] weights,
    output wire signed z_out
    );

    /***********signal declaration & constants*********************/
    //something signally
    reg signed [31:0] temp1  = 0;
    reg signed [31:0] temp2  = 0;
    reg [15:0] i = 0;
    reg signed [15:0] sum = 0;
    reg [15:0] bitCount = 0; 
    reg [15:0] wordCount = 0; 
    reg [15:0] z_Mat [23:0];
    reg [15:0] w_Mat [23:0];

    wire [4:0] countmax ;

    localparam nlSize = 24;
    localparam midSize = 8; 
    localparam outSize = 10;
    localparam fixed = 10;
    /*************body*********************************/
    always@(posedge clk) begin
        bitCount <= bitCount + 1;
        z_Mat[bitCount][wordCount] =  z_in[bitCount];
        w_Mat[bitCount][wordCount] = weights[bitCount];
        wordCount = (bitCount % 16 == 0) ? wordCount + 1 : wordCount;
    end

    always@(wordCount) begin
        temp1 <= z_Mat * w_Mat;   //This is line 51!!
    end

    always@(posedge clk) begin
        sum <= sum + (temp1 >>> 8);    
    end    

    assign countmax = (sel[2] == 1) ? nlSize : (sel[1] == 1)? midSize : outSize; 
    assign z_out = (i == countmax) ? sum : 0;

endmodule

[VRFC 10-394] 无法直接访问内存 z_Mat ["C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":51]

[VRFC 10-845] 运算符的非法操作数 * ["C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":51]

[VRFC 10-395] 无法将未打包类型分配给打包类型 ["C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":51]

[VRFC 10-1523] 解压后的值/目标不能用于赋值 ["C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":51]

[VRFC 10-1040] 模块 Nueron 由于之前的错误而被忽略 ["C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":17]

【问题讨论】:

  • 我想你已经发现了问题,你不能在verilog中做矩阵乘法。您可以在第 51 行周围放置一个循环来分别计算 temp1 的每个元素。但请注意,乘数很大,并行有很多不是标准做法。 TDM 通常用于对设计进行超频,并在多个时钟周期内使用单个乘法器。
  • 我不清楚 TDM 是什么。
  • 时分复用,这意味着使用相同的硬件进行不同的操作,通过将您的设计超频四倍,乘法器可以用于四次乘法。

标签: matrix multidimensional-array verilog matrix-multiplication


【解决方案1】:

您可以在systemVerilog中使用数组端口,您将拥有相同的代码,但将输入端口更改为数组并将文件扩展名更改为.sv,请检查以下代码。

一些注意事项:

  • 余数不可合成。
  • 使用 reset 来初始化计数器。
  • z_out 的大小必须等于(w_Mat 的大小 + z_Mat 的大小 + log2(累积次数))。 .. 我没有更改代码中的大小
  • 记住要有一个有效的输出来表示积累完成并且输出准备好了。

`时间刻度 1ns / 1ps

module Nueron(
    input wire clk,
    input wire nRst,// You will need a reset signal for initialization
    input wire [2:0] sel,
    input wire signed [15:0] z_Mat [23:0],
    input wire signed [15:0] w_Mat [23:0],
    output wire signed [31:0] z_out,
    output reg valid_out
    );

    /***********signal declaration & constants*********************/
    //something signally
    reg signed [31:0] temp1  = 0;
    reg signed [31:0] temp2  = 0;
    reg [15:0] i = 0;
    reg signed [15:0] sum = 0;
    reg [15:0] bitCount = 0; 
    reg [15:0] wordCount = 0; 
    reg valid_sum;
    wire [4:0] countmax ;

    localparam nlSize = 24;
    localparam midSize = 8; 
    localparam outSize = 10;
    localparam fixed = 10;
    /*************body*********************************/
//     always@(posedge clk) begin
//         bitCount <= bitCount + 1;
//         z_Mat[bitCount][wordCount] =  z_in[bitCount];
//         w_Mat[bitCount][wordCount] = weights[bitCount];
//         wordCount = (bitCount % 16 == 0) ? wordCount + 1 : wordCount; // remainder is not synthesizable
//     end

    always @(posedge clk) begin
      if(!nRst)// Active low synchrounous reset
    begin
      wordCount <=0;
      temp1 <=0;
      valid_sum <=0;
      z_out <=0;
    end
      else
    begin
      z_out <= z_out + temp1;
      valid_out <= valid_sum;
      if(wordCount == countmax-1)
        begin
          wordCount <= 0;
          temp1 <= z_Mat[wordCount] * w_Mat[wordCount];
          valid_sum <= 1;
        end
    end

    end


    assign countmax = (sel[2] == 1) ? nlSize : (sel[1] == 1)? midSize : outSize; 

endmodule

【讨论】:

  • 我认为余数运算符是 2 的倍数是可合成的?
  • *如果是 2 的幂
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 2020-04-02
相关资源
最近更新 更多