📄 mult8_rtl.vhd
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY mult8_rtl IS
GENERIC(datawidth:INTEGER:=8); --乘数的数据宽度
PORT (
clk : IN STD_LOGIC; --时钟
A : IN STD_LOGIC_VECTOR (datawidth-1 DOWNTO 0); --第一个乘数
B : IN STD_LOGIC_VECTOR (datawidth-1 DOWNTO 0); --第二个乘数
P : OUT STD_LOGIC_VECTOR (datawidth*2-1 DOWNTO 0); --乘法器的结果
start : IN STD_LOGIC; --计算开始信号
finished : BUFFER STD_LOGIC --计算结束信号
);
END mult8_rtl;
ARCHITECTURE rtl OF mult8_rtl IS
SIGNAL A_sig :STD_LOGIC_VECTOR (datawidth-1 DOWNTO 0); --A移位寄存器中的数据
SIGNAL count :INTEGER RANGE 0 TO datawidth+1 :=0; --主节拍计数器
SIGNAL count2 :INTEGER RANGE 0 TO 2 :=0; --副节拍计数器
COMPONENT addern8 --引用加法器
GENERIC(datawidth:INTEGER:=8);
PORT(
cin : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(datawidth-1 downto 0);
b : IN STD_LOGIC_VECTOR(datawidth-1 downto 0);
sum :OUT STD_LOGIC_VECTOR(datawidth-1 downto 0);
cout :OUT STD_LOGIC
);
END COMPONENT;
--加法器加数输入a
SIGNAL adder_a :STD_LOGIC_VECTOR(datawidth-1 downto 0);
--加法器加数输入b
SIGNAL adder_b :Std_Logic_Vector(datawidth-1 downto 0);
--加法器和输出sum
SIGNAL adder_sum :STD_LOGIC_VECTOR(datawidth-1 downto 0);
--加法器进位输入
SIGNAL adder_cin :STD_LOGIC;
--加法器进位输出
SIGNAL adder_cout :STD_LOGIC;
--一个datawidth宽的全零信号
SIGNAL zero :STD_LOGIC_VECTOR(datawidth-1 downto 0);
--保持乘法结果的移位寄存器
SIGNAL P_sig :STD_LOGIC_VECTOR (datawidth*2-1 DOWNTO 0);
BEGIN
c1: addern8
PORT MAP(
cin=>adder_cin,
a=>adder_a,
b=>adder_b,
sum=>adder_sum,
cout=>adder_cout
);
--主进程。负责乘法结果的移位和从加法器的和中取数据
PROCESS(clk)
BEGIN
IF(clk'event and clk='0') THEN
IF(count=0 and count2=0) THEN
--起始状态清零
P_sig(datawidth-1 downto 0)<=zero;
P_sig(datawidth*2-1 downto datawidth)<=zero;
ELSIF(A_sig(0)='1' and count2=0) THEN
--做加法运算
ELSIF(A_sig(0)='1' and count2=1) THEN
--取和的结果
P_sig(datawidth*2-1 downto datawidth)<=adder_sum;
ELSIF(count2=2 and count/=count'high) THEN
--乘法结果移位
P_sig(datawidth*2-2 downto 0)<=P_sig(datawidth*2-1 downto 1);
P_sig(datawidth*2-1)<=adder_cout;
END IF;
END IF;
END PROCESS;
--该进程控制加法器的输入
PROCESS(clk)
BEGIN
IF(clk'event and clk='0') THEN
IF(A_sig(0)='1') THEN
--相加
adder_a<=P_sig(datawidth*2-1 downto datawidth);
adder_b<=B;
adder_cin<='0';
ELSE
adder_a<=zero;
adder_b<=zero;
adder_cin<='0';
END IF;
END IF;
END PROCESS;
--该进程控制主节拍计数器和副节怕计数器
PROCESS(clk)
BEGIN
IF(Start='1') and finished='1' THEN
--在乘法器空闲并时来了开始信号
--则节怕计数器复位,开始计算乘法,同时输出乘法器计算未完成信号
count<=0;
count2<=0;
finished<='0';
ELSIF(clk'event and clk='1') THEN
IF(count=count'high and count2=count2'high) THEN
--计算完成,节拍计数器停止
count<=count;
count2<=count2;
--输出指示乘法器空闲
finished<='1';
ELSIF(count2=count2'high) THEN
--副节怕计数器复位
count2<=0;
count<=count+1;
finished<='0';
ELSE
count2<=count2+1;
finished<='0';
END IF;
END IF;
END PROCESS;
--控制乘数A寄存器
PROCESS(clk)
BEGIN
IF(clk'event and clk='0') THEN
IF count=0 THEN
--初始化移位寄存器
A_sig<=A;
ELSIF(count2=2) THEN
--移位
A_sig(datawidth-2 downto 0)<=A_sig(datawidth-1 downto 1);
A_sig(datawidth-1)<='0';
ELSE
--其他情况保持
A_sig<=A_sig;
END IF;
ELSE
A_sig<=A_sig;
END IF;
END PROCESS;
--乘法器积输出进程
PROCESS(finished)
BEGIN
IF finished='1' THEN
p<=p_sig;
END IF;
END PROCESS;
--zero:一个datawidth宽的全零信号
g1:FOR i IN 0 TO datawidth-1 GENERATE
zero(i)<='0';
END GENERATE;
END RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -