?? 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 + -