使用VHDL的矩阵乘法设计
应用介绍
此项目是[完整的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;
©版权声明:本文内容由互联网用户自发贡献,版权归原创作者所有,本站不拥有所有权,也不承担相关法律责任。如果您发现本站中有涉嫌抄袭的内容,欢迎发送邮件至: www_apollocode_net@163.com 进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
转载请注明出处: apollocode » 使用VHDL的矩阵乘法设计
文件列表(部分)
名称 | 大小 | 修改日期 |
---|---|---|
使用VHDL的矩阵乘法设计.txt | 2.84 KB | 2020-03-30 |
MUlt1.jpg | 29.77 KB | 2020-03-30 |
MUlt2.jpg | 7.22 KB | 2020-03-30 |
MUlt3.jpg | 22.18 KB | 2020-03-30 |
MUlt4.jpg | 32.08 KB | 2020-03-30 |
image | 0.00 KB | 2020-03-30 |
发表评论 取消回复