📄 alu.vhd
字号:
--算逻运算单元:实现的功能有+、-、+1、-1、与、或、非、异或、六种移位运算以及算术比较运算。其
--中定义了临时变量c_tmp,z_tmp,z1_tmp分别用来表示C,Z符号位,最后赋值输出。
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity alu is
port(
reset,clk : in std_logic; --时钟信号,复位信号
OP: in std_logic_vector(3 downto 0);--操作码
sel: in std_logic;--寄存器选择
write: in std_logic;--写入寄存器
C,Z: out std_logic;--标志位
dinput: in std_logic_vector(15 downto 0);--运算器的输入
result: out std_logic_vector(15 downto 0)--运算器的输出
);
end alu;
architecture behav of alu is
signal c_tmp :std_logic;
signal z_tmp :std_logic; --记录其它运算的临时信号
signal z1_tmp :std_logic; --用于比较时的临时信号
signal A,B :std_logic_vector(15 downto 0);--定义运算器中的两个临时寄存器分别用来存放左右操作数
signal result_t: std_logic_vector(16 downto 0);--中间结果
begin
alu_proc:process(OP,dinput,reset,clk,sel,write)
begin
if reset='0' then --复位时,结果清零
result_t<="00000000000000000";
elsif (clk'event and clk='1') then
if write='1' then
if sel='0' then
A<=dinput; --时钟上升沿打入第一个寄存器
elsif sel='1' then--打入第二个寄存器
B<=dinput;
end if;
elsif write='0' then --当写信号为低电平时则进行运算
case OP is --十六种操作
when "0000" =>
result_t <= ('0' & A) + ('0' & B); --加
when "0001" =>
result_t <= ('0' & A) + '1'; --+1
when "0010" =>
result_t <= ('0' & A) - ('0' & B); --减
when "0011" =>
result_t <= ('0' & A) - '1'; ---1
when "0100" =>
result_t <= ('0' & A) and ('0' & B);--与运算
when "0101" =>
result_t <= ('0' & A) or ('0' & B); --或运算
when "0110" =>
result_t <= not ('0' & B); --非运算
when "0111" =>
result_t <= ('0' & A) xor('0' & B );--异或运算
when "1000" =>
result_t <= A(15 downto 0) & A(0); --算术左移一位
when "1001" =>
result_t <= A(15 downto 0) & '0'; --逻辑左移一位
when "1010" =>
result_t <= A(15 downto 0) & A(15); --循环左移一位
when "1011" =>
result_t <='0'&B; --输出左操作数
when "1100" =>
result_t <= "00" & A(15 downto 1); --逻辑右移一位
c_tmp <= A(0);
when "1101" =>
result_t <= '0' & A(0) & A(15 downto 1);--循环右移一位
c_tmp <= A(0);
when "1110" =>
result_t <= '0' & A(15)& A(15 downto 1);
c_tmp <= A(0); --算术右移一位
when "1111" =>
result_t <= ('0' & A) - ('0' & B);
if (result_t(16)= '1') then --通过最高位是否溢出来判断符号位
c_tmp<='1'; z1_tmp<='0';
elsif (result_t = "00000000000000000") then
c_tmp<='0'; z1_tmp<='1';
else
c_tmp<='0'; z1_tmp<='0';
end if; --比较运算
when others =>
result_t <="XXXXXXXXXXXXXXXXX";
end case;
end if;
end if;
end process;
result <= result_t(15 downto 0);
z_tmp <= (not result_t(15)) and (not result_t(14)) and
(not result_t(13)) and (not result_t(12)) and
(not result_t(11)) and (not result_t(10)) and
(not result_t(9)) and (not result_t(8)) and
(not result_t(7)) and (not result_t(6)) and
(not result_t(5)) and (not result_t(4)) and
(not result_t(3)) and (not result_t(2)) and
(not result_t(1)) and (not result_t(0)); --结果是否为全零
c_proc: Process(reset,clk,result_t,OP)
begin
if reset = '0' then
C <= '0';
elsif clk'event and clk = '1' then
if (op(3 downto 2)/="11" and op(3 downto 0)/="1011") then --移位和传送操作不影响C标志位
C <= result_t(16);
else
C <= c_tmp;
end if;
end if;
end process;
z_proc: process(reset,clk,z_tmp,OP)
begin
if reset = '0' then
Z <= '0';
elsif clk'event and clk = '1' then
if(OP (3 downto 0)/="1011")then
if(OP (3 downto 2)/="11" )then --移位和传送操作不影响Z标志位
Z <= z_tmp;
else
Z <= z1_tmp;
end if;
end if;
end if;
end process;
end behav;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -