使用VHDL的矩阵乘法设计

此项目是[完整的VHDL代码]使用VHDL的矩阵乘法设计。介绍了用于矩阵乘法的VHDL代码。 该VHDL项目在开发和实现可综合的矩阵乘法器内核,该内核能够对32x32大小的矩阵执行矩阵计算。矩阵的每个分量都是16位无符号整数。 该内核在Xilinx FPGA Spartan-6 XC6SLX45-CSG324-3上实现。 行为和路由后验证均已完成。 仿真结果与Matlab实现结果进行了精确比较。想了解更多请下载附件。

应用介绍

此项目是[完整的VHDL代码]使用VHDL的矩阵乘法设计。介绍了用于矩阵乘法的VHDL代码。 该VHDL项目在开发和实现可综合的矩阵乘法器内核,该内核能够对32x32大小的矩阵执行矩阵计算。矩阵的每个分量都是16位无符号整数。 该内核在Xilinx FPGA Spartan-6 XC6SLX45-CSG324-3上实现。 行为和路由后验证均已完成。 仿真结果与Matlab实现结果进行了精确比较。(注意:完成乘法器内核的设计后,我们对内核进行行为仿真。 测试平台正在读取输入A和B,然后生成输出C,然后与Matlab结果进行比较。 如果结果与Matlab相比是100%,则输出文件“OutputMultC.txt”中的数据将为“ true”。 否则,它将是错误的。)

行为模拟波形:

在34816个时钟周期后,对尺寸为32x32的矩阵的矩阵乘法完成,并且信号“ dataready”被置为高电平。 这是合理的,因为要花费32个周期来计算输出矩阵C的每个矩阵分量。还有2个周期,分别为每个矩阵分量保存数据并将数据写入缓冲区C。 因此,有34个时钟周期用于计算矩阵C的一个分量。矩阵C的大小为32x32,则矩阵乘法时间为32x32x34 = 34816个周期。

行为仿真结果与Matlab进行了正确比较。 实际上,输出文件“ OutputMultC.txt”全为“ true”。 我们还检查缓冲区输出的内存内容,其结果当然与Matlab计算类似。

路由后仿真:

为了执行路由后仿真,我们进行合成并获得要翻译的后翻译网表。 综合结果表明,用于该设计的时钟的最大频率为120.757MHz。 这意味着时钟的最小周期为8.281ns。 因此,32x32矩阵的最小乘法时间为34816x8.281ns = 288.311 us。

布线后仿真结果与Matlab结果和行为仿真精确相似。 确实,输出文件“ OutputMultC.txt”符合我们的期望,都是“ true”。

在该项目中,在Xilinx的FPGA Spartan6上实现了具有32x32 16位无符号整数的矩阵的矩阵乘法。 32x32矩阵的最小乘法时间为288.311 us。

本人在下面展示了矩阵乘法器的VHDL顶级代码;如想了解得更多请下载附件。

-- fpga4student.com FPGA projects, Verilog projects, VHDL projects 
 -- VHDL project: VHDL code for matrix multiplcation
 library ieee;   
 use ieee.std_logic_1164.all;   
 use ieee.numeric_std.all;  
 use IEEE.STD_LOGIC_UNSIGNED.ALL;  
 -- Required entity declaration  
 entity IntMatMulCore is  
      port(  
           Reset, Clock,      WriteEnable, BufferSel:      in std_logic;  
           WriteAddress: in std_logic_vector (9 downto 0);  
           WriteData:           in std_logic_vector (15 downto 0);  
           ReadAddress:      in std_logic_vector (9 downto 0);  
           ReadEnable:      in std_logic;  
           ReadData:           out std_logic_vector (63 downto 0);  
           DataReady:           out std_logic  
      );  
 end IntMatMulCore;  
 architecture IntMatMulCore_arch of IntMatMulCore is  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects 
 COMPONENT dpram1024x16  
  PORT (  
   clka : IN STD_LOGIC;  
   wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);  
   addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0);  
   dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);  
   clkb : IN STD_LOGIC;  
       enb : IN STD_LOGIC;  
   addrb : IN STD_LOGIC_VECTOR(9 DOWNTO 0);  
   doutb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)  
  );  
 END COMPONENT;  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects 
 COMPONENT dpram1024x64  
  PORT (  
   clka : IN STD_LOGIC;  
   wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);  
   addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0);  
   dina : IN STD_LOGIC_VECTOR(63 DOWNTO 0);  
   clkb : IN STD_LOGIC;  
   enb : IN STD_LOGIC;  
   addrb : IN STD_LOGIC_VECTOR(9 DOWNTO 0);  
   doutb : OUT STD_LOGIC_VECTOR(63 DOWNTO 0)  
  );  
 END COMPONENT;  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
 type     stateType is (stIdle, stWriteBufferA, stWriteBufferB, stReadBufferAB, stSaveData, stWriteBufferC, stComplete);  
 signal presState: stateType;  
 signal nextState: stateType;  
 signal iReadEnableAB, iCountReset,iCountEnable, iCountEnableAB,iCountResetAB: std_logic;  
 signal iWriteEnableA, iWriteEnableB, iWriteEnableC: std_logic_vector(0 downto 0);  
 signal iReadDataA, iReadDataB: std_logic_vector (15 downto 0);  
 signal iWriteDataC: std_logic_vector (63 downto 0);  
 signal iCount, iReadAddrA, iReadAddrB,iRowA : unsigned(9 downto 0);  
 signal CountAT,CountBT:unsigned(9 downto 0);  
 signal iColB:unsigned(19 downto 0);  
 signal irow,icol,iCountA,iCountB: unsigned(4 downto 0);  
 signal iCountEnableAB_d1,iCountEnableAB_d2,iCountEnableAB_d3: std_logic;  
 begin  
      --Write Enable for RAM A   
      iWriteEnableA(0) <= WriteEnable and BufferSel;  
      --Write Enable for RAM B  
      iWriteEnableB(0) <= WriteEnable and (not BufferSel); 
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects 
      --Input Buffer A Instance  
           InputBufferA : dpram1024x16  
           PORT MAP (  
                clka => Clock,  
                wea  => iWriteEnableA,  
                addra => WriteAddress,  
                dina => WriteData,  
                clkb      => Clock,  
                enb     => iReadEnableAB,  
                addrb => std_logic_vector(iReadAddrA),  
                doutb => iReadDataA  
           );  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
      InputBufferB : dpram1024x16  
           PORT MAP (  
                clka => Clock,  
                wea  => iWriteEnableB,  
                addra => WriteAddress,  
                dina => WriteData,  
                clkb      => Clock,  
                enb     => iReadEnableAB,  
                addrb => std_logic_vector(iReadAddrB),  
                doutb => iReadDataB  
           );  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
      OutputBufferC : dpram1024x64  
           PORT MAP (  
                clka      => Clock,  
                wea      => iWriteEnableC,  
                addra => std_logic_vector(iCount),  
                dina      => iWriteDataC,  
                clkb      => Clock,  
                enb      => ReadEnable,  
                addrb => ReadAddress,  
                doutb => ReadData  
           );  
      process(Clock,Reset)  
      begin  
      if(rising_edge(Clock)) then  
      if(Reset='1') then  
      iCountEnableAB_d1 <= '0';  
      iCountEnableAB_d2 <= '0';  
      else  
      iCountEnableAB_d1 <= iCountEnable;  
      iCountEnableAB_d2 <= iCountEnableAB_d1;  
      end if;  
      end if;  
      end process;  
      iCountEnableAB_d3 <= (not iCountEnableAB_d2) AND iCountEnableAB_d1 ;  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
      process (Clock)  
      begin  
           if rising_edge (Clock) then  
                if(Reset='1') then  
                     iWriteDataC <= (others => '0');  
                elsif(iWriteEnableC(0)='1') then  
                     iWriteDataC <= (others => '0');  
                elsif(iCountEnableAB_d3='1') then  
                     iWriteDataC <= (others => '0');  
                elsif(iReadEnableAB='1') then   
                     iWriteDataC <= iWriteDataC + std_logic_vector(signed(iReadDataA(15)&iReadDataA)*signed(iReadDataB(15)&iReadDataB));       
                end if;   
           end if;   
      end process;  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
       process (Clock)  
      begin  
           if rising_edge (Clock) then  
                if Reset = '1' then  
                     presState <= stIdle;  
                     iCountA <= (others=>'0');  
                     iCountB <= (others=>'0');  
                else  
                     presState <= nextState;  
                     if iCountResetAB = '1' then  
                          iCountA <= (others=>'0');  
                          iCountB <= (others=>'0');  
                     elsif iCountEnableAB = '1' then  
                          iCountA <= iCountA + 1;  
                          iCountB <= iCountB + 1;  
                     end if;  
                end if;  
                if iCountReset = '1' then  
                     iCount <= (others=>'0');  
                elsif iCountEnable = '1' then  
                     iCount <= iCount + 1;  
                end if;  
           end if;  
      end process;  
      iRowA <= iCount srl 5;  
      iColB <= ("0000000000"&iCount) - iRowA*32;  
      irow <= iRowA(4 downto 0);  
      icol <= iColB(4 downto 0);  
      CountAT <= "00000"&iCountA;  
      CountBT <= "00000"&iCountB;  
      iReadAddrA <= (iRowA sll 5)+CountAT;  
      iReadAddrB <= (CountBT sll 5)+ iColB(9 downto 0);  
 -- fpga4student.com FPGA projects, Verilog projects, VHDL projects
      process (presState, WriteEnable, BufferSel, iCount, iCountA, iCountB)  
      begin  
           -- signal defaults  
           iCountResetAB <= '0';  
           iCountReset <= '0';  
           iCountEnable <= '1';  
           iReadEnableAB <= '0';   
           iWriteEnableC(0) <= '0';  
           Dataready <= '0';  
           iCountEnableAB <= '0';  
           case presState is  
                when stIdle =>       
                     if (WriteEnable = '1' and BufferSel = '1') then  
                          nextState <= stWriteBufferA;  
                     else  
                          iCountReset <= '1';  
                          nextState <= stIdle;  
                     end if;  
                when stWriteBufferA =>  
                     if iCount = x"3FF" then  
                          report "Writing A";  
                          iCountReset <= '1';                      
                          nextState <= stWriteBufferB;  
                      else  
                          nextState <= stWriteBufferA;  
                     end if;  
                when stWriteBufferB =>  
                     report "Writing B";  
                     if iCount = x"3FF" then  
                          iCountReset <= '1';                      
                          nextState <= stReadBufferAB;  
                      else  
                          nextState <= stWriteBufferB;  
                     end if;  
                when stReadBufferAB =>  
                     iReadEnableAB <= '1';  
                     iCountEnable <= '0';  
                     report "CalculatingAB";  
                     if iCountA = x"1F" and iCountB = x"1F" then  
                          nextState <= stSaveData;  
                          report "Calculating";  
                          iCountEnableAB <= '0';  
                          iCountResetAB <= '1';  
                     else  
                          nextState <= stReadBufferAB;  
                          iCountEnableAB <= '1';  
                          iCountResetAB <= '0';  
                     end if;  
                when stSaveData =>   
                     iReadEnableAB <= '1';  
                     iCountEnable <= '0';  
                     nextState <= stWriteBufferC;  
                when stWriteBufferC =>  
                     iWriteEnableC(0) <= '1';  
                     report "finish 1 component";  
                     if iCount = x"3FF" then  
                          iCountReset <= '1';                           
                          nextState <= stComplete;  
                      else  
                          nextState <= stReadBufferAB;  
                     end if;                 
                when stComplete =>  
                     DataReady <= '1';  
                     nextState <= stIdle;                      
           end case;  
      end process;  
 end IntMatMulCore_arch;

文件列表(部分)

名称 大小 修改日期
使用VHDL的矩阵乘法设计.txt2.84 KB2020-03-30
MUlt1.jpg29.77 KB2020-03-30
MUlt2.jpg7.22 KB2020-03-30
MUlt3.jpg22.18 KB2020-03-30
MUlt4.jpg32.08 KB2020-03-30
image0.00 KB2020-03-30

立即下载

相关下载

[使用VHDL的矩阵乘法设计] 此项目是[完整的VHDL代码]使用VHDL的矩阵乘法设计。介绍了用于矩阵乘法的VHDL代码。 该VHDL项目在开发和实现可综合的矩阵乘法器内核,该内核能够对32x32大小的矩阵执行矩阵计算。矩阵的每个分量都是16位无符号整数。 该内核在Xilinx FPGA Spartan-6 XC6SLX45-CSG324-3上实现。 行为和路由后验证均已完成。 仿真结果与Matlab实现结果进行了精确比较。想了解更多请下载附件。

评论列表 共有 0 条评论

暂无评论

微信捐赠

微信扫一扫体验

立即
上传
发表
评论
返回
顶部