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

Subversion Repositories light8080

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 63 to Rev 64
    Reverse comparison

Rev 63 → Rev 64

/light8080/trunk/ucode/light8080.m80
1,5 → 1,5
////////////////////////////////////////////////////////////////////////////////
// LIGHT8080 CORE MICROCODE (V.1 November 1st 2007)
// LIGHT8080 CORE MICROCODE (V.2 February 12th 2012)
////////////////////////////////////////////////////////////////////////////////
// NOTE: Except for bug fixing, there's no need to tinker with the microcode.
// Once the microcode table has been generated, this file is is not needed to
61,7 → 61,11
// #halt : Jump to microcode address 0x07 without saving return value.
//
////////////////////////////////////////////////////////////////////////////////
// V.1 November 1st 2007 -- Original version
// V.2 February 12th 2012 -- Fixed CY/AC clear bug with clr_acy flag
////////////////////////////////////////////////////////////////////////////////
 
 
// RESET ucode: from 0 to 2, but uinst at address 0 is never executed
__reset
 
233,13 → 237,13
__asm ANI #imm
 
JSR read_imm
T2 = _a ; _a = AND ; #end, #fp_rc
T2 = _a ; _a = AND ; #end, #fp_rc, #clr_acy
 
__code "11101110"
__asm XRI #imm
 
JSR read_imm
T2 = _a ; _a = XRL ; #end, #fp_rc
T2 = _a ; _a = XRL ; #end, #fp_rc, #clr_acy
 
 
__code "11110110"
246,7 → 250,7
__asm ORI #imm
 
JSR read_imm
T2 = _a ; _a = ORL ; #end, #fp_rc
T2 = _a ; _a = ORL ; #end, #fp_rc, #clr_acy
 
 
__code "11111110"
285,19 → 289,19
__asm ANA {s}
 
T1 = {s} ; NOP
T2 = _a ; _a = AND ; #end, #fp_rc
T2 = _a ; _a = AND ; #end, #fp_rc, #clr_acy
 
__code "10101sss"
__asm XRA {s}
 
T1 = {s} ; NOP
T2 = _a ; _a = XRL ; #end, #fp_rc
T2 = _a ; _a = XRL ; #end, #fp_rc, #clr_acy
 
__code "10110sss"
__asm ORA {s}
 
T1 = {s} ; NOP
T2 = _a ; _a = ORL ; #end, #fp_rc
T2 = _a ; _a = ORL ; #end, #fp_rc, #clr_acy
 
__code "10111sss"
__asm CMP {s}
334,19 → 338,19
__asm ANA M
 
JSR read_m
T2 = _a ; _a = AND ; #end, #fp_rc
T2 = _a ; _a = AND ; #end, #fp_rc, #clr_acy
 
__code "10101110"
__asm XRA M
 
JSR read_m
T2 = _a ; _a = XRL ; #end, #fp_rc
T2 = _a ; _a = XRL ; #end, #fp_rc, #clr_acy
 
__code "10110110"
__asm ORA M
 
JSR read_m
T2 = _a ; _a = ORL ; #end, #fp_rc
T2 = _a ; _a = ORL ; #end, #fp_rc, #clr_acy
 
 
__code "10111110"
/light8080/trunk/asm/tb0.asm
21,7 → 21,7
; Modified 2006/11/16 by Scott Moore to work on CPU8080 FPGA core
;
;***********************************************************************
; Modified 2007/09/24 by Jose Ruiz for use in free8080 FPGA core
; Modified 2007/09/24 by Jose Ruiz for use in light8080 FPGA core
;
; 1.- Changed formatting for compatibility to CP/M's ASM
; 2.- Commented out all Altair / MITS hardware related stuff
28,6 → 28,9
; 3.- Set origin at 0H
;
; Modified again in 2008 to make it compatible with TASM assembler.
;
; Modified 2012/02/12 to add a few CY checks.
; Flags go almost completely unchecked in this test.
;***********************************************************************
 
; DS pseudo-directive; reserve space in bytes, without initializing it
200,14 → 203,20
jz anii ;test "sbi"
call cpuer
anii: ani 055H ;a=f0h<and>55h=50h,c=0,p=1,s=0,z=0
cc cpuer
cz cpuer
cpi 050H
jz orii ;test "ani"
call cpuer
orii: ori 03aH ;a=50h<or>3ah=7ah,c=0,p=0,s=0,z=0
cc cpuer
cz cpuer
cpi 07aH
jz xrii ;test "ori"
call cpuer
xrii: xri 00fH ;a=7ah<xor>0fh=75h,c=0,p=0,s=0,z=0
cc cpuer
cz cpuer
cpi 075H
jz c010 ;test "xri"
call cpuer
438,7 → 447,9
mvi e,07fH
mvi h,0f4H
mvi l,0bfH
stc
ana a
cc cpuer
ana c
ana d
ana e
454,7 → 465,9
mvi e,008H
mvi h,010H
mvi l,020H
stc
ora b
cc cpuer
ora c
ora d
ora e
466,7 → 479,9
mvi a,0H
mvi h,08fH
mvi l,04fH
stc
xra b
cc cpuer
xra c
xra d
xra e
542,13 → 557,19
sbb m
cpi 0cdH
cnz cpuer ;test "sbb" m
stc
ana m
cc cpuer
cnz cpuer ;test "ana" m
mvi a,025H
stc
ora m
cc cpuer
cpi 37H
cnz cpuer ;test "ora" m
stc
xra m
cc cpuer
cpi 005H
cnz cpuer ;test "xra" m
mvi m,055H
/light8080/trunk/doc/designNotes.tex
246,7 → 246,7
t1\textbar rst\textbar daa\textbar cpc\textbar sec\textbar psw
\textless flag list \textgreater := \textless flag \textgreater [, \textless flag \textgreater ...]
\textless flag \textgreater := \#decode\textbar\#di\textbar\#ei\textbar\#io\textbar\#auxcy\textbar\#clrt1\textbar\#halt\textbar\#end\textbar\#ret\textbar\#rd\textbar\#wr\textbar\#setacy
\#ld\_al\textbar\#ld\_addr\textbar\#fp\_c\textbar\#fp\_r\textbar\#fp\_rc \footnote{There are some restrictions on the flags that can be used together} \\
\#ld\_al\textbar\#ld\_addr\textbar\#fp\_c\textbar\#fp\_r\textbar\#fp\_rc\textbar\#clr\_acy \footnote{There are some restrictions on the flags that can be used together} \\
\end{alltt}
 
 
347,7 → 347,7
21 & mux\_in & T1/T2 source mux control (0 for DI, 1 for reg bank) \\ \hline
20..19 & rb\_addr\_sel & Register bank address source control (note 2) \\ \hline
18..15 & ra\_field & Register bank address (used both for write and read) \\ \hline
14 & (unused) & Reserved \\ \hline
14 & clr\_acy & Clear CY and AC -- see explaination below (pipelined signal) \\ \hline
13..10 & (unused) & Reserved for write register bank address, unused yet \\ \hline
11..10 & uc\_jmp\_addr(7..6) & JSR/TJSR jump address, higher 2 bits \\ \hline
9..8 & flag\_pattern & PSW flag update control (note 3) (pipelined signal) \\ \hline
441,6 → 441,10
\item \#ld\_addr : Load address register (H byte = register bank output as read
by operation 1, L byte = AL).
Activate vma signal for 1st cycle.
\item \#clr\_acy : Clear PSW flags AC and CY, except for AND instructions
(ALU operation = 000100), where AC is set.
Meant to be used with flag \#fp\_rc for the logic instructions (AND, OR, XOR).
See \ref{compatibility} for a note about compatibility to the original 8080.
\end{itemize}
 
\item PSW update flags: use only one of these
591,6 → 595,22
 
\end{tabular}
 
\clearpage
 
\subsection{Binary compatibility to original 8080}
\label{compatibility}
 
Flag AC (auxiliary carry) does not work exactly as in the original 8080. In the
original 8080, ANI and ANA don't clear AC but set it to the OR'ing of
bits 3 of the ALU operands.
 
In this core, these two instructions instead set the AC flag to 1. In this, the
core is compatible to the 8085 ad not to the 8080.
 
That is the only difference to the original 8080 that I am aware of.
Unfortunately, the only test bench that I have available right now is not
exhaustive enough to pick that kind of detail. Until I develop a stronger test
bench, full compatibility to the 8080 can't be guaranteed.
\end{document}
 
/light8080/trunk/doc/designNotes.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/light8080/trunk/util/uasm.pl
41,7 → 41,7
# t1|rst|daa|cpc|sec|psw
#<flag list> := <flag> [, <flag> ...]
#<flag> := #decode|#di|#ei|#io|#auxcy|#clrt1|#halt|#end|#ret|#rd|#wr|#setacy
# #ld_al|#ld_addr|#fp_c|#fp_r|#fp_rc (*2)
# #ld_al|#ld_addr|#fp_c|#fp_r|#fp_rc|#clr_cy_ac (*2)
#
# *1 Labels appear alone by themselves in a line
# *2 There are some restrictions on the flags that can be used together
93,6 → 93,7
# #ld_addr : Load address register (H byte = register bank output as read by
# operation 1, L byte = AL).
# Activate vma signal for 1st cycle.
# #clr_acy : Instruction clears CY and AC flags. Use with #fp_rc.
# --- PSW update flags: use only one of these
# #fp_r : This instruction updates all PSW flags except for C.
# #fp_c : This instruction updates only the C flag in the PSW.
566,7 → 567,9
if($uinst->{flags} =~ /#fp_rc/){
substr($uinst->{field1},22,2) = '11';
}
 
if($uinst->{flags} =~ /#clr_acy/){
substr($uinst->{field1},17,1) = '1';
}
}
 
661,6 → 664,9
if($flag_str =~ /#fp_rc/){
$uinst->{flags} = $uinst->{flags}." #fp_rc";
}
if($flag_str =~ /#clr_acy/){
$uinst->{flags} = $uinst->{flags}." #clr_acy";
}
 
if($error ne ''){
$num_errors++;
/light8080/trunk/vhdl/test/light8080_tb0.vhdl
1,521 → 1,549
--------------------------------------------------------------------------------
-- Generated from template tb_template.vhdl by hexconv.pl
--------------------------------------------------------------------------------
-- Light8080 simulation test bench.
--------------------------------------------------------------------------------
-- Source for the 8080 program is in asm\tb0.asm
--------------------------------------------------------------------------------
--
-- This test bench provides a simulated CPU system to test programs. This test
-- bench does not do any assertions or checks, all assertions are left to the
-- software.
--
-- The simulated environment has 2KB of RAM, mirror-mapped to all the memory
-- map of the 8080, initialized with the test program object code. See the perl
-- script 'util\hexconv.pl' and BAT files in the asm directory.
--
-- Besides, it provides some means to trigger hardware irq from software,
-- including the specification of the instructions fed to the CPU as interrupt
-- vectors during inta cycles.
--
-- We will simulate 8 possible irq sources. The software can trigger any one of
-- them by writing at registers 0x010 and 0x011. Register 0x010 holds the irq
-- source to be triggered (0 to 7) and register 0x011 holds the number of clock
-- cycles that will elapse from the end of the instruction that writes to the
-- register to the assertion of intr.
--
-- When the interrupt is acknowledged and inta is asserted, the test bench reads
-- the value at register 0x010 as the irq source, and feeds an instruction to
-- the CPU starting from the RAM address 0040h+source*4.
-- That is, address range 0040h-005fh is reserved for the simulated 'interrupt
-- vectors', a total of 4 bytes for each of the 8 sources. This allows the
-- software to easily test different interrupt vectors without any hand
-- assembly. All of this is strictly simulation-only stuff.
--
--
-- Upon completion, the software must write a value to register 0x020. Writing
-- a 0x055 means 'success', writing a 0x0aa means 'failure'. Success and
-- failure conditions are defined by the software.
--------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.ALL;
 
entity light8080_tb0 is
end entity light8080_tb0;
 
architecture behavior of light8080_tb0 is
 
--------------------------------------------------------------------------------
-- Simulation parameters
 
-- T: simulated clock period
constant T : time := 100 ns;
 
-- MAX_SIM_LENGTH: maximum simulation time
constant MAX_SIM_LENGTH : time := T*7000; -- enough for the tb0
 
 
--------------------------------------------------------------------------------
 
-- Component Declaration for the Unit Under Test (UUT)
component light8080
port (
addr_out : out std_logic_vector(15 downto 0);
inta : out std_logic;
inte : out std_logic;
halt : out std_logic;
intr : in std_logic;
vma : out std_logic;
io : out std_logic;
rd : out std_logic;
wr : out std_logic;
fetch : out std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
clk : in std_logic;
reset : in std_logic );
end component;
 
 
signal data_i : std_logic_vector(7 downto 0) := (others=>'0');
signal vma_o : std_logic;
signal rd_o : std_logic;
signal wr_o : std_logic;
signal io_o : std_logic;
signal data_o : std_logic_vector(7 downto 0);
signal data_mem : std_logic_vector(7 downto 0);
signal addr_o : std_logic_vector(15 downto 0);
signal fetch_o : std_logic;
signal inta_o : std_logic;
signal inte_o : std_logic;
signal intr_i : std_logic := '0';
signal halt_o : std_logic;
signal reset : std_logic := '0';
signal clk : std_logic := '1';
signal done : std_logic := '0';
 
type t_rom is array(0 to 2047) of std_logic_vector(7 downto 0);
 
signal rom : t_rom := (
 
X"31",X"f3",X"05",X"3e",X"77",X"e6",X"00",X"ca",
X"0d",X"00",X"cd",X"e0",X"04",X"d2",X"13",X"00",
X"cd",X"e0",X"04",X"ea",X"19",X"00",X"cd",X"e0",
X"04",X"f2",X"1f",X"00",X"cd",X"e0",X"04",X"c2",
X"2e",X"00",X"da",X"2e",X"00",X"e2",X"2e",X"00",
X"fa",X"2e",X"00",X"c3",X"31",X"00",X"cd",X"e0",
X"04",X"c6",X"06",X"c2",X"39",X"00",X"cd",X"e0",
X"04",X"da",X"42",X"00",X"e2",X"42",X"00",X"f2",
X"45",X"00",X"cd",X"e0",X"04",X"c6",X"70",X"e2",
X"4d",X"00",X"cd",X"e0",X"04",X"fa",X"56",X"00",
X"ca",X"56",X"00",X"d2",X"59",X"00",X"cd",X"e0",
X"04",X"c6",X"81",X"fa",X"61",X"00",X"cd",X"e0",
X"04",X"ca",X"6a",X"00",X"da",X"6a",X"00",X"e2",
X"6d",X"00",X"cd",X"e0",X"04",X"c6",X"fe",X"da",
X"75",X"00",X"cd",X"e0",X"04",X"ca",X"7e",X"00",
X"e2",X"7e",X"00",X"fa",X"81",X"00",X"cd",X"e0",
X"04",X"fe",X"00",X"da",X"99",X"00",X"ca",X"99",
X"00",X"fe",X"f5",X"da",X"99",X"00",X"c2",X"99",
X"00",X"fe",X"ff",X"ca",X"99",X"00",X"da",X"9c",
X"00",X"cd",X"e0",X"04",X"ce",X"0a",X"ce",X"0a",
X"fe",X"0b",X"ca",X"a8",X"00",X"cd",X"e0",X"04",
X"d6",X"0c",X"d6",X"0f",X"fe",X"f0",X"ca",X"b4",
X"00",X"cd",X"e0",X"04",X"de",X"f1",X"de",X"0e",
X"fe",X"f0",X"ca",X"c0",X"00",X"cd",X"e0",X"04",
X"e6",X"55",X"fe",X"50",X"ca",X"ca",X"00",X"cd",
X"e0",X"04",X"f6",X"3a",X"fe",X"7a",X"ca",X"d4",
X"00",X"cd",X"e0",X"04",X"ee",X"0f",X"fe",X"75",
X"ca",X"de",X"00",X"cd",X"e0",X"04",X"e6",X"00",
X"dc",X"e0",X"04",X"e4",X"e0",X"04",X"fc",X"e0",
X"04",X"c4",X"e0",X"04",X"fe",X"00",X"ca",X"f4",
X"00",X"cd",X"e0",X"04",X"d6",X"77",X"d4",X"e0",
X"04",X"ec",X"e0",X"04",X"f4",X"e0",X"04",X"cc",
X"e0",X"04",X"fe",X"89",X"ca",X"0a",X"01",X"cd",
X"e0",X"04",X"e6",X"ff",X"e4",X"17",X"01",X"fe",
X"d9",X"ca",X"74",X"01",X"cd",X"e0",X"04",X"e8",
X"c6",X"10",X"ec",X"23",X"01",X"c6",X"02",X"e0",
X"cd",X"e0",X"04",X"e0",X"c6",X"20",X"fc",X"2f",
X"01",X"c6",X"04",X"e8",X"cd",X"e0",X"04",X"f0",
X"c6",X"80",X"f4",X"3b",X"01",X"c6",X"80",X"f8",
X"cd",X"e0",X"04",X"f8",X"c6",X"40",X"d4",X"47",
X"01",X"c6",X"40",X"f0",X"cd",X"e0",X"04",X"d8",
X"c6",X"8f",X"dc",X"53",X"01",X"d6",X"02",X"d0",
X"cd",X"e0",X"04",X"d0",X"c6",X"f7",X"c4",X"5f",
X"01",X"c6",X"fe",X"d8",X"cd",X"e0",X"04",X"c8",
X"c6",X"01",X"cc",X"6b",X"01",X"c6",X"d0",X"c0",
X"cd",X"e0",X"04",X"c0",X"c6",X"47",X"fe",X"47",
X"c8",X"cd",X"e0",X"04",X"3e",X"77",X"3c",X"47",
X"04",X"48",X"0d",X"51",X"5a",X"63",X"6c",X"7d",
X"3d",X"4f",X"59",X"6b",X"45",X"50",X"62",X"7c",
X"57",X"14",X"6a",X"4d",X"0c",X"61",X"44",X"05",
X"58",X"7b",X"5f",X"1c",X"43",X"60",X"24",X"4c",
X"69",X"55",X"15",X"7a",X"67",X"25",X"54",X"42",
X"68",X"2c",X"5d",X"1d",X"4b",X"79",X"6f",X"2d",
X"65",X"5c",X"53",X"4a",X"41",X"78",X"fe",X"77",
X"c4",X"e0",X"04",X"af",X"06",X"01",X"0e",X"03",
X"16",X"07",X"1e",X"0f",X"26",X"1f",X"2e",X"3f",
X"80",X"81",X"82",X"83",X"84",X"85",X"87",X"fe",
X"f0",X"c4",X"e0",X"04",X"90",X"91",X"92",X"93",
X"94",X"95",X"fe",X"78",X"c4",X"e0",X"04",X"97",
X"c4",X"e0",X"04",X"3e",X"80",X"87",X"06",X"01",
X"0e",X"02",X"16",X"03",X"1e",X"04",X"26",X"05",
X"2e",X"06",X"88",X"06",X"80",X"80",X"80",X"89",
X"80",X"80",X"8a",X"80",X"80",X"8b",X"80",X"80",
X"8c",X"80",X"80",X"8d",X"80",X"80",X"8f",X"fe",
X"37",X"c4",X"e0",X"04",X"3e",X"80",X"87",X"06",
X"01",X"98",X"06",X"ff",X"80",X"99",X"80",X"9a",
X"80",X"9b",X"80",X"9c",X"80",X"9d",X"fe",X"e0",
X"c4",X"e0",X"04",X"3e",X"80",X"87",X"9f",X"fe",
X"ff",X"c4",X"e0",X"04",X"3e",X"ff",X"06",X"fe",
X"0e",X"fc",X"16",X"ef",X"1e",X"7f",X"26",X"f4",
X"2e",X"bf",X"a7",X"a1",X"a2",X"a3",X"a4",X"a5",
X"a7",X"fe",X"24",X"c4",X"e0",X"04",X"af",X"06",
X"01",X"0e",X"02",X"16",X"04",X"1e",X"08",X"26",
X"10",X"2e",X"20",X"b0",X"b1",X"b2",X"b3",X"b4",
X"b5",X"b7",X"fe",X"3f",X"c4",X"e0",X"04",X"3e",
X"00",X"26",X"8f",X"2e",X"4f",X"a8",X"a9",X"aa",
X"ab",X"ac",X"ad",X"fe",X"cf",X"c4",X"e0",X"04",
X"af",X"c4",X"e0",X"04",X"06",X"44",X"0e",X"45",
X"16",X"46",X"1e",X"47",X"26",X"04",X"2e",X"ec",
X"70",X"06",X"00",X"46",X"3e",X"44",X"b8",X"c4",
X"e0",X"04",X"72",X"16",X"00",X"56",X"3e",X"46",
X"ba",X"c4",X"e0",X"04",X"73",X"1e",X"00",X"5e",
X"3e",X"47",X"bb",X"c4",X"e0",X"04",X"74",X"26",
X"04",X"2e",X"ec",X"66",X"3e",X"04",X"bc",X"c4",
X"e0",X"04",X"75",X"26",X"04",X"2e",X"ec",X"6e",
X"3e",X"ec",X"bd",X"c4",X"e0",X"04",X"26",X"04",
X"2e",X"ec",X"3e",X"32",X"77",X"be",X"c4",X"e0",
X"04",X"86",X"fe",X"64",X"c4",X"e0",X"04",X"af",
X"7e",X"fe",X"32",X"c4",X"e0",X"04",X"26",X"04",
X"2e",X"ec",X"7e",X"96",X"c4",X"e0",X"04",X"3e",
X"80",X"87",X"8e",X"fe",X"33",X"c4",X"e0",X"04",
X"3e",X"80",X"87",X"9e",X"fe",X"cd",X"c4",X"e0",
X"04",X"a6",X"c4",X"e0",X"04",X"3e",X"25",X"b6",
X"fe",X"37",X"c4",X"e0",X"04",X"ae",X"fe",X"05",
X"c4",X"e0",X"04",X"36",X"55",X"34",X"35",X"86",
X"fe",X"5a",X"c4",X"e0",X"04",X"01",X"ff",X"12",
X"11",X"ff",X"12",X"21",X"ff",X"12",X"03",X"13",
X"23",X"3e",X"13",X"b8",X"c4",X"e0",X"04",X"ba",
X"c4",X"e0",X"04",X"bc",X"c4",X"e0",X"04",X"3e",
X"00",X"b9",X"c4",X"e0",X"04",X"bb",X"c4",X"e0",
X"04",X"bd",X"c4",X"e0",X"04",X"0b",X"1b",X"2b",
X"3e",X"12",X"b8",X"c4",X"e0",X"04",X"ba",X"c4",
X"e0",X"04",X"bc",X"c4",X"e0",X"04",X"3e",X"ff",
X"b9",X"c4",X"e0",X"04",X"bb",X"c4",X"e0",X"04",
X"bd",X"c4",X"e0",X"04",X"32",X"ec",X"04",X"af",
X"3a",X"ec",X"04",X"fe",X"ff",X"c4",X"e0",X"04",
X"2a",X"ea",X"04",X"22",X"ec",X"04",X"3a",X"ea",
X"04",X"47",X"3a",X"ec",X"04",X"b8",X"c4",X"e0",
X"04",X"3a",X"eb",X"04",X"47",X"3a",X"ed",X"04",
X"b8",X"c4",X"e0",X"04",X"3e",X"aa",X"32",X"ec",
X"04",X"44",X"4d",X"af",X"0a",X"fe",X"aa",X"c4",
X"e0",X"04",X"3c",X"02",X"3a",X"ec",X"04",X"fe",
X"ab",X"c4",X"e0",X"04",X"3e",X"77",X"32",X"ec",
X"04",X"2a",X"ea",X"04",X"11",X"00",X"00",X"eb",
X"af",X"1a",X"fe",X"77",X"c4",X"e0",X"04",X"af",
X"84",X"85",X"c4",X"e0",X"04",X"3e",X"cc",X"12",
X"3a",X"ec",X"04",X"fe",X"cc",X"12",X"3a",X"ec",
X"04",X"fe",X"cc",X"c4",X"e0",X"04",X"21",X"77",
X"77",X"29",X"3e",X"ee",X"bc",X"c4",X"e0",X"04",
X"bd",X"c4",X"e0",X"04",X"21",X"55",X"55",X"01",
X"ff",X"ff",X"09",X"3e",X"55",X"d4",X"e0",X"04",
X"bc",X"c4",X"e0",X"04",X"3e",X"54",X"bd",X"c4",
X"e0",X"04",X"21",X"aa",X"aa",X"11",X"33",X"33",
X"19",X"3e",X"dd",X"bc",X"c4",X"e0",X"04",X"bd",
X"c4",X"e0",X"04",X"37",X"d4",X"e0",X"04",X"3f",
X"dc",X"e0",X"04",X"3e",X"aa",X"2f",X"fe",X"55",
X"c4",X"e0",X"04",X"b7",X"27",X"fe",X"55",X"c4",
X"e0",X"04",X"3e",X"88",X"87",X"27",X"fe",X"76",
X"c4",X"e0",X"04",X"af",X"3e",X"aa",X"27",X"d4",
X"e0",X"04",X"fe",X"10",X"c4",X"e0",X"04",X"af",
X"3e",X"9a",X"27",X"d4",X"e0",X"04",X"c4",X"e0",
X"04",X"37",X"3e",X"42",X"07",X"dc",X"e0",X"04",
X"07",X"d4",X"e0",X"04",X"fe",X"09",X"c4",X"e0",
X"04",X"0f",X"d4",X"e0",X"04",X"0f",X"fe",X"42",
X"c4",X"e0",X"04",X"17",X"17",X"d4",X"e0",X"04",
X"fe",X"08",X"c4",X"e0",X"04",X"1f",X"1f",X"dc",
X"e0",X"04",X"fe",X"02",X"c4",X"e0",X"04",X"01",
X"34",X"12",X"11",X"aa",X"aa",X"21",X"55",X"55",
X"af",X"c5",X"d5",X"e5",X"f5",X"01",X"00",X"00",
X"11",X"00",X"00",X"21",X"00",X"00",X"3e",X"c0",
X"c6",X"f0",X"f1",X"e1",X"d1",X"c1",X"dc",X"e0",
X"04",X"c4",X"e0",X"04",X"e4",X"e0",X"04",X"fc",
X"e0",X"04",X"3e",X"12",X"b8",X"c4",X"e0",X"04",
X"3e",X"34",X"b9",X"c4",X"e0",X"04",X"3e",X"aa",
X"ba",X"c4",X"e0",X"04",X"bb",X"c4",X"e0",X"04",
X"3e",X"55",X"bc",X"c4",X"e0",X"04",X"bd",X"c4",
X"e0",X"04",X"21",X"00",X"00",X"39",X"22",X"f1",
X"04",X"31",X"f0",X"04",X"3b",X"3b",X"33",X"3b",
X"3e",X"55",X"32",X"ee",X"04",X"2f",X"32",X"ef",
X"04",X"c1",X"b8",X"c4",X"e0",X"04",X"2f",X"b9",
X"c4",X"e0",X"04",X"21",X"f0",X"04",X"f9",X"21",
X"33",X"77",X"3b",X"3b",X"e3",X"3a",X"ef",X"04",
X"fe",X"77",X"c4",X"e0",X"04",X"3a",X"ee",X"04",
X"fe",X"33",X"c4",X"e0",X"04",X"3e",X"55",X"bd",
X"c4",X"e0",X"04",X"2f",X"bc",X"c4",X"e0",X"04",
X"2a",X"f1",X"04",X"f9",X"21",X"e5",X"04",X"e9",
X"3e",X"aa",X"d3",X"20",X"76",X"3e",X"55",X"d3",
X"20",X"76",X"ec",X"04",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00"
 
);
 
signal irq_vector_byte: std_logic_vector(7 downto 0);
signal irq_source : integer range 0 to 7;
signal cycles_to_intr : integer range -10 to 255;
signal int_vector_index : integer range 0 to 3;
signal addr_vector_table: integer range 0 to 65535;
 
begin
 
-- Instantiate the Unit Under Test (UUT)
uut: light8080 PORT MAP(
clk => clk,
reset => reset,
vma => vma_o,
rd => rd_o,
wr => wr_o,
io => io_o,
fetch => fetch_o,
addr_out => addr_o,
data_in => data_i,
data_out => data_o,
intr => intr_i,
inte => inte_o,
inta => inta_o,
halt => halt_o
);
 
 
-- clock: run clock until test is done
clock:
process(done, clk)
begin
if done = '0' then
clk <= not clk after T/2;
end if;
end process clock;
 
 
-- Drive reset and done
main_test:
process
begin
-- Assert reset for at least one full clk period
reset <= '1';
wait until clk = '1';
wait for T/2;
reset <= '0';
 
-- Remember to 'cut away' the preceding 3 clk semiperiods from
-- the wait statement...
wait for (MAX_SIM_LENGTH - T*1.5);
 
-- Maximum sim time elapsed, assume the program ran away and
-- stop the clk process asserting 'done' (which will stop the simulation)
done <= '1';
assert (done = '1')
report "Test timed out."
severity failure;
wait;
end process main_test;
 
 
-- Synchronous RAM; 2KB mirrored everywhere
synchronous_ram:
process(clk)
begin
if (clk'event and clk='1') then
data_mem <= rom(conv_integer(addr_o(10 downto 0)));
if wr_o = '1' and addr_o(15 downto 11)="00000" then
rom(conv_integer(addr_o(10 downto 0))) <= data_o;
end if;
end if;
end process synchronous_ram;
 
 
irq_trigger_register:
process(clk)
begin
if (clk'event and clk='1') then
if reset='1' then
cycles_to_intr <= -10; -- meaning no interrupt pending
intr_i <= '0';
else
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"11" then
cycles_to_intr <= conv_integer(data_o) + 1;
else
if cycles_to_intr >= 0 then
cycles_to_intr <= cycles_to_intr - 1;
end if;
if cycles_to_intr = 0 and inta_o = '0' then
intr_i <= '1';
elsif inta_o = '1' then
intr_i <= '0';
end if;
end if;
end if;
end if;
end process irq_trigger_register;
 
 
irq_source_register:
process(clk)
begin
if (clk'event and clk='1') then
if reset='1' then
irq_source <= 0;
else
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"10" then
irq_source <= conv_integer(data_o(2 downto 0));
end if;
end if;
end if;
end process irq_source_register;
 
 
-- 'interrupt vector' logic.
irq_vector_table:
process(clk)
begin
if (clk'event and clk='1') then
if vma_o = '1' and rd_o='1' then
if inta_o = '1' then
int_vector_index <= int_vector_index + 1;
else
int_vector_index <= 0;
end if;
end if;
-- this is the address of the byte we'll feed to the CPU
addr_vector_table <= 64+irq_source*4+int_vector_index;
end if;
end process irq_vector_table;
irq_vector_byte <= rom(addr_vector_table);
 
data_i <= data_mem when inta_o='0' else irq_vector_byte;
 
 
test_outcome_register:
process(clk)
variable outcome : std_logic_vector(7 downto 0);
begin
if (clk'event and clk='1') then
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"20" then
assert (data_o /= X"55") report "Software reports SUCCESS" severity failure;
assert (data_o /= X"aa") report "Software reports FAILURE" severity failure;
assert ((data_o = X"aa") or (data_o = X"55"))
report "Software reports unexpected outcome value."
severity failure;
end if;
end if;
end process test_outcome_register;
 
 
end;
--------------------------------------------------------------------------------
-- Generated from template tb_template.vhdl by hexconv.pl
--------------------------------------------------------------------------------
-- Light8080 simulation test bench.
--------------------------------------------------------------------------------
-- This test bench was built from a generic template. The details on what tests
-- are performed by this test bench can be found in the assembly source for the
-- 8080 program, in file asm\tb0.asm.
--------------------------------------------------------------------------------
--
-- This test bench provides a simulated CPU system to test programs. This test
-- bench does not do any assertions or checks, all assertions are left to the
-- software.
--
-- The simulated environment has 2KB of RAM, mirror-mapped to all the memory
-- map of the 8080, initialized with the test program object code. See the perl
-- script 'util\hexconv.pl' and BAT files in the asm directory.
--
-- Besides, it provides some means to trigger hardware irq from software,
-- including the specification of the instructions fed to the CPU as interrupt
-- vectors during inta cycles.
--
-- We will simulate 8 possible irq sources. The software can trigger any one of
-- them by writing at ports 0x010 to 0x011. Port 0x010 holds the irq source to
-- be triggered (0 to 7) and port 0x011 holds the number of clock cycles that
-- will elapse from the end of the instruction that writes to the register to
-- the assertion of intr. Port 0x012 holds the number of cycles intr will remain
-- high. Intr will be asserted for 1 cycle at least, so writing a 0 here is the
-- same as writing 1.
--
-- When the interrupt is acknowledged and inta is asserted, the test bench reads
-- the value at register 0x010 as the irq source, and feeds an instruction to
-- the CPU starting from the RAM address 0040h+source*4.
-- That is, address range 0040h-005fh is reserved for the simulated 'interrupt
-- vectors', a total of 4 bytes for each of the 8 sources. This allows the
-- software to easily test different interrupt vectors without any hand
-- assembly. All of this is strictly simulation-only stuff.
--
-- Upon completion, the software must write a value to register 0x020. Writing
-- a 0x055 means 'success', writing a 0x0aa means 'failure'. The write operation
-- will stop the simulation. Success and failure conditions are defined by the
-- software.
--
-- If a time period defined as constant MAX_SIM_LENGTH passes before anything
-- is written to io address 0x020, the test bench assumes the software ran away
-- and quits with an error message.
--------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.ALL;
 
entity light8080_tb0 is
end entity light8080_tb0;
 
architecture behavior of light8080_tb0 is
 
--------------------------------------------------------------------------------
-- Simulation parameters
 
-- T: simulated clock period
constant T : time := 100 ns;
 
-- MAX_SIM_LENGTH: maximum simulation time
constant MAX_SIM_LENGTH : time := T*7000; -- enough for the tb0
 
 
--------------------------------------------------------------------------------
 
-- Component Declaration for the Unit Under Test (UUT)
component light8080
port (
addr_out : out std_logic_vector(15 downto 0);
inta : out std_logic;
inte : out std_logic;
halt : out std_logic;
intr : in std_logic;
vma : out std_logic;
io : out std_logic;
rd : out std_logic;
wr : out std_logic;
fetch : out std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
clk : in std_logic;
reset : in std_logic );
end component;
 
 
signal data_i : std_logic_vector(7 downto 0) := (others=>'0');
signal vma_o : std_logic;
signal rd_o : std_logic;
signal wr_o : std_logic;
signal io_o : std_logic;
signal data_o : std_logic_vector(7 downto 0);
signal data_mem : std_logic_vector(7 downto 0);
signal addr_o : std_logic_vector(15 downto 0);
signal fetch_o : std_logic;
signal inta_o : std_logic;
signal inte_o : std_logic;
signal intr_i : std_logic := '0';
signal halt_o : std_logic;
signal reset : std_logic := '0';
signal clk : std_logic := '1';
signal done : std_logic := '0';
 
type t_rom is array(0 to 2047) of std_logic_vector(7 downto 0);
 
signal rom : t_rom := (
 
X"31",X"1d",X"06",X"3e",X"77",X"e6",X"00",X"ca",
X"0d",X"00",X"cd",X"0a",X"05",X"d2",X"13",X"00",
X"cd",X"0a",X"05",X"ea",X"19",X"00",X"cd",X"0a",
X"05",X"f2",X"1f",X"00",X"cd",X"0a",X"05",X"c2",
X"2e",X"00",X"da",X"2e",X"00",X"e2",X"2e",X"00",
X"fa",X"2e",X"00",X"c3",X"31",X"00",X"cd",X"0a",
X"05",X"c6",X"06",X"c2",X"39",X"00",X"cd",X"0a",
X"05",X"da",X"42",X"00",X"e2",X"42",X"00",X"f2",
X"45",X"00",X"cd",X"0a",X"05",X"c6",X"70",X"e2",
X"4d",X"00",X"cd",X"0a",X"05",X"fa",X"56",X"00",
X"ca",X"56",X"00",X"d2",X"59",X"00",X"cd",X"0a",
X"05",X"c6",X"81",X"fa",X"61",X"00",X"cd",X"0a",
X"05",X"ca",X"6a",X"00",X"da",X"6a",X"00",X"e2",
X"6d",X"00",X"cd",X"0a",X"05",X"c6",X"fe",X"da",
X"75",X"00",X"cd",X"0a",X"05",X"ca",X"7e",X"00",
X"e2",X"7e",X"00",X"fa",X"81",X"00",X"cd",X"0a",
X"05",X"fe",X"00",X"da",X"99",X"00",X"ca",X"99",
X"00",X"fe",X"f5",X"da",X"99",X"00",X"c2",X"99",
X"00",X"fe",X"ff",X"ca",X"99",X"00",X"da",X"9c",
X"00",X"cd",X"0a",X"05",X"ce",X"0a",X"ce",X"0a",
X"fe",X"0b",X"ca",X"a8",X"00",X"cd",X"0a",X"05",
X"d6",X"0c",X"d6",X"0f",X"fe",X"f0",X"ca",X"b4",
X"00",X"cd",X"0a",X"05",X"de",X"f1",X"de",X"0e",
X"fe",X"f0",X"ca",X"c0",X"00",X"cd",X"0a",X"05",
X"e6",X"55",X"dc",X"0a",X"05",X"cc",X"0a",X"05",
X"fe",X"50",X"ca",X"d0",X"00",X"cd",X"0a",X"05",
X"f6",X"3a",X"dc",X"0a",X"05",X"cc",X"0a",X"05",
X"fe",X"7a",X"ca",X"e0",X"00",X"cd",X"0a",X"05",
X"ee",X"0f",X"dc",X"0a",X"05",X"cc",X"0a",X"05",
X"fe",X"75",X"ca",X"f0",X"00",X"cd",X"0a",X"05",
X"e6",X"00",X"dc",X"0a",X"05",X"e4",X"0a",X"05",
X"fc",X"0a",X"05",X"c4",X"0a",X"05",X"fe",X"00",
X"ca",X"06",X"01",X"cd",X"0a",X"05",X"d6",X"77",
X"d4",X"0a",X"05",X"ec",X"0a",X"05",X"f4",X"0a",
X"05",X"cc",X"0a",X"05",X"fe",X"89",X"ca",X"1c",
X"01",X"cd",X"0a",X"05",X"e6",X"ff",X"e4",X"29",
X"01",X"fe",X"d9",X"ca",X"86",X"01",X"cd",X"0a",
X"05",X"e8",X"c6",X"10",X"ec",X"35",X"01",X"c6",
X"02",X"e0",X"cd",X"0a",X"05",X"e0",X"c6",X"20",
X"fc",X"41",X"01",X"c6",X"04",X"e8",X"cd",X"0a",
X"05",X"f0",X"c6",X"80",X"f4",X"4d",X"01",X"c6",
X"80",X"f8",X"cd",X"0a",X"05",X"f8",X"c6",X"40",
X"d4",X"59",X"01",X"c6",X"40",X"f0",X"cd",X"0a",
X"05",X"d8",X"c6",X"8f",X"dc",X"65",X"01",X"d6",
X"02",X"d0",X"cd",X"0a",X"05",X"d0",X"c6",X"f7",
X"c4",X"71",X"01",X"c6",X"fe",X"d8",X"cd",X"0a",
X"05",X"c8",X"c6",X"01",X"cc",X"7d",X"01",X"c6",
X"d0",X"c0",X"cd",X"0a",X"05",X"c0",X"c6",X"47",
X"fe",X"47",X"c8",X"cd",X"0a",X"05",X"3e",X"77",
X"3c",X"47",X"04",X"48",X"0d",X"51",X"5a",X"63",
X"6c",X"7d",X"3d",X"4f",X"59",X"6b",X"45",X"50",
X"62",X"7c",X"57",X"14",X"6a",X"4d",X"0c",X"61",
X"44",X"05",X"58",X"7b",X"5f",X"1c",X"43",X"60",
X"24",X"4c",X"69",X"55",X"15",X"7a",X"67",X"25",
X"54",X"42",X"68",X"2c",X"5d",X"1d",X"4b",X"79",
X"6f",X"2d",X"65",X"5c",X"53",X"4a",X"41",X"78",
X"fe",X"77",X"c4",X"0a",X"05",X"af",X"06",X"01",
X"0e",X"03",X"16",X"07",X"1e",X"0f",X"26",X"1f",
X"2e",X"3f",X"80",X"81",X"82",X"83",X"84",X"85",
X"87",X"fe",X"f0",X"c4",X"0a",X"05",X"90",X"91",
X"92",X"93",X"94",X"95",X"fe",X"78",X"c4",X"0a",
X"05",X"97",X"c4",X"0a",X"05",X"3e",X"80",X"87",
X"06",X"01",X"0e",X"02",X"16",X"03",X"1e",X"04",
X"26",X"05",X"2e",X"06",X"88",X"06",X"80",X"80",
X"80",X"89",X"80",X"80",X"8a",X"80",X"80",X"8b",
X"80",X"80",X"8c",X"80",X"80",X"8d",X"80",X"80",
X"8f",X"fe",X"37",X"c4",X"0a",X"05",X"3e",X"80",
X"87",X"06",X"01",X"98",X"06",X"ff",X"80",X"99",
X"80",X"9a",X"80",X"9b",X"80",X"9c",X"80",X"9d",
X"fe",X"e0",X"c4",X"0a",X"05",X"3e",X"80",X"87",
X"9f",X"fe",X"ff",X"c4",X"0a",X"05",X"3e",X"ff",
X"06",X"fe",X"0e",X"fc",X"16",X"ef",X"1e",X"7f",
X"26",X"f4",X"2e",X"bf",X"37",X"a7",X"dc",X"0a",
X"05",X"a1",X"a2",X"a3",X"a4",X"a5",X"a7",X"fe",
X"24",X"c4",X"0a",X"05",X"af",X"06",X"01",X"0e",
X"02",X"16",X"04",X"1e",X"08",X"26",X"10",X"2e",
X"20",X"37",X"b0",X"dc",X"0a",X"05",X"b1",X"b2",
X"b3",X"b4",X"b5",X"b7",X"fe",X"3f",X"c4",X"0a",
X"05",X"3e",X"00",X"26",X"8f",X"2e",X"4f",X"37",
X"a8",X"dc",X"0a",X"05",X"a9",X"aa",X"ab",X"ac",
X"ad",X"fe",X"cf",X"c4",X"0a",X"05",X"af",X"c4",
X"0a",X"05",X"06",X"44",X"0e",X"45",X"16",X"46",
X"1e",X"47",X"26",X"05",X"2e",X"16",X"70",X"06",
X"00",X"46",X"3e",X"44",X"b8",X"c4",X"0a",X"05",
X"72",X"16",X"00",X"56",X"3e",X"46",X"ba",X"c4",
X"0a",X"05",X"73",X"1e",X"00",X"5e",X"3e",X"47",
X"bb",X"c4",X"0a",X"05",X"74",X"26",X"05",X"2e",
X"16",X"66",X"3e",X"05",X"bc",X"c4",X"0a",X"05",
X"75",X"26",X"05",X"2e",X"16",X"6e",X"3e",X"16",
X"bd",X"c4",X"0a",X"05",X"26",X"05",X"2e",X"16",
X"3e",X"32",X"77",X"be",X"c4",X"0a",X"05",X"86",
X"fe",X"64",X"c4",X"0a",X"05",X"af",X"7e",X"fe",
X"32",X"c4",X"0a",X"05",X"26",X"05",X"2e",X"16",
X"7e",X"96",X"c4",X"0a",X"05",X"3e",X"80",X"87",
X"8e",X"fe",X"33",X"c4",X"0a",X"05",X"3e",X"80",
X"87",X"9e",X"fe",X"cd",X"c4",X"0a",X"05",X"37",
X"a6",X"dc",X"0a",X"05",X"c4",X"0a",X"05",X"3e",
X"25",X"37",X"b6",X"dc",X"0a",X"05",X"fe",X"37",
X"c4",X"0a",X"05",X"37",X"ae",X"dc",X"0a",X"05",
X"fe",X"05",X"c4",X"0a",X"05",X"36",X"55",X"34",
X"35",X"86",X"fe",X"5a",X"c4",X"0a",X"05",X"01",
X"ff",X"12",X"11",X"ff",X"12",X"21",X"ff",X"12",
X"03",X"13",X"23",X"3e",X"13",X"b8",X"c4",X"0a",
X"05",X"ba",X"c4",X"0a",X"05",X"bc",X"c4",X"0a",
X"05",X"3e",X"00",X"b9",X"c4",X"0a",X"05",X"bb",
X"c4",X"0a",X"05",X"bd",X"c4",X"0a",X"05",X"0b",
X"1b",X"2b",X"3e",X"12",X"b8",X"c4",X"0a",X"05",
X"ba",X"c4",X"0a",X"05",X"bc",X"c4",X"0a",X"05",
X"3e",X"ff",X"b9",X"c4",X"0a",X"05",X"bb",X"c4",
X"0a",X"05",X"bd",X"c4",X"0a",X"05",X"32",X"16",
X"05",X"af",X"3a",X"16",X"05",X"fe",X"ff",X"c4",
X"0a",X"05",X"2a",X"14",X"05",X"22",X"16",X"05",
X"3a",X"14",X"05",X"47",X"3a",X"16",X"05",X"b8",
X"c4",X"0a",X"05",X"3a",X"15",X"05",X"47",X"3a",
X"17",X"05",X"b8",X"c4",X"0a",X"05",X"3e",X"aa",
X"32",X"16",X"05",X"44",X"4d",X"af",X"0a",X"fe",
X"aa",X"c4",X"0a",X"05",X"3c",X"02",X"3a",X"16",
X"05",X"fe",X"ab",X"c4",X"0a",X"05",X"3e",X"77",
X"32",X"16",X"05",X"2a",X"14",X"05",X"11",X"00",
X"00",X"eb",X"af",X"1a",X"fe",X"77",X"c4",X"0a",
X"05",X"af",X"84",X"85",X"c4",X"0a",X"05",X"3e",
X"cc",X"12",X"3a",X"16",X"05",X"fe",X"cc",X"12",
X"3a",X"16",X"05",X"fe",X"cc",X"c4",X"0a",X"05",
X"21",X"77",X"77",X"29",X"3e",X"ee",X"bc",X"c4",
X"0a",X"05",X"bd",X"c4",X"0a",X"05",X"21",X"55",
X"55",X"01",X"ff",X"ff",X"09",X"3e",X"55",X"d4",
X"0a",X"05",X"bc",X"c4",X"0a",X"05",X"3e",X"54",
X"bd",X"c4",X"0a",X"05",X"21",X"aa",X"aa",X"11",
X"33",X"33",X"19",X"3e",X"dd",X"bc",X"c4",X"0a",
X"05",X"bd",X"c4",X"0a",X"05",X"37",X"d4",X"0a",
X"05",X"3f",X"dc",X"0a",X"05",X"3e",X"aa",X"2f",
X"fe",X"55",X"c4",X"0a",X"05",X"b7",X"27",X"fe",
X"55",X"c4",X"0a",X"05",X"3e",X"88",X"87",X"27",
X"fe",X"76",X"c4",X"0a",X"05",X"af",X"3e",X"aa",
X"27",X"d4",X"0a",X"05",X"fe",X"10",X"c4",X"0a",
X"05",X"af",X"3e",X"9a",X"27",X"d4",X"0a",X"05",
X"c4",X"0a",X"05",X"37",X"3e",X"42",X"07",X"dc",
X"0a",X"05",X"07",X"d4",X"0a",X"05",X"fe",X"09",
X"c4",X"0a",X"05",X"0f",X"d4",X"0a",X"05",X"0f",
X"fe",X"42",X"c4",X"0a",X"05",X"17",X"17",X"d4",
X"0a",X"05",X"fe",X"08",X"c4",X"0a",X"05",X"1f",
X"1f",X"dc",X"0a",X"05",X"fe",X"02",X"c4",X"0a",
X"05",X"01",X"34",X"12",X"11",X"aa",X"aa",X"21",
X"55",X"55",X"af",X"c5",X"d5",X"e5",X"f5",X"01",
X"00",X"00",X"11",X"00",X"00",X"21",X"00",X"00",
X"3e",X"c0",X"c6",X"f0",X"f1",X"e1",X"d1",X"c1",
X"dc",X"0a",X"05",X"c4",X"0a",X"05",X"e4",X"0a",
X"05",X"fc",X"0a",X"05",X"3e",X"12",X"b8",X"c4",
X"0a",X"05",X"3e",X"34",X"b9",X"c4",X"0a",X"05",
X"3e",X"aa",X"ba",X"c4",X"0a",X"05",X"bb",X"c4",
X"0a",X"05",X"3e",X"55",X"bc",X"c4",X"0a",X"05",
X"bd",X"c4",X"0a",X"05",X"21",X"00",X"00",X"39",
X"22",X"1b",X"05",X"31",X"1a",X"05",X"3b",X"3b",
X"33",X"3b",X"3e",X"55",X"32",X"18",X"05",X"2f",
X"32",X"19",X"05",X"c1",X"b8",X"c4",X"0a",X"05",
X"2f",X"b9",X"c4",X"0a",X"05",X"21",X"1a",X"05",
X"f9",X"21",X"33",X"77",X"3b",X"3b",X"e3",X"3a",
X"19",X"05",X"fe",X"77",X"c4",X"0a",X"05",X"3a",
X"18",X"05",X"fe",X"33",X"c4",X"0a",X"05",X"3e",
X"55",X"bd",X"c4",X"0a",X"05",X"2f",X"bc",X"c4",
X"0a",X"05",X"2a",X"1b",X"05",X"f9",X"21",X"0f",
X"05",X"e9",X"3e",X"aa",X"d3",X"20",X"76",X"3e",
X"55",X"d3",X"20",X"76",X"16",X"05",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00"
 
);
 
signal irq_vector_byte: std_logic_vector(7 downto 0);
signal irq_source : integer range 0 to 7;
signal cycles_to_intr : integer range -10 to 255;
signal intr_width : integer range 0 to 255;
signal int_vector_index : integer range 0 to 3;
signal addr_vector_table: integer range 0 to 65535;
 
begin
 
-- Instantiate the Unit Under Test (UUT)
uut: light8080 PORT MAP(
clk => clk,
reset => reset,
vma => vma_o,
rd => rd_o,
wr => wr_o,
io => io_o,
fetch => fetch_o,
addr_out => addr_o,
data_in => data_i,
data_out => data_o,
intr => intr_i,
inte => inte_o,
inta => inta_o,
halt => halt_o
);
 
 
-- clock: run clock until test is done
clock:
process(done, clk)
begin
if done = '0' then
clk <= not clk after T/2;
end if;
end process clock;
 
 
-- Drive reset and done
main_test:
process
begin
-- Assert reset for at least one full clk period
reset <= '1';
wait until clk = '1';
wait for T/2;
reset <= '0';
 
-- Remember to 'cut away' the preceding 3 clk semiperiods from
-- the wait statement...
wait for (MAX_SIM_LENGTH - T*1.5);
 
-- Maximum sim time elapsed, assume the program ran away and
-- stop the clk process asserting 'done' (which will stop the simulation)
done <= '1';
assert (done = '1')
report "Test timed out."
severity failure;
wait;
end process main_test;
 
 
-- Synchronous RAM; 2KB mirrored everywhere
synchronous_ram:
process(clk)
begin
if (clk'event and clk='1') then
data_mem <= rom(conv_integer(addr_o(10 downto 0)));
if wr_o = '1' and addr_o(15 downto 11)="00000" then
rom(conv_integer(addr_o(10 downto 0))) <= data_o;
end if;
end if;
end process synchronous_ram;
 
 
irq_trigger_register:
process(clk)
begin
if (clk'event and clk='1') then
if reset='1' then
cycles_to_intr <= -10; -- meaning no interrupt pending
else
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"11" then
cycles_to_intr <= conv_integer(data_o) + 1;
else
if cycles_to_intr >= 0 then
cycles_to_intr <= cycles_to_intr - 1;
end if;
end if;
end if;
end if;
end process irq_trigger_register;
 
irq_pulse_width_register:
process(clk)
variable intr_pulse_countdown : integer;
begin
if (clk'event and clk='1') then
if reset='1' then
intr_width <= 1;
intr_pulse_countdown := 0;
intr_i <= '0';
else
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"12" then
intr_width <= conv_integer(data_o) + 1;
end if;
 
if cycles_to_intr = 0 then
intr_i <= '1';
intr_pulse_countdown := intr_width;
elsif intr_pulse_countdown <= 1 then
intr_i <= '0';
else
intr_pulse_countdown := intr_pulse_countdown - 1;
end if;
end if;
end if;
end process irq_pulse_width_register;
 
irq_source_register:
process(clk)
begin
if (clk'event and clk='1') then
if reset='1' then
irq_source <= 0;
else
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"10" then
irq_source <= conv_integer(data_o(2 downto 0));
end if;
end if;
end if;
end process irq_source_register;
 
 
-- 'interrupt vector' logic.
irq_vector_table:
process(clk)
begin
if (clk'event and clk='1') then
if vma_o = '1' and rd_o='1' then
if inta_o = '1' then
int_vector_index <= int_vector_index + 1;
else
int_vector_index <= 0;
end if;
end if;
-- this is the address of the byte we'll feed to the CPU
addr_vector_table <= 64+irq_source*4+int_vector_index;
end if;
end process irq_vector_table;
irq_vector_byte <= rom(addr_vector_table);
 
data_i <= data_mem when inta_o='0' else irq_vector_byte;
 
 
test_outcome_register:
process(clk)
variable outcome : std_logic_vector(7 downto 0);
begin
if (clk'event and clk='1') then
if io_o='1' and wr_o='1' and addr_o(7 downto 0)=X"20" then
assert (data_o /= X"55") report "Software reports SUCCESS" severity failure;
assert (data_o /= X"aa") report "Software reports FAILURE" severity failure;
assert ((data_o = X"aa") or (data_o = X"55"))
report "Software reports unexpected outcome value."
severity failure;
end if;
end if;
end process test_outcome_register;
 
 
end;
/light8080/trunk/vhdl/light8080.vhdl
1,6 → 1,7
--##############################################################################
-- light8080 : Intel 8080 binary compatible core
--##############################################################################
-- v1.3 (12 FEB 2012) Fix: General solution to AND, OR, XOR clearing CY,ACY.
-- v1.2 (08 jul 2010) Fix: XOR operations were not clearing CY,ACY.
-- v1.1 (20 sep 2008) Microcode bug in INR fixed.
-- v1.0 (05 nov 2007) First release. Jose A. Ruiz.
59,7 → 60,7
-- works as the master memory and io synchronous enable. More specifically:
--
-- * All memory/io control signals (io,rd,wr) are valid only when vma is
-- high. They never activate when vms is inactive.
-- high. They never activate when vma is inactive.
-- * Signals data_out and address are only valid when vma='1'. The high
-- address byte is 0x00 for all io accesses.
-- * Signal data_in should be valid by the end of the cycle after vma='1',
233,11 → 234,11
"00001000000000000000110000011111", -- 03e
"00000100011000111000001101001111", -- 03f
"00001000000000000000110000011111", -- 040
"00000100011000111000001101000100", -- 041
"00000100011000111100001101000100", -- 041
"00001000000000000000110000011111", -- 042
"00000100011000111000001101000101", -- 043
"00000100011000111100001101000101", -- 043
"00001000000000000000110000011111", -- 044
"00000100011000111000001101000110", -- 045
"00000100011000111100001101000110", -- 045
"00001000000000000000110000011111", -- 046
"00000100011000111000001110001110", -- 047
"00000000101010000000000000000000", -- 048
249,11 → 250,11
"00000000101010000000000000000000", -- 04e
"00000100011000111000001101001111", -- 04f
"00000000101010000000000000000000", -- 050
"00000100011000111000001101000100", -- 051
"00000100011000111100001101000100", -- 051
"00000000101010000000000000000000", -- 052
"00000100011000111000001101000101", -- 053
"00000100011000111100001101000101", -- 053
"00000000101010000000000000000000", -- 054
"00000100011000111000001101000110", -- 055
"00000100011000111100001101000110", -- 055
"00000000101010000000000000000000", -- 056
"00000100011000111000001110001110", -- 057
"00001000000000000000110000011001", -- 058
265,11 → 266,11
"00001000000000000000110000011001", -- 05e
"00000100011000111000001101001111", -- 05f
"00001000000000000000110000011001", -- 060
"00000100011000111000001101000100", -- 061
"00000100011000111100001101000100", -- 061
"00001000000000000000110000011001", -- 062
"00000100011000111000001101000101", -- 063
"00000100011000111100001101000101", -- 063
"00001000000000000000110000011001", -- 064
"00000100011000111000001101000110", -- 065
"00000100011000111100001101000110", -- 065
"00001000000000000000110000011001", -- 066
"00000100011000111000001110001110", -- 067
"10111100101100000000001001001101", -- 068
709,7 → 710,10
signal rbank_wr_addr: std_logic_vector(3 downto 0); -- rbank wr addr
signal DO : std_logic_vector(7 downto 0); -- data output reg
-- Register bank as an array of 16 bytes (asynch. LUT ram)
-- Register bank as an array of 16 bytes.
-- This will be implemented as asynchronous LUT RAM in those devices where this
-- feature is available (Xilinx) and as multiplexed registers where it isn't
-- (Altera).
type t_reg_bank is array(0 to 15) of std_logic_vector(7 downto 0);
-- Register bank : BC, DE, HL, AF, [PC, XY, ZW, SP]
signal rbank : t_reg_bank;
728,7 → 732,9
signal do_cpc : std_logic; -- ALU operation is CPC
signal do_cpc_d : std_logic; -- do_cpc, pipelined
signal do_daa : std_logic; -- ALU operation is DAA
signal do_xor : std_logic; -- ALU operation is some XOR (clears CY)
signal clear_cy : std_logic; -- Instruction unconditionally clears CY
signal clear_ac : std_logic; -- Instruction unconditionally clears AC
signal set_ac : std_logic; -- Instruction unconditionally sets AC
signal flag_ac : std_logic; -- new computed half carry flag
-- flag_aux_cy: new computed half carry flag (used in 16-bit ops)
signal flag_aux_cy : std_logic;
1124,7 → 1130,21
do_cpc <= ucode_field2(23);
do_cy_op <= ucode_field2(24);
do_daa <= '1' when ucode_field2(5 downto 2) = "1010" else '0';
do_xor <= '1' when ucode_field2(5 downto 0) = "000101" else '0';
 
-- ucode_field2(14) will be set for those instructions that modify CY and AC
-- without following the standard rules -- AND, OR and XOR instructions.
 
-- Some instructions will unconditionally clear CY (AND, OR, XOR)
clear_cy <= ucode_field2(14);
 
-- Some instructions will unconditionally clear AC (OR, XOR)...
clear_ac <= '1' when ucode_field2(14) = '1' and
ucode_field2(5 downto 0) /= "000100"
else '0';
-- ...and some others unconditionally SET AC (AND)
set_ac <= '1' when ucode_field2(14) = '1' and
ucode_field2(5 downto 0) = "000100"
else '0';
aux_cy_in <= reg_aux_cy when set_aux_cy = '0' else '1';
 
1230,14 → 1250,15
flag_p <= not(alu_output(7) xor alu_output(6) xor alu_output(5) xor alu_output(4) xor
alu_output(3) xor alu_output(2) xor alu_output(1) xor alu_output(0));
flag_z <= '1' when alu_output=X"00" else '0';
-- FIXED 08/JUL/2010: XOR was not clearing AC as it should
--flag_ac <= (arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4));
flag_ac <= (arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4)) and not do_xor;
-- AC is either the CY from bit 4 OR 0 if the instruction clears it implicitly
flag_ac <= '1' when set_ac = '1' else
'0' when clear_ac = '1' else
(arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4));
 
-- FIXED 08/JUL/2010: XOR was not clearing CY as it should
--flag_cy_1 <= cy_arith when use_logic = '1' else cy_shifter;
flag_cy_1 <= '0' when do_xor='1' else
cy_arith when use_logic = '1' and do_xor='0' else
-- CY comes from the adder or the shifter, or is 0 if the instruction
-- implicitly clears it.
flag_cy_1 <= '0' when clear_cy = '1' else
cy_arith when use_logic = '1' and clear_cy = '0' else
cy_shifter;
flag_cy_2 <= not flag_reg(0) when do_cpc='0' else '1'; -- cmc, stc
flag_cy <= flag_cy_1 when do_cy_op='0' else flag_cy_2;

powered by: WebSVN 2.1.0

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