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/miniuart_tb.vhd
File deleted
/trunk/rtl/vhdl/txunit3.vhd
File deleted
\ No newline at end of file
/trunk/rtl/vhdl/System05_tb.vhd
File deleted
/trunk/rtl/vhdl/bclrrom.vhd
File deleted
/trunk/rtl/vhdl/timer.vhd
File deleted
/trunk/rtl/vhdl/bootrom.vhd
File deleted
/trunk/rtl/vhdl/System05.npl
File deleted
/trunk/rtl/vhdl/system05.ucf
File deleted
/trunk/rtl/vhdl/System05.vhd
File deleted
/trunk/rtl/vhdl/miniUART3.vhd
File deleted
/trunk/rtl/vhdl/bsetrom.vhd
File deleted
/trunk/rtl/vhdl/rxunit3.vhd
File deleted
\ No newline at end of file
/trunk/rtl/vhdl/cpu05.vhd
File deleted
/trunk/rtl/vhdl/ioport.vhd
File deleted
/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 ##