OpenCores
URL https://opencores.org/ocsvn/system05/system05/trunk

Subversion Repositories system05

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/trunk/rtl/vhdl/txunit3.vhd File deleted \ No newline at end of file
/trunk/rtl/vhdl/rxunit3.vhd File deleted \ No newline at end of file
/system05/trunk/rtl/vhdl/bclrrom.vhd
0,0 → 1,44
-- FILE NAME: bclrrom.vhdl
-- ENTITY NAME: bclr_rom
-- ARCHITECTURE NAME: basic
-- REVISION: A
--
-- DESCRIPTION: 8 byte x 8 bit ROM
-- For Bit clear translations
--
-- Written by John Kent for the mc6805 processor
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity bclr_rom is
port (
addr : in std_logic_vector(2 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity bclr_rom;
 
architecture basic of bclr_rom is
constant width : integer := 8;
constant memsize : integer := 8;
 
type bclr_rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant bclr_rom_data : bclr_rom_array :=
( "11111110",
"11111101",
"11111011",
"11110111",
"11101111",
"11011111",
"10111111",
"01111111"
);
begin
data <= bclr_rom_data(conv_integer(addr));
end architecture basic;
 
 
/system05/trunk/rtl/vhdl/timer.vhd
0,0 → 1,144
--===========================================================================--
--
-- S Y N T H E Z I A B L E timer dual 8 Bit timer
--
-- This core adheres to the GNU public license
--
-- File name : timer.vhd
--
-- Purpose : Implements 2 x 8 bit timers
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Initial version - John Kent - 6 Sept 2002
-- Make CS & reset positive sense - John Kent - 30th May 2004
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity timer is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_out : out std_logic;
tim0_in : in std_logic;
tim0_out : out std_logic;
tim1_in : in std_logic;
tim1_out : out std_logic
);
end;
 
architecture timer_arch of timer is
signal timer_ctrl_reg : std_logic_vector(7 downto 0);
signal timer0_reg : std_logic_vector(7 downto 0);
signal timer1_reg : std_logic_vector(7 downto 0);
signal count0 : std_logic_vector(7 downto 0);
signal count1 : std_logic_vector(7 downto 0);
begin
 
--------------------------------
--
-- write control registers
-- doesn't do anything yet
--
--------------------------------
write_timer_control : process( clk, rst, cs, rw, addr, data_in, timer0_reg, timer1_reg, timer_ctrl_reg )
begin
if clk'event and clk = '0' then
if cs = '1' and rw = '0' then
case addr is
when "000" =>
timer_ctrl_reg <= data_in;
timer0_reg <= timer0_reg;
timer1_reg <= timer1_reg;
when "010" =>
timer_ctrl_reg <= timer_ctrl_reg;
timer0_reg <= data_in;
timer1_reg <= timer1_reg;
when "011" =>
timer_ctrl_reg <= timer_ctrl_reg;
timer0_reg <= timer0_reg;
timer1_reg <= data_in;
when others =>
timer_ctrl_reg <= timer_ctrl_reg;
timer0_reg <= timer0_reg;
timer1_reg <= timer1_reg;
end case;
else
timer_ctrl_reg <= timer_ctrl_reg;
timer0_reg <= timer0_reg;
timer1_reg <= timer1_reg;
end if;
end if;
end process;
 
read_timer_control : process( addr, timer_ctrl_reg, timer0_reg, timer1_reg, count0, count1 )
begin
case addr is
when "000" =>
data_out <= timer_ctrl_reg;
when "010" =>
data_out <= timer0_reg;
when "011" =>
data_out <= timer1_reg;
when "110" =>
data_out <= count0;
when "111" =>
data_out <= count1;
when others =>
data_out <= "00000000";
end case;
irq_out <= timer_ctrl_reg(0);
end process;
 
--------------------------------
--
-- counters
--
--------------------------------
 
my_counter: process( clk, rst, count0, count1, tim0_in, tim1_in )
begin
if rst = '1' then
count0 <= "00000000";
elsif tim0_in'event and tim0_in = '0' then
if count0 = timer0_reg then
count0 <= "00000000";
else
count0 <= count0 + 1;
end if;
end if;
 
if rst = '1' then
count1 <= "00000000";
elsif tim1_in'event and tim1_in = '1' then
if count1 = timer1_reg then
count1 <= "00000000";
else
count1 <= count1 + 1;
end if;
end if;
 
tim0_out <= count0(7);
tim1_out <= count1(7);
end process;
end timer_arch;
/system05/trunk/rtl/vhdl/System05.npl
0,0 → 1,37
JDF G
// Created by Project Navigator ver 1.0
PROJECT System05
DESIGN system05
DEVFAM spartan2e
DEVFAMTIME 1085921812
DEVICE xc2s300e
DEVICETIME 1085921812
DEVPKG pq208
DEVPKGTIME 315558000
DEVSPEED -7
DEVSPEEDTIME 1085921812
DEVTOPLEVELMODULETYPE HDL
TOPLEVELMODULETYPETIME 0
DEVSYNTHESISTOOL XST (VHDL/Verilog)
SYNTHESISTOOLTIME 0
DEVSIMULATOR Modelsim
SIMULATORTIME 0
DEVGENERATEDSIMULATIONMODEL VHDL
GENERATEDSIMULATIONMODELTIME 0
SOURCE ioport.vhd
SOURCE bsetrom.vhd
SOURCE System05.vhd
SOURCE timer.vhd
SOURCE bclrrom.vhd
SOURCE bootrom.vhd
SOURCE cpu05.vhd
SOURCE miniUART3.vhd
SOURCE rxunit3.vhd
SOURCE txunit3.vhd
STIMULUS miniuart_tb.vhd
STIMULUS System05_tb.vhd
DEPASSOC system05 system05.ucf
[STATUS-ALL]
system05.bitgenGroup=OK,1085933331
[STRATEGY-LIST]
Normal=True
/system05/trunk/rtl/vhdl/bootrom.vhd
0,0 → 1,67
-- FILE NAME: bootrom.vhdl
-- ENTITY NAME: boot_rom
-- ARCHITECTURE NAME: behave
-- REVISION: A
--
-- DESCRIPTION: 64 byte x 8 bit ROM to down a Monitor
-- program on reset
--
--Written by John Kent for the micro8 processor
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library work;
-- use work.memory.all;
 
entity boot_rom is
port (
addr : in std_logic_vector(5 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity boot_rom;
 
architecture basic of boot_rom is
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
( "10011100", -- $FFC0 - 9C RESET RSP
"10100110", "00010001", -- $FFC1 - A6 11 LDA #$11
"10110111", "00010000", -- $FFC3 - B7 10 STA ACIACS
"10101110", "00000000", -- $FFC5 - AE 00 LDX #$00
"11010110", "11111111", "11100010", -- $FFC7 - D6 FFE2 LOOP0 LDA $FFE0,X
"00100111", "00001000", -- $FFCA - 27 08 BEQ INPUT
"00000011", "00010000", "11111101", -- $FFCC - 03 10 FD LOOP1 BRCLR 1,$10,LOOP1
"10110111", "00010001", -- $FFCF - B7 11 STA ACIADA
"01011100", -- $FFD1 - 5C INCX
"00100000", "11110011", -- $FFD3 - 20 F3 BRA LOOP0
"00000001", "00010000", "11111101", -- $FFD5 - 01 10 FD INPUT BRCLR 0,$10,INPUT
"10110110", "00010001", -- $FFD7 - B6 11 LDA ACIADA
"11001101", "11111111", "11011111", -- $FFD9 - CD FFDF JSR SUBR
"11001100", "11111111", "11000000", -- $FFDC - CC FFC0 JMP RESET
"10110111", "00010001", -- $FFDF - B7 11 SUBR STA ACIADA
"10000001", -- $FFE1 - 81 RTS
"01001000", "01100101", "01101100", -- $FFE2 - 48 65 6c MSG FCC "Hel"
"01101100", "01101111", "00100000", -- $FFE5 - 6c 6f 20 FCC "lo "
"01010111", "01101111", "01110010", -- $FFE8 - 57 6f 72 FCC "Wor"
"01101100", "01100100", -- $FFEB - 6c 64 FCC "ld"
"00001010", "00001101", "00000000", -- $FFED - 0a 0d 00 FCB LF,CR,NULL
"11111111", "11000000", -- $FFF0 - FF C0 FDB RESET
"11111111", "11000000", -- $FFF2 - FF C0 FDB RESET
"11111111", "11000000", -- $FFF4 - FF C0 FDB RESET
"11111111", "11000000", -- $FFF6 - FF C0 FDB RESET
"11111111", "11000000", -- $FFF8 - FF C0 FDB RESET
"11111111", "11000000", -- $FFFA - FF C0 FDB RESET
"11111111", "11000000", -- $FFFC - FF C0 FDB RESET
"11111111", "11000000" -- $FFFE - FF C0 FDB RESET
);
begin
data <= rom_data(conv_integer(addr));
end architecture basic;
 
 
/system05/trunk/rtl/vhdl/system05.ucf
0,0 → 1,230
#### UCF file created by Project Navigator
#
NET "reset_n" LOC = "p57" ;
NET "sysclk" LOC = "p77" ;
#
# I/O Port
# Connector A
#
#NET "timer0_in" LOC = "P3" ; #J1-2
#NET "timer0_out" LOC = "P4" ; #J1-3
NET "portc<0>" LOC = "P5" ; #J1-4
NET "portc<1>" LOC = "P6" ; #J1-5
NET "portc<2>" LOC = "P7" ; #J1-6
NET "portc<3>" LOC = "P8" ; #J1-7
NET "portc<4>" LOC = "P9" ; #J1-8
NET "portc<5>" LOC = "P10" ; #J1-9
NET "portc<6>" LOC = "P11" ; #J1-10
NET "portc<7>" LOC = "P15" ; #J1-11
NET "portd<0>" LOC = "P16" ; #J1-12
NET "portd<1>" LOC = "P17" ; #J1-13
NET "portd<2>" LOC = "P18" ; #J1-14
NET "portd<3>" LOC = "P20" ; #J1-15
NET "portd<4>" LOC = "P21" ; #J1-16
NET "portd<5>" LOC = "P22" ; #J1-17
NET "portd<6>" LOC = "P23" ; #J1-18
NET "portd<7>" LOC = "P24" ; #J1-19
#
# For B5-Compact-Flash:
# Connector B
#
#NET "cf_a<2>" LOC = "P33" ; #J2-6
#NET "cf_a<1>" LOC = "P34" ; #J2-7
#NET "cf_a<0>" LOC = "P35" ; #J2-8
#NET "cf_d<0>" LOC = "P36" ; #J2-9
#NET "cf_d<1>" LOC = "P40" ; #J2-10
#NET "cf_d<2>" LOC = "P41" ; #J2-11
#NET "cf_cs16_n" LOC = "P42" ; #J2-12
#NET "cf_d<10>" LOC = "P43" ; #J2-13
#NET "cf_d<9>" LOC = "P44" ; #J2-14
#NET "cf_d<8>" LOC = "P45" ; #J2-15
#NET "cf_pdiag" LOC = "P46" ; #J2-16
#NET "cf_dase" LOC = "P47" ; #J2-17
#NET "cf_iordy" LOC = "P48" ; #J2-18
#NET "cf_rst_n" LOC = "P49" ; #J2-19
#
# For B5-Peripheral-Connectors
# Connector C
#
#NET "v_drive" LOC = "p55" ; #pin 3
#NET "h_drive" LOC = "p56" ; #pin 4
#NET "blue_lo" LOC = "p58" ; #pin 5
#NET "blue_hi" LOC = "p59" ; #pin 6
#NET "green_lo" LOC = "p60" ; #pin 7
#NET "green_hi" LOC = "p61" ; #pin 8
#NET "red_lo" LOC = "p62" ; #pin 9
#NET "red_hi" LOC = "p63" ; #pin 10
#NET "kb_clock" LOC = "p64" ; #pin 11
#NET "kb_data" LOC = "p68" ; #pin 12
#NET "mouse-clock" LOC = "p69" ; #pin 13
#NET "mouse_data" LOC = "p70" ; #pin 14
#NET "buzzer" LOC = "p71" ; #pin 15
NET "cts_n" LOC = "p73" ; #pin 16
NET "rxbit" LOC = "p74" ; #pin 17
NET "txbit" LOC = "p75" ; #pin 18
NET "rts_n" LOC = "p81" ; #pin 19
#
# I/O Port A & B
# Connector D
#
#NET "pin2clk" LOC = "p80" ; #pin 2 (Clock input)
NET "led" LOC = "p82" ; #pin 3
NET "porta<0>" LOC = "p83" ; #pin 4
NET "porta<1>" LOC = "p84" ; #pin 5
NET "porta<2>" LOC = "p86" ; #pin 6
NET "porta<3>" LOC = "p87" ; #pin 7
NET "porta<4>" LOC = "p88" ; #pin 8
NET "porta<5>" LOC = "p89" ; #pin 9
NET "porta<6>" LOC = "p93" ; #pin 10
NET "porta<7>" LOC = "p94" ; #pin 11
NET "portb<0>" LOC = "p95" ; #pin 12
NET "portb<1>" LOC = "p96" ; #pin 13
NET "portb<2>" LOC = "p97" ; #pin 14
NET "portb<3>" LOC = "p98" ; #pin 15
NET "portb<4>" LOC = "p99" ; #pin 16
NET "portb<5>" LOC = "p100"; #pin 17
NET "portb<6>" LOC = "p101"; #pin 18
NET "portb<7>" LOC = "p102"; #pin 19
#
# For B5-SRAM
# Connector E
#
NET "ram_csn" LOC = "p108"; #J1.2
NET "ram_addr<16>" LOC = "p109"; #J1.3
NET "ram_addr<15>" LOC = "p110"; #J1.4
NET "ram_addr<14>" LOC = "p111"; #J1.5
NET "ram_addr<13>" LOC = "p112"; #J1.6
NET "ram_addr<12>" LOC = "p113"; #J1.7
NET "ram_addr<11>" LOC = "p114"; #J1.8
NET "ram_addr<10>" LOC = "p115"; #J1.9
NET "ram_addr<9>" LOC = "p116"; #J1.10
NET "ram_addr<8>" LOC = "p120"; #J1.11
NET "ram_addr<7>" LOC = "p121"; #J1.12
NET "ram_addr<6>" LOC = "p122"; #J1.13
NET "ram_addr<5>" LOC = "p123"; #J1.14
NET "ram_addr<4>" LOC = "p125"; #J1.15
NET "ram_addr<3>" LOC = "p126"; #J1.16
NET "ram_addr<2>" LOC = "p127"; #J1.17
NET "ram_addr<1>" LOC = "p129"; #J1.18
NET "ram_addr<0>" LOC = "p132"; #J1.19
#
# For B5-SRAM
# Connector F
#
NET "ram_wrun" LOC = "p133"; #J2.2
NET "ram_wrln" LOC = "p134"; #J2.3
NET "ram_data<15>" LOC = "p135"; #J2.4
NET "ram_data<14>" LOC = "p136"; #J2.5
NET "ram_data<13>" LOC = "p138"; #J2.6
NET "ram_data<12>" LOC = "p139"; #J2.7
NET "ram_data<11>" LOC = "p140"; #J2.8
NET "ram_data<10>" LOC = "p141"; #J2.9
NET "ram_data<9>" LOC = "p145"; #J2.10
NET "ram_data<8>" LOC = "p146"; #J2.11
NET "ram_data<7>" LOC = "p147"; #J2.12
NET "ram_data<6>" LOC = "p148"; #J2.13
NET "ram_data<5>" LOC = "p149"; #J2.14
NET "ram_data<4>" LOC = "p150"; #J2.15
NET "ram_data<3>" LOC = "p151"; #J2.16
NET "ram_data<2>" LOC = "p152"; #J2.17
NET "ram_data<1>" LOC = "p153"; #J2.18
NET "ram_data<0>" LOC = "p154"; #J2.19
#
# Connector G
#
#NET "pin2" LOC = "p182"; #pin 2 (clk input)
NET "bus_addr<0>" LOC = "p160"; #pin 3
NET "bus_addr<1>" LOC = "p161"; #pin 4
NET "bus_addr<2>" LOC = "p162"; #pin 5
NET "bus_addr<3>" LOC = "p163"; #pin 6
NET "bus_addr<4>" LOC = "p164"; #pin 7
NET "bus_addr<5>" LOC = "p165"; #pin 8
NET "bus_addr<6>" LOC = "p166"; #pin 9
NET "bus_addr<7>" LOC = "p167"; #pin 10
NET "bus_addr<8>" LOC = "p168"; #pin 11
NET "bus_addr<9>" LOC = "p169"; #pin 12
NET "bus_addr<10>" LOC = "p173"; #pin 13
NET "bus_addr<11>" LOC = "p174"; #pin 14
NET "bus_addr<12>" LOC = "p175"; #pin 15
NET "bus_addr<13>" LOC = "p176"; #pin 16
NET "bus_addr<14>" LOC = "p178"; #pin 17
NET "bus_addr<15>" LOC = "p179"; #pin 18
NET "bus_cs" LOC = "p180"; #pin 19
#
# Connector H
#
#NET "pin2" LOC = "p185"; #pin 2 (clk input)
NET "bus_clk" LOC = "p181"; #pin 3
NET "bus_reset" LOC = "p187"; #pin 4
#NET "pin5" LOC = "p188"; #pin 5
#NET "pin6" LOC = "p189"; #pin 6
#NET "pin7" LOC = "p191"; #pin 7
#NET "pin8" LOC = "p192"; #pin 8
NET "timer0_out" LOC = "p193"; #pin 9
NET "timer1_out" LOC = "p194"; #pin 10
NET "bus_data<0>" LOC = "p198"; #pin 11
NET "bus_data<1>" LOC = "p199"; #pin 12
NET "bus_data<2>" LOC = "p200"; #pin 13
NET "bus_data<3>" LOC = "p201"; #pin 14
NET "bus_data<4>" LOC = "p202"; #pin 15
NET "bus_data<5>" LOC = "p203"; #pin 16
NET "bus_data<6>" LOC = "p204"; #pin 17
NET "bus_data<7>" LOC = "p205"; #pin 18
NET "bus_rw" LOC = "p206"; #pin 19
#
# Timing Groups
#
INST "ram_addr<0>" TNM = "gram_addr";
INST "ram_addr<1>" TNM = "gram_addr";
INST "ram_addr<2>" TNM = "gram_addr";
INST "ram_addr<3>" TNM = "gram_addr";
INST "ram_addr<4>" TNM = "gram_addr";
INST "ram_addr<5>" TNM = "gram_addr";
INST "ram_addr<6>" TNM = "gram_addr";
INST "ram_addr<7>" TNM = "gram_addr";
INST "ram_addr<8>" TNM = "gram_addr";
INST "ram_addr<9>" TNM = "gram_addr";
INST "ram_addr<10>" TNM = "gram_addr";
INST "ram_addr<11>" TNM = "gram_addr";
INST "ram_addr<12>" TNM = "gram_addr";
INST "ram_addr<13>" TNM = "gram_addr";
INST "ram_addr<14>" TNM = "gram_addr";
INST "ram_addr<15>" TNM = "gram_addr";
INST "ram_addr<16>" TNM = "gram_addr";
INST "ram_data<0>" TNM = "gram_data";
INST "ram_data<1>" TNM = "gram_data";
INST "ram_data<2>" TNM = "gram_data";
INST "ram_data<3>" TNM = "gram_data";
INST "ram_data<4>" TNM = "gram_data";
INST "ram_data<5>" TNM = "gram_data";
INST "ram_data<6>" TNM = "gram_data";
INST "ram_data<7>" TNM = "gram_data";
INST "ram_data<8>" TNM = "gram_data";
INST "ram_data<9>" TNM = "gram_data";
INST "ram_data<10>" TNM = "gram_data";
INST "ram_data<11>" TNM = "gram_data";
INST "ram_data<12>" TNM = "gram_data";
INST "ram_data<13>" TNM = "gram_data";
INST "ram_data<14>" TNM = "gram_data";
INST "ram_data<15>" TNM = "gram_data";
INST "ram_wrln" TNM = "gram_wr";
INST "ram_wrun" TNM = "gram_wr";
INST "ram_csn" TNM = "gram_cs";
#
# Timing Constraints
#
#TIMEGRP "gram_cs" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_wr" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_addr" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_data" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_data" OFFSET = IN 15 ns BEFORE "sysclk";
#TIMEGRP "gtest_alu" OFFSET = OUT 90 ns AFTER "sysclk";
#TIMEGRP "gtest_cc" OFFSET = OUT 95 ns AFTER "sysclk";
NET "sysclk" TNM_NET = "sysclk";
TIMESPEC "TS_sysclk" = PERIOD "sysclk" 100 ns LOW 50 %;
#
# Fast I/O Pins
#
NET "ram_csn" FAST;
NET "ram_wrln" FAST;
NET "ram_wrun" FAST;
/system05/trunk/rtl/vhdl/System05.vhd
0,0 → 1,540
--===========================================================================--
--
-- S Y N T H E Z I A B L E System05 System On a Chip
--
-- This core adheres to the GNU public license
--
-- File name : system05.vhd
--
-- Purpose : Top level file for a 6805 compatible system on a chip
-- Designed for the Burch ED B5-Spartan IIe board with
-- X2S300e FPGA,
-- 128K x 16 Word SRAM module (B5-SRAM)
-- CPU I/O module (B5-Peripheral-Connectors)
-- Using mimiUart from open cores modified to look like a 6850
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu05.vhd (6805 compatible CPU core)
-- miniuart3.vhd, (6850 compatible UART)
-- rxunit3.vhd,
-- txunit3.vhd
-- timer.vhd (timer module)
-- ioport.vhd (parallel I/O port)
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version Date Author Notes
-- 0.0 14th July 2001 John Kent Started design
-- 0.1 30th May 2004 John Kent Initial Release
--
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System05 is
port(
SysClk : in Std_Logic; -- System Clock input
Reset_n : in Std_logic; -- Master Reset input (active low)
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrun : out Std_Logic;
ram_wrln : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- Extra clock
-- buzzer : out Std_Logic;
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- Keyboard interface
-- kb_clock : in Std_Logic;
-- kb_data : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
 
-- External Bus
bus_addr : out std_logic_vector(15 downto 0);
bus_data : inout std_logic_vector(7 downto 0);
bus_rw : out std_logic;
bus_cs : out std_logic;
bus_clk : out std_logic;
bus_reset : out std_logic;
 
-- I/O Ports
porta : inout std_logic_vector(7 downto 0);
portb : inout std_logic_vector(7 downto 0);
portc : inout std_logic_vector(7 downto 0);
portd : inout std_logic_vector(7 downto 0);
 
-- Timer I/O
-- timer0_in : in std_logic;
timer0_out : out std_logic;
-- timer1_in : in std_logic;
timer1_out : out std_logic
);
end System05;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System05 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
signal dcd_n : Std_Logic;
 
-- I/O Port
signal ioport_data_out : std_logic_vector(7 downto 0);
signal ioport_cs : std_logic;
 
-- Timer I/O
signal timer_data_out : std_logic_vector(7 downto 0);
signal timer_cs : std_logic;
signal timer_irq : Std_Logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- Sequencer Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
 
-- External interrupt input
signal ext_irq : Std_Logic;
 
-- Counter signals
signal countL : std_logic_vector(23 downto 0);
signal BaudCount : std_logic_vector(4 downto 0);
signal baudclk : Std_Logic;
 
-----------------------------------------------------------------
--
-- CPU Core
--
-----------------------------------------------------------------
 
component cpu05 is
port (
clk : in std_logic;
rst : in std_logic;
vma : out std_logic;
rw : out std_logic;
addr : out std_logic_vector(15 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_ext : in std_logic;
irq_timer : in std_logic;
irq_uart : in std_logic
);
end component cpu05;
 
------------------------------------------
--
-- Program memory
--
------------------------------------------
 
component boot_rom is
port (
addr : in Std_Logic_Vector(5 downto 0); -- 64 byte boot rom
data : out Std_Logic_Vector(7 downto 0)
);
end component boot_rom;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end component;
 
 
---------------------------------------
--
-- Three port parallel I/O
--
---------------------------------------
 
component ioport is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0);
portc_io : inout std_logic_vector(7 downto 0);
portd_io : inout std_logic_vector(7 downto 0)
);
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
component timer is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_out : out std_logic;
tim0_in : in std_logic;
tim0_out : out std_logic;
tim1_in : in std_logic;
tim1_out : out std_logic
);
end component;
 
------------------------------------------
--
-- Global clock buffer for debug
--
------------------------------------------
 
component BUFG is
port (
i: in std_logic;
o: out std_logic
);
end component;
 
begin
 
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu05 port map (
clk => cpu_clk,
rst => cpu_reset,
vma => cpu_vma,
rw => cpu_rw,
addr => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
irq_ext => ext_irq,
irq_timer => timer_irq,
irq_uart => uart_irq
);
 
rom : boot_rom port map (
addr => cpu_addr(5 downto 0),
data => rom_data_out
);
 
my_uart : miniUART port map (
clk => cpu_clk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out,
RxC => baudclk,
TxC => baudclk,
RxD => rxbit,
TxD => txbit,
DCD_n => dcd_n,
CTS_n => cts_n,
RTS_n => rts_n
);
 
my_ioport : ioport port map (
clk => cpu_clk,
rst => cpu_reset,
cs => ioport_cs,
rw => cpu_rw,
addr => cpu_addr(2 downto 0),
data_in => cpu_data_out,
data_out => ioport_data_out,
porta_io => porta,
portb_io => portb,
portc_io => portc,
portd_io => portd
);
 
my_timer : timer port map (
clk => cpu_clk,
rst => cpu_reset,
cs => timer_cs,
rw => cpu_rw,
addr => cpu_addr(2 downto 0),
data_in => cpu_data_out,
data_out => timer_data_out,
irq_out => timer_irq,
tim0_in => CountL(4),
tim0_out => timer0_out,
tim1_in => CountL(6),
tim1_out => timer1_out
);
 
 
 
bufginst: BUFG port map(
i => countL(0),
o => cpu_clk
);
 
-- bufginst: BUFG port map(i => SysClk, o => cpu_clk );
----------------------------------------------------------------------
--
-- Processes to read and write memory based on bus signals
--
----------------------------------------------------------------------
 
memory_decode: process( Reset_n, cpu_clk,
cpu_addr, cpu_vma,
rom_data_out, ram_data_out,
ioport_data_out, timer_data_out, uart_data_out, bus_data )
begin
case cpu_addr(15 downto 6) is
when "1111111111" =>
cpu_data_in <= rom_data_out;
ram_cs <= '0';
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
when "0000000000" =>
--
-- Decode 64 bytes of I/O space here
--
ram_cs <= '0';
case cpu_addr(5 downto 3) is
--
-- I/O ports $0000 - $0007
--
when "000" =>
cpu_data_in <= ioport_data_out;
ioport_cs <= cpu_vma;
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
--
-- Timer $0008 - $000F
--
when "001" =>
cpu_data_in <= timer_data_out;
ioport_cs <= '0';
timer_cs <= cpu_vma;
uart_cs <= '0';
bus_cs <= '0';
--
-- ACIA $0010 - $0017
--
when "010" =>
cpu_data_in <= uart_data_out;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= cpu_vma;
bus_cs <= '0';
--
-- Reserved $0018 - $003F
--
when others =>
cpu_data_in <= bus_data;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= cpu_vma;
end case;
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
end case;
end process;
 
--------------------------------------------------------------
--
-- B5 SRAM interface
--
--------------------------------------------------------------
Ram_decode: process( Reset_n, cpu_clk,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
ram_cs, ram_wrl, ram_wru, ram_data )
begin
cpu_reset <= not Reset_n;
ram_wrl <= (not cpu_rw) and cpu_addr(0);
ram_wru <= (not cpu_rw) and (not cpu_addr(0));
ram_wrln <= not ram_wrl;
ram_wrun <= not ram_wru;
ram_csn <= not( Reset_n and ram_cs and cpu_clk );
ram_addr(16 downto 15) <= "00";
ram_addr(14 downto 0) <= cpu_addr(15 downto 1);
 
if ram_cs = '1' then
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if cpu_addr(0) = '0' then
ram_data_out(7 downto 0) <= ram_data(15 downto 8);
else
ram_data_out(7 downto 0) <= ram_data(7 downto 0);
end if;
 
end process;
 
--
-- CPU bus signals
--
my_bus : process( cpu_clk, cpu_reset, cpu_rw, cpu_addr, cpu_data_out )
begin
bus_clk <= cpu_clk;
bus_reset <= cpu_reset;
bus_rw <= cpu_rw;
bus_addr <= cpu_addr;
if( cpu_rw = '1' ) then
bus_data <= "ZZZZZZZZ";
else
bus_data <= cpu_data_out;
end if;
end process;
 
--
-- flash led to indicate code is working
--
blink: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '0') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
 
 
--
-- 57.6 Kbaud * 16 divider for 25 MHz system clock
--
my_baud_clock: process( SysClk )
begin
if(SysClk'event and SysClk = '0') then
if( BaudCount = 26 ) then
BaudCount <= "00000";
else
BaudCount <= BaudCount + 1;
end if;
end if;
baudclk <= BaudCount(4); -- 25MHz / 27 = 926,000 KHz = 57,870Bd * 16
dcd_n <= '0';
end process;
 
--
-- tie down inputs and outputs
--
-- CRTC output signals
--
-- v_drive <= '0';
-- h_drive <= '0';
-- blue_lo <= '0';
-- blue_hi <= '0';
-- green_lo <= '0';
-- green_hi <= '0';
-- red_lo <= '0';
-- red_hi <= '0';
-- buzzer <= '0';
 
--
-- tie down unused interrupts
--
ext_irq <= '0';
end my_computer; --===================== End of architecture =======================--
 
/system05/trunk/rtl/vhdl/bsetrom.vhd
0,0 → 1,43
-- FILE NAME: bsetrom.vhd
-- ENTITY NAME: bset_rom
-- ARCHITECTURE NAME: basic
-- REVISION: A
--
-- DESCRIPTION: 8 byte x 8 bit ROM
-- For bit set translations
--
-- Written by John Kent for the mc6805 processor
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity bset_rom is
port (
addr : in std_logic_vector(2 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity bset_rom;
 
architecture basic of bset_rom is
constant width : integer := 8;
constant memsize : integer := 8;
 
type bset_rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant bset_rom_data : bset_rom_array :=
( "00000001",
"00000010",
"00000100",
"00001000",
"00010000",
"00100000",
"01000000",
"10000000"
);
begin
data <= bset_rom_data(conv_integer(addr));
end architecture basic;
 
 
/system05/trunk/rtl/vhdl/miniUART3.vhd
0,0 → 1,394
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : miniuart2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations
-- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl
-- the RSBusCtrl did not process all possible situations
--
-- olupas@opencores.org
--
-- 3.0 John Kent October 2002 Changed Status bits to match mc6805
-- Added CTS, RTS, Baud rate control
-- & Software Reset
-- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850
-- 3.2 John Kent 19 July 2003 Latched Data input to UART
-- 3.3 John Kent 16 January 2004 Integrated clkunit in rxunit & txunit
-- Now has external TX 7 RX Baud Clock
-- inputs like the MC6850...
-- also supports x1 clock and DCD.
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Entity for miniUART Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity miniUART is
port (
--
-- CPU signals
--
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
--
-- Uart Signals
--
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for miniUART Controller Unit
-------------------------------------------------------------------------------
architecture uart of miniUART is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxData : Std_Logic_Vector(7 downto 0); --
signal TxData : Std_Logic_Vector(7 downto 0); --
signal StatReg : Std_Logic_Vector(7 downto 0); -- status register
-- StatReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy |
-----------+--------+--------+--------+--------+--------+--------+--------+
signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register
-- CtrlReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- RxIEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
-----------+--------+--------+--------+--------+--------+--------+--------+
-- RxIEnb
-- 0 - Rx Interrupt disabled
-- 1 - Rx Interrupt enabled
-- TxCtl
-- 0 1 - Tx Interrupt Enable
-- 1 0 - RTS high
-- WdFmt
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- BdCtl
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
signal TxDbit : Std_Logic; -- Transmit data bit
signal DRdy : Std_Logic; -- Receive Data ready
signal TBufE : Std_Logic; -- Transmit buffer empty
signal FErr : Std_Logic; -- Frame error
signal OErr : Std_Logic; -- Output error
signal PErr : Std_Logic; -- Parity Error
signal TxIEnb : Std_Logic; -- Transmit interrupt enable
signal Read : Std_Logic; -- Read receive buffer
signal Load : Std_Logic; -- Load transmit buffer
signal ReadCS : Std_Logic; -- Read Status register
signal LoadCS : Std_Logic; -- Load Control register
signal Reset : Std_Logic; -- Reset (Software & Hardware)
signal RxRst : Std_Logic; -- Receive Reset (Software & Hardware)
signal TxRst : Std_Logic; -- Transmit Reset (Software & Hardware)
signal DCDDel : Std_Logic; -- Delayed DCD_n
signal DCDEdge : Std_Logic; -- Rising DCD_N Edge Pulse
signal DCDState : Std_Logic; -- DCD Reset sequencer
signal DCDInt : Std_Logic; -- DCD Interrupt
 
-----------------------------------------------------------------------------
-- Receive Unit
-----------------------------------------------------------------------------
component RxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
ReadD : in Std_Logic; -- Read data signal
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
RxClk : in Std_Logic; -- RS-232 clock input
RxDat : in Std_Logic; -- RS-232 data input
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0));
end component;
-----------------------------------------------------------------------------
-- Transmitter Unit
-----------------------------------------------------------------------------
component TxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
LoadD : in Std_Logic; -- Load transmit data
DAIn : in Std_Logic_Vector(7 downto 0);
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
TxClk : in Std_Logic; -- Enable input
TxDat : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic ); -- Tx buffer empty
end component;
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
RxDev : RxUnit port map (
Clk => clk,
Reset => RxRst,
ReadD => Read,
WdFmt => CtrlReg(4 downto 2),
BdFmt => CtrlReg(1 downto 0),
RxClk => RxC,
RxDat => RxD,
FRErr => FErr,
ORErr => OErr,
PAErr => PErr,
DARdy => DRdy,
DAOut => RxData
);
 
TxDev : TxUnit port map (
Clk => clk,
Reset => TxRst,
LoadD => Load,
DAIn => TxData,
WdFmt => CtrlReg(4 downto 2),
BdFmt => CtrlReg(1 downto 0),
TxClk => TxC,
TxDat => TxDbit,
TBE => TBufE
);
 
-----------------------------------------------------------------------------
-- Implements the controller for Rx&Tx units
-----------------------------------------------------------------------------
miniUart_Status : process(clk, Reset, CtrlReg, TxIEnb,
DRdy, TBufE, DCD_n, CTS_n, DCDInt,
FErr, OErr, PErr )
variable Int : Std_Logic;
begin
if Reset = '1' then
Int := '0';
StatReg <= "00000000";
irq <= '0';
elsif clk'event and clk='0' then
Int := (CtrlReg(7) and DRdy) or
(CtrlReg(7) and DCDInt) or
(TxIEnb and TBufE);
StatReg(0) <= DRdy; -- Receive Data Ready
StatReg(1) <= TBufE and (not CTS_n); -- Transmit Buffer Empty
StatReg(2) <= DCDInt; -- Data Carrier Detect
StatReg(3) <= CTS_n; -- Clear To Send
StatReg(4) <= FErr; -- Framing error
StatReg(5) <= OErr; -- Overrun error
StatReg(6) <= PErr; -- Parity error
StatReg(7) <= Int;
irq <= Int;
end if;
end process;
 
 
-----------------------------------------------------------------------------
-- Transmit control
-----------------------------------------------------------------------------
 
miniUart_TxControl : process( CtrlReg, TxDbit )
begin
case CtrlReg(6 downto 5) is
when "00" => -- Disable TX Interrupts, Assert RTS
RTS_n <= '0';
TxIEnb <= '0';
TxD <= TxDbit;
when "01" => -- Enable TX interrupts, Assert RTS
RTS_n <= '0';
TxIEnb <= '1';
TxD <= TxDbit;
when "10" => -- Disable Tx Interrupts, Clear RTS
RTS_n <= '1';
TxIEnb <= '0';
TxD <= TxDbit;
when "11" => -- Disable Tx interrupts, Assert RTS, send break
RTS_n <= '0';
TxIEnb <= '0';
TxD <= '0';
when others =>
RTS_n <= '0';
TxIEnb <= '0';
TxD <= TxDbit;
end case;
end process;
 
-----------------------------------------------------------------------------
-- Write to control register
-----------------------------------------------------------------------------
 
miniUart_Control: process(clk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData )
begin
if (reset = '1') then
TxData <= "00000000";
Load <= '0';
Read <= '0';
CtrlReg <= "00000000";
LoadCS <= '0';
ReadCS <= '0';
elsif clk'event and clk='0' then
if cs = '1' then
if Addr = '1' then -- Data Register
if rw = '0' then -- write data register
TxData <= DataIn;
Load <= '1';
Read <= '0';
else -- read Data Register
TxData <= TxData;
Load <= '0';
Read <= '1';
end if; -- rw
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '0';
else -- Control / Status register
TxData <= TxData;
Load <= '0';
Read <= '0';
if rw = '0' then -- write control register
CtrlReg <= DataIn;
LoadCS <= '1';
ReadCS <= '0';
else -- read status Register
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '1';
end if; -- rw
end if; -- Addr
else -- not selected
TxData <= TxData;
Load <= '0';
Read <= '0';
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '0';
 
end if; -- cs
end if; -- clk / reset
end process;
 
---------------------------------------------------------------
--
-- set data output mux
--
--------------------------------------------------------------
 
miniUart_data_read: process(Addr, StatReg, RxData)
begin
if Addr = '1' then
DataOut <= RxData; -- read data register
else
DataOut <= StatReg; -- read status register
end if; -- Addr
end process;
 
 
---------------------------------------------------------------
--
-- Data Carrier Detect Edge rising edge detect
--
---------------------------------------------------------------
miniUart_DCD_edge : process( reset, clk, DCD_n, DCDDel )
begin
if reset = '1' then
DCDEdge <= '0';
DCDDel <= '0';
elsif clk'event and clk = '0' then
DCDDel <= DCD_n;
DCDEdge <= DCD_n and (not DCDDel);
end if;
end process;
 
 
---------------------------------------------------------------
--
-- Data Carrier Detect Interrupt
--
---------------------------------------------------------------
miniUart_DCD_int : process( reset, clk, DCDEdge, DCDState, Read, ReadCS, DCDInt )
begin
if reset = '1' then
DCDInt <= '0';
DCDState <= '0';
elsif clk'event and clk = '0' then
if DCDEdge = '1' then
DCDInt <= '1';
DCDState <= '0';
elsif DCDState = '0' then
-- To reset DCD interrupt, First read status
if (ReadCS <= '1') and (DCDInt = '1') then
DCDState <= '1';
else
DCDState <= '0';
end if;
DCDInt <= DCDInt;
else -- DCDstate = '1'
-- Then read the data register
if Read <= '1' then
DCDState <= '0';
DCDInt <= '0';
else
DCDState <= DCDState;
DCDInt <= DCDInt;
end if;
end if; -- DCDState
end if; -- clk / reset
end process;
 
---------------------------------------------------------------
--
-- reset may be hardware or software
--
---------------------------------------------------------------
 
miniUart_reset: process(rst, CtrlReg, Reset, DCD_n )
begin
Reset <= (CtrlReg(1) and CtrlReg(0)) or rst;
TxRst <= Reset;
RxRst <= Reset or DCD_n;
end process;
 
end; --===================== End of architecture =======================--
 
/system05/trunk/rtl/vhdl/cpu05.vhd
0,0 → 1,2252
--===========================================================================--
--
-- S Y N T H E Z I A B L E CPU05 6805 comaptible CPU
--
-- This core adheres to the GNU public license
--
-- File name : cpu05.vhd
--
-- Purpose : 6805 compatible CPU
-- Differences to 6805
-- 64 K addressing range
-- stack starts at $00FF and is 128 bytes deep
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent
--
--
--=====================================================================
--
-- Revision History
--
--=====================================================================
--
-- 0.0 6 Sept 2002 - John Kent - design started
-- 0.1 30 May 2004 - John Kent - Initial release
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity cpu05 is
port (
clk : in std_logic;
rst : in std_logic;
vma : out std_logic;
rw : out std_logic;
addr : out std_logic_vector(15 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_ext : in std_logic;
irq_timer : in std_logic;
irq_uart : in std_logic );
end;
 
architecture cpu_arch of cpu05 is
type state_type is (reset_state, reset1_state, reset2_state,
fetch_state, decode_state, exec_state, halt_state,
brbit_state,
branch_state, bsr_state, jsr_state, jsr1_state, jmp_state,
swi_state, stop_state,
rti_state, rti_cc_state, rti_ac_state, rti_ix_state, rti_pch_state, rti_pcl_state,
rts_state, rts_pch_state, rts_pcl_state,
wait_state, wait1_state, wait2_state, wait3_state, wait4_state,
int_state, int1_state, int2_state, int3_state, int4_state, int5_state, int6_state,
dir_state, ext_state, ix2_state, ix1_state, ix0_state,
write_state );
type addr_type is (reset_addr, idle_addr, fetch_addr, read_addr, write_addr, push_addr, pull_addr, vect_hi_addr, vect_lo_addr );
type data_type is (ac_data, ix_data, cc_data, md_data, pc_lo_data, pc_hi_data );
type pc_type is (reset_pc, latch_pc, inc_pc, jmp_pc, bra_pc, pull_lo_pc, pull_hi_pc );
type ea_type is (reset_ea, latch_ea, fetch_first_ea, fetch_next_ea, loadix_ea, addix_ea, addpc_ea );
type op_type is (reset_op, latch_op, fetch_op );
type ac_type is (reset_ac, latch_ac, load_ac, pull_ac );
type ix_type is (reset_ix, latch_ix, load_ix, pull_ix );
type sp_type is (reset_sp, latch_sp, load_sp, inc_sp, dec_sp );
type cc_type is (reset_cc, latch_cc, load_cc, pull_cc );
type md_type is (reset_md, latch_md, load_md, fetch_md );
type iv_type is (latch_iv, rst_iv, swi_iv, irq_iv, tim_iv, uart_iv );
type left_type is (ac_left, ix_left, md_left );
type right_type is (md_right, bset_right, bclr_right, zero_right, one_right );
type alu_type is (alu_add, alu_adc, alu_sub, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
alu_lsr, alu_lsl, alu_ror, alu_rol, alu_asr,
alu_sei, alu_cli, alu_sec, alu_clc,
alu_bset, alu_bclr, alu_btst,
alu_ld, alu_st, alu_nop );
 
constant HFLAG : integer := 4;
constant IFLAG : integer := 3;
constant NFLAG : integer := 2;
constant ZFLAG : integer := 1;
constant CFLAG : integer := 0;
 
--
-- internal registers
--
signal ac: std_logic_vector(7 downto 0); -- accumulator
signal ix: std_logic_vector(7 downto 0); -- index register
signal sp: std_logic_vector(6 downto 0); -- stack pointer
signal cc: std_logic_vector(4 downto 0); -- condition codes from alu
signal pc: std_logic_vector(15 downto 0); -- program counter for opcode access
signal ea: std_logic_vector(15 downto 0); -- effective addres for memory access
signal op: std_logic_vector(7 downto 0); -- opcode register
signal md: std_logic_vector(7 downto 0); -- memory data
signal iv: std_logic_vector(2 downto 0); -- interrupt vector number
signal state: state_type;
 
--
-- unregistered signals
-- (combinational logic)
--
signal alu_left: std_logic_vector(8 downto 0); -- alu left input (bit 8 for carry)
signal alu_right: std_logic_vector(8 downto 0); -- alu right input
signal alu_out: std_logic_vector(8 downto 0); -- alu result output (unlatched)
signal cc_out: std_logic_vector(4 downto 0); -- alu condition code outout (unlatched)
signal bset_data_out: std_logic_vector(7 downto 0);
signal bclr_data_out: std_logic_vector(7 downto 0);
signal next_state: state_type;
 
--
-- Syncronous Register Controls
--
signal ac_ctrl: ac_type;
signal ix_ctrl: ix_type;
signal sp_ctrl: sp_type;
signal cc_ctrl: cc_type;
signal pc_ctrl: pc_type;
signal ea_ctrl: ea_type;
signal op_ctrl: op_type;
signal md_ctrl: md_type;
signal iv_ctrl: iv_type;
 
--
-- Asynchronous Multiplexer Controls
--
signal addr_ctrl: addr_type; -- address bus mutiplexer
signal data_ctrl: data_type; -- data output mutiplexer
signal left_ctrl: left_type; -- Left ALU input
signal right_ctrl: right_type; -- Right ALU input
signal alu_ctrl: alu_type; -- ALU opeartion
 
--
-- bit set decoder table
--
component bset_rom is
port (
addr : in Std_Logic_Vector(2 downto 0);
data : out Std_Logic_Vector(7 downto 0)
);
end component bset_rom;
--
-- bit clear decoder table
--
component bclr_rom is
port (
addr : in Std_Logic_Vector(2 downto 0);
data : out Std_Logic_Vector(7 downto 0)
);
end component bclr_rom;
 
begin
 
rom_set : bset_rom port map (
addr => op(3 downto 1),
data => bset_data_out
);
 
rom_clear : bclr_rom port map (
addr => op(3 downto 1),
data => bclr_data_out
);
 
 
----------------------------------
--
-- opcode register
--
----------------------------------
 
op_reg: process( clk, op_ctrl, data_in, op )
begin
if clk'event and clk = '0' then
case op_ctrl is
when reset_op =>
op <= "10011101"; -- reset with NOP
when fetch_op =>
op <= data_in;
when others =>
-- when latch_op =>
op <= op;
end case;
end if;
end process;
 
-----------------------------------
--
-- accumulator
--
------------------------------------
ac_reg : process( clk, ac_ctrl, alu_out, ac, ix, data_in )
begin
if clk'event and clk = '0' then
case ac_ctrl is
when reset_ac => -- released from reset
ac <= "00000000";
when load_ac => -- single or dual operation
ac <= alu_out(7 downto 0);
when pull_ac => -- read acc / increment sp
ac <= data_in;
when others => -- halt on undefine states
-- when latch_ac => -- no operation on acc
ac <= ac;
end case;
end if;
end process;
 
------------------------------------
--
-- condition code register
--
------------------------------------
cc_reg : process( clk, cc_ctrl, cc_out )
begin
if clk'event and clk = '0' then
case cc_ctrl is
when reset_cc => -- released from reset
cc <= "00000";
when load_cc => -- single or dual operation
cc <= cc_out;
when pull_cc => -- read cc / increment sp
cc <= data_in(4 downto 0);
when others => -- halt on undefine states
-- when latch_cc => -- no operation on acc
cc <= cc;
end case;
end if;
end process;
 
------------------------------------
--
-- index register
--
------------------------------------
ix_reg : process( clk, ix_ctrl, alu_out, ac, ix, data_in )
begin
if clk'event and clk = '0' then
case ix_ctrl is
when reset_ix => -- released from reset
ix <= "00000000";
when load_ix => -- execute / = alu out
ix <= alu_out(7 downto 0);
when pull_ix => -- read ixreg / increment sp
ix <= data_in;
when others =>
-- when latch_ix => -- no change in ix
ix <= ix;
end case;
end if;
end process;
 
 
------------------------------------
--
-- stack pointer
--
------------------------------------
sp_reg : process( clk, sp_ctrl, sp )
begin
if clk'event and clk = '0' then
case sp_ctrl is
when reset_sp => -- released from reset
sp <= "1111111";
when inc_sp => -- pop registers
sp <= sp + 1;
when dec_sp => -- push registes
sp <= sp - 1;
when others =>
-- when latch_sp => -- no change in sp
sp <= sp;
end case;
end if;
end process;
 
------------------------------------
--
-- program counter
--
------------------------------------
pc_reg : process( clk, pc_ctrl, pc, ea, data_in )
variable offset : std_logic_vector(15 downto 0);
begin
if clk'event and clk = '0' then
case pc_ctrl is
when reset_pc => -- released from reset
pc <= "0000000000000000";
when inc_pc => -- fetch next opcode
pc <= pc + 1;
when jmp_pc => -- load pc with effective address
pc <= ea;
when bra_pc => -- add effective address to pc
if ea(7) = '0' then -- sign extend offset
offset := "00000000" & ea(7 downto 0);
else
offset := "11111111" & ea(7 downto 0);
end if;
pc <= pc + offset;
when pull_lo_pc => -- load pc lo byte from memory
pc(15 downto 8) <= pc(15 downto 8);
pc(7 downto 0) <= data_in;
when pull_hi_pc => -- load pc hi byte from memory
pc(15 downto 8) <= data_in;
pc(7 downto 0) <= pc(7 downto 0);
when others => -- halt on undefine states
-- when latch_pc => -- no change in pc
pc <= pc;
end case;
end if;
end process;
 
------------------------------------
--
-- effective address register
--
------------------------------------
ea_reg: process( clk, ea_ctrl, ea, pc, ix, data_in )
variable offset : std_logic_vector(15 downto 0);
begin
if clk'event and clk = '0' then
case ea_ctrl is
when reset_ea => -- released from reset / fetch
ea <= "0000000000000000";
when loadix_ea => -- load ea with index register
ea <= "00000000" & ix;
when addpc_ea => -- add pc to ea
if ea(7) = '0' then -- sign extend offset
offset := "00000000" & ea(7 downto 0);
else
offset := "11111111" & ea(7 downto 0);
end if;
ea <= offset + pc;
when addix_ea => -- add index register to ea
ea <= ea + ("00000000" & ix );
when fetch_first_ea => -- load ea lo byte from memory
ea(15 downto 8) <= "00000000";
ea(7 downto 0) <= data_in;
when fetch_next_ea => -- load ea with second from memory
ea(15 downto 8) <= ea(7 downto 0);
ea(7 downto 0) <= data_in;
when others => -- halt on undefine states
-- when latch_ea => -- no change in ea
ea <= ea;
end case;
end if;
end process;
 
----------------------------------
--
-- memory data register
-- latch memory byte input
--
----------------------------------
 
md_reg: process( clk, md_ctrl, data_in, md )
begin
if clk'event and clk = '0' then
case md_ctrl is
when reset_md =>
md <= "00000000";
when latch_md =>
md <= md;
when load_md => -- latch alu output
md <= alu_out(7 downto 0);
when fetch_md =>
md <= data_in;
when others =>
null;
end case;
end if;
end process;
 
----------------------------------
--
-- interrupt vector register
--
----------------------------------
 
iv_reg: process( clk, iv_ctrl, iv )
begin
if clk'event and clk = '0' then
case iv_ctrl is
when rst_iv =>
iv <= "111"; -- $FFFE/$FFFF
when swi_iv =>
iv <= "110"; -- $FFFC/$FFFD
when irq_iv =>
iv <= "101"; -- $FFFA/$FFFB
when tim_iv =>
iv <= "100"; -- $FFF8/$FFF9
when uart_iv =>
iv <= "011"; -- $FFFA/$FFFB
when others =>
-- when latch_iv =>
iv <= iv;
end case;
end if;
end process;
 
----------------------------------
--
-- Address output multiplexer
-- Work out which register to apply to the address bus
-- Note that the multiplexer output is asyncronous
--
----------------------------------
 
mux_addr: process( clk, addr_ctrl, pc, ea, sp, iv )
begin
case addr_ctrl is
when reset_addr => -- when held in reset
addr <= "1111111111111111";
vma <= '0';
rw <= '1';
when fetch_addr => -- fetch opcode from pc
addr <= pc;
vma <= '1';
rw <= '1';
when read_addr => -- read from memory
addr <= ea;
vma <= '1';
rw <= '1';
when write_addr => -- write to memory
addr <= ea;
vma <= '1';
rw <= '0';
when pull_addr => -- read from stack
addr <= ("000000001" & sp);
vma <= '1';
rw <= '1';
when push_addr => -- write to stack
addr <= ("000000001" & sp);
vma <= '1';
rw <= '0';
when vect_hi_addr => -- fetch interrupt vector hi
addr <= "111111111111" & iv & "0";
vma <= '1';
rw <= '1';
when vect_lo_addr => -- fetch interrupt vector lo
addr <= "111111111111" & iv & "1";
vma <= '1';
rw <= '1';
when others => -- undefined all high
addr <= "1111111111111111";
vma <= '0';
rw <= '1';
end case;
end process;
 
----------------------------------
--
-- Data Output Multiplexer
-- select data to be written to memory
-- note that the output is asynchronous
--
----------------------------------
 
mux_data: process( clk, data_ctrl, md, pc, cc, ac, ix )
variable data_out_v : std_logic_vector(7 downto 0);
begin
case data_ctrl is
when cc_data => -- save condition codes
data_out <= "000" & cc;
when ac_data => -- save accumulator
data_out <= ac;
when ix_data => -- save index register
data_out <= ix;
when pc_lo_data => -- save pc low byte
data_out <= pc(7 downto 0);
when pc_hi_data =>
data_out <= pc(15 downto 8); -- save pc high byte
when others =>
-- when md_data => -- alu latched output
data_out <= md;
end case;
end process;
 
----------------------------------
--
-- alu left mux
-- asynchronous input as register is already latched
--
----------------------------------
 
mux_left: process( clk, left_ctrl, ac, ix, md )
begin
case left_ctrl is
when ac_left =>
alu_left <= "0" & ac; -- dual op argument
when ix_left =>
alu_left <= "0" & ix; -- dual op argument
when md_left =>
alu_left <= "0" & md;
when others =>
alu_left <= "000000000";
end case;
end process;
 
 
----------------------------------
--
-- alu right mux
-- asynchronous input as register is already latched
--
----------------------------------
 
mux_right: process( clk, right_ctrl, data_in, bset_data_out, bclr_data_out, md )
begin
case right_ctrl is
when bset_right =>
alu_right <= "0" & bset_data_out;
when bclr_right =>
alu_right <= "0" & bclr_data_out;
when zero_right =>
alu_right <= "000000000";
when one_right =>
alu_right <= "000000001";
when others =>
-- when md_right =>
alu_right <= "0" & md; -- dual op argument
end case;
end process;
 
 
----------------------------------
--
-- Arithmetic Logic Unit
--
----------------------------------
 
mux_alu: process( clk, alu_ctrl, cc, alu_left, alu_right )
variable alu_v : std_logic_vector(8 downto 0);
variable low_v : std_logic_vector(4 downto 0);
variable high_v : std_logic_vector(4 downto 0);
begin
 
case alu_ctrl is
when alu_bset =>
alu_v := alu_left or alu_right; -- bit
when alu_bclr =>
alu_v := alu_left and alu_right; -- bclr
when alu_btst =>
alu_v := alu_left and alu_right; -- tst
when alu_add =>
low_v := ("0" & alu_left(3 downto 0)) + ("0" & alu_right(3 downto 0));
high_v := ("0" & alu_left(7 downto 4)) + ("0" & alu_right(7 downto 4)) + low_v(4);
alu_v := high_v(4 downto 0) & low_v(3 downto 0); -- add
when alu_adc =>
low_v := ("0" & alu_left(3 downto 0)) + ("0" & alu_right(3 downto 0)) + ("0000" & cc(CFLAG));
high_v := ("0" & alu_left(7 downto 4)) + ("0" & alu_right(7 downto 4)) + low_v(4);
alu_v := high_v(4 downto 0) & low_v(3 downto 0); -- adc
when alu_sub =>
alu_v := alu_left - alu_right; -- sub / cmp
when alu_sbc =>
alu_v := alu_left - alu_right - ("00000000" & cc(CFLAG)); -- sbc
when alu_and =>
alu_v := alu_left and alu_right; -- and/bit
when alu_ora =>
alu_v := alu_left or alu_right; -- or
when alu_eor =>
alu_v := alu_left xor alu_right; -- eor/xor
when alu_lsl =>
alu_v := alu_left(7 downto 0) & "0"; -- lsl
when alu_lsr =>
alu_v := alu_left(0) & "0" & alu_left(7 downto 1); -- lsr
when alu_asr =>
alu_v := alu_left(0) & alu_left(7) & alu_left(7 downto 1); -- asr
when alu_rol =>
alu_v := alu_left(7 downto 0) & cc(CFLAG); -- rol
when alu_ror =>
alu_v := alu_left(0) & cc(CFLAG) & alu_left(7 downto 1); -- ror
when alu_inc =>
alu_v := alu_left + "000000001"; -- inc
when alu_dec =>
alu_v := alu_left(8 downto 0) - "000000001"; -- dec
when alu_neg =>
alu_v := "000000000" - alu_left(8 downto 0); -- neg
when alu_com =>
alu_v := not alu_left(8 downto 0); -- com
when alu_clr =>
alu_v := "000000000"; -- clr
when alu_ld =>
alu_v := alu_right(8 downto 0);
when alu_st =>
alu_v := alu_left(8 downto 0);
when others =>
alu_v := alu_left(8 downto 0); -- nop
end case;
 
--
-- carry bit
--
case alu_ctrl is
when alu_add | alu_adc | alu_sub | alu_sbc |
alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
alu_neg | alu_com =>
cc_out(CFLAG) <= alu_v(8);
when alu_btst =>
cc_out(CFLAG) <= not( alu_v(7) or alu_v(6) or alu_v(5) or alu_v(4) or
alu_v(3) or alu_v(2) or alu_v(1) or alu_v(0) );
when alu_sec =>
cc_out(CFLAG) <= '1';
when alu_clc =>
cc_out(CFLAG) <= '0';
when others =>
cc_out(CFLAG) <= cc(CFLAG);
end case;
 
--
-- Zero flag
--
case alu_ctrl is
when alu_add | alu_adc | alu_sub | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
alu_ld | alu_st =>
cc_out(ZFLAG) <= not( alu_v(7) or alu_v(6) or alu_v(5) or alu_v(4) or
alu_v(3) or alu_v(2) or alu_v(1) or alu_v(0) );
when others =>
cc_out(ZFLAG) <= cc(ZFLAG);
end case;
 
--
-- negative flag
--
case alu_ctrl is
when alu_add | alu_adc | alu_sub | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
alu_ld | alu_st =>
cc_out(NFLAG) <= alu_v(7);
when others =>
cc_out(NFLAG) <= cc(NFLAG);
end case;
 
--
-- Interrupt mask flag
--
case alu_ctrl is
when alu_sei =>
cc_out(IFLAG) <= '1'; -- set interrupt mask
when alu_cli =>
cc_out(IFLAG) <= '0'; -- clear interrupt mask
when others =>
cc_out(IFLAG) <= cc(IFLAG); -- interrupt mask
end case;
 
--
-- Half Carry flag
--
case alu_ctrl is
when alu_add | alu_adc =>
cc_out(HFLAG) <= low_v(4);
when others =>
cc_out(HFLAG) <= cc(HFLAG);
end case;
 
alu_out <= alu_v;
 
end process;
 
 
------------------------------------
--
-- state sequencer
--
------------------------------------
 
sequencer : process( state, data_in,
ac, cc, ix, sp, ea, md, pc, op,
irq_ext, irq_timer, irq_uart )
begin
case state is
--
-- RESET:
-- Here if processor held in reset
-- On release of reset go to RESET1
--
when reset_state => -- release from reset
ac_ctrl <= reset_ac;
cc_ctrl <= reset_cc;
ix_ctrl <= reset_ix;
sp_ctrl <= reset_sp;
pc_ctrl <= reset_pc;
op_ctrl <= reset_op;
ea_ctrl <= reset_ea;
md_ctrl <= reset_md;
iv_ctrl <= rst_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= reset_addr; -- address bus mutiplexer
data_ctrl <= md_data; -- data output mutiplexer
next_state <= reset1_state;
--
-- RESET1:
-- address bus = reset vector hi
-- Load PC high with high byte
-- go to RESET2
--
when reset1_state => -- fetch hi reset vector
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
pc_ctrl <= pull_hi_pc;
op_ctrl <= latch_op;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= vect_hi_addr;
data_ctrl <= md_data; -- data output mutiplexer
next_state <= reset2_state;
--
-- RESET2:
-- address bus = reset vector lo
-- Load PC low with low byte
-- go to FETCH
--
when reset2_state => -- fetch low reset vector
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
pc_ctrl <= pull_lo_pc;
op_ctrl <= latch_op;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= vect_lo_addr;
data_ctrl <= md_data; -- data output mutiplexer
next_state <= fetch_state;
--
-- FETCH:
-- fetch opcode,
-- advance the pc,
-- clear the effective address (ea) register
-- goto DECODE
--
when fetch_state => -- fetch instruction
case op(7 downto 4) is
-- when "0000" => -- BRSET/ BRCLR
-- null;
-- when "0001" => -- BSET/ BCLR
-- null;
-- when "0010" => -- BR conditional
-- null;
-- when "0011" => -- single op direct
-- null;
when "0100" => -- single op accum
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
case op( 3 downto 0 ) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr;
when "1000" => -- lsl
right_ctrl <= zero_right;
alu_ctrl <= alu_lsl;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
when "1011" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_tst;
when "1110" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_clr;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
end case;
 
when "0101" => -- single op ix reg
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= load_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
case op( 3 downto 0 ) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr;
when "1000" => -- lsl
right_ctrl <= zero_right;
alu_ctrl <= alu_lsl;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
when "1011" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_tst;
when "1110" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_clr;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
end case;
-- when "0110" => -- single op IX1
-- null;
-- when "0111" => -- single op IX0
-- null;
-- when "1000" => -- inherent stack operators
-- null;
when "1001" => -- inherent operators
case op( 3 downto 0 ) is
-- when "0000" => -- undef
-- null;
-- when "0001" => -- undef
-- null;
-- when "0010" => -- undef
-- null;
-- when "0011" => -- undef
-- null;
-- when "0100" => -- undef
-- null;
-- when "0101" => -- undef
-- null;
-- when "0110" => -- undef
-- null;
when "0111" => -- tax
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= load_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_st;
 
when "1000" => -- clc
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_clc;
 
when "1001" => -- sec
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_sec;
 
when "1010" => -- cli
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_cli;
 
when "1011" => -- sei
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_sei;
 
when "1100" => -- rsp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= reset_sp;
left_ctrl <= ac_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_nop;
 
-- when "1101" => -- nop
-- null;
-- when "1110" => -- undef
-- null;
when "1111" => -- txa
ac_ctrl <= load_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_st;
 
when others =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_nop;
end case;
--
-- dual operand addressing modes
--
when "1010" | -- dual op imm
"1011" | -- dual op dir
"1100" | -- dual op ext
"1101" | -- dual op ix2
"1110" | -- dual op ix1
"1111" => -- dual op ix0
case op( 3 downto 0 ) is
when "0000" => -- sub
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub;
when "0001" => -- cmp
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub;
when "0010" => -- sbc
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sbc;
when "0011" => -- cpx
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub;
when "0100" => -- and
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
when "0101" => -- bit
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
when "0110" => -- lda
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld;
when "0111" => -- sta
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st;
when "1000" => -- eor
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_eor;
when "1001" => -- adc
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_adc;
when "1010" => -- ora
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ora;
when "1011" => -- add
ac_ctrl <= load_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add;
-- when "1100" => -- jmp
-- null;
-- when "1101" => -- jsr
-- null;
when "1110" => -- ldx
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= load_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld;
when "1111" => -- stx
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st;
when others =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
end case;
when others =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= ac_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
end case;
 
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= inc_pc;
op_ctrl <= fetch_op;
addr_ctrl <= fetch_addr;
data_ctrl <= md_data; -- data output mutiplexer
if irq_ext = '1' and cc(IFLAG) = '0' then
iv_ctrl <= irq_iv;
next_state <= int_state;
elsif irq_timer = '1' and cc(IFLAG) = '0' then
iv_ctrl <= tim_iv;
next_state <= int_state;
elsif irq_uart = '1' and cc(IFLAG) = '0' then
iv_ctrl <= uart_iv;
next_state <= int_state;
else
iv_ctrl <= latch_iv;
next_state <= decode_state;
end if;
--
-- DECODE:
-- decode the new opcode,
-- fetch the next byte into the low byte of the ea ,
-- work out if you need to advance the pc, (two or three byte op)
-- work out the next state based on the addressing mode.
-- evaluate conditional branch execution
--
when decode_state => -- decode instruction / fetch next byte
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_md;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= fetch_addr;
data_ctrl <= md_data; -- data output mutiplexer
case op(7 downto 4) is -- addressing modes
--
-- branch on bit set / clear
--
when "0000" =>
pc_ctrl <= inc_pc; -- advance the pc
next_state <= dir_state;
--
-- bit set / clear direct page
--
when "0001" =>
pc_ctrl <= inc_pc; -- advance the pc
next_state <= dir_state;
--
-- branch on condition codes
-- if condtion = true
-- go to "branch" state
-- if conition = false
-- go to "fetch" state
--
when "0010" =>
pc_ctrl <= inc_pc; -- advance the pc
case op(3 downto 0) is
when "0000" => -- bra
next_state <= branch_state;
when "0001" => -- brn
next_state <= fetch_state;
when "0010" => -- bhi
if cc(CFLAG) = '0' and cc(ZFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "0011" => -- bls
if cc(CFLAG) = '1' or cc(ZFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "0100" => -- bcc
if cc(CFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "0101" => -- bcs
if cc(CFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "0110" => -- bne
if cc(ZFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "0111" => -- beq
if cc(ZFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1000" => -- bhcc
if cc(HFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1001" => -- bhcs
if cc(HFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1010" => -- bpl
if cc(NFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1011" => -- bmi
if cc(NFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1100" => -- bmc
if cc(IFLAG) = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1101" => -- bms
if cc(IFLAG) = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1110" => -- bil
if irq_ext = '0' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when "1111" => -- bih
if irq_ext = '1' then
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
when others =>
null;
end case; -- end of conditional branch decode
--
-- Single Operand direct addressing
--
when "0011" =>
pc_ctrl <= inc_pc; -- advance the pc (2 byte instruction)
next_state <= dir_state;
--
-- Single Operand accumulator
--
when "0100" =>
pc_ctrl <= latch_pc;
next_state <= fetch_state;
--
-- Single Operand index register
--
when "0101" =>
pc_ctrl <= latch_pc;
next_state <= fetch_state;
--
-- Single Operand memory 8 bit indexed
--
when "0110" =>
pc_ctrl <= inc_pc; -- advance the pc (2 byte instruction)
next_state <= ix1_state;
--
-- Single Operand memory 0 bit indexed
--
when "0111" =>
pc_ctrl <= latch_pc; -- hold the pc (1 byte instruction)
next_state <= ix0_state;
--
-- stack and interrupt operators
--
when "1000" =>
pc_ctrl <= latch_pc;
case op(3 downto 0) is
when "0000" =>
next_state <= rti_state;
when "0001" =>
next_state <= rts_state;
when "0011" =>
next_state <= swi_state;
when "1110" =>
next_state <= stop_state;
when "1111" =>
next_state <= wait_state;
when others =>
next_state <= fetch_state;
end case; -- end of stack decode
--
-- Inherent operators
--
when "1001" =>
pc_ctrl <= latch_pc;
next_state <= fetch_state;
--
-- dual operand immediate addressing
--
when "1010" =>
pc_ctrl <= inc_pc; -- advance the pc (2 byte instruction)
case op(3 downto 0) is
when "1101" => -- bsr
next_state <= bsr_state;
when others =>
next_state <= fetch_state;
end case;
--
-- dual operand direct addressing
--
when "1011" =>
pc_ctrl <= inc_pc; -- advance the pc (2 byte instruction)
next_state <= dir_state;
--
-- dual operand extended addressing
--
when "1100" =>
pc_ctrl <= inc_pc; -- advance the pc (3 byte instruction)
next_state <= ext_state;
--
-- dual operand 16 bit indexed addressing
--
when "1101" =>
pc_ctrl <= inc_pc; -- advance the pc (3 byte instruction)
next_state <= ix2_state;
--
-- dual operand 8 bit indexed addressing
--
when "1110" =>
pc_ctrl <= inc_pc; -- advance the pc (3 byte instruction)
next_state <= ix1_state;
--
-- dual operand direct page indexed addressing
--
when "1111" =>
pc_ctrl <= latch_pc;
next_state <= ix0_state;
--
-- catch undefined states
--
when others =>
pc_ctrl <= latch_pc;
next_state <= fetch_state;
end case;
-- end of instruction decode state
--
-- perform addressing state sequence
--
when ext_state => -- fetch second address byte
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
cc_ctrl <= latch_cc;
pc_ctrl <= inc_pc;
ea_ctrl <= fetch_next_ea;
op_ctrl <= latch_op;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= fetch_addr; -- read effective address
data_ctrl <= pc_lo_data; -- read memory data
next_state <= dir_state;
 
when ix2_state => -- fetch second index offest byte
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
cc_ctrl <= latch_cc;
pc_ctrl <= inc_pc;
ea_ctrl <= fetch_next_ea;
op_ctrl <= latch_op;
md_ctrl <= fetch_md;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= fetch_addr;
data_ctrl <= pc_lo_data;
next_state <= ix1_state;
 
when ix1_state => -- add ixreg to effective address
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
cc_ctrl <= latch_cc;
pc_ctrl <= latch_pc;
ea_ctrl <= addix_ea;
op_ctrl <= latch_op;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr;
data_ctrl <= pc_lo_data;
next_state <= dir_state;
 
when ix0_state => -- load effective address with ixreg
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= loadix_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr;
data_ctrl <= pc_lo_data;
next_state <= dir_state;
 
when dir_state => -- read memory cycle
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
data_ctrl <= pc_lo_data;
case op(7 downto 4) is
when "0000" | -- BRSET / BRCLR
"0001" | -- BSET / BCLR
"0011" | -- single op DIR
"0110" | -- single op IX1
"0111" => -- single op IX0
md_ctrl <= fetch_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= read_addr; -- read effective address
next_state <= exec_state;
when "1011" | -- dual op direct
"1100" | -- dual op extended
"1101" | -- dual op ix2
"1110" | -- dual op ix1
"1111" => -- dual op ix0
case op(3 downto 0) is
when "0111" => -- sta
md_ctrl <= load_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_st; -- ALU opeartion
addr_ctrl <= idle_addr; -- read effective address
next_state <= write_state;
when "1100" => -- jmp
md_ctrl <= latch_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr; -- idle address
next_state <= jmp_state;
when "1101" => -- jsr
md_ctrl <= latch_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr; -- idle address
next_state <= jsr_state;
when "1111" => -- stx
md_ctrl <= load_md;
left_ctrl <= ix_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_st; -- ALU opeartion
addr_ctrl <= idle_addr; -- read effective address
next_state <= write_state;
when others =>
md_ctrl <= fetch_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= read_addr; -- read effective address
next_state <= fetch_state;
end case;
when others =>
md_ctrl <= fetch_md;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= read_addr; -- read effective address
next_state <= fetch_state;
end case;
 
--
-- EXECUTE:
-- decode opcode
-- to determine if output of the ALU is transfered to a register
-- or if alu output is written back to memory
--
-- if opcode = dual operand or
-- opcode = single operand accum / ixreg or
-- opcode = branch on bit then
-- goto fetch_state
--
-- if opcode = single operand memory or
-- opcode = bit set / clear or
-- goto write_state
--
when exec_state => -- execute alu operation
pc_ctrl <= latch_pc;
ea_ctrl <= latch_ea;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
 
case op(7 downto 4) is
when "0000" => -- branch set / clear
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= md_left;
right_ctrl <= bset_right;
alu_ctrl <= alu_btst;
md_ctrl <= load_md;
cc_ctrl <= load_cc;
next_state <= brbit_state;
 
when "0001" => -- bit set / clear
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
case op(0) is
when '0' => -- bset
left_ctrl <= md_left;
right_ctrl <= bset_right;
alu_ctrl <= alu_ora;
md_ctrl <= load_md;
cc_ctrl <= load_cc;
 
when '1' => -- bclr
left_ctrl <= md_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_and;
md_ctrl <= load_md;
cc_ctrl <= load_cc;
 
when others =>
left_ctrl <= md_left;
right_ctrl <= bclr_right;
alu_ctrl <= alu_nop;
md_ctrl <= latch_md;
cc_ctrl <= latch_cc;
end case;
next_state <= write_state;
 
when "0011" | -- single op direct
"0110" | -- single op ix1
"0111" => -- single op ix0
ac_ctrl <= latch_ac;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
left_ctrl <= md_left;
md_ctrl <= load_md;
cc_ctrl <= load_cc;
case op( 3 downto 0 ) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr;
when "1000" => -- lsl
right_ctrl <= zero_right;
alu_ctrl <= alu_lsl;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
when "1011" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_tst;
when "1110" => -- undef
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_clr;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
end case;
next_state <= write_state;
 
when others =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
md_ctrl <= latch_md;
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
next_state <= fetch_state;
end case;
--
-- WRITE:
-- write latched alu output to memory pointed to by ea register
-- go to fetch state
--
when write_state => -- write alu output to memory
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
addr_ctrl <= write_addr;
data_ctrl <= md_data; -- select latched alu output to data bus
next_state <= fetch_state;
--
-- BRBIT
-- Branch on condition of bit
-- fetch the address offset
-- advance the pc
-- evaluate the carry bit to determine if we take the branch
-- Carry = 0 if tested bit set
-- Carry = 1 if tested bit clear
-- op(0) = 0 if BRSET
-- op(0) = 1 if BRCLR
-- if carry = '1'
-- goto branch state
-- else
-- goto execute state
--
when brbit_state => -- fetch address offset
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= fetch_first_ea;
md_ctrl <= latch_md;
pc_ctrl <= inc_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
addr_ctrl <= fetch_addr;
data_ctrl <= md_data; -- select latched alu output to data bus
if (cc(CFLAG) xor op(0)) = '0' then -- check this ... I think it's right
next_state <= branch_state;
else
next_state <= fetch_state;
end if;
 
--
-- BRANCH:
-- take conditional branch
-- branch (pc relative addressing)
-- add effective address (ea register) to pc
-- go to "fetch" state
---
when branch_state => -- calculate branch address
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= bra_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr; -- idle address bus
data_ctrl <= md_data; -- read memory data
next_state <= fetch_state;
--
-- jump to subroutine
--
when bsr_state => -- calculate effective jump address
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= addpc_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
next_state <= jsr_state;
 
when jsr_state => -- store pc low / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr; -- write stack address
data_ctrl <= pc_lo_data; -- write PC low
next_state <= jsr1_state;
 
when jsr1_state => -- store pc high / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr; -- write stack address
data_ctrl <= pc_hi_data; -- write PC high
next_state <= jmp_state;
--
-- jump to address
--
when jmp_state => -- load pc with effective address
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= jmp_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion (do nothing)
addr_ctrl <= idle_addr; -- idle address
data_ctrl <= pc_lo_data; --
next_state <= fetch_state;
--
-- return from subroutine
--
when rts_state => -- increment stack pointer
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
next_state <= rts_pch_state;
 
when rts_pch_state => -- load pc high return address / increment sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_hi_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr;
data_ctrl <= pc_hi_data;
next_state <= rts_pcl_state;
 
when rts_pcl_state => -- load pc low return address
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_lo_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr;
data_ctrl <= pc_lo_data;
next_state <= fetch_state;
 
--
--
-- return from interrupt
--
when rti_state => -- increment sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= fetch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
next_state <= rti_cc_state;
 
when rti_cc_state => -- read cc / increment sp
ac_ctrl <= latch_ac;
cc_ctrl <= pull_cc; -- read Condition codes
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr; -- read stack address
data_ctrl <= cc_data; -- output old CC
next_state <= rti_ac_state;
 
when rti_ac_state => -- read acc / increment sp
ac_ctrl <= pull_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr; -- read stack address
data_ctrl <= ac_data; -- output Accumulator
next_state <= rti_ix_state;
 
when rti_ix_state => -- read ix / increment sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= pull_ix; -- read IX register
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr; -- read stack address
data_ctrl <= ix_data; -- output old ix register
next_state <= rti_pch_state;
 
when rti_pch_state => -- read pc hi / increment sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= inc_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_hi_pc; -- read PC high
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr; -- read stack address
data_ctrl <= pc_hi_data; -- output old PC high
next_state <= rti_pcl_state;
 
when rti_pcl_state => -- read pc lo
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_lo_pc; -- read PC low
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= pull_addr; -- read stack address
data_ctrl <= pc_lo_data; -- output old PC Low
next_state <= fetch_state;
--
-- sofwtare interrupt (or any others interrupt state)
--
when swi_state =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= swi_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
next_state <= int_state;
 
--
-- any sort of interrupt
--
when int_state => -- store pc low / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr;
data_ctrl <= pc_lo_data;
next_state <= int1_state;
 
when int1_state => -- store pc hi / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr;
data_ctrl <= pc_hi_data;
next_state <= int2_state;
 
when int2_state => -- store ix / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr;
data_ctrl <= ix_data;
next_state <= int3_state;
 
when int3_state => -- store ac / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr;
data_ctrl <= ac_data;
next_state <= int4_state;
 
when int4_state => -- store cc / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU opeartion
addr_ctrl <= push_addr;
data_ctrl <= cc_data;
next_state <= int5_state;
 
when int5_state => -- fetch pc hi = int vector hi
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_hi_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_sei; -- ALU operation
addr_ctrl <= vect_hi_addr;
data_ctrl <= pc_hi_data;
next_state <= int6_state;
 
when int6_state => -- fetch pc low = int vector low
ac_ctrl <= latch_ac;
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= pull_lo_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_sei; -- ALU operation
addr_ctrl <= vect_lo_addr;
data_ctrl <= pc_lo_data;
next_state <= fetch_state;
--
-- stop the processor
--
when stop_state =>
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= idle_addr;
data_ctrl <= md_data;
next_state <= stop_state;
--
-- wait for interrupt
--
when wait_state => -- push pclow / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= push_addr;
data_ctrl <= pc_lo_data;
next_state <= wait1_state;
 
when wait1_state => -- push pchi / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= push_addr;
data_ctrl <= pc_hi_data;
next_state <= wait2_state;
 
when wait2_state => -- push ix / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= push_addr;
data_ctrl <= ix_data;
next_state <= wait3_state;
 
when wait3_state => -- push ac / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= push_addr;
data_ctrl <= ac_data;
next_state <= wait4_state;
 
when wait4_state => -- push cc / decrement sp
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= dec_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= ac_left; -- Left ALU input
right_ctrl <= md_right; -- Right ALU input
alu_ctrl <= alu_nop; -- ALU operation
addr_ctrl <= push_addr;
data_ctrl <= cc_data;
next_state <= halt_state;
--
-- halt cpu
--
when halt_state => -- halt on halt
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
addr_ctrl <= idle_addr;
data_ctrl <= md_data; -- select latched alu output to data bus
next_state <= halt_state;
--
-- undefined instruction
--
when others => -- halt on undefine states
ac_ctrl <= latch_ac;
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
sp_ctrl <= latch_sp;
ea_ctrl <= latch_ea;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
op_ctrl <= latch_op;
iv_ctrl <= latch_iv;
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
addr_ctrl <= idle_addr;
data_ctrl <= md_data; -- select latched alu output to data bus
next_state <= halt_state;
 
end case;
 
end process;
--------------------------------
--
-- state machine
--
--------------------------------
 
change_state: process( clk, rst, state )
begin
if rst = '1' then
state <= reset_state;
elsif clk'event and clk = '0' then
state <= next_state;
end if;
end process;
-- output
end CPU_ARCH;
/system05/trunk/rtl/vhdl/ioport.vhd
0,0 → 1,312
--===========================================================================--
--
-- S Y N T H E Z I A B L E ioport Quad 8 Bit I/O port
--
-- This core adheres to the GNU public license
--
-- File name : ioport.vhd
--
-- Purpose : Implements 4 x 8 bit bi-directional I/O ports
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Initial version John Kent - 6 Sept 2002
-- Cleaned up 30th May 2004
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity ioport is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0);
portc_io : inout std_logic_vector(7 downto 0);
portd_io : inout std_logic_vector(7 downto 0) );
end;
 
architecture ioport_arch of ioport is
signal porta_ddr : std_logic_vector(7 downto 0);
signal portb_ddr : std_logic_vector(7 downto 0);
signal portc_ddr : std_logic_vector(7 downto 0);
signal portd_ddr : std_logic_vector(7 downto 0);
signal porta_data : std_logic_vector(7 downto 0);
signal portb_data : std_logic_vector(7 downto 0);
signal portc_data : std_logic_vector(7 downto 0);
signal portd_data : std_logic_vector(7 downto 0);
 
begin
 
 
--------------------------------
--
-- read I/O port
--
--------------------------------
 
ioport_read : process( addr,
porta_ddr, portb_ddr, portc_ddr, portd_ddr,
porta_data, portb_data, portc_data, portd_data,
porta_io, portb_io, portc_io, portd_io )
variable count : integer;
begin
case addr is
 
when "000" =>
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
data_out(count) <= porta_data(count);
else
data_out(count) <= porta_io(count);
end if;
end loop;
 
when "001" =>
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
data_out(count) <= portb_data(count);
else
data_out(count) <= portb_io(count);
end if;
end loop;
 
when "010" =>
for count in 0 to 7 loop
if portc_ddr(count) = '1' then
data_out(count) <= portc_data(count);
else
data_out(count) <= portc_io(count);
end if;
end loop;
 
when "011" =>
for count in 0 to 7 loop
if portd_ddr(count) = '1' then
data_out(count) <= portd_data(count);
else
data_out(count) <= portd_io(count);
end if;
end loop;
 
when "100" =>
data_out <= porta_ddr;
 
when "101" =>
data_out <= portb_ddr;
 
when "110" =>
data_out <= portc_ddr;
 
when "111" =>
data_out <= portd_ddr;
 
when others =>
data_out <= "00000000";
end case;
end process;
 
---------------------------------
--
-- Write I/O ports
--
---------------------------------
 
ioport_write : process( clk, rst, addr, cs, rw, data_in,
porta_data, portb_data, portc_data, portd_data,
porta_ddr, portb_ddr, portc_ddr, portd_ddr )
begin
if clk'event and clk = '0' then
if rst = '1' then
porta_data <= "00000000";
portb_data <= "00000000";
portc_data <= "00000000";
portd_data <= "00000000";
porta_ddr <= "00000000";
portb_ddr <= "00000000";
portc_ddr <= "00000000";
portd_ddr <= "00000000";
elsif cs = '1' and rw = '0' then
case addr is
when "000" =>
porta_data <= data_in;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "001" =>
porta_data <= porta_data;
portb_data <= data_in;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "010" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= data_in;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "011" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= data_in;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "100" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= data_in;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "101" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= data_in;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
when "110" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= data_in;
portd_ddr <= portd_ddr;
when "111" =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= data_in;
when others =>
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
end case;
else
porta_data <= porta_data;
portb_data <= portb_data;
portc_data <= portc_data;
portd_data <= portd_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
portc_ddr <= portc_ddr;
portd_ddr <= portd_ddr;
end if;
end if;
end process;
 
---------------------------------
--
-- direction control port a
--
---------------------------------
porta_direction : process ( porta_data, porta_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
porta_io(count) <= porta_data(count);
else
porta_io(count) <= 'Z';
end if;
end loop;
end process;
 
---------------------------------
--
-- direction control port b
--
---------------------------------
portb_direction : process ( portb_data, portb_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
portb_io(count) <= portb_data(count);
else
portb_io(count) <= 'Z';
end if;
end loop;
end process;
 
---------------------------------
--
-- direction control port c
--
---------------------------------
portc_direction : process ( portc_data, portc_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if portc_ddr(count) = '1' then
portc_io(count) <= portc_data(count);
else
portc_io(count) <= 'Z';
end if;
end loop;
end process;
 
---------------------------------
--
-- direction control port d
--
---------------------------------
portd_direction : process ( portd_data, portd_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if portd_ddr(count) = '1' then
portd_io(count) <= portd_data(count);
else
portd_io(count) <= 'Z';
end if;
end loop;
end process;
 
end ioport_arch;
/system05/trunk/rtl/vhdl/rxunit3.vhd
0,0 → 1,396
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : rxunit3.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the cpu68 cpu and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164.all;
-- ieee.numeric_std.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
-- 3.2 John Kent 10 January 2004 Rewrite of code.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Implements the receive unit of the miniUART core. Samples
-- 16 times the RxD line and retain the value in the middle of
-- the time interval.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Receive unit
-------------------------------------------------------------------------------
entity RxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
ReadD : in Std_Logic; -- Read data signal
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
RxClk : in Std_Logic; -- RS-232 clock input
RxDat : in Std_Logic; -- RS-232 data input
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0)
);
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for receive Unit
-------------------------------------------------------------------------------
architecture Behaviour of RxUnit is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxDebDel0 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel1 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel2 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel3 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDeb : Std_Logic; -- Debounced Rx Data
signal RxDatDel : Std_Logic; -- Delayed Rx Data
signal RxDatEdge : Std_Logic; -- Rx Data Edge pulse
signal RxClkDel : Std_Logic; -- Delayed Rx Input Clock
signal RxClkEdge : Std_Logic; -- Rx Input Clock Edge pulse
signal RxClkCnt : Std_Logic_Vector(5 downto 0); -- Rx Baud Clock Counter
signal RxBdClk : Std_Logic; -- Rx Baud Clock
signal RxBdDel : Std_Logic; -- Delayed Rx Baud Clock
signal RxBdEdge : Std_Logic; -- Rx Baud Clock Edge pulse
signal RxStart : Std_Logic; -- Rx Start bit detected
 
signal tmpDRdy : Std_Logic; -- Data Ready flag
signal RxValid : Std_Logic; -- Rx Data Valid
signal tmpRxVal : Std_Logic; -- Rx Data Valid
signal outErr : Std_Logic; -- Over run error bit
signal frameErr : Std_Logic; -- Framing error bit
signal ParityErr : Std_Logic; -- Parity Error Bit
signal RxParity : Std_Logic; -- Calculated RX parity bit
signal RxState : Std_Logic_Vector(3 downto 0); -- receive bit state
signal ShtReg : Std_Logic_Vector(7 downto 0); -- Shift Register
signal DataOut : Std_Logic_Vector(7 downto 0); -- Data Output register
 
begin
 
---------------------------------------------------------------------
-- Receiver Data Debounce
-- Input level must be stable for 4 Receive Clock cycles.
---------------------------------------------------------------------
rxunit_data_debounce : process(Clk, Reset, RxClkEdge, RxDat,
RxDebDel0, RxDebDel1, RxDebDel2, RxDebDel3 )
begin
if Reset = '1' then
RxDebDel0 <= RxDat;
RxDebDel1 <= RxDat;
RxDebDel2 <= RxDat;
RxDebDel3 <= RxDat;
elsif Clk'event and Clk = '0' then
if RxClkEdge = '1' then
RxDebDel0 <= RxDat;
RxDebDel1 <= RxDebDel0;
RxDebDel2 <= RxDebDel1;
RxDebDel3 <= RxDebDel2;
if (RxDebDel3 or RxDebDel2 or RxDebDel1 or RxDebDel0) = '0' then
RxDeb <= '0';
elsif (RxDebDel3 and RxDebDel2 and RxDebDel1 and RxDebDel0) = '1' then
RxDeb <= '1';
else
RxDeb <= RxDeb;
end if;
else
RxDebDel0 <= RxDebDel0;
RxDebDel1 <= RxDebDel1;
RxDebDel2 <= RxDebDel2;
RxDebDel3 <= RxDebDel3;
RxDeb <= RxDeb;
end if;
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Data Edge Detection
-- A falling edge will produce a one clock cycle pulse
---------------------------------------------------------------------
rxunit_data_edge : process(Clk, Reset, RxDeb, RxDatDel )
begin
if Reset = '1' then
RxDatDel <= RxDeb;
RxDatEdge <= '0';
elsif Clk'event and Clk = '0' then
RxDatDel <= RxDeb;
RxDatEdge <= RxDatDel and (not RxDeb);
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Edge Detection
-- A rising edge will produce a one clock cycle pulse
-- RxClock
---------------------------------------------------------------------
rxunit_clock_edge : process(Clk, Reset, RxClk, RxClkDel )
begin
if Reset = '1' then
RxClkDel <= RxClk;
RxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
RxClkDel <= RxClk;
RxClkEdge <= RxClk and (not RxClkDel);
end if;
end process;
 
 
---------------------------------------------------------------------
-- Receiver Clock Divider
-- Reset the Rx Clock divider on any data edge
-- Note that debounce data will be skewed by 4 clock cycles.
-- Advance the count only on an input clock pulse
---------------------------------------------------------------------
rxunit_clock_divide : process(Clk, Reset, RxDatEdge, RxState, RxStart,
RxClkEdge, RxClkCnt )
begin
if Reset = '1' then
RxClkCnt <= "000000";
RxStart <= '0';
elsif Clk'event and Clk = '0' then
 
if RxState = "1111" then -- idle state
if RxStart = '0' then -- in hunt mode
if RxDatEdge = '1' then -- falling edge starts counter
RxStart <= '1';
else
RxStart <= RxStart; -- other wise remain halted
end if;
else
RxStart <= RxStart; -- Acquired start, stay in this state
end if;
else
RxStart <= '0'; -- non idle, reset start flag
end if; -- RxState
 
if RxState = "1111" and RxStart = '0' then
RxClkCnt <= "000011"; -- Reset to 3 to account for debounce skew
else
if RxClkEdge = '1' then
RxClkCnt <= RxClkCnt + "000001";
else
RxClkCnt <= RxClkCnt;
end if; -- RxClkEdge
end if; -- RxState
end if; -- clk / reset
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Selector
-- Select output then look for rising edge
---------------------------------------------------------------------
rxunit_clock_select : process(Clk, Reset, BdFmt, RxClk, RxClkCnt,
RxBdDel, RxBdEdge )
begin
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
case BdFmt is
when "00" => -- Div by 1
RxBdClk <= RxClk;
when "01" => -- Div by 16
RxBdClk <= RxClkCnt(3);
when "10" => -- Div by 64
RxBdClk <= RxClkCnt(5);
when others => -- reset
RxBdClk <= '0';
end case;
 
if Reset = '1' then
RxBdDel <= RxBdClk;
RxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
RxBdDel <= RxBdClk;
RxBdEdge <= RxBdClk and (not RxBdDel);
end if;
 
end process;
 
 
---------------------------------------------------------------------
-- Receiver process
---------------------------------------------------------------------
rxunit_receive : process(Clk, Reset, RxState, RxBdEdge, RxDat )
begin
if Reset = '1' then
frameErr <= '0';
outErr <= '0';
parityErr <= '0';
 
ShtReg <= "00000000"; -- Shift register
DataOut <= "00000000";
RxParity <= '0'; -- Parity bit
RxValid <= '0'; -- Data RX data valid flag
RxState <= "1111";
elsif Clk'event and Clk='0' then
if RxBdEdge = '1' then
case RxState is
when "0000" | "0001" | "0010" | "0011" |
"0100" | "0101" | "0110" => -- data bits 0 to 6
ShtReg <= RxDat & ShtReg(7 downto 1);
RxParity <= RxParity xor RxDat;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxState = "0110" then
if WdFmt(2) = '0' then
RxState <= "1000"; -- 7 data + parity
else
RxState <= "0111"; -- 8 data bits
end if; -- WdFmt(2)
else
RxState <= RxState + "0001";
end if; -- RxState
 
when "0111" => -- data bit 7
ShtReg <= RxDat & ShtReg(7 downto 1);
RxParity <= RxParity xor RxDat;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if WdFmt(1) = '1' then -- parity bit ?
RxState <= "1000"; -- yes, go to parity
else
RxState <= "1001"; -- no, must be 2 stop bit bits
end if;
 
when "1000" => -- parity bit
if WdFmt(2) = '0' then
ShtReg <= RxDat & ShtReg(7 downto 1); -- 7 data + parity
else
ShtReg <= ShtReg; -- 8 data + parity
end if;
RxParity <= RxParity;
if WdFmt(0) = '0' then -- parity polarity ?
if RxParity = RxDat then -- check even parity
parityErr <= '1';
else
parityErr <= '0';
end if;
else
if RxParity = RxDat then -- check for odd parity
parityErr <= '0';
else
parityErr <= '1';
end if;
end if;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxState <= "1001";
 
when "1001" => -- stop bit (Only one required for RX)
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
if RxDat = '1' then -- stop bit expected
frameErr <= '0'; -- yes, no framing error
else
frameErr <= '1'; -- no, framing error
end if;
if tmpDRdy = '1' then -- Has previous data been read ?
outErr <= '1'; -- no, overrun error
else
outErr <= '0'; -- yes, no over run error
end if;
RxValid <= '1';
DataOut <= ShtReg;
RxState <= "1111";
 
when others => -- this is the idle state
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxDat = '0' then -- look for start request
RxState <= "0000"; -- yes, read data
else
RxState <= "1111"; -- otherwise idle
end if;
end case; -- RxState
else -- RxBdEdge
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= RxValid;
DataOut <= DataOut;
RxState <= RxState;
end if; -- RxBdEdge
end if; -- clk / reset
end process;
 
 
---------------------------------------------------------------------
-- Receiver Read process
---------------------------------------------------------------------
rxunit_read : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy )
begin
if Reset = '1' then
tmpDRdy <= '0';
tmpRxVal <= '0';
elsif Clk'event and Clk='0' then
if ReadD = '1' then
-- Data was read, reset data ready
tmpDRdy <= '0';
tmpRxVal <= tmpRxVal;
else
if RxValid = '1' and tmpRxVal = '0' then
-- Data was received, set Data ready
tmpDRdy <= '1';
tmpRxVal <= '1';
else
-- Test for falling edge of RxValid.
tmpDRdy <= tmpDRdy;
if RxValid = '0' and tmpRxVal = '1' then
tmpRxVal <= '0';
else
tmpRxVal <= tmpRxVal;
end if;
end if; -- RxValid
end if; -- ReadD
end if; -- clk / reset
end process;
 
 
DARdy <= tmpDRdy;
DAOut <= DataOut;
FRErr <= frameErr;
ORErr <= outErr;
PAErr <= parityErr;
 
end Behaviour; --==================== End of architecture ====================--
/system05/trunk/rtl/vhdl/miniuart_tb.vhd
0,0 → 1,197
--===========================================================================--
--
-- MiniUart3 Test Bench
--
--
-- John Kent 16th January 2004
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity miniuart3_testbench is
end miniuart3_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of miniuart3_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- CPU Interface signals
signal SysClk : Std_Logic;
signal uart_reset : Std_Logic;
signal uart_cs : Std_Logic;
signal uart_rw : Std_Logic;
signal uart_addr : Std_Logic;
signal uart_data_in : Std_Logic_Vector(7 downto 0);
signal uart_data_out: Std_Logic_Vector(7 downto 0);
signal uart_irq : Std_Logic;
signal rxclk : Std_Logic;
signal txclk : Std_Logic;
signal rxbit : Std_Logic;
signal txbit : Std_Logic;
signal dcd_n : Std_Logic;
signal cts_n : Std_Logic;
signal rts_n : Std_Logic;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
component miniUART
port (
--
-- CPU signals
--
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
--
-- Uart Signals
--
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end component; --================== End of entity ==============================--
 
begin
 
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_uart : miniUART port map (
clk => SysClk,
rst => uart_reset,
cs => uart_cs,
rw => uart_rw,
Irq => uart_irq,
Addr => uart_addr,
Datain => uart_data_in,
DataOut => uart_data_out,
RxC => rxclk,
TxC => txclk,
RxD => rxbit,
TxD => txbit,
DCD_n => dcd_n,
CTS_n => cts_n,
RTS_n => rts_n
);
 
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cts_n <= '0';
dcd_n <= '0';
 
for count in 0 to 4096 loop
if (count mod 16) = 0 then
rxclk <= '1';
txclk <= '1';
elsif (count mod 16) = 8 then
rxclk <= '0';
txclk <= '0';
end if;
 
case count is
when 0 =>
uart_reset <= '1';
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
uart_data_in <= "00000000";
rxbit <= '1';
when 1 =>
uart_reset <= '0';
when 3 =>
uart_cs <= '1';
uart_rw <= '0'; -- write control
uart_addr <= '0';
uart_data_in <= "00010001";
when 4 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
uart_data_in <= "00000000";
when 5 =>
uart_cs <= '1';
uart_rw <= '0'; -- write data
uart_addr <= '1';
uart_data_in <= "01010101";
when 6 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '1';
uart_data_in <= "00000000";
when 256 =>
rxbit <= '0'; -- start
when 512 =>
rxbit <= '1'; -- bit 0
when 768 =>
rxbit <= '0'; -- bit 1
when 1024 =>
rxbit <= '1'; -- bit 2
when 1280 =>
rxbit <= '1'; -- bit3
when 1536 =>
rxbit <= '0'; -- bit 4
when 1792 =>
rxbit <= '0'; -- bit 5
when 2048 =>
rxbit <= '1'; -- bit 6
when 2304 =>
rxbit <= '0'; -- bit 7
when 2560 =>
rxbit <= '1'; -- stop 1
when 2816 =>
rxbit <= '1'; -- stop 2
when 3100 =>
uart_cs <= '1';
uart_rw <= '1'; -- read control
uart_addr <= '0';
when 3101 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
when 3102 =>
uart_cs <= '1';
uart_rw <= '1'; -- read data
uart_addr <= '1';
when 3103 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '1';
when others =>
null;
end case;
SysClk <= '1';
wait for 100 ns;
SysClk <= '0';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
end behavior; --===================== End of architecture =======================--
 
/system05/trunk/rtl/vhdl/System05_tb.vhd
0,0 → 1,564
--===========================================================================--
--
-- S Y N T H E Z I A B L E System05 System On a Chip
--
-- This core adheres to the GNU public license
--
-- File name : system05.vhd
--
-- Purpose : Top level file for a 6805 compatible system on a chip
-- Designed for the Burch ED B5-Spartan IIe board with
-- X2S300e FPGA,
-- 128K x 16 Word SRAM module (B5-SRAM)
-- CPU I/O module (B5-Peripheral-Connectors)
-- Using mimiUart from open cores modified to look like a 6850
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu05.vhd (6805 compatible CPU core)
-- miniuart3.vhd, (6850 compatible UART)
-- rxunit3.vhd,
-- txunit3.vhd
-- timer.vhd (timer module)
-- ioport.vhd (parallel I/O port)
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version Date Author Notes
-- 0.0 14th July 2001 John Kent Started design
-- 0.1 30th May 2004 John Kent Initial Release
--
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System05_tb is
port(
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrun : out Std_Logic;
ram_wrln : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- Extra clock
-- buzzer : out Std_Logic;
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- Keyboard interface
-- kb_clock : in Std_Logic;
-- kb_data : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
 
-- External Bus
bus_addr : out std_logic_vector(15 downto 0);
bus_data : inout std_logic_vector(7 downto 0);
bus_rw : out std_logic;
bus_cs : out std_logic;
bus_clk : out std_logic;
bus_reset : out std_logic;
 
-- I/O Ports
porta : inout std_logic_vector(7 downto 0);
portb : inout std_logic_vector(7 downto 0);
portc : inout std_logic_vector(7 downto 0);
portd : inout std_logic_vector(7 downto 0);
 
-- Timer I/O
-- timer0_in : in std_logic;
timer0_out : out std_logic;
-- timer1_in : in std_logic;
timer1_out : out std_logic
);
end System05_tb;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System05_tb is
signal SysClk : Std_Logic; -- System Clock input
signal Reset_n : Std_logic; -- Master Reset input (active low)
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
signal dcd_n : Std_Logic;
 
-- I/O Port
signal ioport_data_out : std_logic_vector(7 downto 0);
signal ioport_cs : std_logic;
 
-- Timer I/O
signal timer_data_out : std_logic_vector(7 downto 0);
signal timer_cs : std_logic;
signal timer_irq : Std_Logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- Sequencer Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
 
-- External interrupt input
signal ext_irq : Std_Logic;
 
-- Counter signals
signal countL : std_logic_vector(23 downto 0);
signal BaudCount : std_logic_vector(4 downto 0);
signal baudclk : Std_Logic;
 
-----------------------------------------------------------------
--
-- CPU Core
--
-----------------------------------------------------------------
 
component cpu05 is
port (
clk : in std_logic;
rst : in std_logic;
vma : out std_logic;
rw : out std_logic;
addr : out std_logic_vector(15 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_ext : in std_logic;
irq_timer : in std_logic;
irq_uart : in std_logic
);
end component cpu05;
 
------------------------------------------
--
-- Program memory
--
------------------------------------------
 
component boot_rom is
port (
addr : in Std_Logic_Vector(5 downto 0); -- 64 byte boot rom
data : out Std_Logic_Vector(7 downto 0)
);
end component boot_rom;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end component;
 
 
---------------------------------------
--
-- Three port parallel I/O
--
---------------------------------------
 
component ioport is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0);
portc_io : inout std_logic_vector(7 downto 0);
portd_io : inout std_logic_vector(7 downto 0)
);
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
component timer is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(2 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq_out : out std_logic;
tim0_in : in std_logic;
tim0_out : out std_logic;
tim1_in : in std_logic;
tim1_out : out std_logic
);
end component;
 
------------------------------------------
--
-- Global clock buffer for debug
--
------------------------------------------
 
--component BUFG is
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
--end component;
 
begin
 
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu05 port map (
clk => cpu_clk,
rst => cpu_reset,
vma => cpu_vma,
rw => cpu_rw,
addr => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
irq_ext => ext_irq,
irq_timer => timer_irq,
irq_uart => uart_irq
);
 
rom : boot_rom port map (
addr => cpu_addr(5 downto 0),
data => rom_data_out
);
 
my_uart : miniUART port map (
clk => cpu_clk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out,
RxC => baudclk,
TxC => baudclk,
RxD => rxbit,
TxD => txbit,
DCD_n => dcd_n,
CTS_n => cts_n,
RTS_n => rts_n
);
 
my_ioport : ioport port map (
clk => cpu_clk,
rst => cpu_reset,
cs => ioport_cs,
rw => cpu_rw,
addr => cpu_addr(2 downto 0),
data_in => cpu_data_out,
data_out => ioport_data_out,
porta_io => porta,
portb_io => portb,
portc_io => portc,
portd_io => portd
);
 
my_timer : timer port map (
clk => cpu_clk,
rst => cpu_reset,
cs => timer_cs,
rw => cpu_rw,
addr => cpu_addr(2 downto 0),
data_in => cpu_data_out,
data_out => timer_data_out,
irq_out => timer_irq,
tim0_in => CountL(4),
tim0_out => timer0_out,
tim1_in => CountL(6),
tim1_out => timer1_out
);
 
 
 
--bufginst: BUFG port map(
-- i => countL(0),
-- o => cpu_clk
-- );
 
-- bufginst: BUFG port map(i => SysClk, o => cpu_clk );
----------------------------------------------------------------------
--
-- Processes to read and write memory based on bus signals
--
----------------------------------------------------------------------
 
memory_decode: process( Reset_n, cpu_clk,
cpu_addr, cpu_vma,
rom_data_out, ram_data_out,
ioport_data_out, timer_data_out, uart_data_out, bus_data )
begin
case cpu_addr(15 downto 6) is
when "1111111111" =>
cpu_data_in <= rom_data_out;
ram_cs <= '0';
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
when "0000000000" =>
--
-- Decode 64 bytes of I/O space here
--
ram_cs <= '0';
case cpu_addr(5 downto 3) is
--
-- I/O ports $0000 - $0007
--
when "000" =>
cpu_data_in <= ioport_data_out;
ioport_cs <= cpu_vma;
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
--
-- Timer $0008 - $000F
--
when "001" =>
cpu_data_in <= timer_data_out;
ioport_cs <= '0';
timer_cs <= cpu_vma;
uart_cs <= '0';
bus_cs <= '0';
--
-- ACIA $0010 - $0017
--
when "010" =>
cpu_data_in <= uart_data_out;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= cpu_vma;
bus_cs <= '0';
--
-- Reserved $0018 - $003F
--
when others =>
cpu_data_in <= bus_data;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= cpu_vma;
end case;
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
ioport_cs <= '0';
timer_cs <= '0';
uart_cs <= '0';
bus_cs <= '0';
end case;
end process;
 
--------------------------------------------------------------
--
-- B5 SRAM interface
--
--------------------------------------------------------------
Ram_decode: process( Reset_n, cpu_clk,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
ram_cs, ram_wrl, ram_wru, ram_data )
begin
cpu_reset <= not Reset_n;
ram_wrl <= (not cpu_rw) and cpu_addr(0);
ram_wru <= (not cpu_rw) and (not cpu_addr(0));
ram_wrln <= not ram_wrl;
ram_wrun <= not ram_wru;
ram_csn <= not( Reset_n and ram_cs and cpu_clk );
ram_addr(16 downto 15) <= "00";
ram_addr(14 downto 0) <= cpu_addr(15 downto 1);
 
if ram_cs = '1' then
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if cpu_addr(0) = '0' then
ram_data_out(7 downto 0) <= ram_data(15 downto 8);
else
ram_data_out(7 downto 0) <= ram_data(7 downto 0);
end if;
 
end process;
 
--
-- CPU bus signals
--
my_bus : process( cpu_clk, cpu_reset, cpu_rw, cpu_addr, cpu_data_out )
begin
bus_clk <= cpu_clk;
bus_reset <= cpu_reset;
bus_rw <= cpu_rw;
bus_addr <= cpu_addr;
if( cpu_rw = '1' ) then
bus_data <= "ZZZZZZZZ";
else
bus_data <= cpu_data_out;
end if;
end process;
 
--
-- flash led to indicate code is working
--
blink: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '0') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
 
 
--
-- 57.6 Kbaud * 16 divider for 25 MHz system clock
--
my_baud_clock: process( SysClk )
begin
if(SysClk'event and SysClk = '0') then
if( BaudCount = 26 ) then
BaudCount <= "00000";
else
BaudCount <= BaudCount + 1;
end if;
end if;
baudclk <= BaudCount(4); -- 25MHz / 27 = 926,000 KHz = 57,870Bd * 16
dcd_n <= '0';
end process;
 
--
-- tie down inputs and outputs
--
-- CRTC output signals
--
-- v_drive <= '0';
-- h_drive <= '0';
-- blue_lo <= '0';
-- blue_hi <= '0';
-- green_lo <= '0';
-- green_hi <= '0';
-- red_lo <= '0';
-- red_hi <= '0';
-- buzzer <= '0';
 
--
-- tie down unused interrupts
--
ext_irq <= '0';
cpu_clk <= SysClk;
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
SysClk <= '0';
Reset_n <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
Reset_n <= '0';
elsif count = 1 then
Reset_n <= '1';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
end my_computer; --===================== End of architecture =======================--
 
/system05/trunk/rtl/vhdl/txunit3.vhd
0,0 → 1,302
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : txunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : IEEE.Std_Logic_1164
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 added 6850 word format control
-- 3.1 John Kent 12 January 2003 Rearranged state machine code
-- 3.2 John Kent 30 March 2003 Revamped State machine
-- 3.3 John Kent 16 January 2004 Major re-write - added baud rate gen
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Description :
-------------------------------------------------------------------------------
-- Entity for the Tx Unit --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Transmitter unit
-------------------------------------------------------------------------------
entity TxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
LoadD : in Std_Logic; -- Load transmit data
DAIn : in Std_Logic_Vector(7 downto 0);
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
TxClk : in Std_Logic; -- Enable input
TxDat : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic ); -- Tx buffer empty
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for TxUnit
-------------------------------------------------------------------------------
architecture Behaviour of TxUnit is
type TxStateType is ( TxIdle_State, Start_State, Data_State, Parity_State, Stop_State );
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal TxClkDel : Std_Logic; -- Delayed Tx Input Clock
signal TxClkEdge : Std_Logic; -- Tx Input Clock Edge pulse
signal TxClkCnt : Std_Logic_Vector(5 downto 0); -- Tx Baud Clock Counter
signal TxBdDel : Std_Logic; -- Delayed Tx Baud Clock
signal TxBdEdge : Std_Logic; -- Tx Baud Clock Edge pulse
signal TxBdClk : Std_Logic; -- Tx Baud Clock
 
signal TBuff : Std_Logic_Vector(7 downto 0); -- transmit buffer
signal TBufE : Std_Logic; -- Transmit Buffer Empty
 
signal TReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal TxParity : Std_logic; -- Parity Bit
signal DataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal TRegE : Std_Logic; -- Transmit Register empty
signal TRegEDel : Std_Logic; -- Transmit Register empty
signal TRegEEdge : Std_Logic;
signal TxState : TxStateType;
signal TxDbit : Std_Logic;
begin
 
---------------------------------------------------------------------
-- Transmit Clock Edge Detection
-- A falling edge will produce a one clock cycle pulse
---------------------------------------------------------------------
txunit_clock_edge : process(Clk, Reset, TxClk, TxClkDel )
begin
if Reset = '1' then
TxClkDel <= TxClk;
TxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
TxClkDel <= TxClk;
TxClkEdge <= TxClkDel and (not TxClk);
end if;
end process;
 
 
---------------------------------------------------------------------
-- Transmit Clock Divider
-- Advance the count only on an input clock pulse
---------------------------------------------------------------------
txunit_clock_divide : process(Clk, Reset, TxClkEdge, TxClkCnt )
begin
if Reset = '1' then
TxClkCnt <= "000000";
elsif Clk'event and Clk = '0' then
if TxClkEdge = '1' then
TxClkCnt <= TxClkCnt + "000001";
else
TxClkCnt <= TxClkCnt;
end if; -- TxClkEdge
end if; -- reset / clk
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Selector
-- Select output then look for rising edge
---------------------------------------------------------------------
txunit_clock_select : process(Clk, Reset, BdFmt, TxClk, TxClkCnt,
TxBdDel, TxBdEdge )
begin
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
case BdFmt is
when "00" => -- Div by 1
TxBdClk <= TxClk;
when "01" => -- Div by 16
TxBdClk <= TxClkCnt(3);
when "10" => -- Div by 64
TxBdClk <= TxClkCnt(5);
when others => -- reset
TxBdClk <= '0';
end case;
 
if Reset = '1' then
TxBdDel <= TxBdClk;
TxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
TxBdDel <= TxBdClk;
TxBdEdge <= TxBdClk and (not TxBdDel);
end if;
end process;
 
---------------------------------------------------------------------
-- Transmit Buffer Empty Edge
-- generate a negative edge pulse
---------------------------------------------------------------------
txunit_busy : process(Clk, Reset, TRegE, TRegEDel )
begin
if Reset = '1' then
TRegEDel <= '0';
TRegEEdge <= '0';
elsif Clk'event and Clk = '0' then
TRegEDel <= TRegE;
TRegEEdge <= TregEDel and (not TRegE ); -- falling edge
end if;
end process;
 
---------------------------------------------------------------------
-- Transmitter activation process
---------------------------------------------------------------------
txunit_write : process(Clk, Reset, LoadD, DAIn, TBufE, TRegEEdge )
begin
if Reset = '1' then
TBufE <= '1';
TBuff <= "00000000";
elsif Clk'event and Clk = '0' then
if LoadD = '1' then
TBuff <= DAIn;
TBufE <= '0';
else
TBuff <= TBuff;
if (TBufE = '0') and (TRegEEdge = '1') then
-- Once the transmitter is started
-- We can flag the buffer empty again.
TBufE <= '1';
else
TBufE <= TBufE;
end if;
end if;
end if; -- clk / reset
TBE <= TBufE;
 
end process;
 
-----------------------------------------------------------------------------
-- Implements the Tx unit
-----------------------------------------------------------------------------
txunit_transmit : process(Reset, Clk, TxState, TxDbit, TBuff, TReg,
TxBdEdge, TxParity, DataCnt, WdFmt,
TBufE, TRegE )
begin
if Reset = '1' then
TxDbit <= '1';
TReg <= "00000000";
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '1';
TxState <= TxIdle_State;
elsif Clk'event and Clk = '0' then
if TxBdEdge = '1' then
case TxState is
when TxIdle_State => -- TxIdle_State (also 1st or 2nd Stop bit)
TxDbit <= '1';
TReg <= TBuff;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '1';
if TBufE = '0' then
TxState <= Start_State;
else
TxState <= TxIdle_State;
end if;
 
when Start_State =>
TxDbit <= '0'; -- Start bit
TReg <= TReg;
TxParity <= '0';
if WdFmt(2) = '0' then
DataCnt <= "0110"; -- 7 data + parity
else
DataCnt <= "0111"; -- 8 data
end if;
TRegE <= '0';
TxState <= Data_State;
 
when Data_State =>
TxDbit <= TReg(0);
TReg <= '1' & TReg(7 downto 1);
TxParity <= TxParity xor TReg(0);
TRegE <= '0';
DataCnt <= DataCnt - "0001";
if DataCnt = "0000" then
if (WdFmt(2) = '1') and (WdFmt(1) = '0') then
if WdFmt(0) = '0' then -- 8 data bits
TxState <= Stop_State; -- 2 stops
else
TxState <= TxIdle_State; -- 1 stop
end if;
else
TxState <= Parity_State; -- parity
end if;
else
TxState <= Data_State;
end if;
 
when Parity_State => -- 7/8 data + parity bit
if WdFmt(0) = '0' then
TxDbit <= not( TxParity ); -- even parity
else
TXDbit <= TxParity; -- odd parity
end if;
Treg <= Treg;
TxParity <= '0';
TRegE <= '0';
DataCnt <= "0000";
if WdFmt(1) = '0' then
TxState <= Stop_State; -- 2 stops
else
TxState <= TxIdle_State; -- 1 stop
end if;
 
when Stop_State => -- first stop bit
TxDbit <= '1'; -- 2 stop bits
Treg <= Treg;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '0';
TxState <= TxIdle_State;
 
when others => -- Undefined
TxDbit <= TxDbit;
Treg <= Treg;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= TregE;
TxState <= TxIdle_State;
 
end case; -- TxState
 
else -- TxBdEdge
TxDbit <= TxDbit;
TReg <= TReg;
TxParity <= TxParity;
DataCnt <= DataCnt;
TRegE <= TRegE;
TxState <= TxState;
end if; -- TxBdEdge
end if; -- clk / reset
 
TxDat <= TxDbit;
end process;
 
end Behaviour; --=================== End of architecture ====================--
system05/trunk Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: system05/web_uploads =================================================================== --- system05/web_uploads (nonexistent) +++ system05/web_uploads (revision 3)
system05/web_uploads Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: system05/branches =================================================================== --- system05/branches (nonexistent) +++ system05/branches (revision 3)
system05/branches Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: system05/tags =================================================================== --- system05/tags (nonexistent) +++ system05/tags (revision 3)
system05/tags Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.