URL
https://opencores.org/ocsvn/RISCMCU/RISCMCU/trunk
Subversion Repositories RISCMCU
[/] [RISCMCU/] [trunk/] [vhdl/] [v_alu.vhd] - Rev 8
Go to most recent revision | Compare with Previous | Blame | View Log
---------------------------------------------------------------------------- ---- ---- ---- WISHBONE RISCMCU IP Core ---- ---- ---- ---- This file is part of the RISCMCU project ---- ---- http://www.opencores.org/projects/riscmcu/ ---- ---- ---- ---- Description ---- ---- Implementation of a RISC Microcontroller based on Atmel AVR ---- ---- AT90S1200 instruction set and features with Altera Flex10k20 FPGA. ---- ---- ---- ---- Author(s): ---- ---- - Yap Zi He, yapzihe@hotmail.com ---- ---- ---- ---------------------------------------------------------------------------- ---- ---- ---- Copyright (C) 2001 Authors and OPENCORES.ORG ---- ---- ---- ---- This source file may be used and distributed without ---- ---- restriction provided that this copyright statement is not ---- ---- removed from the file and that any derivative work contains ---- ---- the original copyright notice and the associated disclaimer. ---- ---- ---- ---- This source file is free software; you can redistribute it ---- ---- and/or modify it under the terms of the GNU Lesser General ---- ---- Public License as published by the Free Software Foundation; ---- ---- either version 2.1 of the License, or (at your option) any ---- ---- later version. ---- ---- ---- ---- This source is distributed in the hope that it will be ---- ---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- ---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- ---- PURPOSE. See the GNU Lesser General Public License for more ---- ---- details. ---- ---- ---- ---- You should have received a copy of the GNU Lesser General ---- ---- Public License along with this source; if not, download it ---- ---- from http://www.opencores.org/lgpl.shtml ---- ---- ---- ---------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.all; entity v_alu is port( reg_rd, reg_rr, imm_value : in std_logic_vector(7 downto 0); c2a, c2b : in std_logic; asel : in integer range 0 to 1; bsel : in integer range 0 to 3; bitsel : in integer range 0 to 7; set : in std_logic; c_flag, t_flag : in std_logic; add, subcp, logic, right, dir, bld, cbisbi, pass_a : in std_logic; cpse, skiptest : in std_logic; wcarry : in std_logic; logicsel : in integer range 0 to 3; rightsel : in integer range 0 to 2; dirsel : in integer range 0 to 1; clk, clrn : in std_logic; c : buffer std_logic_vector(7 downto 0); tosr : buffer std_logic_vector (6 downto 0); skip : out std_logic ); end v_alu; architecture alu of v_alu is signal a, b : std_logic_vector(7 downto 0); signal sr : std_logic_vector(6 downto 0); signal cin, overflow, cout : std_logic; signal sum, logic_out, right_out, dir_out, bldcbi_out : std_logic_vector(7 downto 0); begin -- Operand Fetch Unit -- process(clrn, clk) begin if clrn = '0' then a <= "00000000"; b <= "00000000"; elsif clk'event and clk = '1' then case asel is when 0 => if c2a = '1' then a <= c; else a <= reg_rd; end if; when 1 => a <= "00000000"; end case; case bsel is when 0 => if c2b = '1' then b <= c; else b <= reg_rr; end if; when 1 => b <= reg_rd; when 2 => b <= imm_value; when 3 => b <= "00000001"; end case; end if; end process; -- Execution Unit -- cin <= c_flag when add = '1' and wcarry = '1' else '0' when add = '1' and wcarry = '0' else not c_flag when wcarry = '1' else '1'; -- Adder-Subtracter adder1 : lpm_add_sub generic map(lpm_width => 8) port map (dataa => a, datab => b, cin => cin, add_sub => add, result => sum, cout => cout, overflow => overflow); -- Logic Unit with logicsel select logic_out <= a and b when 0, -- and, andi a or b when 1, -- or, ori a xor b when 2, -- eor not a when 3; -- com -- Shifter right_out(6 downto 0) <= a(7 downto 1); with rightsel select right_out(7) <= '0' when 0, -- lsr c_flag when 1, -- ror a(7) when 2; -- asr -- Direct Unit with dirsel select dir_out <= b when 0, -- ldi, mov (a(3 downto 0) & a(7 downto 4)) when 1; -- swap -- Bit Loader process(bld, bitsel, a, t_flag, set) begin for i in 0 to 7 loop if i /= bitsel then bldcbi_out(i) <= a(i); elsif bld = '1' then bldcbi_out(i) <= t_flag; else bldcbi_out(i) <= set; end if; end loop; end process; -- Results to Data Bus process(add, subcp, logic, right, dir, bld, cbisbi, pass_a, sum, logic_out, right_out, dir_out, bldcbi_out, a) begin c <= "ZZZZZZZZ"; -- add, adc, inc, sub, sbc, subi, sbci, cp, cpc, cpi, dec, neg if add = '1' or subcp = '1' then c <= sum; end if; -- and, andi, or, ori, eor, com if logic = '1' then c <= logic_out; end if; -- lsr, lsr, asr if right = '1' then c <= right_out; end if; -- ldi, mov, swap if dir = '1' then c <= dir_out; end if; -- bld, cbisbi if bld = '1' or cbisbi = '1' then c <= bldcbi_out; end if; -- out, st z, st z+, st -z if pass_a = '1' then c <= a; end if; end process; -- Skip Evaluation Unit -- process(cpse, skiptest, a, b, set, bitsel, c) begin skip <= '0'; -- cpse if cpse = '1' then if a = b then skip <= '1'; end if; -- sbrc, sbrs elsif skiptest = '1' then if (set = '1' and a(bitsel) = '1') or (set = '0' and a(bitsel) = '0') then skip <= '1'; end if; end if; end process; -- Flags Evaluation Unit -- process(add, subcp, cout, right, a, logic, a, b, sum, logic_out, right_out, c, overflow, sr, bitsel) begin -- C sr(0) if add = '1' then sr(0) <= cout; elsif right = '1' then sr(0) <= a(0); elsif logic = '1' then -- com sr(0) <= '1'; else -- subcp sr(0) <= not cout; --sr(0) <= (not a(7) and b(7)) or (b(7) and c(7)) or (c(7) and not a(7)); end if; -- Z sr(1) if (add = '1' or subcp = '1') and sum = "00000000" then sr(1) <= '1'; elsif logic = '1' and logic_out = "00000000" then sr(1) <= '1'; elsif right = '1' and right_out = "00000000" then sr(1) <= '1'; else sr(1) <= '0'; end if; -- N sr(2) if (add = '1' or subcp = '1') and sum(7) = '1' then sr(2) <= '1'; elsif logic = '1' and logic_out(7) = '1' then sr(2) <= '1'; elsif right = '1' and right_out(7) = '1' then sr(2) <= '1'; else sr(2) <= '0'; end if; -- V sr(3) if right = '1' then sr(3) <= right_out(7) xor a(0); elsif logic = '1' then sr(3) <= '0'; else sr(3) <= overflow; end if; -- S sr(4) sr(4) <= sr(2) xor sr(3); -- H sr(5) if add = '1' then sr(5) <= (a(3) and b(3)) or (b(3) and not sum(3)) or (not sum(3) and a(3)); else -- subcp sr(5) <= (not a(3) and b(3)) or (b(3) and sum(3)) or (sum(3) and not a(3)); end if; -- T sr(6) sr(6) <= a(bitsel); end process; tosr <= sr; end alu;
Go to most recent revision | Compare with Previous | Blame | View Log