verilog中的矩阵重构和乘法

时间:2014-11-27 02:52:20

标签: matrix multidimensional-array verilog matrix-multiplication

我试图在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 [&#34; C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v" ;:51]

[VRFC 10-845]运营商的非法操作数* [&#34; C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v" ;:51]

[VRFC 10-395]无法将解压缩类型分配给打包类型[&#34; C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v" ;:51] < / p>

[VRFC 10-1523]解压缩的值/目标不能用于作业[&#34; C:/Users/tomdi_000/capstone/capstone.srcs/sources_1/new/Nueron.v":51] < / p>

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

1 个答案:

答案 0 :(得分:0)

你可以在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