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