Matrix verilog中的矩阵重构与乘法

Matrix verilog中的矩阵重构与乘法,matrix,multidimensional-array,verilog,matrix-multiplication,Matrix,Multidimensional Array,Verilog,Matrix Multiplication,我试图在verilog中乘以两个16位定点数字数组。我已经把每个固定点数取8的2比特流,重建成一个2-D数组,并尝试乘法。我得到代码后面出现的错误。我知道重建阵列的方法会很慢,但我没有主意。我遇到的问题是无法将二维数组作为输入,也无法在索引中使用变量。如果有人能帮助我理解我为什么会犯这些错误,或者提出更好的方法来完成这项任务,我将不胜感激 仅供参考,我已标记第51行 `timescale 1ns / 1ps module Nueron( input wire clk, inpu

我试图在verilog中乘以两个16位定点数字数组。我已经把每个固定点数取8的2比特流,重建成一个2-D数组,并尝试乘法。我得到代码后面出现的错误。我知道重建阵列的方法会很慢,但我没有主意。我遇到的问题是无法将二维数组作为输入,也无法在索引中使用变量。如果有人能帮助我理解我为什么会犯这些错误,或者提出更好的方法来完成这项任务,我将不胜感激

仅供参考,我已标记第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]

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

一些注意事项:

余数是不可合成的。 使用重置来初始化计数器。 z_out的大小必须等于w_Mat的大小+z_Mat的大小+log2累计数。。我没有在代码中更改大小 记住要有一个有效的out来指示累加完成和输出准备就绪。 `时间刻度为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

我想你已经发现了问题,你不能在verilog中进行矩阵乘法。您可以在第51行周围放置一个循环,分别计算temp1的每个元素。但要注意的是,乘数是巨大的,有许多乘数同时存在并不是标准做法。TDM通常用于超频设计,并在多个时钟周期内使用单个乘法器。我不清楚TDM是什么。时分复用,它意味着在不同的操作中使用相同的硬件,通过将您的设计超频四倍,乘法器可以用于四次乘法。我认为余数运算符是可合成的,如果它是2的倍数?*如果它是2的幂