📄 alu.vhd
字号:
--实验8 ALU
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
LIBRARY LPM;
USE LPM.LPM_COMPONENTS.ALL;
ENTITY ALU IS
GENERIC (width:NATURAL:=7; op_w:NATURAL:=3);
PORT (
a, b : IN std_logic_vector(width DOWNTO 0);
op : IN std_logic_vector(op_w DOWNTO 0);
result : OUT std_logic_vector(width DOWNTO 0);
c : OUT std_logic ;
z : OUT std_logic ;
v : OUT std_logic ;
n : OUT std_logic
);
END ALU;
ARCHITECTURE struct OF ALU IS
CONSTANT ALU_ADD : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0000";
CONSTANT ALU_SUB : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0001";
CONSTANT ALU_ADDU : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0010";
CONSTANT ALU_SUBU : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0011";
CONSTANT ALU_AND : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0100";
CONSTANT ALU_OR : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0101";
CONSTANT ALU_XOR : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0110";
CONSTANT ALU_NOTA : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0111";
CONSTANT ALU_SLL : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1000";
CONSTANT ALU_SRL : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1001";
CONSTANT ALU_SLA : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1010";
CONSTANT ALU_SRA : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1011";
CONSTANT ALU_ROL : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1100";
CONSTANT ALU_ROR : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1101";
CONSTANT ALU_SET : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1110";
CONSTANT ALU_CLR : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1111";
CONSTANT NC8 : STD_LOGIC_VECTOR(width DOWNTO 0):= "--------";
CONSTANT ZR8 : STD_LOGIC_VECTOR(width DOWNTO 0):= "00000000";
COMPONENT lpm_add_sub
GENERIC (
lpm_width : NATURAL;
lpm_direction : STRING;
lpm_type : STRING;
lpm_hint : STRING
);
PORT (
dataa : IN STD_LOGIC_VECTOR (width DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (width DOWNTO 0);
cin : IN STD_LOGIC ;
cout, overflow : OUT STD_LOGIC;
result : OUT STD_LOGIC_VECTOR (width DOWNTO 0)
);
END COMPONENT;
SIGNAL ADDER_out_overflow : STD_LOGIC;
SIGNAL ADDER_out_cout : STD_LOGIC;
SIGNAL ADDER_out_result : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL ADDER_in_dataa : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL ADDER_in_datab : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL ADDER_in_cin : STD_LOGIC;
SIGNAL r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL sll_r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL srl_r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL sla_r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL sra_r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL rol_r : STD_LOGIC_VECTOR(width DOWNTO 0);
SIGNAL ror_r : STD_LOGIC_VECTOR(width DOWNTO 0);
BEGIN
ADDER_in_dataa <= a;
ADDER_in_datab <= NOT b WHEN op=ALU_SUB ELSE
NOT b WHEN op=ALU_SUBU ELSE
b;
ADDER_in_cin <= '1' WHEN op=ALU_SUB ELSE
'1' WHEN op=ALU_SUBU ELSE
'0';
ALU_ADDER : lpm_add_sub
GENERIC MAP (
lpm_width => (width+1),
lpm_direction => "ADD",
lpm_type => "LPM_ADD_SUB",
lpm_hint => "ONE_INPUT_IS_CONSTANT=NO,CIN_USED=YES"
)
PORT MAP (
dataa => ADDER_in_dataa,
datab => ADDER_in_datab,
cin => ADDER_in_cin,
overflow => ADDER_out_overflow,
cout => ADDER_out_cout,
result => ADDER_out_result
);
--SLL
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := a((width-1) DOWNTO 0) & '0';
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := x((width-2) DOWNTO 0) & "00";
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => sll_r <= y;
WHEN '1' => sll_r <= y((width-4) DOWNTO 0) & "0000";
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--SRL
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := '0' & a(width DOWNTO 1);
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := "00" & x(width DOWNTO 2);
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => srl_r <= y;
WHEN '1' => srl_r <= "0000" & y(width DOWNTO 4);
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--SLA
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := a((width-1) DOWNTO 0) & a(0);
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := x((width-2) DOWNTO 0) & x(0) & x(0);
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => sla_r <= y;
WHEN '1' => sla_r <= y((width-4) DOWNTO 0) & y(0) & y(0) & y(0) & y(0);
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--SRA
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := a(width) & a(width DOWNTO 1);
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := x(width) & x(width) & x(width DOWNTO 2);
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => sra_r <= y;
WHEN '1' => sra_r <= y(width) & y(width) & y(width) & y(width) & y(width DOWNTO 4);
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--ROL
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := a((width-1) DOWNTO 0) & a(width);
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := x((width-2) DOWNTO 0) & x(width DOWNTO (width-1));
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => rol_r <= y;
WHEN '1' => rol_r <= y((width-4) DOWNTO 0) & y(width DOWNTO (width-3));
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--ROR
PROCESS (a, b) IS
VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
BEGIN
CASE b(0) IS
WHEN '0' => x := a;
WHEN '1' => x := a(0) & a(width DOWNTO 1);
WHEN OTHERS => NULL;
END CASE;
CASE b(1) IS
WHEN '0' => y := x;
WHEN '1' => y := x(1 DOWNTO 0) & x(width DOWNTO 2);
WHEN OTHERS => NULL;
END CASE;
CASE b(2) IS
WHEN '0' => ror_r <= y;
WHEN '1' => ror_r <= y(3 DOWNTO 0) & y(width DOWNTO 4);
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
RESULT_MUX : PROCESS (a, b, ADDER_out_result, sll_r, srl_r,
sla_r, sra_r, rol_r, ror_r, op) IS
BEGIN
CASE op IS
WHEN ALU_ADD | ALU_SUB | ALU_ADDU | ALU_SUBU =>
r <= ADDER_out_result;
WHEN ALU_AND =>
r <= a AND b;
WHEN ALU_OR =>
r <= a OR b;
WHEN ALU_XOR =>
r <= a XOR b;
WHEN ALU_NOTA =>
r <= NOT a;
WHEN ALU_SLL =>
r <= sll_r;
WHEN ALU_SRL =>
r <= srl_r;
WHEN ALU_SLA =>
r <= sla_r;
WHEN ALU_SRA =>
r <= sra_r;
WHEN ALU_ROL =>
r <= rol_r;
WHEN ALU_ROR =>
r <= ror_r;
WHEN ALU_SET =>
r <= "11111111";
WHEN ALU_CLR =>
r <= "00000000";
WHEN OTHERS =>
r <= NC8;
END CASE;
END PROCESS;
v <= ADDER_out_overflow WHEN op=ALU_ADD ELSE
ADDER_out_overflow WHEN op=ALU_SUB ELSE
'0';
z <= '1' WHEN r=ZR8 ELSE '0';
c <= ADDER_out_cout WHEN op=ALU_ADD ELSE
ADDER_out_cout;
n <= '0' WHEN op=ALU_ADDU ELSE
NOT ADDER_out_cout WHEN op=ALU_SUBU ELSE
r(width);
result <= r;
END struct;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -