📄 6805.vhd
字号:
-----------------------------------------------------------------------------------
-- 68HC05 microcontroller implementation
-- Ulrich Riedel
-- v1.0 2006.01.21 first version
-----------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity fadd is -- full adder stage, interface
port(a : in std_logic;
b : in std_logic;
cin : in std_logic;
s : out std_logic;
cout : out std_logic);
end entity fadd;
architecture behavior of fadd is -- full adder stage, body
begin -- circuits of fadd
s <= a xor b xor cin after 1 ns;
cout <= (a and b) or (a and cin) or (b and cin) after 1 ns;
end architecture behavior; -- fadd
-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity add8 is -- simple 8 bit ripple carry adder
port(a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
cin : in std_logic;
sum : out std_logic_vector(7 downto 0);
cout : out std_logic);
end entity add8;
architecture behavior of add8 is
signal c : std_logic_vector(0 to 6); -- internal carry signals
component fadd -- duplicates entity port
port(a : in std_logic;
b : in std_logic;
cin : in std_logic;
s : out std_logic;
cout : out std_logic);
end component fadd ;
begin
a0: fadd port map(a(0), b(0), cin, sum(0), c(0));
stage: for I in 1 to 6 generate
as: fadd port map(a(I), b(I), c(I-1) , sum(I), c(I));
end generate stage;
a31: fadd port map(a(7), b(7), c(6) , sum(7), cout);
end architecture behavior; -- add8
-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity add8c is -- one stage of carry save adder for multiplier
port(
b : in std_logic; -- a multiplier bit
a : in std_logic_vector(7 downto 0); -- multiplicand
sum_in : in std_logic_vector(7 downto 0); -- sums from previous stage
cin : in std_logic_vector(7 downto 0); -- carrys from previous stage
sum_out : out std_logic_vector(7 downto 0); -- sums to next stage
cout : out std_logic_vector(7 downto 0)); -- carrys to next stage
end add8c;
architecture behavior of add8c is
signal zero : std_logic_vector(7 downto 0) := x"00";
signal aa : std_logic_vector(7 downto 0) := x"00";
component fadd
port(a : in std_logic;
b : in std_logic;
cin : in std_logic;
s : out std_logic;
cout : out std_logic);
end component fadd;
begin
aa <= a when b = '1' else zero after 1 ns;
stage: for I in 0 to 7 generate
sta: fadd port map(aa(I), sum_in(I), cin(I) , sum_out(I), cout(I));
end generate stage;
end architecture behavior; -- add8csa
-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity mul8 is -- 8 x 8 = 16 bit unsigned product multiplier
port(a : in std_logic_vector(7 downto 0); -- multiplicand
b : in std_logic_vector(7 downto 0); -- multiplier
prod : out std_logic_vector(15 downto 0)); -- product
end mul8;
architecture behavior of mul8 is
signal zero : std_logic_vector(7 downto 0) := x"00";
signal nc1 : std_logic;
type arr8 is array(0 to 7) of std_logic_vector(7 downto 0);
signal s : arr8; -- partial sums
signal c : arr8; -- partial carries
signal ss : arr8; -- shifted sums
component add8c is
port(b : in std_logic;
a : in std_logic_vector(7 downto 0);
sum_in : in std_logic_vector(7 downto 0);
cin : in std_logic_vector(7 downto 0);
sum_out : out std_logic_vector(7 downto 0);
cout : out std_logic_vector(7 downto 0));
end component add8c;
component add8
port(a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
cin : in std_logic;
sum : out std_logic_vector(7 downto 0);
cout : out std_logic);
end component add8;
begin
st0: add8c port map(b(0), a, zero , zero, s(0), c(0)); -- CSA stage
ss(0) <= '0' & s(0)(7 downto 1) after 1 ns;
prod(0) <= s(0)(0) after 1 ns;
stage: for I in 1 to 7 generate
st: add8c port map(b(I), a, ss(I-1) , c(I-1), s(I), c(I)); -- CSA stage
ss(I) <= '0' & s(I)(7 downto 1) after 1 ns;
prod(I) <= s(I)(0) after 1 ns;
end generate stage;
add: add8 port map(ss(7), c(7), '0' , prod(15 downto 8), nc1); -- adder
end architecture behavior; -- mul8
-------------------------------------------------------------------------
-- begin of 6805
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;
ENTITY UR6805 IS
PORT(
clk : in std_logic;
rst : in std_logic;
irq : in std_logic;
addr : out std_logic_vector(15 downto 0);
wr : out std_logic;
datain : in std_logic_vector(7 downto 0);
state : out std_logic_vector(3 downto 0);
dataout : out std_logic_vector(7 downto 0)
);
END UR6805;
ARCHITECTURE behavior OF UR6805 IS
component mul8 port(
a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
prod : out std_logic_vector(15 downto 0)
);
end component mul8;
constant CPUread : std_logic := '1';
constant CPUwrite : std_logic := '0';
constant addrPC : std_logic_vector(2 downto 0) := "000";
constant addrSP : std_logic_vector(2 downto 0) := "001";
constant addrHX : std_logic_vector(2 downto 0) := "010";
constant addrTM : std_logic_vector(2 downto 0) := "011";
constant addrX2 : std_logic_vector(2 downto 0) := "100";
constant addrS2 : std_logic_vector(2 downto 0) := "101";
constant addrX1 : std_logic_vector(2 downto 0) := "110";
constant addrS1 : std_logic_vector(2 downto 0) := "111";
constant outA : std_logic_vector(3 downto 0) := "0000";
constant outH : std_logic_vector(3 downto 0) := "0001";
constant outX : std_logic_vector(3 downto 0) := "0010";
constant outSPL : std_logic_vector(3 downto 0) := "0011";
constant outSPH : std_logic_vector(3 downto 0) := "0100";
constant outPCL : std_logic_vector(3 downto 0) := "0101";
constant outPCH : std_logic_vector(3 downto 0) := "0110";
constant outTL : std_logic_vector(3 downto 0) := "0111";
constant outTH : std_logic_vector(3 downto 0) := "1000";
constant outHelp : std_logic_vector(3 downto 0) := "1001";
constant outCode : std_logic_vector(3 downto 0) := "1010";
type masker is array (0 to 7) of std_logic_vector(7 downto 0);
signal mask0 : masker;
signal mask1 : masker;
signal regA : std_logic_vector(7 downto 0);
signal regX : std_logic_vector(7 downto 0);
signal regSP : std_logic_vector(15 downto 0);
signal regPC : std_logic_vector(15 downto 0);
signal flagH : std_logic;
signal flagI : std_logic;
signal flagN : std_logic;
signal flagZ : std_logic;
signal flagC : std_logic;
signal help : std_logic_vector(7 downto 0);
signal temp : std_logic_vector(15 downto 0);
signal mainFSM : std_logic_vector(3 downto 0);
signal addrMux : std_logic_vector(2 downto 0);
signal dataMux : std_logic_vector(3 downto 0);
signal opcode : std_logic_vector(7 downto 0);
signal prod : std_logic_vector(15 downto 0);
signal irq_d : std_logic;
signal irqRequest : std_logic;
signal trace : std_logic;
signal trace_i : std_logic;
signal traceOpCode : std_logic_vector(7 downto 0);
begin
mul: mul8 port map(
a => regA,
b => regX,
prod => prod
);
addr <= regPC when addrMux = addrPC else
regSP when addrMux = addrSP else
x"00" & regX when addrMux = addrHX else
temp when addrMux = addrTM else
((x"00" & regX) + temp) when addrMux = addrX2 else
(regSP + temp) when addrMux = addrS2 else
((x"00" & regX) + (x"00" & temp(7 downto 0))) when addrMux = addrX1 else
(regSP + (x"00" & temp(7 downto 0)));
dataout <= regA when dataMux = outA else
regX when dataMux = outH else
regX when dataMux = outX else
regSP( 7 downto 0) when dataMux = outSPL else
regSP(15 downto 8) when dataMux = outSPH else
regPC( 7 downto 0) when dataMux = outPCL else
regPC(15 downto 8) when dataMux = outPCH else
temp ( 7 downto 0) when dataMux = outTL else
temp (15 downto 8) when dataMux = outTH else
help when dataMux = outHelp else
traceOpCode;
state <= mainFSM;
process(clk, rst)
variable tres : std_logic_vector(7 downto 0);
variable lres : std_logic_vector(15 downto 0);
begin
if rst = '0' then
trace <= '0';
trace_i <= '0';
mask0(0) <= "11111110";
mask0(1) <= "11111101";
mask0(2) <= "11111011";
mask0(3) <= "11110111";
mask0(4) <= "11101111";
mask0(5) <= "11011111";
mask0(6) <= "10111111";
mask0(7) <= "01111111";
mask1(0) <= "00000001";
mask1(1) <= "00000010";
mask1(2) <= "00000100";
mask1(3) <= "00001000";
mask1(4) <= "00010000";
mask1(5) <= "00100000";
mask1(6) <= "01000000";
mask1(7) <= "10000000";
wr <= CPUread;
flagH <= '0';
flagI <= '1'; -- irq disabled
flagN <= '0';
flagZ <= '0';
flagC <= '0';
regA <= x"00";
regX <= x"00";
regSP <= x"00FF";
regPC <= x"FFFE";
temp <= x"FFFE";
help <= x"00";
dataMux <= outA;
addrMux <= addrTM;
irq_d <= '1';
irqRequest <= '0';
mainFSM <= "0000";
else
if rising_edge(clk) then
irq_d <= irq;
if (irq <= '0') and (irq_d = '1') and (flagI = '0') then -- irq falling edge ?
irqRequest <= '1';
end if;
case mainFSM is
when "0000" => --############# reset fetch PCH from FFFE
regPC(15 downto 8) <= datain;
temp <= temp + 1;
mainFSM <= "0001";
when "0001" => --############# reset fetch PCL from FFFF
regPC(7 downto 0) <= datain;
addrMux <= addrPC;
mainFSM <= "0010";
when "0010" => --##################### fetch opcode, instruction cycle 1
trace <= trace_i;
if trace = '1' then
opcode <= x"83"; -- special SWI trace
traceOpCode <= datain;
addrMux <= addrSP;
mainFSM <= "0011";
elsif irqRequest = '1' then
opcode <= x"83"; -- special SWI interrupt
addrMux <= addrSP;
mainFSM <= "0011";
else
opcode <= datain;
case datain is
when x"82" => -- RTT return trace special propietary instruction
trace_i <= '1'; -- arm trace for next instruction
regSP <= regSP + 1;
addrMux <= addrSP;
mainFSM <= "0011";
when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" | -- BRSET n,opr8a,rel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -