Это пример реализации простого 4-х битного ALU на VHDL: (Сигналы можно посмотреть в тексте программы ниже). Управляющие сигналы: EN - Enable - разрешает использовать ALU без этого сигнала ALU не работает ENX - Enable Output - разрешает вывод результата на шину C (например для комманды CMP это не надо) OPCODE - Operation code - команда для ALU: 000000 NOT B 000001 A AND B 000010 A OR B 000011 A XOR B 000101 A NAND B 000110 A NOR B 000111 A EQV B 001000 A SHL 1 001001 A SHR 1 010010 A RCL 1 010011 A RCR 1 010100 A SAL 1 010101 A SAR 1 100000 -A 100001 A + B 100010 A + B + CF 100100 A - B 100101 A - B - CF Как реализовать команды не требующие результата? ENX OPCODE 1 100100 A - B (SUB) 0 100100 Flg(A - B) (CMP) no result, only flags set 1 000001 A and B (AND) 0 000001 Flg(A and B) (TEST) no result, only flags set
-- -- ALU_N.vhd -- -- Generic ALU implementation -- library ieee; use ieee.std_logic_1164.all; entity alu_N is generic(N: positive); port( A: in std_logic_vector((N-1) downto 0); -- Input Bus 0 B: in std_logic_vector((N-1) downto 0); -- Input Bus 1 C: out std_logic_vector((N-1) downto 0); -- Output Buse CI: in std_logic; -- carry flag in EN: in std_logic; -- Enable ENX: in std_logic; -- Enable Output RST: in std_logic; -- Reset OPCODE: in std_logic_vector (5 downto 0); -- Opcode -- Flags output CFLG: out std_logic; -- Carry flag ZFLG: out std_logic; -- Zero flag SFLG: out std_logic; -- Sign flag OFLG: out std_logic -- Overflow ); end alu_N; architecture Example of alu_N is component add_NC is generic(N: positive); port( A: in std_logic_vector((N-1) downto 0); B: in std_logic_vector((N-1) downto 0); X: out std_logic_vector((N-1) downto 0); C: out std_logic; CI: in std_logic ); end component; signal AA: std_logic_vector((N-1) downto 0); signal BB: std_logic_vector((N-1) downto 0); signal CC: std_logic_vector((N-1) downto 0); signal CCX: std_logic_vector((N-1) downto 0); signal CFXX: std_logic := '0'; signal CFX: std_logic := '0'; signal ZFX: std_logic := '0'; signal SFX: std_logic := '0'; signal OFX: std_logic := '0'; signal CIX: std_logic := '0'; signal use_adder : std_logic := '0'; begin -- Main opcode parsing ------------------------- process(EN,OPCODE,A,B,CI) begin use_adder <= '0'; case OPCODE is when "000000" => -- NOT B CC <= not B; when "000001" => -- AND CC <= A and B; when "000010" => -- OR CC <= A or B; when "000011" => -- XOR CC <= A xor B; when "000101" => -- NAND CC <= A nand B; when "000110" => -- NOR CC <= A nor B; when "000111" => -- EQV CC <= not (A xor B); when "001000" => -- SHL CC <= '0' & A(N-1 downto 1); CFX <= A(0); when "001001" => -- SHR CC <= A(N-2 downto 0) & '0'; CFX <= A(N-1); when "010010" => -- RCL CC <= CI & A(N-1 downto 1); CFX <= A(0); when "010011" => -- RCR CC <= A(N-2 downto 0) & CI; CFX <= A(N-1); when "010100" => -- SAL CC <= '0' & A(N-1 downto 1); CFX <= A(0); when "010101" => -- SAR CC <= A(N-2 downto 0) & A(N-1); CFX <= A(0); when "100000" => -- NEG AA <= not A; BB <= (BB'range => '0'); CIX <= '1'; use_adder <= '1'; when "100001" => -- ADD AA <= A; BB <= B; CIX <= '0'; use_adder <= '1'; when "100010" => -- ADC AA <= A; BB <= B; CIX <= CI; use_adder <= '1'; when "100100" => -- SUB AA <= A; BB <= not B; CIX <= '1'; use_adder <= '1'; when "100101" => -- SBC AA <= A; BB <= not B; CIX <= not CI; use_adder <= '1'; when others => -- Default Zero CC <= (CC'range => '0'); end case; end process; -- Adder mapping ---------------------------------- XADD: add_NC generic map (N => N) port map( A => AA, B => BB, X => CCX, C => CFXX, CI => CIX); -- Output data process -------------------------- process(CCX,CC,CFXX,OPCODE) begin case ENX is when '1' => if (use_adder = '1') then C <= CCX; CFLG <= CFXX; else C <= CC; OFX <= '0'; SFX <= CC(N-1); end if; CFLG <= CFX; ZFLG <= ZFX; OFLG <= OFX; SFLG <= SFX; when others => C <= (C'range => 'Z'); end case; end process; end Example;
Результат синтеза ALU на 4бита.