Matrix 乘法矩阵和存储sram或sdram

Matrix 乘法矩阵和存储sram或sdram,matrix,verilog,multiplication,Matrix,Verilog,Multiplication,我正在开始一个项目,在那里我乘矩阵并在FPGA/DE2中合成它。 在我开始的时候,我想知道如何操作并在内存中存储这个值。 我想做的是[C]=[A]*[B]。 注:数值​​[A]、[B]和[C]中的任何一个自动存储在SRAM或SDRAM中? 当我读到这个问题时:变得更清楚如何操作,但我看不到如何管理它以输入内存。 有谁有一些代码可以让我适应读写记忆? 我走这条路对吗 编辑: 我有这个矩阵4x4乘法的代码。你能告诉我这个密码是否正确吗?我尝试运行,但C值没有保存到内存中 module rams( i

我正在开始一个项目,在那里我乘矩阵并在FPGA/DE2中合成它。 在我开始的时候,我想知道如何操作并在内存中存储这个值。 我想做的是[C]=[A]*[B]。 注:数值​​[A]、[B]和[C]中的任何一个自动存储在SRAM或SDRAM中? 当我读到这个问题时:变得更清楚如何操作,但我看不到如何管理它以输入内存。 有谁有一些代码可以让我适应读写记忆? 我走这条路对吗

编辑:

我有这个矩阵4x4乘法的代码。你能告诉我这个密码是否正确吗?我尝试运行,但C值没有保存到内存中

module rams(
input clk,
  //  SRAM Interface
  inout  [15:0] SRAM_DQ,   // SRAM Data bus 16 Bits
  output [17:0] SRAM_ADDR, // SRAM Address bus 18 Bits
  output SRAM_UB_N,        // SRAM High-byte Data Mask
  output SRAM_LB_N,        // SRAM Low-byte Data Mask 
  output SRAM_WE_N,    // SRAM Write Enable
  output SRAM_CE_N,        // SRAM Chip Enable
  output SRAM_OE_N        // SRAM Output Enable
);

parameter mat_size = 4;  // change the size of the matrices here.
reg [7:0] A_mat [0:mat_size*mat_size-1];
reg [7:0] B_mat [0:mat_size*mat_size-1];


wire [15:0] mem_in;
reg [17:0] mem_address;

wire [7:0] A,B;
wire [7:0] C;
wire [19:0] A_addr,B_addr,C_addr;
reg reset;
wire start;
reg [9:0] Cr,Cc;

assign SRAM_ADDR = mem_address;
assign SRAM_UB_N = 1'b0;        // SRAM High-byte Data Mask
assign SRAM_LB_N = 1'b0;        // SRAM Low-byte Data Mask 
assign SRAM_CE_N = 1'b0;        // SRAM Chip Enable
assign SRAM_OE_N = 1'b0;        // SRAM Output Enable

reg [2:0] state;
parameter idle=0, read_A=1, read_B=2, start_process=3,do_nothing = 4;;

assign SRAM_WE_N = (valid_output ? 1'b0 : 1'b1);
assign start = !(valid_output | reset);//(valid_output ? 1'b0 : 1'b1);
assign SRAM_DQ = (valid_output ? mem_in : 16'hzzzz);

    // Instantiate the Unit Under Test (UUT)
    mat_mult uut (
        .clk(clk), 
        .reset(reset), 
        .start(start),
        .A_addr(A_addr), 
        .B_addr(B_addr), 
        .C_addr(C_addr), 
        .A(A), 
        .B(B), 
        .mat_size(mat_size), 
        .C(C), 
        .valid_output(valid_output)
    );

assign mem_in = {4'h00,C};

initial begin
    state = idle;
end     

always @(posedge clk)
begin
    case (state)
        idle :
            begin
                mem_address <= 16'h0000;
                state = read_A;
                reset <= 1'b1;
            end
        read_A :    
            begin
                A_mat[mem_address] <= SRAM_DQ;
                if(mem_address < mat_size*mat_size) begin
                    state = read_A;
                    mem_address <= mem_address + 1;
                end else begin
                    state = read_B;
                end 
            end
        read_B :    
            begin
                B_mat[mem_address-(mat_size*mat_size)] <= SRAM_DQ;
                if(mem_address < 2*mat_size*mat_size) begin
                    state = read_B;
                    mem_address <= mem_address + 1;
                end else begin
                    state = start_process;
                    reset <= 1'b0;
                end 
            end 
        start_process : 
            begin
                state = start_process;
                mem_address <= 2*mat_size*mat_size + C_addr;
                if(C_addr == mat_size*mat_size-1) begin 
                    state = do_nothing;
                end else begin
                    reset <= 1'b0;
                end
            end     
        do_nothing : 
            if(valid_output) begin
                reset <= 1'b1;
            end 
    endcase

end

assign A = A_mat[A_addr];
assign B = B_mat[B_addr];

endmodule
模块rams(
输入时钟,
//SRAM接口
inout[15:0]SRAM_DQ,//SRAM数据总线16位
输出[17:0]SRAM_ADDR,//SRAM地址总线18位
输出SRAM_UB_N,//SRAM高字节数据掩码
输出SRAM_LB_N,//SRAM低字节数据掩码
输出SRAM\u WE\N,//SRAM写入启用
输出SRAM\u CE\N,//SRAM芯片启用
输出SRAM\u OE\u N//SRAM输出启用
);
参数mat_size=4;//在此处更改矩阵的大小。
reg[7:0]A_mat[0:mat_size*mat_size-1];
reg[7:0]B_mat[0:mat_size*mat_size-1];
导线[15:0]内存输入;
注册[17:0]成员地址;
导线[7:0]A,B;
导线[7:0]C;
连线[19:0]A_addr,B_addr,C_addr;
reg复位;
导线起动;
reg[9:0]Cr,Cc;
分配SRAM\u ADDR=mem\u地址;
分配SRAM_UB_N=1'b0;//SRAM高字节数据掩码
分配SRAM_LB_N=1'b0;//SRAM低字节数据掩码
分配SRAM\u CE\u N=1'b0;//SRAM芯片使能
分配SRAM_OE_N=1'b0;//SRAM输出使能
reg[2:0]状态;
参数idle=0,read_A=1,read_B=2,start_process=3,do_nothing=4;;
分配SRAM\u WE\u N=(有效的\u输出?1'b0:1'b1);
分配开始=!(有效|u输出|复位)//(有效_输出?1'b0:1'b1);
分配SRAM_DQ=(有效输出?内存输入:16'hzzzz);
//实例化被测单元(UUT)
mat_mult uut(
.clk(clk),
.重置(重置),
.开始(开始),
.A_addr(A_addr),
.B_addr(B_addr),
.C_addr(C_addr),
.A(A),
.B(B),
.材料尺寸(材料尺寸),
.C(C),
.valid\u输出(valid\u输出)
);
分配mem_in={4'h00,C};
初始开始
状态=空闲;
结束
始终@(posedge clk)
开始
案件(州)
闲置:
开始

mem_address使用内存时,请记住它只是地址和字节之间的映射。因此,如果你想到一个矩阵(为了简单起见,我假设32位浮点数为4x4),那么你真正拥有的只是16个浮点32位数字

如果您打算将它们存储在片上内存(集成到FPGA芯片中的SRAM单元)或片外内存中,存储在内存中的方式将有所不同

将它们存储在芯片上更容易操作,在本例中,在verilog中,您只需声明一个数组,然后一次读取和写入一个元素。您的合成器将推断这是一个RAM,前提是您的FPGA具有合适大小的可用RAM单元

module matrixmem;

input clk;
input [3:0] addr;
input [31:0] data_in;
output [31:0] data_out;
input write;
input read;

reg [31:0] mem [0:15]; //16 32-bit elements, enough to store one 4x4 array.

always @(posedge clk) begin
   if(write)
       mem[addr] <= data_in;
   else if (read)
       data_out <= mem[addr];
end
模块矩阵em;
输入时钟;
输入[3:0]地址;
输入[31:0]数据;
输出[31:0]数据输出;
输入写入;
输入读取;
注册[31:0]成员[0:15]//16个32位元素,足以存储一个4x4阵列。
始终@(posedge clk)开始
如果(写入)

mem[addr]您必须始终记住的另一个预防措施是,在声明always块时,如果输出端口是顺序块,则建议将其声明为reg类型


对于这里的解决方案,如果我们想使用data_out来存储值,我们需要将其声明为reg type。否则就好了。

非常感谢您!
module matrixmem;

input clk;
input [3:0] addr;
input [31:0] data_in;
output [31:0] data_out;
input write;
input read;

reg [31:0] mem [0:15]; //16 32-bit elements, enough to store one 4x4 array.

always @(posedge clk) begin
   if(write)
       mem[addr] <= data_in;
   else if (read)
       data_out <= mem[addr];
end