URL
https://opencores.org/ocsvn/z80soc/z80soc/trunk
Subversion Repositories z80soc
Compare Revisions
- This comparison shows the changes necessary to convert path
/z80soc/tags/z80soc05b/rtl
- from Rev 8 to Rev 31
- ↔ Reverse comparison
Rev 8 → Rev 31
/VHDL/PS2/ps2bkd.vhd.bak
0,0 → 1,143
library IEEE; |
use IEEE.std_logic_1164.all; |
|
entity ps2kbd is |
PORT ( |
keyboard_clk : inout std_logic; |
keyboard_data : inout std_logic; |
clock : in std_logic; |
reset : in std_logic; |
read : in std_logic; |
scan_ready : out std_logic; |
ps2_ascii_code : out std_logic_vector(7 downto 0)); |
end ps2kbd; |
|
architecture rtl of ps2kbd is |
|
signal scan_code_sig : std_logic_vector(7 downto 0); |
signal scode_shf_sig : std_logic_vector(11 downto 0); |
|
begin |
|
scode_shf_sig <= "0000" & scan_code_sig; |
|
ps2_ascii_decode : process(scode_shf_sig) |
begin |
case scode_shf_sig is |
when x"066" => ps2_ascii_code <= x"08"; -- Backspace ("backspace" key) |
when x"00d" => ps2_ascii_code <= x"09"; -- Horizontal Tab |
when x"05a" => ps2_ascii_code <= x"0d"; -- Carriage return ("enter" key) |
when x"076" => ps2_ascii_code <= x"1b"; -- Escape ("esc" key) |
when x"029" => ps2_ascii_code <= x"20"; -- Space |
when x"116" => ps2_ascii_code <= x"21"; -- ! |
when x"152" => ps2_ascii_code <= x"22"; -- " |
when x"126" => ps2_ascii_code <= x"23"; -- # |
when x"125" => ps2_ascii_code <= x"24"; -- $ |
when x"12e" => ps2_ascii_code <= x"25"; -- |
when x"13d" => ps2_ascii_code <= x"26"; -- |
when x"052" => ps2_ascii_code <= x"27"; -- |
when x"146" => ps2_ascii_code <= x"28"; -- |
when x"145" => ps2_ascii_code <= x"29"; -- |
when x"13e" => ps2_ascii_code <= x"2a"; -- * |
when x"155" => ps2_ascii_code <= x"2b"; -- + |
when x"041" => ps2_ascii_code <= x"2c"; -- , |
when x"04e" => ps2_ascii_code <= x"2d"; -- - |
when x"049" => ps2_ascii_code <= x"2e"; -- . |
when x"04a" => ps2_ascii_code <= x"2f"; -- / |
when x"045" => ps2_ascii_code <= x"30"; -- 0 |
when x"016" => ps2_ascii_code <= x"31"; -- 1 |
when x"01e" => ps2_ascii_code <= x"32"; -- 2 |
when x"026" => ps2_ascii_code <= x"33"; -- 3 |
when x"025" => ps2_ascii_code <= x"34"; -- 4 |
when x"02e" => ps2_ascii_code <= x"35"; -- 5 |
when x"036" => ps2_ascii_code <= x"36"; -- 6 |
when x"03d" => ps2_ascii_code <= x"37"; -- 7 |
when x"03e" => ps2_ascii_code <= x"38"; -- 8 |
when x"046" => ps2_ascii_code <= x"39"; -- 9 |
when x"14c" => ps2_ascii_code <= x"3a"; -- : |
when x"04c" => ps2_ascii_code <= x"3b"; -- ; |
when x"141" => ps2_ascii_code <= x"3c"; -- < |
when x"055" => ps2_ascii_code <= x"3d"; -- = |
when x"149" => ps2_ascii_code <= x"3e"; -- > |
when x"14a" => ps2_ascii_code <= x"3f"; -- ? |
when x"11e" => ps2_ascii_code <= x"40"; -- @ |
when x"01c" => ps2_ascii_code <= x"41"; -- A |
when x"032" => ps2_ascii_code <= x"42"; -- B |
when x"021" => ps2_ascii_code <= x"43"; -- C |
when x"023" => ps2_ascii_code <= x"44"; -- D |
when x"024" => ps2_ascii_code <= x"45"; -- E |
when x"02b" => ps2_ascii_code <= x"46"; -- F |
when x"034" => ps2_ascii_code <= x"47"; -- G |
when x"033" => ps2_ascii_code <= x"48"; -- H |
when x"043" => ps2_ascii_code <= x"49"; -- I |
when x"03b" => ps2_ascii_code <= x"4a"; -- J |
when x"042" => ps2_ascii_code <= x"4b"; -- K |
when x"04b" => ps2_ascii_code <= x"4c"; -- L |
when x"03a" => ps2_ascii_code <= x"4d"; -- M |
when x"031" => ps2_ascii_code <= x"4e"; -- N |
when x"044" => ps2_ascii_code <= x"4f"; -- O |
when x"04d" => ps2_ascii_code <= x"50"; -- P |
when x"015" => ps2_ascii_code <= x"51"; -- Q |
when x"02d" => ps2_ascii_code <= x"52"; -- R |
when x"01b" => ps2_ascii_code <= x"53"; -- S |
when x"02c" => ps2_ascii_code <= x"54"; -- T |
when x"03c" => ps2_ascii_code <= x"55"; -- U |
when x"02a" => ps2_ascii_code <= x"56"; -- V |
when x"01d" => ps2_ascii_code <= x"57"; -- W |
when x"022" => ps2_ascii_code <= x"58"; -- X |
when x"035" => ps2_ascii_code <= x"59"; -- Y |
when x"01a" => ps2_ascii_code <= x"5a"; -- Z |
when x"054" => ps2_ascii_code <= x"5b"; -- [ |
when x"05d" => ps2_ascii_code <= x"5c"; -- \ |
when x"05b" => ps2_ascii_code <= x"5d"; -- ] |
when x"136" => ps2_ascii_code <= x"5e"; -- ^ |
when x"14e" => ps2_ascii_code <= x"5f"; -- _ |
when x"00e" => ps2_ascii_code <= x"60"; -- ` |
when x"01c" => ps2_ascii_code <= x"61"; -- a |
when x"032" => ps2_ascii_code <= x"62"; -- b |
when x"021" => ps2_ascii_code <= x"63"; -- c |
when x"023" => ps2_ascii_code <= x"64"; -- d |
when x"024" => ps2_ascii_code <= x"65"; -- e |
when x"02b" => ps2_ascii_code <= x"66"; -- f |
when x"034" => ps2_ascii_code <= x"67"; -- g |
when x"033" => ps2_ascii_code <= x"68"; -- h |
when x"043" => ps2_ascii_code <= x"69"; -- i |
when x"03b" => ps2_ascii_code <= x"6a"; -- j |
when x"042" => ps2_ascii_code <= x"6b"; -- k |
when x"04b" => ps2_ascii_code <= x"6c"; -- l |
when x"03a" => ps2_ascii_code <= x"6d"; -- m |
when x"031" => ps2_ascii_code <= x"6e"; -- n |
when x"044" => ps2_ascii_code <= x"6f"; -- o |
when x"04d" => ps2_ascii_code <= x"70"; -- p |
when x"015" => ps2_ascii_code <= x"71"; -- q |
when x"02d" => ps2_ascii_code <= x"72"; -- r |
when x"01b" => ps2_ascii_code <= x"73"; -- s |
when x"02c" => ps2_ascii_code <= x"74"; -- t |
when x"03c" => ps2_ascii_code <= x"75"; -- u |
when x"02a" => ps2_ascii_code <= x"76"; -- v |
when x"01d" => ps2_ascii_code <= x"77"; -- w |
when x"022" => ps2_ascii_code <= x"78"; -- x |
when x"035" => ps2_ascii_code <= x"79"; -- y |
when x"01a" => ps2_ascii_code <= x"7a"; -- z |
when x"154" => ps2_ascii_code <= x"7b"; -- { |
when x"15d" => ps2_ascii_code <= x"7c"; -- | |
when x"15b" => ps2_ascii_code <= x"7d"; -- } |
when x"10e" => ps2_ascii_code <= x"7e"; -- ~ |
when x"071" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad) |
when x"171" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad) |
when others => ps2_ascii_code <= x"FF"; -- keys not mapped |
end case; |
end process; |
|
kbd_inst: work.keyboard port map ( |
keyboard_clk => keyboard_clk, |
keyboard_data => keyboard_data, |
clock => clock, |
reset => reset, |
read => read, |
scan_ready => scan_ready, |
scan_code => scan_code_sig |
); |
|
end; |
|
/VHDL/PS2/ps2bkd.vhd
0,0 → 1,143
library IEEE; |
use IEEE.std_logic_1164.all; |
|
entity ps2kbd is |
PORT ( |
keyboard_clk : inout std_logic; |
keyboard_data : inout std_logic; |
clock : in std_logic; |
reset : in std_logic; |
read : in std_logic; |
scan_ready : out std_logic; |
ps2_ascii_code : out std_logic_vector(7 downto 0)); |
end ps2kbd; |
|
architecture rtl of ps2kbd is |
|
signal scan_code_sig : std_logic_vector(7 downto 0); |
signal scode_shf_sig : std_logic_vector(11 downto 0); |
|
begin |
|
scode_shf_sig <= "0000" & scan_code_sig; |
|
ps2_ascii_decode : process(scode_shf_sig) |
begin |
case scode_shf_sig is |
when x"066" => ps2_ascii_code <= x"08"; -- Backspace ("backspace" key) |
when x"00d" => ps2_ascii_code <= x"09"; -- Horizontal Tab |
when x"05a" => ps2_ascii_code <= x"0d"; -- Carriage return ("enter" key) |
when x"076" => ps2_ascii_code <= x"1b"; -- Escape ("esc" key) |
when x"029" => ps2_ascii_code <= x"20"; -- Space |
when x"116" => ps2_ascii_code <= x"21"; -- ! |
when x"152" => ps2_ascii_code <= x"22"; -- " |
when x"126" => ps2_ascii_code <= x"23"; -- # |
when x"125" => ps2_ascii_code <= x"24"; -- $ |
when x"12e" => ps2_ascii_code <= x"25"; -- |
when x"13d" => ps2_ascii_code <= x"26"; -- |
when x"052" => ps2_ascii_code <= x"27"; -- |
when x"146" => ps2_ascii_code <= x"28"; -- |
when x"145" => ps2_ascii_code <= x"29"; -- |
when x"13e" => ps2_ascii_code <= x"2a"; -- * |
when x"155" => ps2_ascii_code <= x"2b"; -- + |
when x"041" => ps2_ascii_code <= x"2c"; -- , |
when x"04e" => ps2_ascii_code <= x"2d"; -- - |
when x"049" => ps2_ascii_code <= x"2e"; -- . |
when x"04a" => ps2_ascii_code <= x"2f"; -- / |
when x"045" => ps2_ascii_code <= x"30"; -- 0 |
when x"016" => ps2_ascii_code <= x"31"; -- 1 |
when x"01e" => ps2_ascii_code <= x"32"; -- 2 |
when x"026" => ps2_ascii_code <= x"33"; -- 3 |
when x"025" => ps2_ascii_code <= x"34"; -- 4 |
when x"02e" => ps2_ascii_code <= x"35"; -- 5 |
when x"036" => ps2_ascii_code <= x"36"; -- 6 |
when x"03d" => ps2_ascii_code <= x"37"; -- 7 |
when x"03e" => ps2_ascii_code <= x"38"; -- 8 |
when x"046" => ps2_ascii_code <= x"39"; -- 9 |
when x"14c" => ps2_ascii_code <= x"3a"; -- : |
when x"04c" => ps2_ascii_code <= x"3b"; -- ; |
when x"141" => ps2_ascii_code <= x"3c"; -- < |
when x"055" => ps2_ascii_code <= x"3d"; -- = |
when x"149" => ps2_ascii_code <= x"3e"; -- > |
when x"14a" => ps2_ascii_code <= x"3f"; -- ? |
when x"11e" => ps2_ascii_code <= x"40"; -- @ |
when x"01c" => ps2_ascii_code <= x"41"; -- A |
when x"032" => ps2_ascii_code <= x"42"; -- B |
when x"021" => ps2_ascii_code <= x"43"; -- C |
when x"023" => ps2_ascii_code <= x"44"; -- D |
when x"024" => ps2_ascii_code <= x"45"; -- E |
when x"02b" => ps2_ascii_code <= x"46"; -- F |
when x"034" => ps2_ascii_code <= x"47"; -- G |
when x"033" => ps2_ascii_code <= x"48"; -- H |
when x"043" => ps2_ascii_code <= x"49"; -- I |
when x"03b" => ps2_ascii_code <= x"4a"; -- J |
when x"042" => ps2_ascii_code <= x"4b"; -- K |
when x"04b" => ps2_ascii_code <= x"4c"; -- L |
when x"03a" => ps2_ascii_code <= x"4d"; -- M |
when x"031" => ps2_ascii_code <= x"4e"; -- N |
when x"044" => ps2_ascii_code <= x"4f"; -- O |
when x"04d" => ps2_ascii_code <= x"50"; -- P |
when x"015" => ps2_ascii_code <= x"51"; -- Q |
when x"02d" => ps2_ascii_code <= x"52"; -- R |
when x"01b" => ps2_ascii_code <= x"53"; -- S |
when x"02c" => ps2_ascii_code <= x"54"; -- T |
when x"03c" => ps2_ascii_code <= x"55"; -- U |
when x"02a" => ps2_ascii_code <= x"56"; -- V |
when x"01d" => ps2_ascii_code <= x"57"; -- W |
when x"022" => ps2_ascii_code <= x"58"; -- X |
when x"035" => ps2_ascii_code <= x"59"; -- Y |
when x"01a" => ps2_ascii_code <= x"5a"; -- Z |
when x"054" => ps2_ascii_code <= x"5b"; -- [ |
when x"05d" => ps2_ascii_code <= x"5c"; -- \ |
when x"05b" => ps2_ascii_code <= x"5d"; -- ] |
when x"136" => ps2_ascii_code <= x"5e"; -- ^ |
when x"14e" => ps2_ascii_code <= x"5f"; -- _ |
when x"00e" => ps2_ascii_code <= x"60"; -- ` |
when x"11c" => ps2_ascii_code <= x"61"; -- a |
when x"132" => ps2_ascii_code <= x"62"; -- b |
when x"121" => ps2_ascii_code <= x"63"; -- c |
when x"123" => ps2_ascii_code <= x"64"; -- d |
when x"124" => ps2_ascii_code <= x"65"; -- e |
when x"12b" => ps2_ascii_code <= x"66"; -- f |
when x"134" => ps2_ascii_code <= x"67"; -- g |
when x"133" => ps2_ascii_code <= x"68"; -- h |
when x"143" => ps2_ascii_code <= x"69"; -- i |
when x"13b" => ps2_ascii_code <= x"6a"; -- j |
when x"142" => ps2_ascii_code <= x"6b"; -- k |
when x"14b" => ps2_ascii_code <= x"6c"; -- l |
when x"13a" => ps2_ascii_code <= x"6d"; -- m |
when x"131" => ps2_ascii_code <= x"6e"; -- n |
when x"144" => ps2_ascii_code <= x"6f"; -- o |
when x"14d" => ps2_ascii_code <= x"70"; -- p |
when x"115" => ps2_ascii_code <= x"71"; -- q |
when x"12d" => ps2_ascii_code <= x"72"; -- r |
when x"11b" => ps2_ascii_code <= x"73"; -- s |
when x"12c" => ps2_ascii_code <= x"74"; -- t |
when x"13c" => ps2_ascii_code <= x"75"; -- u |
when x"12a" => ps2_ascii_code <= x"76"; -- v |
when x"11d" => ps2_ascii_code <= x"77"; -- w |
when x"122" => ps2_ascii_code <= x"78"; -- x |
when x"135" => ps2_ascii_code <= x"79"; -- y |
when x"11a" => ps2_ascii_code <= x"7a"; -- z |
when x"154" => ps2_ascii_code <= x"7b"; -- { |
when x"15d" => ps2_ascii_code <= x"7c"; -- | |
when x"15b" => ps2_ascii_code <= x"7d"; -- } |
when x"10e" => ps2_ascii_code <= x"7e"; -- ~ |
when x"071" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad) |
when x"171" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad) |
when others => ps2_ascii_code <= x"FF"; -- keys not mapped |
end case; |
end process; |
|
kbd_inst: work.keyboard port map ( |
keyboard_clk => keyboard_clk, |
keyboard_data => keyboard_data, |
clock => clock, |
reset => reset, |
read => read, |
scan_ready => scan_ready, |
scan_code => scan_code_sig |
); |
|
end; |
|
/VHDL/PS2/KEYBOARD.VHD
0,0 → 1,78
LIBRARY IEEE; |
USE IEEE.STD_LOGIC_1164.all; |
USE IEEE.STD_LOGIC_ARITH.all; |
USE IEEE.STD_LOGIC_UNSIGNED.all; |
|
ENTITY keyboard IS |
PORT( keyboard_clk, keyboard_data, clock , |
reset, read : IN STD_LOGIC; |
scan_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); |
scan_ready : OUT STD_LOGIC); |
END keyboard; |
|
ARCHITECTURE a OF keyboard IS |
SIGNAL INCNT : std_logic_vector(3 downto 0); |
SIGNAL SHIFTIN : std_logic_vector(8 downto 0); |
SIGNAL READ_CHAR, clock_enable : std_logic; |
SIGNAL INFLAG, ready_set : std_logic; |
SIGNAL keyboard_clk_filtered : std_logic; |
SIGNAL filter : std_logic_vector(7 downto 0); |
BEGIN |
|
PROCESS (read, ready_set) |
BEGIN |
IF read = '1' THEN scan_ready <= '0'; |
ELSIF ready_set'EVENT and ready_set = '1' THEN |
scan_ready <= '1'; |
END IF; |
END PROCESS; |
|
|
--This process filters the raw clock signal coming from the keyboard using a shift register and two AND gates |
Clock_filter: PROCESS |
BEGIN |
WAIT UNTIL clock'EVENT AND clock= '1'; |
clock_enable <= NOT clock_enable; |
IF clock_enable = '1' THEN |
filter (6 DOWNTO 0) <= filter(7 DOWNTO 1) ; |
filter(7) <= keyboard_clk; |
IF filter = "11111111" THEN keyboard_clk_filtered <= '1'; |
ELSIF filter= "00000000" THEN keyboard_clk_filtered <= '0'; |
END IF; |
END IF; |
END PROCESS Clock_filter; |
|
|
--This process reads in serial data coming from the terminal |
PROCESS |
BEGIN |
WAIT UNTIL (KEYBOARD_CLK_filtered'EVENT AND KEYBOARD_CLK_filtered='1'); |
IF RESET='0' THEN |
INCNT <= "0000"; |
READ_CHAR <= '0'; |
ready_set<= '0'; |
ELSE |
IF KEYBOARD_DATA='0' AND READ_CHAR='0' THEN |
READ_CHAR<= '1'; |
ready_set<= '0'; |
ELSE |
-- Shift in next 8 data bits to assemble a scan code |
IF READ_CHAR = '1' THEN |
IF INCNT < "1001" THEN |
INCNT <= INCNT + 1; |
SHIFTIN(7 DOWNTO 0) <= SHIFTIN(8 DOWNTO 1); |
SHIFTIN(8) <= KEYBOARD_DATA; |
-- End of scan code character, so set flags and exit loop |
ELSE |
scan_code <= SHIFTIN(7 DOWNTO 0); |
READ_CHAR <= '0'; |
ready_set <= '1'; |
INCNT <= "0000"; |
END IF; |
END IF; |
END IF; |
END IF; |
END PROCESS; |
END a; |
|
|
/VHDL/rom.vhd
0,0 → 1,568
library IEEE; |
use IEEE.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity rom is |
port( |
Clk : in std_logic; |
A : in std_logic_vector(15 downto 0); |
D : out std_logic_vector(7 downto 0) |
); |
end rom; |
|
architecture rtl of rom is |
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
case A is |
when x"0000" => D <= x"31"; |
when x"0001" => D <= x"FF"; |
when x"0002" => D <= x"FF"; |
when x"0003" => D <= x"CD"; |
when x"0004" => D <= x"C7"; |
when x"0005" => D <= x"00"; |
when x"0006" => D <= x"21"; |
when x"0007" => D <= x"32"; |
when x"0008" => D <= x"20"; |
when x"0009" => D <= x"11"; |
when x"000A" => D <= x"0E"; |
when x"000B" => D <= x"01"; |
when x"000C" => D <= x"CD"; |
when x"000D" => D <= x"D7"; |
when x"000E" => D <= x"00"; |
when x"000F" => D <= x"21"; |
when x"0010" => D <= x"5A"; |
when x"0011" => D <= x"20"; |
when x"0012" => D <= x"11"; |
when x"0013" => D <= x"21"; |
when x"0014" => D <= x"01"; |
when x"0015" => D <= x"CD"; |
when x"0016" => D <= x"D7"; |
when x"0017" => D <= x"00"; |
when x"0018" => D <= x"CD"; |
when x"0019" => D <= x"E8"; |
when x"001A" => D <= x"00"; |
when x"001B" => D <= x"21"; |
when x"001C" => D <= x"46"; |
when x"001D" => D <= x"21"; |
when x"001E" => D <= x"11"; |
when x"001F" => D <= x"34"; |
when x"0020" => D <= x"01"; |
when x"0021" => D <= x"CD"; |
when x"0022" => D <= x"D7"; |
when x"0023" => D <= x"00"; |
when x"0024" => D <= x"21"; |
when x"0025" => D <= x"96"; |
when x"0026" => D <= x"21"; |
when x"0027" => D <= x"11"; |
when x"0028" => D <= x"50"; |
when x"0029" => D <= x"01"; |
when x"002A" => D <= x"CD"; |
when x"002B" => D <= x"D7"; |
when x"002C" => D <= x"00"; |
when x"002D" => D <= x"21"; |
when x"002E" => D <= x"E6"; |
when x"002F" => D <= x"21"; |
when x"0030" => D <= x"11"; |
when x"0031" => D <= x"6D"; |
when x"0032" => D <= x"01"; |
when x"0033" => D <= x"CD"; |
when x"0034" => D <= x"D7"; |
when x"0035" => D <= x"00"; |
when x"0036" => D <= x"21"; |
when x"0037" => D <= x"36"; |
when x"0038" => D <= x"22"; |
when x"0039" => D <= x"11"; |
when x"003A" => D <= x"8A"; |
when x"003B" => D <= x"01"; |
when x"003C" => D <= x"CD"; |
when x"003D" => D <= x"D7"; |
when x"003E" => D <= x"00"; |
when x"003F" => D <= x"21"; |
when x"0040" => D <= x"5E"; |
when x"0041" => D <= x"22"; |
when x"0042" => D <= x"11"; |
when x"0043" => D <= x"9E"; |
when x"0044" => D <= x"01"; |
when x"0045" => D <= x"CD"; |
when x"0046" => D <= x"D7"; |
when x"0047" => D <= x"00"; |
when x"0048" => D <= x"DB"; |
when x"0049" => D <= x"20"; |
when x"004A" => D <= x"32"; |
when x"004B" => D <= x"00"; |
when x"004C" => D <= x"E0"; |
when x"004D" => D <= x"11"; |
when x"004E" => D <= x"D6"; |
when x"004F" => D <= x"22"; |
when x"0050" => D <= x"01"; |
when x"0051" => D <= x"1E"; |
when x"0052" => D <= x"00"; |
when x"0053" => D <= x"CD"; |
when x"0054" => D <= x"DF"; |
when x"0055" => D <= x"00"; |
when x"0056" => D <= x"FE"; |
when x"0057" => D <= x"41"; |
when x"0058" => D <= x"28"; |
when x"0059" => D <= x"0B"; |
when x"005A" => D <= x"D3"; |
when x"005B" => D <= x"11"; |
when x"005C" => D <= x"12"; |
when x"005D" => D <= x"13"; |
when x"005E" => D <= x"0B"; |
when x"005F" => D <= x"78"; |
when x"0060" => D <= x"B1"; |
when x"0061" => D <= x"28"; |
when x"0062" => D <= x"EA"; |
when x"0063" => D <= x"18"; |
when x"0064" => D <= x"EE"; |
when x"0065" => D <= x"21"; |
when x"0066" => D <= x"00"; |
when x"0067" => D <= x"40"; |
when x"0068" => D <= x"3E"; |
when x"0069" => D <= x"00"; |
when x"006A" => D <= x"77"; |
when x"006B" => D <= x"23"; |
when x"006C" => D <= x"3C"; |
when x"006D" => D <= x"20"; |
when x"006E" => D <= x"FB"; |
when x"006F" => D <= x"3E"; |
when x"0070" => D <= x"01"; |
when x"0071" => D <= x"D3"; |
when x"0072" => D <= x"01"; |
when x"0073" => D <= x"CD"; |
when x"0074" => D <= x"B9"; |
when x"0075" => D <= x"00"; |
when x"0076" => D <= x"CD"; |
when x"0077" => D <= x"B9"; |
when x"0078" => D <= x"00"; |
when x"0079" => D <= x"CD"; |
when x"007A" => D <= x"B9"; |
when x"007B" => D <= x"00"; |
when x"007C" => D <= x"CD"; |
when x"007D" => D <= x"A6"; |
when x"007E" => D <= x"00"; |
when x"007F" => D <= x"CD"; |
when x"0080" => D <= x"B9"; |
when x"0081" => D <= x"00"; |
when x"0082" => D <= x"CD"; |
when x"0083" => D <= x"A6"; |
when x"0084" => D <= x"00"; |
when x"0085" => D <= x"21"; |
when x"0086" => D <= x"00"; |
when x"0087" => D <= x"40"; |
when x"0088" => D <= x"7C"; |
when x"0089" => D <= x"D3"; |
when x"008A" => D <= x"11"; |
when x"008B" => D <= x"7D"; |
when x"008C" => D <= x"D3"; |
when x"008D" => D <= x"10"; |
when x"008E" => D <= x"7E"; |
when x"008F" => D <= x"D3"; |
when x"0090" => D <= x"01"; |
when x"0091" => D <= x"CD"; |
when x"0092" => D <= x"B9"; |
when x"0093" => D <= x"00"; |
when x"0094" => D <= x"23"; |
when x"0095" => D <= x"7E"; |
when x"0096" => D <= x"FE"; |
when x"0097" => D <= x"FF"; |
when x"0098" => D <= x"20"; |
when x"0099" => D <= x"EE"; |
when x"009A" => D <= x"3E"; |
when x"009B" => D <= x"00"; |
when x"009C" => D <= x"D3"; |
when x"009D" => D <= x"01"; |
when x"009E" => D <= x"D3"; |
when x"009F" => D <= x"02"; |
when x"00A0" => D <= x"CD"; |
when x"00A1" => D <= x"A6"; |
when x"00A2" => D <= x"00"; |
when x"00A3" => D <= x"C3"; |
when x"00A4" => D <= x"03"; |
when x"00A5" => D <= x"00"; |
when x"00A6" => D <= x"CD"; |
when x"00A7" => D <= x"B9"; |
when x"00A8" => D <= x"00"; |
when x"00A9" => D <= x"DB"; |
when x"00AA" => D <= x"30"; |
when x"00AB" => D <= x"D3"; |
when x"00AC" => D <= x"10"; |
when x"00AD" => D <= x"FE"; |
when x"00AE" => D <= x"0E"; |
when x"00AF" => D <= x"20"; |
when x"00B0" => D <= x"F5"; |
when x"00B1" => D <= x"C9"; |
when x"00B2" => D <= x"3A"; |
when x"00B3" => D <= x"00"; |
when x"00B4" => D <= x"E0"; |
when x"00B5" => D <= x"3D"; |
when x"00B6" => D <= x"20"; |
when x"00B7" => D <= x"FD"; |
when x"00B8" => D <= x"C9"; |
when x"00B9" => D <= x"3A"; |
when x"00BA" => D <= x"00"; |
when x"00BB" => D <= x"E0"; |
when x"00BC" => D <= x"F5"; |
when x"00BD" => D <= x"3E"; |
when x"00BE" => D <= x"FF"; |
when x"00BF" => D <= x"3D"; |
when x"00C0" => D <= x"20"; |
when x"00C1" => D <= x"FD"; |
when x"00C2" => D <= x"F1"; |
when x"00C3" => D <= x"3D"; |
when x"00C4" => D <= x"20"; |
when x"00C5" => D <= x"F6"; |
when x"00C6" => D <= x"C9"; |
when x"00C7" => D <= x"21"; |
when x"00C8" => D <= x"00"; |
when x"00C9" => D <= x"20"; |
when x"00CA" => D <= x"11"; |
when x"00CB" => D <= x"B0"; |
when x"00CC" => D <= x"04"; |
when x"00CD" => D <= x"3E"; |
when x"00CE" => D <= x"20"; |
when x"00CF" => D <= x"77"; |
when x"00D0" => D <= x"23"; |
when x"00D1" => D <= x"1B"; |
when x"00D2" => D <= x"7A"; |
when x"00D3" => D <= x"B3"; |
when x"00D4" => D <= x"20"; |
when x"00D5" => D <= x"F7"; |
when x"00D6" => D <= x"C9"; |
when x"00D7" => D <= x"1A"; |
when x"00D8" => D <= x"B7"; |
when x"00D9" => D <= x"C8"; |
when x"00DA" => D <= x"77"; |
when x"00DB" => D <= x"23"; |
when x"00DC" => D <= x"13"; |
when x"00DD" => D <= x"18"; |
when x"00DE" => D <= x"F8"; |
when x"00DF" => D <= x"CD"; |
when x"00E0" => D <= x"B9"; |
when x"00E1" => D <= x"00"; |
when x"00E2" => D <= x"DB"; |
when x"00E3" => D <= x"80"; |
when x"00E4" => D <= x"B7"; |
when x"00E5" => D <= x"28"; |
when x"00E6" => D <= x"F8"; |
when x"00E7" => D <= x"C9"; |
when x"00E8" => D <= x"11"; |
when x"00E9" => D <= x"BD"; |
when x"00EA" => D <= x"01"; |
when x"00EB" => D <= x"21"; |
when x"00EC" => D <= x"F5"; |
when x"00ED" => D <= x"20"; |
when x"00EE" => D <= x"CD"; |
when x"00EF" => D <= x"D7"; |
when x"00F0" => D <= x"00"; |
when x"00F1" => D <= x"21"; |
when x"00F2" => D <= x"1D"; |
when x"00F3" => D <= x"21"; |
when x"00F4" => D <= x"3E"; |
when x"00F5" => D <= x"0A"; |
when x"00F6" => D <= x"11"; |
when x"00F7" => D <= x"FF"; |
when x"00F8" => D <= x"01"; |
when x"00F9" => D <= x"F5"; |
when x"00FA" => D <= x"E5"; |
when x"00FB" => D <= x"CD"; |
when x"00FC" => D <= x"D7"; |
when x"00FD" => D <= x"00"; |
when x"00FE" => D <= x"E1"; |
when x"00FF" => D <= x"F1"; |
when x"0100" => D <= x"01"; |
when x"0101" => D <= x"28"; |
when x"0102" => D <= x"00"; |
when x"0103" => D <= x"09"; |
when x"0104" => D <= x"3D"; |
when x"0105" => D <= x"20"; |
when x"0106" => D <= x"EF"; |
when x"0107" => D <= x"11"; |
when x"0108" => D <= x"DE"; |
when x"0109" => D <= x"01"; |
when x"010A" => D <= x"CD"; |
when x"010B" => D <= x"D7"; |
when x"010C" => D <= x"00"; |
when x"010D" => D <= x"C9"; |
when x"010E" => D <= x"5A"; |
when x"010F" => D <= x"38"; |
when x"0110" => D <= x"30"; |
when x"0111" => D <= x"20"; |
when x"0112" => D <= x"53"; |
when x"0113" => D <= x"59"; |
when x"0114" => D <= x"53"; |
when x"0115" => D <= x"54"; |
when x"0116" => D <= x"45"; |
when x"0117" => D <= x"4D"; |
when x"0118" => D <= x"20"; |
when x"0119" => D <= x"4F"; |
when x"011A" => D <= x"4E"; |
when x"011B" => D <= x"20"; |
when x"011C" => D <= x"43"; |
when x"011D" => D <= x"48"; |
when x"011E" => D <= x"49"; |
when x"011F" => D <= x"50"; |
when x"0120" => D <= x"00"; |
when x"0121" => D <= x"52"; |
when x"0122" => D <= x"4F"; |
when x"0123" => D <= x"4E"; |
when x"0124" => D <= x"49"; |
when x"0125" => D <= x"56"; |
when x"0126" => D <= x"4F"; |
when x"0127" => D <= x"4E"; |
when x"0128" => D <= x"20"; |
when x"0129" => D <= x"43"; |
when x"012A" => D <= x"4F"; |
when x"012B" => D <= x"53"; |
when x"012C" => D <= x"54"; |
when x"012D" => D <= x"41"; |
when x"012E" => D <= x"20"; |
when x"012F" => D <= x"32"; |
when x"0130" => D <= x"30"; |
when x"0131" => D <= x"30"; |
when x"0132" => D <= x"38"; |
when x"0133" => D <= x"00"; |
when x"0134" => D <= x"20"; |
when x"0135" => D <= x"20"; |
when x"0136" => D <= x"7C"; |
when x"0137" => D <= x"21"; |
when x"0138" => D <= x"23"; |
when x"0139" => D <= x"24"; |
when x"013A" => D <= x"25"; |
when x"013B" => D <= x"26"; |
when x"013C" => D <= x"2F"; |
when x"013D" => D <= x"28"; |
when x"013E" => D <= x"29"; |
when x"013F" => D <= x"3D"; |
when x"0140" => D <= x"3F"; |
when x"0141" => D <= x"2A"; |
when x"0142" => D <= x"60"; |
when x"0143" => D <= x"2B"; |
when x"0144" => D <= x"B4"; |
when x"0145" => D <= x"E7"; |
when x"0146" => D <= x"7E"; |
when x"0147" => D <= x"5E"; |
when x"0148" => D <= x"2C"; |
when x"0149" => D <= x"2E"; |
when x"014A" => D <= x"3B"; |
when x"014B" => D <= x"3A"; |
when x"014C" => D <= x"5C"; |
when x"014D" => D <= x"3C"; |
when x"014E" => D <= x"3E"; |
when x"014F" => D <= x"00"; |
when x"0150" => D <= x"20"; |
when x"0151" => D <= x"20"; |
when x"0152" => D <= x"41"; |
when x"0153" => D <= x"42"; |
when x"0154" => D <= x"43"; |
when x"0155" => D <= x"44"; |
when x"0156" => D <= x"45"; |
when x"0157" => D <= x"46"; |
when x"0158" => D <= x"47"; |
when x"0159" => D <= x"48"; |
when x"015A" => D <= x"49"; |
when x"015B" => D <= x"4A"; |
when x"015C" => D <= x"4B"; |
when x"015D" => D <= x"4C"; |
when x"015E" => D <= x"4D"; |
when x"015F" => D <= x"4E"; |
when x"0160" => D <= x"4F"; |
when x"0161" => D <= x"50"; |
when x"0162" => D <= x"51"; |
when x"0163" => D <= x"52"; |
when x"0164" => D <= x"53"; |
when x"0165" => D <= x"54"; |
when x"0166" => D <= x"55"; |
when x"0167" => D <= x"56"; |
when x"0168" => D <= x"57"; |
when x"0169" => D <= x"58"; |
when x"016A" => D <= x"59"; |
when x"016B" => D <= x"5A"; |
when x"016C" => D <= x"00"; |
when x"016D" => D <= x"20"; |
when x"016E" => D <= x"20"; |
when x"016F" => D <= x"61"; |
when x"0170" => D <= x"62"; |
when x"0171" => D <= x"63"; |
when x"0172" => D <= x"64"; |
when x"0173" => D <= x"65"; |
when x"0174" => D <= x"66"; |
when x"0175" => D <= x"67"; |
when x"0176" => D <= x"68"; |
when x"0177" => D <= x"69"; |
when x"0178" => D <= x"6A"; |
when x"0179" => D <= x"6B"; |
when x"017A" => D <= x"6C"; |
when x"017B" => D <= x"6D"; |
when x"017C" => D <= x"6E"; |
when x"017D" => D <= x"6F"; |
when x"017E" => D <= x"70"; |
when x"017F" => D <= x"71"; |
when x"0180" => D <= x"72"; |
when x"0181" => D <= x"73"; |
when x"0182" => D <= x"74"; |
when x"0183" => D <= x"75"; |
when x"0184" => D <= x"76"; |
when x"0185" => D <= x"77"; |
when x"0186" => D <= x"78"; |
when x"0187" => D <= x"79"; |
when x"0188" => D <= x"7A"; |
when x"0189" => D <= x"00"; |
when x"018A" => D <= x"20"; |
when x"018B" => D <= x"20"; |
when x"018C" => D <= x"20"; |
when x"018D" => D <= x"20"; |
when x"018E" => D <= x"20"; |
when x"018F" => D <= x"20"; |
when x"0190" => D <= x"20"; |
when x"0191" => D <= x"20"; |
when x"0192" => D <= x"20"; |
when x"0193" => D <= x"30"; |
when x"0194" => D <= x"31"; |
when x"0195" => D <= x"32"; |
when x"0196" => D <= x"33"; |
when x"0197" => D <= x"34"; |
when x"0198" => D <= x"35"; |
when x"0199" => D <= x"36"; |
when x"019A" => D <= x"37"; |
when x"019B" => D <= x"38"; |
when x"019C" => D <= x"39"; |
when x"019D" => D <= x"00"; |
when x"019E" => D <= x"02"; |
when x"019F" => D <= x"03"; |
when x"01A0" => D <= x"04"; |
when x"01A1" => D <= x"0B"; |
when x"01A2" => D <= x"0C"; |
when x"01A3" => D <= x"0D"; |
when x"01A4" => D <= x"0E"; |
when x"01A5" => D <= x"12"; |
when x"01A6" => D <= x"18"; |
when x"01A7" => D <= x"19"; |
when x"01A8" => D <= x"1A"; |
when x"01A9" => D <= x"1B"; |
when x"01AA" => D <= x"E8"; |
when x"01AB" => D <= x"E9"; |
when x"01AC" => D <= x"EB"; |
when x"01AD" => D <= x"BB"; |
when x"01AE" => D <= x"BC"; |
when x"01AF" => D <= x"8A"; |
when x"01B0" => D <= x"86"; |
when x"01B1" => D <= x"87"; |
when x"01B2" => D <= x"81"; |
when x"01B3" => D <= x"80"; |
when x"01B4" => D <= x"01"; |
when x"01B5" => D <= x"06"; |
when x"01B6" => D <= x"07"; |
when x"01B7" => D <= x"08"; |
when x"01B8" => D <= x"09"; |
when x"01B9" => D <= x"0A"; |
when x"01BA" => D <= x"1D"; |
when x"01BB" => D <= x"1F"; |
when x"01BC" => D <= x"00"; |
when x"01BD" => D <= x"C9"; |
when x"01BE" => D <= x"CD"; |
when x"01BF" => D <= x"CD"; |
when x"01C0" => D <= x"CD"; |
when x"01C1" => D <= x"CD"; |
when x"01C2" => D <= x"CD"; |
when x"01C3" => D <= x"CD"; |
when x"01C4" => D <= x"CD"; |
when x"01C5" => D <= x"CD"; |
when x"01C6" => D <= x"CD"; |
when x"01C7" => D <= x"CD"; |
when x"01C8" => D <= x"CD"; |
when x"01C9" => D <= x"CD"; |
when x"01CA" => D <= x"CD"; |
when x"01CB" => D <= x"CD"; |
when x"01CC" => D <= x"CD"; |
when x"01CD" => D <= x"CD"; |
when x"01CE" => D <= x"CD"; |
when x"01CF" => D <= x"CD"; |
when x"01D0" => D <= x"CD"; |
when x"01D1" => D <= x"CD"; |
when x"01D2" => D <= x"CD"; |
when x"01D3" => D <= x"CD"; |
when x"01D4" => D <= x"CD"; |
when x"01D5" => D <= x"CD"; |
when x"01D6" => D <= x"CD"; |
when x"01D7" => D <= x"CD"; |
when x"01D8" => D <= x"CD"; |
when x"01D9" => D <= x"CD"; |
when x"01DA" => D <= x"CD"; |
when x"01DB" => D <= x"CD"; |
when x"01DC" => D <= x"BB"; |
when x"01DD" => D <= x"00"; |
when x"01DE" => D <= x"C8"; |
when x"01DF" => D <= x"CD"; |
when x"01E0" => D <= x"CD"; |
when x"01E1" => D <= x"CD"; |
when x"01E2" => D <= x"CD"; |
when x"01E3" => D <= x"CD"; |
when x"01E4" => D <= x"CD"; |
when x"01E5" => D <= x"CD"; |
when x"01E6" => D <= x"CD"; |
when x"01E7" => D <= x"CD"; |
when x"01E8" => D <= x"CD"; |
when x"01E9" => D <= x"CD"; |
when x"01EA" => D <= x"CD"; |
when x"01EB" => D <= x"CD"; |
when x"01EC" => D <= x"CD"; |
when x"01ED" => D <= x"CD"; |
when x"01EE" => D <= x"CD"; |
when x"01EF" => D <= x"CD"; |
when x"01F0" => D <= x"CD"; |
when x"01F1" => D <= x"CD"; |
when x"01F2" => D <= x"CD"; |
when x"01F3" => D <= x"CD"; |
when x"01F4" => D <= x"CD"; |
when x"01F5" => D <= x"CD"; |
when x"01F6" => D <= x"CD"; |
when x"01F7" => D <= x"CD"; |
when x"01F8" => D <= x"CD"; |
when x"01F9" => D <= x"CD"; |
when x"01FA" => D <= x"CD"; |
when x"01FB" => D <= x"CD"; |
when x"01FC" => D <= x"CD"; |
when x"01FD" => D <= x"BC"; |
when x"01FE" => D <= x"00"; |
when x"01FF" => D <= x"BA"; |
when x"0200" => D <= x"20"; |
when x"0201" => D <= x"20"; |
when x"0202" => D <= x"20"; |
when x"0203" => D <= x"20"; |
when x"0204" => D <= x"20"; |
when x"0205" => D <= x"20"; |
when x"0206" => D <= x"20"; |
when x"0207" => D <= x"20"; |
when x"0208" => D <= x"20"; |
when x"0209" => D <= x"20"; |
when x"020A" => D <= x"20"; |
when x"020B" => D <= x"20"; |
when x"020C" => D <= x"20"; |
when x"020D" => D <= x"20"; |
when x"020E" => D <= x"20"; |
when x"020F" => D <= x"20"; |
when x"0210" => D <= x"20"; |
when x"0211" => D <= x"20"; |
when x"0212" => D <= x"20"; |
when x"0213" => D <= x"20"; |
when x"0214" => D <= x"20"; |
when x"0215" => D <= x"20"; |
when x"0216" => D <= x"20"; |
when x"0217" => D <= x"20"; |
when x"0218" => D <= x"20"; |
when x"0219" => D <= x"20"; |
when x"021A" => D <= x"20"; |
when x"021B" => D <= x"20"; |
when x"021C" => D <= x"20"; |
when x"021D" => D <= x"20"; |
when x"021E" => D <= x"BA"; |
when x"021F" => D <= x"00"; |
when others => D <= x"00"; |
end case; |
end if; |
end process; |
end; |
/VHDL/VIDEO_80X40.vhd
0,0 → 1,81
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_unsigned.all; |
-- use IEEE.std_logic_arith.all; |
use IEEE.numeric_std.all; |
--use IEEE.std_logic_signed.all; |
--use IEEE.math_real.all; |
--use IEEE.math_complex.all; |
|
|
ENTITY video_80x40 is |
PORT( CLOCK_50 : IN STD_LOGIC; |
VRAM_DATA : IN STD_LOGIC_VECTOR(7 DOWNTO 0); |
VRAM_ADDR : OUT STD_LOGIC_VECTOR(12 DOWNTO 0); |
VRAM_CLOCK : OUT STD_LOGIC; |
VRAM_WREN : OUT STD_LOGIC; |
VGA_R, |
VGA_G, |
VGA_B : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); |
VGA_HS, |
VGA_VS : OUT STD_LOGIC); |
END video_80x40; |
|
ARCHITECTURE A OF video_80x40 IS |
|
-- Added for VDU support |
signal Clock_video : std_logic; |
signal VGA_R_sig : std_logic_vector(3 downto 0); |
signal VGA_G_sig : std_logic_vector(3 downto 0); |
signal VGA_B_sig : std_logic_vector(3 downto 0); |
signal pixel_row_sig : std_logic_vector(9 downto 0); |
signal pixel_column_sig : std_logic_vector(9 downto 0); |
signal pixel_clock_sig : std_logic; |
signal char_addr_sig : std_logic_vector(7 downto 0); |
signal font_row_sig : std_logic_vector(2 downto 0); |
signal font_col_sig : std_logic_vector(2 downto 0); |
signal pixel_sig : std_logic; |
signal video_on_sig : std_logic; |
|
BEGIN |
|
VGA_R_sig <= "0000"; |
VGA_G_sig <= "0000"; |
VGA_B_sig <= pixel_sig & pixel_sig & pixel_sig & pixel_sig; |
|
VRAM_WREN <= video_on_sig; |
VRAM_CLOCK <= pixel_clock_sig; |
VRAM_ADDR <= (pixel_row_sig(9 downto 4) * "0101000" + pixel_column_sig(9 downto 4)); |
|
-- Fonts ROM read |
char_addr_sig <= VRAM_DATA; |
font_row_sig(2 downto 0) <= pixel_row_sig(3 downto 1); |
font_col_sig(2 downto 0) <= pixel_column_sig(3 downto 1); |
|
vga_sync_inst : work.vga_sync |
port map ( |
clock_50Mhz => CLOCK_50, |
red => VGA_R_sig, |
green => VGA_G_sig, |
blue => VGA_B_sig, |
red_out => VGA_R, |
green_out => VGA_G, |
blue_out => VGA_B, |
horiz_sync_out => VGA_HS, |
vert_sync_out => VGA_VS, |
video_on => video_on_sig, |
pixel_clock => pixel_clock_sig, |
pixel_row => pixel_row_sig, |
pixel_column => pixel_column_sig |
); |
|
char_rom_inst : work.char_rom |
port map ( |
clock => pixel_clock_sig, |
character_address => char_addr_sig, |
font_row => font_row_sig, |
font_col => font_col_sig, |
rom_mux_output => pixel_sig |
); |
|
END A; |
/VHDL/CHAR_ROM.VHD
0,0 → 1,36
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
LIBRARY lpm; |
USE lpm.lpm_components.ALL; |
|
ENTITY Char_ROM IS |
PORT( clock : IN STD_LOGIC; |
character_address : IN STD_LOGIC_VECTOR(7 DOWNTO 0); |
font_row, font_col : IN STD_LOGIC_VECTOR(2 DOWNTO 0); |
rom_mux_output : OUT STD_LOGIC); |
END Char_ROM; |
|
ARCHITECTURE a OF Char_ROM IS |
SIGNAL rom_data: STD_LOGIC_VECTOR(7 DOWNTO 0); |
SIGNAL rom_address: STD_LOGIC_VECTOR(10 DOWNTO 0); |
BEGIN |
-- Small 8 by 8 Character Generator ROM for Video Display |
-- Each character is 8 8-bits words of pixel data |
char_gen_rom: lpm_rom |
GENERIC MAP ( lpm_widthad => 11, |
lpm_numwords => 2048, |
lpm_outdata => "UNREGISTERED", |
lpm_address_control => "REGISTERED", |
-- Reads in mif file for character generator font data |
lpm_file => "..\..\ROM\CHARROM.MIF", |
lpm_width => 8) |
PORT MAP ( inclock => clock, address => rom_address, q => rom_data); |
|
rom_address <= character_address & font_row; |
-- Mux to pick off correct rom data bit from 8-bit word |
-- for on screen character generation |
rom_mux_output <= rom_data ( (CONV_INTEGER(NOT font_col(2 downto 0)))); |
|
END a; |
/VHDL/top_de1.vhd
0,0 → 1,505
------------------------------------------------------------------------------------------------- |
-- Z80_Soc (Z80 System on Chip) |
-- |
-- Version 0.5 Beta |
-- |
-- Developer: Ronivon Candido Costa |
-- Release Date: 2008 / 04 / 16 |
-- |
-- Based on the T80 core: http://www.opencores.org/projects.cgi/web/t80 |
-- This version developed and tested on: Altera DE1 Development Board |
-- |
-- Please, see the RevisionHistory.txt file for complete features and change history. |
-- |
-- Peripherals configured (Using Ports): |
-- |
-- 08 KB Internal ROM Read (0x0000h - 0x1FFFh) |
-- 08 KB INTERNAL VRAM Write (0x2000h - 0x3FFFh) |
-- 48 KB External SRAM Read/Write (0x4000h - 0xFFFFh) |
-- 08 Green Leds Out (Port 0x01h) |
-- 08 Red Leds Out (Port 0x02h) |
-- 04 Seven Seg displays Out (Ports 0x10h and 0x11h) |
-- 36 Pins GPIO0 In/Out (Ports 0xA0h, 0xA1h, 0xA2h, 0xA3h, 0xA4h, 0xC0h) |
-- 36 Pins GPIO1 In/Out (Ports 0xB0h, 0xB1h, 0xB2h, 0xB3h, 0xB4h, 0xC1h) |
-- 08 Switches In (Port 0x20h) |
-- 04 Push buttons In (Port 0x30h) |
-- PS/2 keyboard In (Port 0x80h) |
-- Video Out 40x30 (VGA) Out (0x2000h - 0x24B0) |
-- |
-- TO-DO: |
-- - Monitor program to introduce Z80 Assmebly codes and run |
-- - Serial communication, to download assembly code from PC |
-- - Add hardware support for 80x40 Video out |
-- - SD/MMC card interface to read/store data and programs |
------------------------------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use IEEE.std_logic_unsigned.all; |
|
entity TOP_DE1 is |
port( |
|
-- Clocks |
CLOCK_27, -- 27 MHz |
CLOCK_50, -- 50 MHz |
EXT_CLOCK : in std_logic; -- External Clock |
|
-- Buttons and switches |
KEY : in std_logic_vector(3 downto 0); -- Push buttons |
SW : in std_logic_vector(9 downto 0); -- Switches |
|
-- LED displays |
HEX0, HEX1, HEX2, HEX3 -- 7-segment displays |
: out std_logic_vector(6 downto 0); |
LEDG : out std_logic_vector(7 downto 0); -- Green LEDs |
LEDR : out std_logic_vector(9 downto 0); -- Red LEDs |
|
-- RS-232 interface |
UART_TXD : out std_logic; -- UART transmitter |
UART_RXD : in std_logic; -- UART receiver |
|
-- IRDA interface |
|
-- IRDA_TXD : out std_logic; -- IRDA Transmitter |
IRDA_RXD : in std_logic; -- IRDA Receiver |
|
-- SDRAM |
DRAM_DQ : inout std_logic_vector(15 downto 0); -- Data Bus |
DRAM_ADDR : out std_logic_vector(11 downto 0); -- Address Bus |
DRAM_LDQM, -- Low-byte Data Mask |
DRAM_UDQM, -- High-byte Data Mask |
DRAM_WE_N, -- Write Enable |
DRAM_CAS_N, -- Column Address Strobe |
DRAM_RAS_N, -- Row Address Strobe |
DRAM_CS_N, -- Chip Select |
DRAM_BA_0, -- Bank Address 0 |
DRAM_BA_1, -- Bank Address 0 |
DRAM_CLK, -- Clock |
DRAM_CKE : out std_logic; -- Clock Enable |
|
-- FLASH |
FL_DQ : inout std_logic_vector(7 downto 0); -- Data bus |
FL_ADDR : out std_logic_vector(21 downto 0); -- Address bus |
FL_WE_N, -- Write Enable |
FL_RST_N, -- Reset |
FL_OE_N, -- Output Enable |
FL_CE_N : out std_logic; -- Chip Enable |
|
-- SRAM |
SRAM_DQ : inout std_logic_vector(15 downto 0); -- Data bus 16 Bits |
SRAM_ADDR : out std_logic_vector(17 downto 0); -- Address bus 18 Bits |
SRAM_UB_N, -- High-byte Data Mask |
SRAM_LB_N, -- Low-byte Data Mask |
SRAM_WE_N, -- Write Enable |
SRAM_CE_N, -- Chip Enable |
SRAM_OE_N : out std_logic; -- Output Enable |
|
-- SD card interface |
SD_DAT : in std_logic; -- SD Card Data SD pin 7 "DAT 0/DataOut" |
SD_DAT3 : out std_logic; -- SD Card Data 3 SD pin 1 "DAT 3/nCS" |
SD_CMD : out std_logic; -- SD Card Command SD pin 2 "CMD/DataIn" |
SD_CLK : out std_logic; -- SD Card Clock SD pin 5 "CLK" |
|
-- USB JTAG link |
TDI, -- CPLD -> FPGA (data in) |
TCK, -- CPLD -> FPGA (clk) |
TCS : in std_logic; -- CPLD -> FPGA (CS) |
TDO : out std_logic; -- FPGA -> CPLD (data out) |
|
-- I2C bus |
I2C_SDAT : inout std_logic; -- I2C Data |
I2C_SCLK : out std_logic; -- I2C Clock |
|
-- PS/2 port |
PS2_DAT, -- Data |
PS2_CLK : inout std_logic; -- Clock |
|
-- VGA output |
VGA_HS, -- H_SYNC |
VGA_VS : out std_logic; -- SYNC |
VGA_R, -- Red[3:0] |
VGA_G, -- Green[3:0] |
VGA_B : out std_logic_vector(3 downto 0); -- Blue[3:0] |
|
-- Audio CODEC |
AUD_ADCLRCK : inout std_logic; -- ADC LR Clock |
AUD_ADCDAT : in std_logic; -- ADC Data |
AUD_DACLRCK : inout std_logic; -- DAC LR Clock |
AUD_DACDAT : out std_logic; -- DAC Data |
AUD_BCLK : inout std_logic; -- Bit-Stream Clock |
AUD_XCK : out std_logic; -- Chip Clock |
|
-- General-purpose I/O |
GPIO_0, -- GPIO Connection 0 |
GPIO_1 : inout std_logic_vector(35 downto 0) -- GPIO Connection 1 |
); |
end TOP_DE1; |
|
architecture rtl of TOP_DE1 is |
|
component T80s |
generic( |
Mode : integer := 0); |
port ( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
MREQ_n : out std_logic; |
IORQ_n : out std_logic; |
RD_n : out std_logic; |
WR_n : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0)); |
end component; |
|
component rom |
port ( |
Clk : in std_logic; |
A : in std_logic_vector(15 downto 0); |
D : out std_logic_vector(7 downto 0)); |
end component; |
|
component Clock_357Mhz |
PORT ( |
clock_50Mhz : IN STD_LOGIC; |
clock_357Mhz : OUT STD_LOGIC); |
end component; |
|
component clk_div |
PORT |
( |
clock_25Mhz : IN STD_LOGIC; |
clock_1MHz : OUT STD_LOGIC; |
clock_100KHz : OUT STD_LOGIC; |
clock_10KHz : OUT STD_LOGIC; |
clock_1KHz : OUT STD_LOGIC; |
clock_100Hz : OUT STD_LOGIC; |
clock_10Hz : OUT STD_LOGIC; |
clock_1Hz : OUT STD_LOGIC); |
end component; |
|
component decoder_7seg |
port ( |
NUMBER : in std_logic_vector(3 downto 0); |
HEX_DISP : out std_logic_vector(6 downto 0)); |
end component; |
|
signal MREQ_n : std_logic; |
signal IORQ_n : std_logic; |
signal RD_n : std_logic; |
signal WR_n : std_logic; |
signal MWr_n : std_logic; |
signal Rst_n_s : std_logic; |
signal Clk_Z80 : std_logic; |
signal DI_CPU : std_logic_vector(7 downto 0); |
signal DO_CPU : std_logic_vector(7 downto 0); |
signal A : std_logic_vector(15 downto 0); |
signal One : std_logic; |
|
signal D_ROM : std_logic_vector(7 downto 0); |
|
signal clk25mhz_sig : std_logic; |
signal Clk_1hz : std_logic; |
|
signal HEX_DISP0 : std_logic_vector(6 downto 0); |
signal HEX_DISP1 : std_logic_vector(6 downto 0); |
signal HEX_DISP2 : std_logic_vector(6 downto 0); |
signal HEX_DISP3 : std_logic_vector(6 downto 0); |
|
signal NUMBER0 : std_logic_vector(3 downto 0); |
signal NUMBER1 : std_logic_vector(3 downto 0); |
signal NUMBER2 : std_logic_vector(3 downto 0); |
signal NUMBER3 : std_logic_vector(3 downto 0); |
|
signal GPIO_0_buf_in : std_logic_vector(35 downto 0); |
signal GPIO_1_buf_in : std_logic_vector(35 downto 0); |
|
signal vram_rdaddress_sig : std_logic_vector(12 downto 0); |
signal vram_wraddress_sig : std_logic_vector(15 downto 0); |
signal vram_data_sig : std_logic_vector(7 downto 0); |
signal vram_q_sig : std_logic_vector(7 downto 0); |
signal vram_q_reg : std_logic_vector(7 downto 0); |
signal vram_wren_sig : std_logic; |
signal vram_rden_sig : std_logic; |
signal vram_rdcycle_count : std_logic_vector(3 downto 0); |
signal vram_wrcycle_count : std_logic_vector(3 downto 0); |
signal VRAM_CLOCK : std_logic; |
|
-- PS/2 Keyboard |
signal ps2_read : std_logic; |
signal ps2_scan_ready : std_logic; |
signal ps2_ascii_sig : std_logic_vector(7 downto 0); |
signal ps2_ascii_reg1 : std_logic_vector(7 downto 0); |
signal ps2_ascii_reg : std_logic_vector(7 downto 0); |
|
begin |
|
HEX0 <= HEX_DISP0; |
HEX1 <= HEX_DISP1; |
HEX2 <= HEX_DISP2; |
HEX3 <= HEX_DISP3; |
|
SRAM_ADDR(15 downto 0) <= A - x"4000" when (A >= x"4000" and MReq_n = '0'); |
SRAM_DQ(15 downto 8) <= (others => 'Z'); |
SRAM_ADDR(17 downto 16) <= "00"; |
SRAM_UB_N <= '1'; |
SRAM_LB_N <= '0'; |
SRAM_CE_N <= '0'; |
SRAM_WE_N <= Wr_n or MReq_n when A >= x"4000"; |
SRAM_OE_N <= Rd_n; |
|
-- Write to SRAM (0x4000 - 0xFFFF) |
SRAM_DQ(7 downto 0) <= DO_CPU when (Wr_n = '0' and MReq_n = '0' and A >= x"4000") else (others => 'Z'); |
|
-- Write into VRAM |
vram_wraddress_sig <= A - x"2000" when (A >= x"2000" and A < x"4000" and MReq_n = '0'); |
vram_wren_sig <= not Wr_n when (A >= x"2000" and A < x"4000" and IORQ_n = '1'); |
vram_data_sig <= DO_CPU when (Wr_n = '0' and MReq_n = '0' and A >= x"2000" and A < x"4000") else (others => 'Z'); |
|
-- Input to Z80 |
DI_CPU <= SRAM_DQ(7 downto 0) when (Rd_n = '0' and MReq_n = '0' and A >= x"4000") else |
-- vram_q_sig when (A >= x"2000" and A < x"4000") else |
D_ROM when (Rd_n = '0' and MReq_n = '0' and A < x"2000") else |
SW(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"20") else |
("0000" & KEY) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"30") else |
GPIO_0(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A0") else |
GPIO_0(15 downto 8) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A1") else |
GPIO_0(23 downto 16) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A2") else |
GPIO_0(31 downto 24) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A3") else |
("0000" & GPIO_0(35 downto 32)) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A4") else |
GPIO_1(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B0") else |
GPIO_1(15 downto 8) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B1") else |
GPIO_1(23 downto 16) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B2") else |
GPIO_1(31 downto 24) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B3") else |
("0000" & GPIO_1(35 downto 32)) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B4") else |
ps2_ascii_reg when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"80"); |
|
-- Process to latch leds and hex displays |
process(Clk_Z80) |
variable NUMBER0_sig : std_logic_vector(3 downto 0); |
variable NUMBER1_sig : std_logic_vector(3 downto 0); |
variable NUMBER2_sig : std_logic_vector(3 downto 0); |
variable NUMBER3_sig : std_logic_vector(3 downto 0); |
variable LEDG_sig : std_logic_vector(7 downto 0); |
variable LEDR_sig : std_logic_vector(9 downto 0); |
|
variable GPIO_0_buf_out: std_logic_vector(35 downto 0); |
variable GPIO_1_buf_out: std_logic_vector(35 downto 0); |
|
begin |
|
if Clk_Z80'event and Clk_Z80 = '1' then |
if IORQ_n = '0' and Wr_n = '0' then |
-- LEDG |
if A(7 downto 0) = x"01" then |
LEDG_sig := DO_CPU; |
-- LEDR |
elsif A(7 downto 0) = x"02" then |
LEDR_sig(7 downto 0) := DO_CPU; |
-- HEX1 and HEX0 |
elsif A(7 downto 0) = x"10" then |
NUMBER0_sig := DO_CPU(3 downto 0); |
NUMBER1_sig := DO_CPU(7 downto 4); |
-- HEX3 and HEX2 |
elsif A(7 downto 0) = x"11" then |
NUMBER2_sig := DO_CPU(3 downto 0); |
NUMBER3_sig := DO_CPU(7 downto 4); |
-- GPIO_0 |
elsif A(7 downto 0) = x"A0" then |
GPIO_0_buf_out(7 downto 0) := DO_CPU; |
elsif A(7 downto 0) = x"A1" then |
GPIO_0_buf_out(15 downto 8) := DO_CPU; |
elsif A(7 downto 0) = x"A2" then |
GPIO_0_buf_out(23 downto 16) := DO_CPU; |
elsif A(7 downto 0) = x"A3" then |
GPIO_0_buf_out(31 downto 24) := DO_CPU; |
elsif A(7 downto 0) = x"A4" then |
GPIO_0_buf_out(35 downto 32) := DO_CPU(3 downto 0); |
-- GPIO_1 |
elsif A(7 downto 0) = x"B0" then |
GPIO_1_buf_out(7 downto 0) := DO_CPU; |
elsif A(7 downto 0) = x"B1" then |
GPIO_1_buf_out(15 downto 8) := DO_CPU; |
elsif A(7 downto 0) = x"B2" then |
GPIO_1_buf_out(23 downto 16) := DO_CPU; |
elsif A(7 downto 0) = x"B3" then |
GPIO_1_buf_out(31 downto 24) := DO_CPU; |
elsif A(7 downto 0) = x"B4" then |
GPIO_1_buf_out(35 downto 32) := DO_CPU(3 downto 0); |
elsif A(7 downto 0) = x"C0" then |
GPIO_0 <= GPIO_0_buf_out; |
elsif A(7 downto 0) = x"C1" then |
GPIO_1 <= GPIO_1_buf_out; |
end if; |
end if; |
end if; |
|
-- Latches the signals |
NUMBER0 <= NUMBER0_sig; |
NUMBER1 <= NUMBER1_sig; |
NUMBER2 <= NUMBER2_sig; |
NUMBER3 <= NUMBER3_sig; |
LEDR(7 downto 0) <= LEDR_sig(7 downto 0); |
LEDG <= LEDG_sig; |
|
end process; |
|
-- the following three processes deals with different clock domain signals |
ps2_process1: process(CLOCK_50) |
begin |
if CLOCK_50'event and CLOCK_50 = '1' then |
if ps2_read = '1' then |
if ps2_ascii_sig /= x"FF" then |
ps2_read <= '0'; |
ps2_ascii_reg1 <= "00000000"; |
end if; |
elsif ps2_scan_ready = '1' then |
if ps2_ascii_sig = x"FF" then |
ps2_read <= '1'; |
else |
ps2_ascii_reg1 <= ps2_ascii_sig; |
end if; |
end if; |
end if; |
end process; |
|
ps2_process2: process(Clk_Z80) |
begin |
if Clk_Z80'event and Clk_Z80 = '1' then |
ps2_ascii_reg <= ps2_ascii_reg1; |
end if; |
end process; |
|
|
One <= '1'; |
Rst_n_s <= not SW(9); |
|
z80_inst: T80s |
port map ( |
M1_n => open, |
MREQ_n => MReq_n, |
IORQ_n => IORq_n, |
RD_n => Rd_n, |
WR_n => Wr_n, |
RFSH_n => open, |
HALT_n => open, |
WAIT_n => One, |
INT_n => One, |
NMI_n => One, |
RESET_n => Rst_n_s, |
BUSRQ_n => One, |
BUSAK_n => open, |
CLK_n => Clk_Z80, |
A => A, |
DI => DI_CPU, |
DO => DO_CPU |
); |
|
vga80x40_inst: work.video_80x40 port map ( |
CLOCK_50 => CLOCK_50, |
VRAM_DATA => vram_q_sig, |
VRAM_ADDR => vram_rdaddress_sig, |
VRAM_CLOCK => VRAM_CLOCK, |
VRAM_WREN => vram_rden_sig, |
VGA_R => VGA_R, |
VGA_G => VGA_G, |
VGA_B => VGA_B, |
VGA_HS => VGA_HS, |
VGA_VS => VGA_VS |
); |
|
vram8k_inst : work.vram8k PORT MAP ( |
rdaddress => vram_rdaddress_sig, |
rdclock => not VRAM_CLOCK, |
rden => vram_rden_sig, |
q => vram_q_sig, |
wraddress => vram_wraddress_sig(12 downto 0), |
wrclock => Clk_Z80, |
wren => vram_wren_sig, |
data => vram_data_sig |
); |
|
rom_inst: rom |
port map ( |
Clk => Clk_Z80, |
A => A, |
D => D_ROM |
); |
|
clock_z80_inst : Clock_357Mhz |
port map ( |
clock_50Mhz => CLOCK_50, |
clock_357Mhz => Clk_Z80 |
); |
|
DISPHEX0 : decoder_7seg PORT MAP ( |
NUMBER => NUMBER0, |
HEX_DISP => HEX_DISP0 |
); |
|
DISPHEX1 : decoder_7seg PORT MAP ( |
NUMBER => NUMBER1, |
HEX_DISP => HEX_DISP1 |
); |
|
DISPHEX2 : decoder_7seg PORT MAP ( |
NUMBER => NUMBER2, |
HEX_DISP => HEX_DISP2 |
); |
|
DISPHEX3 : decoder_7seg PORT MAP ( |
NUMBER => NUMBER3, |
HEX_DISP => HEX_DISP3 |
); |
|
ps2_kbd_inst : work.ps2kbd PORT MAP ( |
keyboard_clk => PS2_CLK, |
keyboard_data => PS2_DAT, |
clock => CLOCK_50, |
reset => Rst_n_s, |
read => ps2_read, |
scan_ready => ps2_scan_ready, |
ps2_ascii_code => ps2_ascii_sig |
); |
|
UART_TXD <= 'Z'; |
DRAM_ADDR <= (others => '0'); |
DRAM_LDQM <= '0'; |
DRAM_UDQM <= '0'; |
DRAM_WE_N <= '1'; |
DRAM_CAS_N <= '1'; |
DRAM_RAS_N <= '1'; |
DRAM_CS_N <= '1'; |
DRAM_BA_0 <= '0'; |
DRAM_BA_1 <= '0'; |
DRAM_CLK <= '0'; |
DRAM_CKE <= '0'; |
FL_ADDR <= (others => '0'); |
FL_WE_N <= '1'; |
FL_RST_N <= '0'; |
FL_OE_N <= '1'; |
FL_CE_N <= '1'; |
TDO <= '0'; |
I2C_SCLK <= '0'; |
AUD_DACDAT <= '0'; |
AUD_XCK <= '0'; |
-- Set all bidirectional ports to tri-state |
DRAM_DQ <= (others => 'Z'); |
FL_DQ <= (others => 'Z'); |
I2C_SDAT <= 'Z'; |
AUD_ADCLRCK <= 'Z'; |
AUD_DACLRCK <= 'Z'; |
AUD_BCLK <= 'Z'; |
GPIO_0 <= (others => 'Z'); |
GPIO_1 <= (others => 'Z'); |
end; |
/VHDL/clock_357mhz.vhd
0,0 → 1,37
-- 3.57 Mhz clock from a 50 Mhz input |
-- Ronivon C. costa |
-- 03/2008 |
------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
ENTITY Clock_357Mhz IS |
PORT ( |
clock_50Mhz : IN STD_LOGIC; |
clock_357Mhz : OUT STD_LOGIC); |
END Clock_357Mhz; |
|
ARCHITECTURE rtl OF Clock_357Mhz IS |
|
SIGNAL counter: STD_LOGIC_VECTOR(3 DOWNTO 0); |
SIGNAL clock_357Mhz_int : STD_LOGIC; |
|
BEGIN |
|
PROCESS (clock_50Mhz) |
BEGIN |
IF clock_50Mhz'EVENT and clock_50Mhz = '1' THEN |
IF counter < "1110" THEN |
counter <= counter + 1; |
ELSE |
counter <= "0000"; |
clock_357Mhz_int <= not clock_357Mhz_int; |
END IF; |
END IF; |
|
clock_357Mhz <= clock_357Mhz_int; |
|
END PROCESS; |
END rtl; |
/VHDL/vram8k.vhd
0,0 → 1,243
-- megafunction wizard: %RAM: 2-PORT% |
-- GENERATION: STANDARD |
-- VERSION: WM1.0 |
-- MODULE: altsyncram |
|
-- ============================================================ |
-- File Name: vram8k.vhd |
-- Megafunction Name(s): |
-- altsyncram |
-- |
-- Simulation Library Files(s): |
-- altera_mf |
-- ============================================================ |
-- ************************************************************ |
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! |
-- |
-- 7.2 Build 175 11/20/2007 SP 1 SJ Web Edition |
-- ************************************************************ |
|
|
--Copyright (C) 1991-2007 Altera Corporation |
--Your use of Altera Corporation's design tools, logic functions |
--and other software and tools, and its AMPP partner logic |
--functions, and any output files from any of the foregoing |
--(including device programming or simulation files), and any |
--associated documentation or information are expressly subject |
--to the terms and conditions of the Altera Program License |
--Subscription Agreement, Altera MegaCore Function License |
--Agreement, or other applicable license agreement, including, |
--without limitation, that your use is for the sole purpose of |
--programming logic devices manufactured by Altera and sold by |
--Altera or its authorized distributors. Please refer to the |
--applicable agreement for further details. |
|
|
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
LIBRARY altera_mf; |
USE altera_mf.all; |
|
ENTITY vram8k IS |
PORT |
( |
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); |
rdaddress : IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
rdclock : IN STD_LOGIC ; |
rden : IN STD_LOGIC := '1'; |
wraddress : IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
wrclock : IN STD_LOGIC ; |
wren : IN STD_LOGIC := '1'; |
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) |
); |
END vram8k; |
|
|
ARCHITECTURE SYN OF vram8k IS |
|
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); |
|
|
|
COMPONENT altsyncram |
GENERIC ( |
address_reg_b : STRING; |
clock_enable_input_a : STRING; |
clock_enable_input_b : STRING; |
clock_enable_output_a : STRING; |
clock_enable_output_b : STRING; |
intended_device_family : STRING; |
lpm_type : STRING; |
numwords_a : NATURAL; |
numwords_b : NATURAL; |
operation_mode : STRING; |
outdata_aclr_b : STRING; |
outdata_reg_b : STRING; |
power_up_uninitialized : STRING; |
rdcontrol_reg_b : STRING; |
widthad_a : NATURAL; |
widthad_b : NATURAL; |
width_a : NATURAL; |
width_b : NATURAL; |
width_byteena_a : NATURAL |
); |
PORT ( |
wren_a : IN STD_LOGIC ; |
clock0 : IN STD_LOGIC ; |
clock1 : IN STD_LOGIC ; |
address_a : IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
address_b : IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
rden_b : IN STD_LOGIC ; |
q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); |
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0) |
); |
END COMPONENT; |
|
BEGIN |
q <= sub_wire0(7 DOWNTO 0); |
|
altsyncram_component : altsyncram |
GENERIC MAP ( |
address_reg_b => "CLOCK1", |
clock_enable_input_a => "BYPASS", |
clock_enable_input_b => "BYPASS", |
clock_enable_output_a => "BYPASS", |
clock_enable_output_b => "BYPASS", |
intended_device_family => "Cyclone II", |
lpm_type => "altsyncram", |
numwords_a => 8192, |
numwords_b => 8192, |
operation_mode => "DUAL_PORT", |
outdata_aclr_b => "NONE", |
outdata_reg_b => "UNREGISTERED", |
power_up_uninitialized => "FALSE", |
rdcontrol_reg_b => "CLOCK1", |
widthad_a => 13, |
widthad_b => 13, |
width_a => 8, |
width_b => 8, |
width_byteena_a => 1 |
) |
PORT MAP ( |
wren_a => wren, |
clock0 => wrclock, |
clock1 => rdclock, |
address_a => wraddress, |
address_b => rdaddress, |
rden_b => rden, |
data_a => data, |
q_b => sub_wire0 |
); |
|
|
|
END SYN; |
|
-- ============================================================ |
-- CNX file retrieval info |
-- ============================================================ |
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" |
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" |
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" |
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" |
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" |
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" |
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" |
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1" |
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" |
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" |
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" |
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRq NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" |
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0" |
-- Retrieval info: PRIVATE: Clock NUMERIC "1" |
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0" |
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0" |
-- Retrieval info: PRIVATE: ECC NUMERIC "0" |
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" |
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" |
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" |
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" |
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" |
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II" |
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" |
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" |
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" |
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "65536" |
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" |
-- Retrieval info: PRIVATE: MIFfilename STRING "" |
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" |
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" |
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" |
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" |
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" |
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" |
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" |
-- Retrieval info: PRIVATE: REGdata NUMERIC "1" |
-- Retrieval info: PRIVATE: REGq NUMERIC "1" |
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" |
-- Retrieval info: PRIVATE: REGrren NUMERIC "1" |
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1" |
-- Retrieval info: PRIVATE: REGwren NUMERIC "1" |
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" |
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" |
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" |
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0" |
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8" |
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8" |
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8" |
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8" |
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" |
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" |
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" |
-- Retrieval info: PRIVATE: enable NUMERIC "0" |
-- Retrieval info: PRIVATE: rden NUMERIC "1" |
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1" |
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" |
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" |
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" |
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" |
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II" |
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" |
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192" |
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "8192" |
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" |
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" |
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" |
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" |
-- Retrieval info: CONSTANT: RDCONTROL_REG_B STRING "CLOCK1" |
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13" |
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "13" |
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" |
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "8" |
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" |
-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0] |
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0] |
-- Retrieval info: USED_PORT: rdaddress 0 0 13 0 INPUT NODEFVAL rdaddress[12..0] |
-- Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL rdclock |
-- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC rden |
-- Retrieval info: USED_PORT: wraddress 0 0 13 0 INPUT NODEFVAL wraddress[12..0] |
-- Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT NODEFVAL wrclock |
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT VCC wren |
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 |
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 |
-- Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0 |
-- Retrieval info: CONNECT: @address_a 0 0 13 0 wraddress 0 0 13 0 |
-- Retrieval info: CONNECT: @address_b 0 0 13 0 rdaddress 0 0 13 0 |
-- Retrieval info: CONNECT: @rden_b 0 0 0 0 rden 0 0 0 0 |
-- Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0 |
-- Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0 |
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.vhd TRUE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.inc FALSE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.cmp TRUE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.bsf TRUE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_inst.vhd TRUE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_waveforms.html TRUE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_wave*.jpg FALSE |
-- Retrieval info: LIB_FILE: altera_mf |
/VHDL/vga_sync.vhd
0,0 → 1,333
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
-- Module Generates Video Sync Signals for Video Montor Interface |
-- RGB and Sync outputs tie directly to monitor conector pins |
ENTITY VGA_SYNC IS |
PORT( clock_50Mhz : IN STD_LOGIC; |
red, green, blue : IN STD_LOGIC_VECTOR(3 DOWNTO 0); |
red_out, green_out, blue_out : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); |
horiz_sync_out, vert_sync_out, |
video_on, pixel_clock : OUT STD_LOGIC; |
pixel_row, pixel_column : OUT STD_LOGIC_VECTOR(9 DOWNTO 0)); |
END VGA_SYNC; |
ARCHITECTURE a OF VGA_SYNC IS |
SIGNAL horiz_sync, vert_sync, pixel_clock_int : STD_LOGIC; |
SIGNAL video_on_int, video_on_v, video_on_h : STD_LOGIC; |
SIGNAL h_count, v_count :STD_LOGIC_VECTOR(9 DOWNTO 0); |
-- |
-- To select a different screen resolution, clock rate, and refresh rate |
-- pick a set of new video timing constant values from table at end of code section |
-- enter eight new sync timing constants below and |
-- adjust PLL frequency output to pixel clock rate from table |
-- using MegaWizard to edit video_PLL.vhd |
-- Horizontal Timing Constants |
CONSTANT H_pixels_across: Natural := 640; |
CONSTANT H_sync_low: Natural := 664; |
CONSTANT H_sync_high: Natural := 760; |
CONSTANT H_end_count: Natural := 800; |
-- Vertical Timing Constants |
CONSTANT V_pixels_down: Natural := 480; |
CONSTANT V_sync_low: Natural := 491; |
CONSTANT V_sync_high: Natural := 493; |
CONSTANT V_end_count: Natural := 525; |
COMPONENT video_PLL |
PORT |
( |
inclk0 : IN STD_LOGIC := '0'; |
c0 : OUT STD_LOGIC |
); |
end component; |
|
BEGIN |
|
-- PLL below is used to generate the pixel clock frequency |
-- Uses DE1 50Mhz clock for PLL's input clock |
video_PLL_inst : video_PLL PORT MAP ( |
inclk0 => Clock_50Mhz, |
c0 => pixel_clock_int |
); |
|
-- video_on is high only when RGB pixel data is being displayed |
-- used to blank color signals at screen edges during retrace |
video_on_int <= video_on_H AND video_on_V; |
-- output pixel clock and video on for external user logic |
pixel_clock <= pixel_clock_int; |
video_on <= video_on_int; |
|
PROCESS |
BEGIN |
WAIT UNTIL(pixel_clock_int'EVENT) AND (pixel_clock_int='1'); |
|
--Generate Horizontal and Vertical Timing Signals for Video Signal |
-- H_count counts pixels (#pixels across + extra time for sync signals) |
-- |
-- Horiz_sync ------------------------------------__________-------- |
-- H_count 0 #pixels sync low end |
-- |
IF (h_count = H_end_count) THEN |
h_count <= "0000000000"; |
ELSE |
h_count <= h_count + 1; |
END IF; |
|
--Generate Horizontal Sync Signal using H_count |
IF (h_count <= H_sync_high) AND (h_count >= H_sync_low) THEN |
horiz_sync <= '0'; |
ELSE |
horiz_sync <= '1'; |
END IF; |
|
--V_count counts rows of pixels (#pixel rows down + extra time for V sync signal) |
-- |
-- Vert_sync -----------------------------------------------_______------------ |
-- V_count 0 last pixel row V sync low end |
-- |
IF (v_count >= V_end_count) AND (h_count >= H_sync_low) THEN |
v_count <= "0000000000"; |
ELSIF (h_count = H_sync_low) THEN |
v_count <= v_count + 1; |
END IF; |
|
-- Generate Vertical Sync Signal using V_count |
IF (v_count <= V_sync_high) AND (v_count >= V_sync_low) THEN |
vert_sync <= '0'; |
ELSE |
vert_sync <= '1'; |
END IF; |
|
-- Generate Video on Screen Signals for Pixel Data |
-- Video on = 1 indicates pixel are being displayed |
-- Video on = 0 retrace - user logic can update pixel |
-- memory without needing to read memory for display |
IF (h_count < H_pixels_across) THEN |
video_on_h <= '1'; |
pixel_column <= h_count; |
ELSE |
video_on_h <= '0'; |
END IF; |
|
IF (v_count <= V_pixels_down) THEN |
video_on_v <= '1'; |
pixel_row <= v_count; |
ELSE |
video_on_v <= '0'; |
END IF; |
|
-- Put all video signals through DFFs to elminate any small timing delays that cause a blurry image |
horiz_sync_out <= horiz_sync; |
vert_sync_out <= vert_sync; |
|
red_out <= red AND video_on_int & video_on_int & video_on_int & video_on_int; |
green_out <= green AND video_on_int & video_on_int & video_on_int & video_on_int; |
blue_out <= blue AND video_on_int & video_on_int & video_on_int & video_on_int; |
|
END PROCESS; |
END a; |
-- |
-- Common Video Modes - pixel clock and sync counter values |
-- |
-- Mode Refresh Hor. Sync Pixel clock Interlaced? VESA? |
-- ------------------------------------------------------------ |
-- 640x480 60Hz 31.5khz 25.175Mhz No No |
-- 640x480 63Hz 32.8khz 28.322Mhz No No |
-- 640x480 70Hz 36.5khz 31.5Mhz No No |
-- 640x480 72Hz 37.9khz 31.5Mhz No Yes |
-- 800x600 56Hz 35.1khz 36.0Mhz No Yes |
-- 800x600 56Hz 35.4khz 36.0Mhz No No |
-- 800x600 60Hz 37.9khz 40.0Mhz No Yes |
-- 800x600 60Hz 37.9khz 40.0Mhz No No |
-- 800x600 72Hz 48.0khz 50.0Mhz No Yes |
-- 1024x768 60Hz 48.4khz 65.0Mhz No Yes |
-- 1024x768 60Hz 48.4khz 62.0Mhz No No |
-- 1024x768 70Hz 56.5khz 75.0Mhz No Yes |
-- 1024x768 70Hz 56.25khz 72.0Mhz No No |
-- 1024x768 76Hz 62.5khz 85.0Mhz No No |
-- 1280x1024 59Hz 63.6khz 110.0Mhz No No |
-- 1280x1024 61Hz 64.24khz 110.0Mhz No No |
-- 1280x1024 74Hz 78.85khz 135.0Mhz No No |
-- |
-- Pixel clock within 5% works on most monitors. |
-- Faster clocks produce higher refresh rates at the same resolution on |
-- most new monitors up to the maximum rate. |
-- Some older monitors may not support higher refresh rates |
-- or may only sync at specific refresh rates - VESA modes most common. |
-- Pixel clock within 5% works on most old monitors. |
-- Refresh rates below 60Hz will have some flicker. |
-- Bad values such as very high refresh rates may damage some monitors |
-- that do not support faster refreseh rates - check monitor specs. |
-- |
-- Small adjustments to the sync low count ranges can be used to move |
-- video image left, right (H), down or up (V) on the monitor |
-- |
-- |
-- 640x480@60Hz Non-Interlaced mode |
-- Horizontal Sync = 31.5kHz |
-- Timing: H=(0.95us, 3.81us, 1.59us), V=(0.35ms, 0.064ms, 1.02ms) |
-- |
-- clock horizontal timing vertical timing flags |
-- Mhz pix.col low high end pix.rows low high end |
--640x480 25.175 640 664 760 800 480 491 493 525 |
-- <-> <-> |
-- sync pulses: Horiz----------___------ Vert-----------___------- |
-- |
-- Alternate 640x480@60Hz Non-Interlaced mode |
-- Horizontal Sync = 31.5kHz |
-- Timing: H=(1.27us, 3.81us, 1.27us) V=(0.32ms, 0.06ms, 1.05ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--640x480 25.175 640 672 768 800 480 490 492 525 |
-- |
-- |
-- 640x480@63Hz Non-Interlaced mode (non-standard) |
-- Horizontal Sync = 32.8kHz |
-- Timing: H=(1.41us, 1.41us, 5.08us) V=(0.24ms, 0.092ms, 0.92ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--640x480 28.322 640 680 720 864 480 488 491 521 |
-- |
-- |
-- 640x480@70Hz Non-Interlaced mode (non-standard) |
-- Horizontal Sync = 36.5kHz |
-- Timing: H=(1.27us, 1.27us, 4.57us) V=(0.22ms, 0.082ms, 0.82ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--640x480 31.5 640 680 720 864 480 488 491 521 |
-- |
-- |
-- VESA 640x480@72Hz Non-Interlaced mode |
-- Horizontal Sync = 37.9kHz |
-- Timing: H=(0.76us, 1.27us, 4.06us) V=(0.24ms, 0.079ms, 0.74ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--640x480 31.5 640 664 704 832 480 489 492 520 |
-- |
-- |
-- VESA 800x600@56Hz Non-Interlaced mode |
-- Horizontal Sync = 35.1kHz |
-- Timing: H=(0.67us, 2.00us, 3.56us) V=(0.03ms, 0.063ms, 0.70ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--800x600 36 800 824 896 1024 600 601 603 625 |
-- |
-- |
-- Alternate 800x600@56Hz Non-Interlaced mode |
-- Horizontal Sync = 35.4kHz |
-- Timing: H=(0.89us, 4.00us, 1.11us) V=(0.11ms, 0.057ms, 0.79ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--800x600 36 800 832 976 1016 600 604 606 634 |
-- |
-- |
-- VESA 800x600@60Hz Non-Interlaced mode |
-- Horizontal Sync = 37.9kHz |
-- Timing: H=(1.00us, 3.20us, 2.20us) V=(0.03ms, 0.106ms, 0.61ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--800x600 40 800 840 968 1056 600 601 605 628 +hsync +vsync |
-- |
-- |
-- Alternate 800x600@60Hz Non-Interlaced mode |
-- Horizontal Sync = 37.9kHz |
-- Timing: H=(1.20us, 3.80us, 1.40us) V=(0.13ms, 0.053ms, 0.69ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--800x600 40 800 848 1000 1056 600 605 607 633 |
-- |
-- |
-- VESA 800x600@72Hz Non-Interlaced mode |
-- Horizontal Sync = 48kHz |
-- Timing: H=(1.12us, 2.40us, 1.28us) V=(0.77ms, 0.13ms, 0.48ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--800x600 50 800 856 976 1040 600 637 643 666 +hsync +vsync |
-- |
-- |
-- VESA 1024x768@60Hz Non-Interlaced mode |
-- Horizontal Sync = 48.4kHz |
-- Timing: H=(0.12us, 2.22us, 2.58us) V=(0.06ms, 0.12ms, 0.60ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1024x768 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync |
-- |
-- |
-- 1024x768@60Hz Non-Interlaced mode (non-standard dot-clock) |
-- Horizontal Sync = 48.4kHz |
-- Timing: H=(0.65us, 2.84us, 0.65us) V=(0.12ms, 0.041ms, 0.66ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1024x768 62 1024 1064 1240 1280 768 774 776 808 |
-- |
-- |
-- VESA 1024x768@70Hz Non-Interlaced mode |
-- Horizontal Sync=56.5kHz |
-- Timing: H=(0.32us, 1.81us, 1.92us) V=(0.05ms, 0.14ms, 0.51ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1024x768 75 1024 1048 1184 1328 768 771 777 806 -hsync -vsync |
-- |
-- |
-- 1024x768@70Hz Non-Interlaced mode (non-standard dot-clock) |
-- Horizontal Sync=56.25kHz |
-- Timing: H=(0.44us, 1.89us, 1.22us) V=(0.036ms, 0.11ms, 0.53ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1024x768 72 1024 1056 1192 1280 768 770 776 806 -hsync -vsync |
-- |
-- |
-- 1024x768@76Hz Non-Interlaced mode |
-- Horizontal Sync=62.5kHz |
-- Timing: H=(0.09us, 1.41us, 2.45us) V=(0.09ms, 0.048ms, 0.62ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1024x768 85 1024 1032 1152 1360 768 784 787 823 |
-- |
-- |
-- 1280x1024@59Hz Non-Interlaced mode (non-standard) |
-- Horizontal Sync=63.6kHz |
-- Timing: H=(0.36us, 1.45us, 2.25us) V=(0.08ms, 0.11ms, 0.65ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1280x1024 110 1280 1320 1480 1728 1024 1029 1036 1077 |
-- |
-- |
-- 1280x1024@61Hz, Non-Interlaced mode |
-- Horizontal Sync=64.25kHz |
-- Timing: H=(0.44us, 1.67us, 1.82us) V=(0.02ms, 0.05ms, 0.41ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1280x1024 110 1280 1328 1512 1712 1024 1025 1028 1054 |
-- |
-- |
-- 1280x1024@74Hz, Non-Interlaced mode |
-- Horizontal Sync=78.85kHz |
-- Timing: H=(0.24us, 1.07us, 1.90us) V=(0.04ms, 0.04ms, 0.43ms) |
-- |
-- name clock horizontal timing vertical timing flags |
--1280x1024 135 1280 1312 1456 1712 1024 1027 1030 1064 |
-- |
-- VGA female connector: 15 pin small "D" connector |
-- _________________________ |
-- \ 5 4 3 2 1 / |
-- \ 10 X 8 7 6 / |
-- \ 15 14 13 12 11 / |
-- \_________________/ |
-- Signal Name Pin Number Notes |
-- ----------------------------------------------------------------------- |
-- RED video 1 Analog signal, around 0.7 volt, peak-to-peak 75 ohm |
-- GREEN video 2 Analog signal, sround 0.7 volt, peak-to-peak 75 ohm |
-- BLUE video 3 Analog signal, around 0.7 volt, peak-to-peak 75 ohm |
-- Monitor ID #2 4 |
-- Digital Ground 5 Ground for the video system. |
-- RED ground 6 \ The RGB color video signals each have a separate |
-- GREEN ground 7 | ground connection. |
-- BLUE ground 8 / |
-- KEY 9 (X = Not present) |
-- SYNC ground 10 TTL return for the SYNC lines. |
-- Monitor ID #0 11 |
-- Monitor ID #1 12 |
-- Horizontal Sync 13 Digital levels (0 to 5 volts, TTL output) |
-- Vertical Sync 14 Digital levels (0 to 5 volts, TTL output) |
-- Not Connected 15 (Not used) |
-- |
/VHDL/decoder_7seg.vhd
0,0 → 1,40
LIBRARY IEEE; |
USE IEEE.STD_LOGIC_1164.all; |
USE IEEE.STD_LOGIC_UNSIGNED.all; |
|
entity decoder_7seg is |
port |
( |
NUMBER : in std_logic_vector(3 downto 0); |
HEX_DISP : out std_logic_vector(6 downto 0) |
); |
end decoder_7seg; |
|
architecture rtl of decoder_7seg is |
begin |
process(NUMBER) |
begin |
case NUMBER is |
--0 to 9 |
when "0000" => HEX_DISP <= "1000000"; |
when "0001" => HEX_DISP <= "1111001"; |
when "0010" => HEX_DISP <= "0100100"; |
when "0011" => HEX_DISP <= "0110000"; |
when "0100" => HEX_DISP <= "0011001"; |
when "0101" => HEX_DISP <= "0010010"; |
when "0110" => HEX_DISP <= "0000011"; |
when "0111" => HEX_DISP <= "1111000"; |
when "1000" => HEX_DISP <= "0000000"; |
when "1001" => HEX_DISP <= "0011000"; |
-- A to F |
when "1010" => HEX_DISP <= "0001000"; |
when "1011" => HEX_DISP <= "0000011"; |
when "1100" => HEX_DISP <= "1000110"; |
when "1101" => HEX_DISP <= "0100001"; |
when "1110" => HEX_DISP <= "0000110"; |
when "1111" => HEX_DISP <= "0001110"; |
when others => HEX_DISP <= "1111111"; |
end case; |
end process; |
end rtl; |
|
/VHDL/t80/T80_RegX.vhd
0,0 → 1,167
-- |
-- T80 Registers for Xilinx Select RAM |
-- |
-- Version : 0244 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0242 : Initial release |
-- |
-- 0244 : Removed UNISIM library and added componet declaration |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T80_Reg is |
port( |
Clk : in std_logic; |
CEN : in std_logic; |
WEH : in std_logic; |
WEL : in std_logic; |
AddrA : in std_logic_vector(2 downto 0); |
AddrB : in std_logic_vector(2 downto 0); |
AddrC : in std_logic_vector(2 downto 0); |
DIH : in std_logic_vector(7 downto 0); |
DIL : in std_logic_vector(7 downto 0); |
DOAH : out std_logic_vector(7 downto 0); |
DOAL : out std_logic_vector(7 downto 0); |
DOBH : out std_logic_vector(7 downto 0); |
DOBL : out std_logic_vector(7 downto 0); |
DOCH : out std_logic_vector(7 downto 0); |
DOCL : out std_logic_vector(7 downto 0) |
); |
end T80_Reg; |
|
architecture rtl of T80_Reg is |
|
component RAM16X1D |
port( |
DPO : out std_ulogic; |
SPO : out std_ulogic; |
A0 : in std_ulogic; |
A1 : in std_ulogic; |
A2 : in std_ulogic; |
A3 : in std_ulogic; |
D : in std_ulogic; |
DPRA0 : in std_ulogic; |
DPRA1 : in std_ulogic; |
DPRA2 : in std_ulogic; |
DPRA3 : in std_ulogic; |
WCLK : in std_ulogic; |
WE : in std_ulogic); |
end component; |
|
signal ENH : std_logic; |
signal ENL : std_logic; |
|
begin |
|
ENH <= CEN and WEH; |
ENL <= CEN and WEL; |
|
bG1: for I in 0 to 7 generate |
begin |
Reg1H : RAM16X1D |
port map( |
DPO => DOBH(i), |
SPO => DOAH(i), |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIH(i), |
DPRA0 => AddrB(0), |
DPRA1 => AddrB(1), |
DPRA2 => AddrB(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENH); |
Reg1L : RAM16X1D |
port map( |
DPO => DOBL(i), |
SPO => DOAL(i), |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIL(i), |
DPRA0 => AddrB(0), |
DPRA1 => AddrB(1), |
DPRA2 => AddrB(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENL); |
Reg2H : RAM16X1D |
port map( |
DPO => DOCH(i), |
SPO => open, |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIH(i), |
DPRA0 => AddrC(0), |
DPRA1 => AddrC(1), |
DPRA2 => AddrC(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENH); |
Reg2L : RAM16X1D |
port map( |
DPO => DOCL(i), |
SPO => open, |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIL(i), |
DPRA0 => AddrC(0), |
DPRA1 => AddrC(1), |
DPRA2 => AddrC(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENL); |
end generate; |
|
end; |
/VHDL/t80/T80se.vhd
0,0 → 1,184
-- |
-- Z80 compatible microprocessor core, synchronous top level with clock enable |
-- Different timing than the original z80 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0235 : First release |
-- |
-- 0236 : Added T2Write generic |
-- |
-- 0237 : Fixed T2Write with wait state |
-- |
-- 0238 : Updated for T80 interface change |
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80se is |
generic( |
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 |
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
CLKEN : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
MREQ_n : out std_logic; |
IORQ_n : out std_logic; |
RD_n : out std_logic; |
WR_n : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0) |
); |
end T80se; |
|
architecture rtl of T80se is |
|
signal IntCycle_n : std_logic; |
signal NoRead : std_logic; |
signal Write : std_logic; |
signal IORQ : std_logic; |
signal DI_Reg : std_logic_vector(7 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal TState : std_logic_vector(2 downto 0); |
|
begin |
|
u0 : T80 |
generic map( |
Mode => Mode, |
IOWait => IOWait) |
port map( |
CEN => CLKEN, |
M1_n => M1_n, |
IORQ => IORQ, |
NoRead => NoRead, |
Write => Write, |
RFSH_n => RFSH_n, |
HALT_n => HALT_n, |
WAIT_n => Wait_n, |
INT_n => INT_n, |
NMI_n => NMI_n, |
RESET_n => RESET_n, |
BUSRQ_n => BUSRQ_n, |
BUSAK_n => BUSAK_n, |
CLK_n => CLK_n, |
A => A, |
DInst => DI, |
DI => DI_Reg, |
DO => DO, |
MC => MCycle, |
TS => TState, |
IntCycle_n => IntCycle_n); |
|
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
DI_Reg <= "00000000"; |
elsif CLK_n'event and CLK_n = '1' then |
if CLKEN = '1' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
if MCycle = "001" then |
if TState = "001" or (TState = "010" and Wait_n = '0') then |
RD_n <= not IntCycle_n; |
MREQ_n <= not IntCycle_n; |
IORQ_n <= IntCycle_n; |
end if; |
if TState = "011" then |
MREQ_n <= '0'; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then |
RD_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
if T2Write = 0 then |
if TState = "010" and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
end if; |
end if; |
if TState = "010" and Wait_n = '1' then |
DI_Reg <= DI; |
end if; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/T16450.vhd
0,0 → 1,459
-- |
-- 16450 compatible UART with synchronous bus interface |
-- RClk/BaudOut is XIn enable instead of actual clock |
-- |
-- Version : 0249b |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First release |
-- |
-- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer |
-- Added modem status and break detection |
-- Added support for 1.5 and 2 stop bits |
-- |
-- 0249b : Fixed loopback break generation bugs found by Andy Dyer |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T16450 is |
port( |
MR_n : in std_logic; |
XIn : in std_logic; |
RClk : in std_logic; |
CS_n : in std_logic; |
Rd_n : in std_logic; |
Wr_n : in std_logic; |
A : in std_logic_vector(2 downto 0); |
D_In : in std_logic_vector(7 downto 0); |
D_Out : out std_logic_vector(7 downto 0); |
SIn : in std_logic; |
CTS_n : in std_logic; |
DSR_n : in std_logic; |
RI_n : in std_logic; |
DCD_n : in std_logic; |
SOut : out std_logic; |
RTS_n : out std_logic; |
DTR_n : out std_logic; |
OUT1_n : out std_logic; |
OUT2_n : out std_logic; |
BaudOut : out std_logic; |
Intr : out std_logic |
); |
end T16450; |
|
architecture rtl of T16450 is |
|
signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register |
signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register |
signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register |
signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register |
signal LCR : std_logic_vector(7 downto 0); -- Line Control Register |
signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register |
signal LSR : std_logic_vector(7 downto 0); -- Line Status Register |
signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register |
signal SCR : std_logic_vector(7 downto 0); -- Scratch Register |
signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS) |
signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS) |
|
signal DM0 : std_logic_vector(7 downto 0); |
signal DM1 : std_logic_vector(7 downto 0); |
|
signal MSR_In : std_logic_vector(3 downto 0); |
|
signal Bit_Phase : unsigned(3 downto 0); |
signal Brk_Cnt : unsigned(3 downto 0); |
signal RX_Filtered : std_logic; |
signal RX_ShiftReg : std_logic_vector(7 downto 0); |
signal RX_Bit_Cnt : integer range 0 to 11; |
signal RX_Parity : std_logic; |
signal RXD : std_logic; |
|
signal TX_Tick : std_logic; |
signal TX_ShiftReg : std_logic_vector(7 downto 0); |
signal TX_Bit_Cnt : integer range 0 to 11; |
signal TX_Parity : std_logic; |
signal TX_Next_Is_Stop : std_logic; |
signal TX_Stop_Bit : std_logic; |
signal TXD : std_logic; |
|
begin |
|
DTR_n <= MCR(4) or not MCR(0); |
RTS_n <= MCR(4) or not MCR(1); |
OUT1_n <= MCR(4) or not MCR(2); |
OUT2_n <= MCR(4) or not MCR(3); |
SOut <= MCR(4) or (TXD and not LCR(6)); |
RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6)); |
|
Intr <= not IIR(0); |
|
-- Registers |
DM0 <= DLL when LCR(7) = '1' else RBR; |
DM1 <= DLM when LCR(7) = '1' else IER; |
with A select |
D_Out <= |
DM0 when "000", |
DM1 when "001", |
IIR when "010", |
LCR when "011", |
MCR when "100", |
LSR when "101", |
MSR when "110", |
SCR when others; |
process (MR_n, XIn) |
begin |
if MR_n = '0' then |
THR <= "00000000"; |
IER <= "00000000"; |
LCR <= "00000000"; |
MCR <= "00000000"; |
MSR(3 downto 0) <= "0000"; |
SCR <= "00000000"; -- ?? |
DLL <= "00000000"; -- ?? |
DLM <= "00000000"; -- ?? |
elsif XIn'event and XIn = '1' then |
if Wr_n = '0' and CS_n = '0' then |
case A is |
when "000" => |
if LCR(7) = '1' then |
DLL <= D_In; |
else |
THR <= D_In; |
end if; |
when "001" => |
if LCR(7) = '1' then |
DLM <= D_In; |
else |
IER(3 downto 0) <= D_In(3 downto 0); |
end if; |
when "011" => |
LCR <= D_In; |
when "100" => |
MCR <= D_In; |
when "111" => |
SCR <= D_In; |
when others => |
end case; |
end if; |
if Rd_n = '0' and CS_n = '0' and A = "110" then |
MSR(3 downto 0) <= "0000"; |
end if; |
if MSR(4) /= MSR_In(0) then |
MSR(0) <= '1'; |
end if; |
if MSR(5) /= MSR_In(1) then |
MSR(1) <= '1'; |
end if; |
if MSR(6) = '0' and MSR_In(2) = '1' then |
MSR(2) <= '1'; |
end if; |
if MSR(7) /= MSR_In(3) then |
MSR(3) <= '1'; |
end if; |
end if; |
end process; |
process (XIn) |
begin |
if XIn'event and XIn = '1' then |
if MCR(4) = '0' then |
MSR(4) <= MSR_In(0); |
MSR(5) <= MSR_In(1); |
MSR(6) <= MSR_In(2); |
MSR(7) <= MSR_In(3); |
else |
MSR(4) <= MCR(1); |
MSR(5) <= MCR(0); |
MSR(6) <= MCR(2); |
MSR(7) <= MCR(3); |
end if; |
MSR_In(0) <= CTS_n; |
MSR_In(1) <= DSR_n; |
MSR_In(2) <= RI_n; |
MSR_In(3) <= DCD_n; |
end if; |
end process; |
|
IIR(7 downto 3) <= "00000"; |
IIR(2 downto 0) <= |
"110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else |
"100" when (IER(0) and LSR(0)) = '1' else |
"010" when (IER(1) and LSR(5)) = '1' else |
"000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or |
(MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else |
"001"; |
|
-- Baud x 16 clock generator |
process (MR_n, XIn) |
variable Baud_Cnt : unsigned(15 downto 0); |
begin |
if MR_n = '0' then |
Baud_Cnt := "0000000000000000"; |
BaudOut <= '0'; |
elsif XIn'event and XIn = '1' then |
if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then |
Baud_Cnt(15 downto 8) := unsigned(DLM); |
Baud_Cnt(7 downto 0) := unsigned(DLL); |
BaudOut <= '1'; |
else |
Baud_Cnt := Baud_Cnt - 1; |
BaudOut <= '0'; |
end if; |
end if; |
end process; |
|
-- Input filter |
process (MR_n, XIn) |
variable Samples : std_logic_vector(1 downto 0); |
begin |
if MR_n = '0' then |
Samples := "11"; |
RX_Filtered <= '1'; |
elsif XIn'event and XIn = '1' then |
if RClk = '1' then |
Samples(1) := Samples(0); |
Samples(0) := RXD; |
end if; |
if Samples = "00" then |
RX_Filtered <= '0'; |
end if; |
if Samples = "11" then |
RX_Filtered <= '1'; |
end if; |
end if; |
end process; |
|
-- Receive state machine |
process (MR_n, XIn) |
begin |
if MR_n = '0' then |
RBR <= "00000000"; |
LSR(4 downto 0) <= "00000"; |
Bit_Phase <= "0000"; |
Brk_Cnt <= "0000"; |
RX_ShiftReg(7 downto 0) <= "00000000"; |
RX_Bit_Cnt <= 0; |
RX_Parity <= '0'; |
elsif XIn'event and XIn = '1' then |
if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then |
LSR(0) <= '0'; -- DR |
end if; |
if A = "101" and Rd_n = '0' and CS_n = '0' then |
LSR(4) <= '0'; -- BI |
LSR(3) <= '0'; -- FE |
LSR(2) <= '0'; -- PE |
LSR(1) <= '0'; -- OE |
end if; |
if RClk = '1' then |
if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then |
Bit_Phase <= "0000"; |
else |
Bit_Phase <= Bit_Phase + 1; |
end if; |
if Bit_Phase = "1111" then |
if RX_Filtered = '1' then |
Brk_Cnt <= "0000"; |
else |
Brk_Cnt <= Brk_Cnt + 1; |
end if; |
if Brk_Cnt = "1100" then |
LSR(4) <= '1'; -- BI |
end if; |
end if; |
if RX_Bit_Cnt = 0 then |
if Bit_Phase = "0111" then |
RX_Bit_Cnt <= RX_Bit_Cnt + 1; |
RX_Parity <= not LCR(4); -- EPS |
end if; |
elsif Bit_Phase = "1111" then |
RX_Bit_Cnt <= RX_Bit_Cnt + 1; |
if RX_Bit_Cnt = 10 then -- Parity stop bit |
RX_Bit_Cnt <= 0; |
LSR(0) <= '1'; -- UART Receive complete |
LSR(3) <= not RX_Filtered; -- Framing error |
elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or |
(RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or |
(RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or |
(RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity |
RX_Bit_Cnt <= 0; |
if LCR(3) = '1' then -- PEN |
RX_Bit_Cnt <= 10; |
if LCR(5) = '1' then -- Stick parity |
if RX_Filtered = LCR(4) then |
LSR(2) <= '1'; |
end if; |
else |
if RX_Filtered /= RX_Parity then |
LSR(2) <= '1'; |
end if; |
end if; |
else |
LSR(0) <= '1'; -- UART Receive complete |
LSR(3) <= not RX_Filtered; -- Framing error |
end if; |
RBR <= RX_ShiftReg(7 downto 0); |
LSR(1) <= LSR(0); |
if A = "101" and Rd_n = '0' and CS_n = '0' then |
LSR(1) <= '0'; |
end if; |
else |
RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1); |
RX_ShiftReg(7) <= RX_Filtered; |
if LCR(1 downto 0) = "10" then |
RX_ShiftReg(7) <= '0'; |
RX_ShiftReg(6) <= RX_Filtered; |
end if; |
if LCR(1 downto 0) = "01" then |
RX_ShiftReg(7) <= '0'; |
RX_ShiftReg(6) <= '0'; |
RX_ShiftReg(5) <= RX_Filtered; |
end if; |
if LCR(1 downto 0) = "00" then |
RX_ShiftReg(7) <= '0'; |
RX_ShiftReg(6) <= '0'; |
RX_ShiftReg(5) <= '0'; |
RX_ShiftReg(4) <= RX_Filtered; |
end if; |
RX_Parity <= RX_Filtered xor RX_Parity; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
-- Transmit bit tick |
process (MR_n, XIn) |
variable TX_Cnt : unsigned(4 downto 0); |
begin |
if MR_n = '0' then |
TX_Cnt := "00000"; |
TX_Tick <= '0'; |
elsif XIn'event and XIn = '1' then |
TX_Tick <= '0'; |
if RClk = '1' then |
TX_Cnt := TX_Cnt + 1; |
if LCR(2) = '1' and TX_Stop_Bit = '1' then |
if LCR(1 downto 0) = "00" then |
if TX_Cnt = "10111" then |
TX_Tick <= '1'; |
TX_Cnt(3 downto 0) := "0000"; |
end if; |
else |
if TX_Cnt = "11111" then |
TX_Tick <= '1'; |
TX_Cnt(3 downto 0) := "0000"; |
end if; |
end if; |
else |
TX_Cnt(4) := '1'; |
if TX_Cnt(3 downto 0) = "1111" then |
TX_Tick <= '1'; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
-- Transmit state machine |
process (MR_n, XIn) |
begin |
if MR_n = '0' then |
LSR(7 downto 5) <= "011"; |
TX_Bit_Cnt <= 0; |
TX_ShiftReg <= (others => '0'); |
TXD <= '1'; |
TX_Parity <= '0'; |
TX_Next_Is_Stop <= '0'; |
TX_Stop_Bit <= '0'; |
elsif XIn'event and XIn = '1' then |
if TX_Tick = '1' then |
TX_Next_Is_Stop <= '0'; |
TX_Stop_Bit <= TX_Next_Is_Stop; |
case TX_Bit_Cnt is |
when 0 => |
if LSR(5) <= '0' then -- THRE |
TX_Bit_Cnt <= 1; |
end if; |
TXD <= '1'; |
when 1 => -- Start bit |
TX_ShiftReg(7 downto 0) <= THR; |
LSR(5) <= '1'; -- THRE |
TXD <= '0'; |
TX_Parity <= not LCR(4); -- EPS |
TX_Bit_Cnt <= TX_Bit_Cnt + 1; |
when 10 => -- Parity bit |
TXD <= TX_Parity; |
if LCR(5) = '1' then -- Stick parity |
TXD <= not LCR(4); |
end if; |
TX_Bit_Cnt <= 0; |
TX_Next_Is_Stop <= '1'; |
when others => |
TX_Bit_Cnt <= TX_Bit_Cnt + 1; |
if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or |
(TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or |
(TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or |
(TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then |
TX_Bit_Cnt <= 0; |
if LCR(3) = '1' then -- PEN |
TX_Bit_Cnt <= 10; |
else |
TX_Next_Is_Stop <= '1'; |
end if; |
LSR(6) <= '1'; -- TEMT |
end if; |
TXD <= TX_ShiftReg(0); |
TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1); |
TX_Parity <= TX_ShiftReg(0) xor TX_Parity; |
end case; |
end if; |
if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then |
LSR(5) <= '0'; -- THRE |
LSR(6) <= '0'; -- TEMT |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/DebugSystemXR.vhd
0,0 → 1,185
-- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs |
-- that can be synthesized and used with |
-- the NoICE debugger that can be found at |
-- http://www.noicedebugger.com/ |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
entity DebugSystemXR is |
port( |
Reset_n : in std_logic; |
Clk : in std_logic; |
NMI_n : in std_logic; |
OE_n : out std_logic; |
WE_n : out std_logic; |
RAMCS_n : out std_logic; |
ROMCS_n : out std_logic; |
PGM_n : out std_logic; |
A : out std_logic_vector(16 downto 0); |
D : inout std_logic_vector(7 downto 0); |
RXD0 : in std_logic; |
CTS0 : in std_logic; |
DSR0 : in std_logic; |
RI0 : in std_logic; |
DCD0 : in std_logic; |
RXD1 : in std_logic; |
CTS1 : in std_logic; |
DSR1 : in std_logic; |
RI1 : in std_logic; |
DCD1 : in std_logic; |
TXD0 : out std_logic; |
RTS0 : out std_logic; |
DTR0 : out std_logic; |
TXD1 : out std_logic; |
RTS1 : out std_logic; |
DTR1 : out std_logic |
); |
end entity DebugSystemXR; |
|
architecture struct of DebugSystemXR is |
|
signal M1_n : std_logic; |
signal MREQ_n : std_logic; |
signal IORQ_n : std_logic; |
signal RD_n : std_logic; |
signal WR_n : std_logic; |
signal RFSH_n : std_logic; |
signal HALT_n : std_logic; |
signal WAIT_n : std_logic; |
signal INT_n : std_logic; |
signal RESET_s : std_logic; |
signal BUSRQ_n : std_logic; |
signal BUSAK_n : std_logic; |
signal A_i : std_logic_vector(15 downto 0); |
signal D_i : std_logic_vector(7 downto 0); |
signal ROM_D : std_logic_vector(7 downto 0); |
signal UART0_D : std_logic_vector(7 downto 0); |
signal UART1_D : std_logic_vector(7 downto 0); |
signal CPU_D : std_logic_vector(7 downto 0); |
|
signal Mirror : std_logic; |
|
signal IOWR_n : std_logic; |
signal RAMCS_n_i : std_logic; |
signal UART0CS_n : std_logic; |
signal UART1CS_n : std_logic; |
|
signal BaudOut0 : std_logic; |
signal BaudOut1 : std_logic; |
|
begin |
|
Wait_n <= '1'; |
BusRq_n <= '1'; |
INT_n <= '1'; |
|
OE_n <= RD_n; |
WE_n <= WR_n; |
RAMCS_n <= RAMCS_n_i; |
ROMCS_n <= '1'; |
PGM_n <= '1'; |
A(14 downto 0) <= A_i(14 downto 0); |
A(16 downto 15) <= "00"; |
D <= D_i when WR_n = '0' else "ZZZZZZZZ"; |
|
process (Reset_n, Clk) |
begin |
if Reset_n = '0' then |
Reset_s <= '0'; |
Mirror <= '0'; |
elsif Clk'event and Clk = '1' then |
Reset_s <= '1'; |
if IORQ_n = '0' and A_i(7 downto 4) = "1111" then |
Mirror <= D_i(0); |
end if; |
end if; |
end process; |
|
IOWR_n <= WR_n or IORQ_n; |
RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n; |
UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1'; |
UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1'; |
|
CPU_D <= |
D when RAMCS_n_i = '0' else |
UART0_D when UART0CS_n = '0' else |
UART1_D when UART1CS_n = '0' else |
ROM_D; |
|
u0 : entity work.T80s |
generic map(Mode => 1, T2Write => 1, IOWait => 0) |
port map( |
RESET_n => RESET_s, |
CLK_n => Clk, |
WAIT_n => WAIT_n, |
INT_n => INT_n, |
NMI_n => NMI_n, |
BUSRQ_n => BUSRQ_n, |
M1_n => M1_n, |
MREQ_n => MREQ_n, |
IORQ_n => IORQ_n, |
RD_n => RD_n, |
WR_n => WR_n, |
RFSH_n => RFSH_n, |
HALT_n => HALT_n, |
BUSAK_n => BUSAK_n, |
A => A_i, |
DI => CPU_D, |
DO => D_i); |
|
u1 : entity work.MonZ80 |
port map( |
Clk => Clk, |
A => A_i(10 downto 0), |
D => ROM_D); |
|
u3 : entity work.T16450 |
port map( |
MR_n => Reset_s, |
XIn => Clk, |
RClk => BaudOut0, |
CS_n => UART0CS_n, |
Rd_n => RD_n, |
Wr_n => IOWR_n, |
A => A_i(2 downto 0), |
D_In => D_i, |
D_Out => UART0_D, |
SIn => RXD0, |
CTS_n => CTS0, |
DSR_n => DSR0, |
RI_n => RI0, |
DCD_n => DCD0, |
SOut => TXD0, |
RTS_n => RTS0, |
DTR_n => DTR0, |
OUT1_n => open, |
OUT2_n => open, |
BaudOut => BaudOut0, |
Intr => open); |
|
u4 : entity work.T16450 |
port map( |
MR_n => Reset_s, |
XIn => Clk, |
RClk => BaudOut1, |
CS_n => UART1CS_n, |
Rd_n => RD_n, |
Wr_n => IOWR_n, |
A => A_i(2 downto 0), |
D_In => D_i, |
D_Out => UART1_D, |
SIn => RXD1, |
CTS_n => CTS1, |
DSR_n => DSR1, |
RI_n => RI1, |
DCD_n => DCD1, |
SOut => TXD1, |
RTS_n => RTS1, |
DTR_n => DTR1, |
OUT1_n => open, |
OUT2_n => open, |
BaudOut => BaudOut1, |
Intr => open); |
|
end; |
/VHDL/t80/SSRAM2.vhd
0,0 → 1,92
-- |
-- Inferrable Synchronous SRAM for Leonardo synthesis, no write through! |
-- |
-- Version : 0236 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity SSRAM is |
generic( |
AddrWidth : integer := 16; |
DataWidth : integer := 8 |
); |
port( |
Clk : in std_logic; |
CE_n : in std_logic; |
WE_n : in std_logic; |
A : in std_logic_vector(AddrWidth - 1 downto 0); |
DIn : in std_logic_vector(DataWidth - 1 downto 0); |
DOut : out std_logic_vector(DataWidth - 1 downto 0) |
); |
end SSRAM; |
|
architecture behaviour of SSRAM is |
|
type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); |
signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); |
-- signal A_r : std_logic_vector(AddrWidth - 1 downto 0); |
|
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
-- pragma translate_off |
if not is_x(A) then |
-- pragma translate_on |
DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0)))); |
-- pragma translate_off |
end if; |
-- pragma translate_on |
if CE_n = '0' and WE_n = '0' then |
RAM(to_integer(unsigned(A))) <= DIn; |
end if; |
-- A_r <= A; |
end if; |
end process; |
|
end; |
/VHDL/t80/T80_Reg.vhd
0,0 → 1,105
-- |
-- T80 Registers, technology independent |
-- |
-- Version : 0244 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0242 : Initial release |
-- |
-- 0244 : Changed to single register file |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T80_Reg is |
port( |
Clk : in std_logic; |
CEN : in std_logic; |
WEH : in std_logic; |
WEL : in std_logic; |
AddrA : in std_logic_vector(2 downto 0); |
AddrB : in std_logic_vector(2 downto 0); |
AddrC : in std_logic_vector(2 downto 0); |
DIH : in std_logic_vector(7 downto 0); |
DIL : in std_logic_vector(7 downto 0); |
DOAH : out std_logic_vector(7 downto 0); |
DOAL : out std_logic_vector(7 downto 0); |
DOBH : out std_logic_vector(7 downto 0); |
DOBL : out std_logic_vector(7 downto 0); |
DOCH : out std_logic_vector(7 downto 0); |
DOCL : out std_logic_vector(7 downto 0) |
); |
end T80_Reg; |
|
architecture rtl of T80_Reg is |
|
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); |
signal RegsH : Register_Image(0 to 7); |
signal RegsL : Register_Image(0 to 7); |
|
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
if CEN = '1' then |
if WEH = '1' then |
RegsH(to_integer(unsigned(AddrA))) <= DIH; |
end if; |
if WEL = '1' then |
RegsL(to_integer(unsigned(AddrA))) <= DIL; |
end if; |
end if; |
end if; |
end process; |
|
DOAH <= RegsH(to_integer(unsigned(AddrA))); |
DOAL <= RegsL(to_integer(unsigned(AddrA))); |
DOBH <= RegsH(to_integer(unsigned(AddrB))); |
DOBL <= RegsL(to_integer(unsigned(AddrB))); |
DOCH <= RegsH(to_integer(unsigned(AddrC))); |
DOCL <= RegsL(to_integer(unsigned(AddrC))); |
|
end; |
/VHDL/t80/T80_Pack.vhd
0,0 → 1,208
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package T80_Pack is |
|
component T80 |
generic( |
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
CEN : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
IORQ : out std_logic; |
NoRead : out std_logic; |
Write : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DInst : in std_logic_vector(7 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0); |
MC : out std_logic_vector(2 downto 0); |
TS : out std_logic_vector(2 downto 0); |
IntCycle_n : out std_logic; |
IntE : out std_logic; |
Stop : out std_logic |
); |
end component; |
|
component T80_Reg |
port( |
Clk : in std_logic; |
CEN : in std_logic; |
WEH : in std_logic; |
WEL : in std_logic; |
AddrA : in std_logic_vector(2 downto 0); |
AddrB : in std_logic_vector(2 downto 0); |
AddrC : in std_logic_vector(2 downto 0); |
DIH : in std_logic_vector(7 downto 0); |
DIL : in std_logic_vector(7 downto 0); |
DOAH : out std_logic_vector(7 downto 0); |
DOAL : out std_logic_vector(7 downto 0); |
DOBH : out std_logic_vector(7 downto 0); |
DOBL : out std_logic_vector(7 downto 0); |
DOCH : out std_logic_vector(7 downto 0); |
DOCL : out std_logic_vector(7 downto 0) |
); |
end component; |
|
component T80_MCode |
generic( |
Mode : integer := 0; |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
IR : in std_logic_vector(7 downto 0); |
ISet : in std_logic_vector(1 downto 0); |
MCycle : in std_logic_vector(2 downto 0); |
F : in std_logic_vector(7 downto 0); |
NMICycle : in std_logic; |
IntCycle : in std_logic; |
MCycles : out std_logic_vector(2 downto 0); |
TStates : out std_logic_vector(2 downto 0); |
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD |
Inc_PC : out std_logic; |
Inc_WZ : out std_logic; |
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc |
Read_To_Reg : out std_logic; |
Read_To_Acc : out std_logic; |
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F |
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 |
ALU_Op : out std_logic_vector(3 downto 0); |
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
Save_ALU : out std_logic; |
PreserveC : out std_logic; |
Arith16 : out std_logic; |
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI |
IORQ : out std_logic; |
Jump : out std_logic; |
JumpE : out std_logic; |
JumpXY : out std_logic; |
Call : out std_logic; |
RstP : out std_logic; |
LDZ : out std_logic; |
LDW : out std_logic; |
LDSPHL : out std_logic; |
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None |
ExchangeDH : out std_logic; |
ExchangeRp : out std_logic; |
ExchangeAF : out std_logic; |
ExchangeRS : out std_logic; |
I_DJNZ : out std_logic; |
I_CPL : out std_logic; |
I_CCF : out std_logic; |
I_SCF : out std_logic; |
I_RETN : out std_logic; |
I_BT : out std_logic; |
I_BC : out std_logic; |
I_BTR : out std_logic; |
I_RLD : out std_logic; |
I_RRD : out std_logic; |
I_INRC : out std_logic; |
SetDI : out std_logic; |
SetEI : out std_logic; |
IMode : out std_logic_vector(1 downto 0); |
Halt : out std_logic; |
NoRead : out std_logic; |
Write : out std_logic |
); |
end component; |
|
component T80_ALU |
generic( |
Mode : integer := 0; |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
Arith16 : in std_logic; |
Z16 : in std_logic; |
ALU_Op : in std_logic_vector(3 downto 0); |
IR : in std_logic_vector(5 downto 0); |
ISet : in std_logic_vector(1 downto 0); |
BusA : in std_logic_vector(7 downto 0); |
BusB : in std_logic_vector(7 downto 0); |
F_In : in std_logic_vector(7 downto 0); |
Q : out std_logic_vector(7 downto 0); |
F_Out : out std_logic_vector(7 downto 0) |
); |
end component; |
|
end; |
/VHDL/t80/T80.vhd
0,0 → 1,1073
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0247 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First complete release |
-- |
-- 0210 : Fixed wait and halt |
-- |
-- 0211 : Fixed Refresh addition and IM 1 |
-- |
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test |
-- |
-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson |
-- |
-- 0235 : Added clock enable and IM 2 fix by Mike Johnson |
-- |
-- 0237 : Changed 8080 I/O address output, added IntE output |
-- |
-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag |
-- |
-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode |
-- |
-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM |
-- |
-- 0247 : Fixed bus req/ack cycle |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80 is |
generic( |
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
CEN : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
IORQ : out std_logic; |
NoRead : out std_logic; |
Write : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DInst : in std_logic_vector(7 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0); |
MC : out std_logic_vector(2 downto 0); |
TS : out std_logic_vector(2 downto 0); |
IntCycle_n : out std_logic; |
IntE : out std_logic; |
Stop : out std_logic |
); |
end T80; |
|
architecture rtl of T80 is |
|
constant aNone : std_logic_vector(2 downto 0) := "111"; |
constant aBC : std_logic_vector(2 downto 0) := "000"; |
constant aDE : std_logic_vector(2 downto 0) := "001"; |
constant aXY : std_logic_vector(2 downto 0) := "010"; |
constant aIOA : std_logic_vector(2 downto 0) := "100"; |
constant aSP : std_logic_vector(2 downto 0) := "101"; |
constant aZI : std_logic_vector(2 downto 0) := "110"; |
|
-- Registers |
signal ACC, F : std_logic_vector(7 downto 0); |
signal Ap, Fp : std_logic_vector(7 downto 0); |
signal I : std_logic_vector(7 downto 0); |
signal R : unsigned(7 downto 0); |
signal SP, PC : unsigned(15 downto 0); |
signal RegDIH : std_logic_vector(7 downto 0); |
signal RegDIL : std_logic_vector(7 downto 0); |
signal RegBusA : std_logic_vector(15 downto 0); |
signal RegBusB : std_logic_vector(15 downto 0); |
signal RegBusC : std_logic_vector(15 downto 0); |
signal RegAddrA_r : std_logic_vector(2 downto 0); |
signal RegAddrA : std_logic_vector(2 downto 0); |
signal RegAddrB_r : std_logic_vector(2 downto 0); |
signal RegAddrB : std_logic_vector(2 downto 0); |
signal RegAddrC : std_logic_vector(2 downto 0); |
signal RegWEH : std_logic; |
signal RegWEL : std_logic; |
signal Alternate : std_logic; |
|
-- Help Registers |
signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register |
signal IR : std_logic_vector(7 downto 0); -- Instruction register |
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector |
signal RegBusA_r : std_logic_vector(15 downto 0); |
|
signal ID16 : signed(15 downto 0); |
signal Save_Mux : std_logic_vector(7 downto 0); |
|
signal TState : unsigned(2 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal IntE_FF1 : std_logic; |
signal IntE_FF2 : std_logic; |
signal Halt_FF : std_logic; |
signal BusReq_s : std_logic; |
signal BusAck : std_logic; |
signal ClkEn : std_logic; |
signal NMI_s : std_logic; |
signal INT_s : std_logic; |
signal IStatus : std_logic_vector(1 downto 0); |
|
signal DI_Reg : std_logic_vector(7 downto 0); |
signal T_Res : std_logic; |
signal XY_State : std_logic_vector(1 downto 0); |
signal Pre_XY_F_M : std_logic_vector(2 downto 0); |
signal NextIs_XY_Fetch : std_logic; |
signal XY_Ind : std_logic; |
signal No_BTR : std_logic; |
signal BTR_r : std_logic; |
signal Auto_Wait : std_logic; |
signal Auto_Wait_t1 : std_logic; |
signal Auto_Wait_t2 : std_logic; |
signal IncDecZ : std_logic; |
|
-- ALU signals |
signal BusB : std_logic_vector(7 downto 0); |
signal BusA : std_logic_vector(7 downto 0); |
signal ALU_Q : std_logic_vector(7 downto 0); |
signal F_Out : std_logic_vector(7 downto 0); |
|
-- Registered micro code outputs |
signal Read_To_Reg_r : std_logic_vector(4 downto 0); |
signal Arith16_r : std_logic; |
signal Z16_r : std_logic; |
signal ALU_Op_r : std_logic_vector(3 downto 0); |
signal Save_ALU_r : std_logic; |
signal PreserveC_r : std_logic; |
signal MCycles : std_logic_vector(2 downto 0); |
|
-- Micro code outputs |
signal MCycles_d : std_logic_vector(2 downto 0); |
signal TStates : std_logic_vector(2 downto 0); |
signal IntCycle : std_logic; |
signal NMICycle : std_logic; |
signal Inc_PC : std_logic; |
signal Inc_WZ : std_logic; |
signal IncDec_16 : std_logic_vector(3 downto 0); |
signal Prefix : std_logic_vector(1 downto 0); |
signal Read_To_Acc : std_logic; |
signal Read_To_Reg : std_logic; |
signal Set_BusB_To : std_logic_vector(3 downto 0); |
signal Set_BusA_To : std_logic_vector(3 downto 0); |
signal ALU_Op : std_logic_vector(3 downto 0); |
signal Save_ALU : std_logic; |
signal PreserveC : std_logic; |
signal Arith16 : std_logic; |
signal Set_Addr_To : std_logic_vector(2 downto 0); |
signal Jump : std_logic; |
signal JumpE : std_logic; |
signal JumpXY : std_logic; |
signal Call : std_logic; |
signal RstP : std_logic; |
signal LDZ : std_logic; |
signal LDW : std_logic; |
signal LDSPHL : std_logic; |
signal IORQ_i : std_logic; |
signal Special_LD : std_logic_vector(2 downto 0); |
signal ExchangeDH : std_logic; |
signal ExchangeRp : std_logic; |
signal ExchangeAF : std_logic; |
signal ExchangeRS : std_logic; |
signal I_DJNZ : std_logic; |
signal I_CPL : std_logic; |
signal I_CCF : std_logic; |
signal I_SCF : std_logic; |
signal I_RETN : std_logic; |
signal I_BT : std_logic; |
signal I_BC : std_logic; |
signal I_BTR : std_logic; |
signal I_RLD : std_logic; |
signal I_RRD : std_logic; |
signal I_INRC : std_logic; |
signal SetDI : std_logic; |
signal SetEI : std_logic; |
signal IMode : std_logic_vector(1 downto 0); |
signal Halt : std_logic; |
|
begin |
|
mcode : T80_MCode |
generic map( |
Mode => Mode, |
Flag_C => Flag_C, |
Flag_N => Flag_N, |
Flag_P => Flag_P, |
Flag_X => Flag_X, |
Flag_H => Flag_H, |
Flag_Y => Flag_Y, |
Flag_Z => Flag_Z, |
Flag_S => Flag_S) |
port map( |
IR => IR, |
ISet => ISet, |
MCycle => MCycle, |
F => F, |
NMICycle => NMICycle, |
IntCycle => IntCycle, |
MCycles => MCycles_d, |
TStates => TStates, |
Prefix => Prefix, |
Inc_PC => Inc_PC, |
Inc_WZ => Inc_WZ, |
IncDec_16 => IncDec_16, |
Read_To_Acc => Read_To_Acc, |
Read_To_Reg => Read_To_Reg, |
Set_BusB_To => Set_BusB_To, |
Set_BusA_To => Set_BusA_To, |
ALU_Op => ALU_Op, |
Save_ALU => Save_ALU, |
PreserveC => PreserveC, |
Arith16 => Arith16, |
Set_Addr_To => Set_Addr_To, |
IORQ => IORQ_i, |
Jump => Jump, |
JumpE => JumpE, |
JumpXY => JumpXY, |
Call => Call, |
RstP => RstP, |
LDZ => LDZ, |
LDW => LDW, |
LDSPHL => LDSPHL, |
Special_LD => Special_LD, |
ExchangeDH => ExchangeDH, |
ExchangeRp => ExchangeRp, |
ExchangeAF => ExchangeAF, |
ExchangeRS => ExchangeRS, |
I_DJNZ => I_DJNZ, |
I_CPL => I_CPL, |
I_CCF => I_CCF, |
I_SCF => I_SCF, |
I_RETN => I_RETN, |
I_BT => I_BT, |
I_BC => I_BC, |
I_BTR => I_BTR, |
I_RLD => I_RLD, |
I_RRD => I_RRD, |
I_INRC => I_INRC, |
SetDI => SetDI, |
SetEI => SetEI, |
IMode => IMode, |
Halt => Halt, |
NoRead => NoRead, |
Write => Write); |
|
alu : T80_ALU |
generic map( |
Mode => Mode, |
Flag_C => Flag_C, |
Flag_N => Flag_N, |
Flag_P => Flag_P, |
Flag_X => Flag_X, |
Flag_H => Flag_H, |
Flag_Y => Flag_Y, |
Flag_Z => Flag_Z, |
Flag_S => Flag_S) |
port map( |
Arith16 => Arith16_r, |
Z16 => Z16_r, |
ALU_Op => ALU_Op_r, |
IR => IR(5 downto 0), |
ISet => ISet, |
BusA => BusA, |
BusB => BusB, |
F_In => F, |
Q => ALU_Q, |
F_Out => F_Out); |
|
ClkEn <= CEN and not BusAck; |
|
T_Res <= '1' when TState = unsigned(TStates) else '0'; |
|
NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and |
((Set_Addr_To = aXY) or |
(MCycle = "001" and IR = "11001011") or |
(MCycle = "001" and IR = "00110110")) else '0'; |
|
Save_Mux <= BusB when ExchangeRp = '1' else |
DI_Reg when Save_ALU_r = '0' else |
ALU_Q; |
|
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
PC <= (others => '0'); -- Program Counter |
A <= (others => '0'); |
TmpAddr <= (others => '0'); |
IR <= "00000000"; |
ISet <= "00"; |
XY_State <= "00"; |
IStatus <= "00"; |
MCycles <= "000"; |
DO <= "00000000"; |
|
ACC <= (others => '1'); |
F <= (others => '1'); |
Ap <= (others => '1'); |
Fp <= (others => '1'); |
I <= (others => '0'); |
R <= (others => '0'); |
SP <= (others => '1'); |
Alternate <= '0'; |
|
Read_To_Reg_r <= "00000"; |
F <= (others => '1'); |
Arith16_r <= '0'; |
BTR_r <= '0'; |
Z16_r <= '0'; |
ALU_Op_r <= "0000"; |
Save_ALU_r <= '0'; |
PreserveC_r <= '0'; |
XY_Ind <= '0'; |
|
elsif CLK_n'event and CLK_n = '1' then |
|
if ClkEn = '1' then |
|
ALU_Op_r <= "0000"; |
Save_ALU_r <= '0'; |
Read_To_Reg_r <= "00000"; |
|
MCycles <= MCycles_d; |
|
if IMode /= "11" then |
IStatus <= IMode; |
end if; |
|
Arith16_r <= Arith16; |
PreserveC_r <= PreserveC; |
if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then |
Z16_r <= '1'; |
else |
Z16_r <= '0'; |
end if; |
|
if MCycle = "001" and TState(2) = '0' then |
-- MCycle = 1 and TState = 1, 2, or 3 |
|
if TState = 2 and Wait_n = '1' then |
if Mode < 2 then |
A(7 downto 0) <= std_logic_vector(R); |
A(15 downto 8) <= I; |
R(6 downto 0) <= R(6 downto 0) + 1; |
end if; |
|
if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then |
PC <= PC + 1; |
end if; |
|
if IntCycle = '1' and IStatus = "01" then |
IR <= "11111111"; |
elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then |
IR <= "00000000"; |
else |
IR <= DInst; |
end if; |
|
ISet <= "00"; |
if Prefix /= "00" then |
if Prefix = "11" then |
if IR(5) = '1' then |
XY_State <= "10"; |
else |
XY_State <= "01"; |
end if; |
else |
if Prefix = "10" then |
XY_State <= "00"; |
XY_Ind <= '0'; |
end if; |
ISet <= Prefix; |
end if; |
else |
XY_State <= "00"; |
XY_Ind <= '0'; |
end if; |
end if; |
|
else |
-- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) |
|
if MCycle = "110" then |
XY_Ind <= '1'; |
if Prefix = "01" then |
ISet <= "01"; |
end if; |
end if; |
|
if T_Res = '1' then |
BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; |
if Jump = '1' then |
A(15 downto 8) <= DI_Reg; |
A(7 downto 0) <= TmpAddr(7 downto 0); |
PC(15 downto 8) <= unsigned(DI_Reg); |
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); |
elsif JumpXY = '1' then |
A <= RegBusC; |
PC <= unsigned(RegBusC); |
elsif Call = '1' or RstP = '1' then |
A <= TmpAddr; |
PC <= unsigned(TmpAddr); |
elsif MCycle = MCycles and NMICycle = '1' then |
A <= "0000000001100110"; |
PC <= "0000000001100110"; |
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then |
A(15 downto 8) <= I; |
A(7 downto 0) <= TmpAddr(7 downto 0); |
PC(15 downto 8) <= unsigned(I); |
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); |
else |
case Set_Addr_To is |
when aXY => |
if XY_State = "00" then |
A <= RegBusC; |
else |
if NextIs_XY_Fetch = '1' then |
A <= std_logic_vector(PC); |
else |
A <= TmpAddr; |
end if; |
end if; |
when aIOA => |
if Mode = 3 then |
-- Memory map I/O on GBZ80 |
A(15 downto 8) <= (others => '1'); |
elsif Mode = 2 then |
-- Duplicate I/O address on 8080 |
A(15 downto 8) <= DI_Reg; |
else |
A(15 downto 8) <= ACC; |
end if; |
A(7 downto 0) <= DI_Reg; |
when aSP => |
A <= std_logic_vector(SP); |
when aBC => |
if Mode = 3 and IORQ_i = '1' then |
-- Memory map I/O on GBZ80 |
A(15 downto 8) <= (others => '1'); |
A(7 downto 0) <= RegBusC(7 downto 0); |
else |
A <= RegBusC; |
end if; |
when aDE => |
A <= RegBusC; |
when aZI => |
if Inc_WZ = '1' then |
A <= std_logic_vector(unsigned(TmpAddr) + 1); |
else |
A(15 downto 8) <= DI_Reg; |
A(7 downto 0) <= TmpAddr(7 downto 0); |
end if; |
when others => |
A <= std_logic_vector(PC); |
end case; |
end if; |
|
Save_ALU_r <= Save_ALU; |
ALU_Op_r <= ALU_Op; |
|
if I_CPL = '1' then |
-- CPL |
ACC <= not ACC; |
F(Flag_Y) <= not ACC(5); |
F(Flag_H) <= '1'; |
F(Flag_X) <= not ACC(3); |
F(Flag_N) <= '1'; |
end if; |
if I_CCF = '1' then |
-- CCF |
F(Flag_C) <= not F(Flag_C); |
F(Flag_Y) <= ACC(5); |
F(Flag_H) <= F(Flag_C); |
F(Flag_X) <= ACC(3); |
F(Flag_N) <= '0'; |
end if; |
if I_SCF = '1' then |
-- SCF |
F(Flag_C) <= '1'; |
F(Flag_Y) <= ACC(5); |
F(Flag_H) <= '0'; |
F(Flag_X) <= ACC(3); |
F(Flag_N) <= '0'; |
end if; |
end if; |
|
if TState = 2 and Wait_n = '1' then |
if ISet = "01" and MCycle = "111" then |
IR <= DInst; |
end if; |
if JumpE = '1' then |
PC <= unsigned(signed(PC) + signed(DI_Reg)); |
elsif Inc_PC = '1' then |
PC <= PC + 1; |
end if; |
if BTR_r = '1' then |
PC <= PC - 2; |
end if; |
if RstP = '1' then |
TmpAddr <= (others =>'0'); |
TmpAddr(5 downto 3) <= IR(5 downto 3); |
end if; |
end if; |
if TState = 3 and MCycle = "110" then |
TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); |
end if; |
|
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then |
if IncDec_16(2 downto 0) = "111" then |
if IncDec_16(3) = '1' then |
SP <= SP - 1; |
else |
SP <= SP + 1; |
end if; |
end if; |
end if; |
|
if LDSPHL = '1' then |
SP <= unsigned(RegBusC); |
end if; |
if ExchangeAF = '1' then |
Ap <= ACC; |
ACC <= Ap; |
Fp <= F; |
F <= Fp; |
end if; |
if ExchangeRS = '1' then |
Alternate <= not Alternate; |
end if; |
end if; |
|
if TState = 3 then |
if LDZ = '1' then |
TmpAddr(7 downto 0) <= DI_Reg; |
end if; |
if LDW = '1' then |
TmpAddr(15 downto 8) <= DI_Reg; |
end if; |
|
if Special_LD(2) = '1' then |
case Special_LD(1 downto 0) is |
when "00" => |
ACC <= I; |
F(Flag_P) <= IntE_FF2; |
when "01" => |
ACC <= std_logic_vector(R); |
F(Flag_P) <= IntE_FF2; |
when "10" => |
I <= ACC; |
when others => |
R <= unsigned(ACC); |
end case; |
end if; |
end if; |
|
if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then |
if Mode = 3 then |
F(6) <= F_Out(6); |
F(5) <= F_Out(5); |
F(7) <= F_Out(7); |
if PreserveC_r = '0' then |
F(4) <= F_Out(4); |
end if; |
else |
F(7 downto 1) <= F_Out(7 downto 1); |
if PreserveC_r = '0' then |
F(Flag_C) <= F_Out(0); |
end if; |
end if; |
end if; |
if T_Res = '1' and I_INRC = '1' then |
F(Flag_H) <= '0'; |
F(Flag_N) <= '0'; |
if DI_Reg(7 downto 0) = "00000000" then |
F(Flag_Z) <= '1'; |
else |
F(Flag_Z) <= '0'; |
end if; |
F(Flag_S) <= DI_Reg(7); |
F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor |
DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); |
end if; |
|
if TState = 1 and Auto_Wait_t1 = '0' then |
DO <= BusB; |
if I_RLD = '1' then |
DO(3 downto 0) <= BusA(3 downto 0); |
DO(7 downto 4) <= BusB(3 downto 0); |
end if; |
if I_RRD = '1' then |
DO(3 downto 0) <= BusB(7 downto 4); |
DO(7 downto 4) <= BusA(3 downto 0); |
end if; |
end if; |
|
if T_Res = '1' then |
Read_To_Reg_r(3 downto 0) <= Set_BusA_To; |
Read_To_Reg_r(4) <= Read_To_Reg; |
if Read_To_Acc = '1' then |
Read_To_Reg_r(3 downto 0) <= "0111"; |
Read_To_Reg_r(4) <= '1'; |
end if; |
end if; |
|
if TState = 1 and I_BT = '1' then |
F(Flag_X) <= ALU_Q(3); |
F(Flag_Y) <= ALU_Q(1); |
F(Flag_H) <= '0'; |
F(Flag_N) <= '0'; |
end if; |
if I_BC = '1' or I_BT = '1' then |
F(Flag_P) <= IncDecZ; |
end if; |
|
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or |
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then |
case Read_To_Reg_r is |
when "10111" => |
ACC <= Save_Mux; |
when "10110" => |
DO <= Save_Mux; |
when "11000" => |
SP(7 downto 0) <= unsigned(Save_Mux); |
when "11001" => |
SP(15 downto 8) <= unsigned(Save_Mux); |
when "11011" => |
F <= Save_Mux; |
when others => |
end case; |
end if; |
|
end if; |
|
end if; |
|
end process; |
|
--------------------------------------------------------------------------- |
-- |
-- BC('), DE('), HL('), IX and IY |
-- |
--------------------------------------------------------------------------- |
process (CLK_n) |
begin |
if CLK_n'event and CLK_n = '1' then |
if ClkEn = '1' then |
-- Bus A / Write |
RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); |
if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then |
RegAddrA_r <= XY_State(1) & "11"; |
end if; |
|
-- Bus B |
RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); |
if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then |
RegAddrB_r <= XY_State(1) & "11"; |
end if; |
|
-- Address from register |
RegAddrC <= Alternate & Set_Addr_To(1 downto 0); |
-- Jump (HL), LD SP,HL |
if (JumpXY = '1' or LDSPHL = '1') then |
RegAddrC <= Alternate & "10"; |
end if; |
if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then |
RegAddrC <= XY_State(1) & "11"; |
end if; |
|
if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then |
IncDecZ <= F_Out(Flag_Z); |
end if; |
if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then |
if ID16 = 0 then |
IncDecZ <= '0'; |
else |
IncDecZ <= '1'; |
end if; |
end if; |
|
RegBusA_r <= RegBusA; |
end if; |
end if; |
end process; |
|
RegAddrA <= |
-- 16 bit increment/decrement |
Alternate & IncDec_16(1 downto 0) when (TState = 2 or |
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else |
XY_State(1) & "11" when (TState = 2 or |
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else |
-- EX HL,DL |
Alternate & "10" when ExchangeDH = '1' and TState = 3 else |
Alternate & "01" when ExchangeDH = '1' and TState = 4 else |
-- Bus A / Write |
RegAddrA_r; |
|
RegAddrB <= |
-- EX HL,DL |
Alternate & "01" when ExchangeDH = '1' and TState = 3 else |
-- Bus B |
RegAddrB_r; |
|
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else |
signed(RegBusA) + 1; |
|
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, |
ExchangeDH, IncDec_16, MCycle, TState, Wait_n) |
begin |
RegWEH <= '0'; |
RegWEL <= '0'; |
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or |
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then |
case Read_To_Reg_r is |
when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => |
RegWEH <= not Read_To_Reg_r(0); |
RegWEL <= Read_To_Reg_r(0); |
when others => |
end case; |
end if; |
|
if ExchangeDH = '1' and (TState = 3 or TState = 4) then |
RegWEH <= '1'; |
RegWEL <= '1'; |
end if; |
|
if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then |
case IncDec_16(1 downto 0) is |
when "00" | "01" | "10" => |
RegWEH <= '1'; |
RegWEL <= '1'; |
when others => |
end case; |
end if; |
end process; |
|
process (Save_Mux, RegBusB, RegBusA_r, ID16, |
ExchangeDH, IncDec_16, MCycle, TState, Wait_n) |
begin |
RegDIH <= Save_Mux; |
RegDIL <= Save_Mux; |
|
if ExchangeDH = '1' and TState = 3 then |
RegDIH <= RegBusB(15 downto 8); |
RegDIL <= RegBusB(7 downto 0); |
end if; |
if ExchangeDH = '1' and TState = 4 then |
RegDIH <= RegBusA_r(15 downto 8); |
RegDIL <= RegBusA_r(7 downto 0); |
end if; |
|
if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then |
RegDIH <= std_logic_vector(ID16(15 downto 8)); |
RegDIL <= std_logic_vector(ID16(7 downto 0)); |
end if; |
end process; |
|
Regs : T80_Reg |
port map( |
Clk => CLK_n, |
CEN => ClkEn, |
WEH => RegWEH, |
WEL => RegWEL, |
AddrA => RegAddrA, |
AddrB => RegAddrB, |
AddrC => RegAddrC, |
DIH => RegDIH, |
DIL => RegDIL, |
DOAH => RegBusA(15 downto 8), |
DOAL => RegBusA(7 downto 0), |
DOBH => RegBusB(15 downto 8), |
DOBL => RegBusB(7 downto 0), |
DOCH => RegBusC(15 downto 8), |
DOCL => RegBusC(7 downto 0)); |
|
--------------------------------------------------------------------------- |
-- |
-- Buses |
-- |
--------------------------------------------------------------------------- |
process (CLK_n) |
begin |
if CLK_n'event and CLK_n = '1' then |
if ClkEn = '1' then |
case Set_BusB_To is |
when "0111" => |
BusB <= ACC; |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => |
if Set_BusB_To(0) = '1' then |
BusB <= RegBusB(7 downto 0); |
else |
BusB <= RegBusB(15 downto 8); |
end if; |
when "0110" => |
BusB <= DI_Reg; |
when "1000" => |
BusB <= std_logic_vector(SP(7 downto 0)); |
when "1001" => |
BusB <= std_logic_vector(SP(15 downto 8)); |
when "1010" => |
BusB <= "00000001"; |
when "1011" => |
BusB <= F; |
when "1100" => |
BusB <= std_logic_vector(PC(7 downto 0)); |
when "1101" => |
BusB <= std_logic_vector(PC(15 downto 8)); |
when "1110" => |
BusB <= "00000000"; |
when others => |
BusB <= "--------"; |
end case; |
|
case Set_BusA_To is |
when "0111" => |
BusA <= ACC; |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => |
if Set_BusA_To(0) = '1' then |
BusA <= RegBusA(7 downto 0); |
else |
BusA <= RegBusA(15 downto 8); |
end if; |
when "0110" => |
BusA <= DI_Reg; |
when "1000" => |
BusA <= std_logic_vector(SP(7 downto 0)); |
when "1001" => |
BusA <= std_logic_vector(SP(15 downto 8)); |
when "1010" => |
BusA <= "00000000"; |
when others => |
BusB <= "--------"; |
end case; |
end if; |
end if; |
end process; |
|
--------------------------------------------------------------------------- |
-- |
-- Generate external control signals |
-- |
--------------------------------------------------------------------------- |
process (RESET_n,CLK_n) |
begin |
if RESET_n = '0' then |
RFSH_n <= '1'; |
elsif CLK_n'event and CLK_n = '1' then |
if CEN = '1' then |
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then |
RFSH_n <= '0'; |
else |
RFSH_n <= '1'; |
end if; |
end if; |
end if; |
end process; |
|
MC <= std_logic_vector(MCycle); |
TS <= std_logic_vector(TState); |
DI_Reg <= DI; |
HALT_n <= not Halt_FF; |
BUSAK_n <= not BusAck; |
IntCycle_n <= not IntCycle; |
IntE <= IntE_FF1; |
IORQ <= IORQ_i; |
Stop <= I_DJNZ; |
|
------------------------------------------------------------------------- |
-- |
-- Syncronise inputs |
-- |
------------------------------------------------------------------------- |
process (RESET_n, CLK_n) |
variable OldNMI_n : std_logic; |
begin |
if RESET_n = '0' then |
BusReq_s <= '0'; |
INT_s <= '0'; |
NMI_s <= '0'; |
OldNMI_n := '0'; |
elsif CLK_n'event and CLK_n = '1' then |
if CEN = '1' then |
BusReq_s <= not BUSRQ_n; |
INT_s <= not INT_n; |
if NMICycle = '1' then |
NMI_s <= '0'; |
elsif NMI_n = '0' and OldNMI_n = '1' then |
NMI_s <= '1'; |
end if; |
OldNMI_n := NMI_n; |
end if; |
end if; |
end process; |
|
------------------------------------------------------------------------- |
-- |
-- Main state machine |
-- |
------------------------------------------------------------------------- |
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
MCycle <= "001"; |
TState <= "000"; |
Pre_XY_F_M <= "000"; |
Halt_FF <= '0'; |
BusAck <= '0'; |
NMICycle <= '0'; |
IntCycle <= '0'; |
IntE_FF1 <= '0'; |
IntE_FF2 <= '0'; |
No_BTR <= '0'; |
Auto_Wait_t1 <= '0'; |
Auto_Wait_t2 <= '0'; |
M1_n <= '1'; |
elsif CLK_n'event and CLK_n = '1' then |
if CEN = '1' then |
if T_Res = '1' then |
Auto_Wait_t1 <= '0'; |
else |
Auto_Wait_t1 <= Auto_Wait or IORQ_i; |
end if; |
Auto_Wait_t2 <= Auto_Wait_t1; |
No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or |
(I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or |
(I_BTR and (not IR(4) or F(Flag_Z))); |
if TState = 2 then |
if SetEI = '1' then |
IntE_FF1 <= '1'; |
IntE_FF2 <= '1'; |
end if; |
if I_RETN = '1' then |
IntE_FF1 <= IntE_FF2; |
end if; |
end if; |
if TState = 3 then |
if SetDI = '1' then |
IntE_FF1 <= '0'; |
IntE_FF2 <= '0'; |
end if; |
end if; |
if IntCycle = '1' or NMICycle = '1' then |
Halt_FF <= '0'; |
end if; |
if MCycle = "001" and TState = 2 and Wait_n = '1' then |
M1_n <= '1'; |
end if; |
if BusReq_s = '1' and BusAck = '1' then |
else |
BusAck <= '0'; |
if TState = 2 and Wait_n = '0' then |
elsif T_Res = '1' then |
if Halt = '1' then |
Halt_FF <= '1'; |
end if; |
if BusReq_s = '1' then |
BusAck <= '1'; |
else |
TState <= "001"; |
if NextIs_XY_Fetch = '1' then |
MCycle <= "110"; |
Pre_XY_F_M <= MCycle; |
if IR = "00110110" and Mode = 0 then |
Pre_XY_F_M <= "010"; |
end if; |
elsif (MCycle = "111") or |
(MCycle = "110" and Mode = 1 and ISet /= "01") then |
MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); |
elsif (MCycle = MCycles) or |
No_BTR = '1' or |
(MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then |
M1_n <= '0'; |
MCycle <= "001"; |
IntCycle <= '0'; |
NMICycle <= '0'; |
if NMI_s = '1' and Prefix = "00" then |
NMICycle <= '1'; |
IntE_FF1 <= '0'; |
elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then |
IntCycle <= '1'; |
IntE_FF1 <= '0'; |
IntE_FF2 <= '0'; |
end if; |
else |
MCycle <= std_logic_vector(unsigned(MCycle) + 1); |
end if; |
end if; |
else |
if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor |
(IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then |
TState <= TState + 1; |
end if; |
end if; |
end if; |
if TState = 0 then |
M1_n <= '0'; |
end if; |
end if; |
end if; |
end process; |
|
process (IntCycle, NMICycle, MCycle) |
begin |
Auto_Wait <= '0'; |
if IntCycle = '1' or NMICycle = '1' then |
if MCycle = "001" then |
Auto_Wait <= '1'; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/T8080se.vhd
0,0 → 1,185
-- |
-- 8080 compatible microprocessor core, synchronous top level with clock enable |
-- Different timing than the original 8080 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- STACK status output not supported |
-- |
-- File history : |
-- |
-- 0237 : First version |
-- |
-- 0238 : Updated for T80 interface change |
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T8080se is |
generic( |
Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 |
); |
port( |
RESET_n : in std_logic; |
CLK : in std_logic; |
CLKEN : in std_logic; |
READY : in std_logic; |
HOLD : in std_logic; |
INT : in std_logic; |
INTE : out std_logic; |
DBIN : out std_logic; |
SYNC : out std_logic; |
VAIT : out std_logic; |
HLDA : out std_logic; |
WR_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0) |
); |
end T8080se; |
|
architecture rtl of T8080se is |
|
signal IntCycle_n : std_logic; |
signal NoRead : std_logic; |
signal Write : std_logic; |
signal IORQ : std_logic; |
signal INT_n : std_logic; |
signal HALT_n : std_logic; |
signal BUSRQ_n : std_logic; |
signal BUSAK_n : std_logic; |
signal DO_i : std_logic_vector(7 downto 0); |
signal DI_Reg : std_logic_vector(7 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal TState : std_logic_vector(2 downto 0); |
signal One : std_logic; |
|
begin |
|
INT_n <= not INT; |
BUSRQ_n <= HOLD; |
HLDA <= not BUSAK_n; |
SYNC <= '1' when TState = "001" else '0'; |
VAIT <= '1' when TState = "010" else '0'; |
One <= '1'; |
|
DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA |
DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n |
DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! |
DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA |
DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT |
DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 |
DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP |
DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR |
|
u0 : T80 |
generic map( |
Mode => Mode, |
IOWait => 0) |
port map( |
CEN => CLKEN, |
M1_n => open, |
IORQ => IORQ, |
NoRead => NoRead, |
Write => Write, |
RFSH_n => open, |
HALT_n => HALT_n, |
WAIT_n => READY, |
INT_n => INT_n, |
NMI_n => One, |
RESET_n => RESET_n, |
BUSRQ_n => One, |
BUSAK_n => BUSAK_n, |
CLK_n => CLK, |
A => A, |
DInst => DI, |
DI => DI_Reg, |
DO => DO_i, |
MC => MCycle, |
TS => TState, |
IntCycle_n => IntCycle_n, |
IntE => INTE); |
|
process (RESET_n, CLK) |
begin |
if RESET_n = '0' then |
DBIN <= '0'; |
WR_n <= '1'; |
DI_Reg <= "00000000"; |
elsif CLK'event and CLK = '1' then |
if CLKEN = '1' then |
DBIN <= '0'; |
WR_n <= '1'; |
if MCycle = "001" then |
if TState = "001" or (TState = "010" and READY = '0') then |
DBIN <= IntCycle_n; |
end if; |
else |
if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then |
DBIN <= '1'; |
end if; |
if T2Write = 0 then |
if TState = "010" and Write = '1' then |
WR_n <= '0'; |
end if; |
else |
if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then |
WR_n <= '0'; |
end if; |
end if; |
end if; |
if TState = "010" and READY = '1' then |
DI_Reg <= DI; |
end if; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/T80_ALU.vhd
0,0 → 1,351
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0247 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test |
-- |
-- 0238 : Fixed zero flag for 16 bit SBC and ADC |
-- |
-- 0240 : Added GB operations |
-- |
-- 0242 : Cleanup |
-- |
-- 0247 : Cleanup |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T80_ALU is |
generic( |
Mode : integer := 0; |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
Arith16 : in std_logic; |
Z16 : in std_logic; |
ALU_Op : in std_logic_vector(3 downto 0); |
IR : in std_logic_vector(5 downto 0); |
ISet : in std_logic_vector(1 downto 0); |
BusA : in std_logic_vector(7 downto 0); |
BusB : in std_logic_vector(7 downto 0); |
F_In : in std_logic_vector(7 downto 0); |
Q : out std_logic_vector(7 downto 0); |
F_Out : out std_logic_vector(7 downto 0) |
); |
end T80_ALU; |
|
architecture rtl of T80_ALU is |
|
procedure AddSub(A : std_logic_vector; |
B : std_logic_vector; |
Sub : std_logic; |
Carry_In : std_logic; |
signal Res : out std_logic_vector; |
signal Carry : out std_logic) is |
variable B_i : unsigned(A'length - 1 downto 0); |
variable Res_i : unsigned(A'length + 1 downto 0); |
begin |
if Sub = '1' then |
B_i := not unsigned(B); |
else |
B_i := unsigned(B); |
end if; |
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); |
Carry <= Res_i(A'length + 1); |
Res <= std_logic_vector(Res_i(A'length downto 1)); |
end; |
|
-- AddSub variables (temporary signals) |
signal UseCarry : std_logic; |
signal Carry7_v : std_logic; |
signal Overflow_v : std_logic; |
signal HalfCarry_v : std_logic; |
signal Carry_v : std_logic; |
signal Q_v : std_logic_vector(7 downto 0); |
|
signal BitMask : std_logic_vector(7 downto 0); |
|
begin |
|
with IR(5 downto 3) select BitMask <= "00000001" when "000", |
"00000010" when "001", |
"00000100" when "010", |
"00001000" when "011", |
"00010000" when "100", |
"00100000" when "101", |
"01000000" when "110", |
"10000000" when others; |
|
UseCarry <= not ALU_Op(2) and ALU_Op(0); |
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); |
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); |
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); |
OverFlow_v <= Carry_v xor Carry7_v; |
|
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) |
variable Q_t : std_logic_vector(7 downto 0); |
variable DAA_Q : unsigned(8 downto 0); |
begin |
Q_t := "--------"; |
F_Out <= F_In; |
DAA_Q := "---------"; |
case ALU_Op is |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_C) <= '0'; |
case ALU_OP(2 downto 0) is |
when "000" | "001" => -- ADD, ADC |
Q_t := Q_v; |
F_Out(Flag_C) <= Carry_v; |
F_Out(Flag_H) <= HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "010" | "011" | "111" => -- SUB, SBC, CP |
Q_t := Q_v; |
F_Out(Flag_N) <= '1'; |
F_Out(Flag_C) <= not Carry_v; |
F_Out(Flag_H) <= not HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "100" => -- AND |
Q_t(7 downto 0) := BusA and BusB; |
F_Out(Flag_H) <= '1'; |
when "101" => -- XOR |
Q_t(7 downto 0) := BusA xor BusB; |
F_Out(Flag_H) <= '0'; |
when others => -- OR "110" |
Q_t(7 downto 0) := BusA or BusB; |
F_Out(Flag_H) <= '0'; |
end case; |
if ALU_Op(2 downto 0) = "111" then -- CP |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
else |
F_Out(Flag_X) <= Q_t(3); |
F_Out(Flag_Y) <= Q_t(5); |
end if; |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
if Z16 = '1' then |
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC |
end if; |
else |
F_Out(Flag_Z) <= '0'; |
end if; |
F_Out(Flag_S) <= Q_t(7); |
case ALU_Op(2 downto 0) is |
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP |
when others => |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
end case; |
if Arith16 = '1' then |
F_Out(Flag_S) <= F_In(Flag_S); |
F_Out(Flag_Z) <= F_In(Flag_Z); |
F_Out(Flag_P) <= F_In(Flag_P); |
end if; |
when "1100" => |
-- DAA |
F_Out(Flag_H) <= F_In(Flag_H); |
F_Out(Flag_C) <= F_In(Flag_C); |
DAA_Q(7 downto 0) := unsigned(BusA); |
DAA_Q(8) := '0'; |
if F_In(Flag_N) = '0' then |
-- After addition |
-- Alow > 9 or H = 1 |
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then |
if (DAA_Q(3 downto 0) > 9) then |
F_Out(Flag_H) <= '1'; |
else |
F_Out(Flag_H) <= '0'; |
end if; |
DAA_Q := DAA_Q + 6; |
end if; |
-- new Ahigh > 9 or C = 1 |
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then |
DAA_Q := DAA_Q + 96; -- 0x60 |
end if; |
else |
-- After subtraction |
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then |
if DAA_Q(3 downto 0) > 5 then |
F_Out(Flag_H) <= '0'; |
end if; |
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; |
end if; |
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then |
DAA_Q := DAA_Q - 352; -- 0x160 |
end if; |
end if; |
F_Out(Flag_X) <= DAA_Q(3); |
F_Out(Flag_Y) <= DAA_Q(5); |
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); |
Q_t := std_logic_vector(DAA_Q(7 downto 0)); |
if DAA_Q(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
end if; |
F_Out(Flag_S) <= DAA_Q(7); |
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor |
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); |
when "1101" | "1110" => |
-- RLD, RRD |
Q_t(7 downto 4) := BusA(7 downto 4); |
if ALU_Op(0) = '1' then |
Q_t(3 downto 0) := BusB(7 downto 4); |
else |
Q_t(3 downto 0) := BusB(3 downto 0); |
end if; |
F_Out(Flag_H) <= '0'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= Q_t(3); |
F_Out(Flag_Y) <= Q_t(5); |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
end if; |
F_Out(Flag_S) <= Q_t(7); |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
when "1001" => |
-- BIT |
Q_t(7 downto 0) := BusB and BitMask; |
F_Out(Flag_S) <= Q_t(7); |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
F_Out(Flag_P) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
F_Out(Flag_P) <= '0'; |
end if; |
F_Out(Flag_H) <= '1'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= '0'; |
F_Out(Flag_Y) <= '0'; |
if IR(2 downto 0) /= "110" then |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
end if; |
when "1010" => |
-- SET |
Q_t(7 downto 0) := BusB or BitMask; |
when "1011" => |
-- RES |
Q_t(7 downto 0) := BusB and not BitMask; |
when "1000" => |
-- ROT |
case IR(5 downto 3) is |
when "000" => -- RLC |
Q_t(7 downto 1) := BusA(6 downto 0); |
Q_t(0) := BusA(7); |
F_Out(Flag_C) <= BusA(7); |
when "010" => -- RL |
Q_t(7 downto 1) := BusA(6 downto 0); |
Q_t(0) := F_In(Flag_C); |
F_Out(Flag_C) <= BusA(7); |
when "001" => -- RRC |
Q_t(6 downto 0) := BusA(7 downto 1); |
Q_t(7) := BusA(0); |
F_Out(Flag_C) <= BusA(0); |
when "011" => -- RR |
Q_t(6 downto 0) := BusA(7 downto 1); |
Q_t(7) := F_In(Flag_C); |
F_Out(Flag_C) <= BusA(0); |
when "100" => -- SLA |
Q_t(7 downto 1) := BusA(6 downto 0); |
Q_t(0) := '0'; |
F_Out(Flag_C) <= BusA(7); |
when "110" => -- SLL (Undocumented) / SWAP |
if Mode = 3 then |
Q_t(7 downto 4) := BusA(3 downto 0); |
Q_t(3 downto 0) := BusA(7 downto 4); |
F_Out(Flag_C) <= '0'; |
else |
Q_t(7 downto 1) := BusA(6 downto 0); |
Q_t(0) := '1'; |
F_Out(Flag_C) <= BusA(7); |
end if; |
when "101" => -- SRA |
Q_t(6 downto 0) := BusA(7 downto 1); |
Q_t(7) := BusA(7); |
F_Out(Flag_C) <= BusA(0); |
when others => -- SRL |
Q_t(6 downto 0) := BusA(7 downto 1); |
Q_t(7) := '0'; |
F_Out(Flag_C) <= BusA(0); |
end case; |
F_Out(Flag_H) <= '0'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= Q_t(3); |
F_Out(Flag_Y) <= Q_t(5); |
F_Out(Flag_S) <= Q_t(7); |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
end if; |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
if ISet = "00" then |
F_Out(Flag_P) <= F_In(Flag_P); |
F_Out(Flag_S) <= F_In(Flag_S); |
F_Out(Flag_Z) <= F_In(Flag_Z); |
end if; |
when others => |
null; |
end case; |
Q <= Q_t; |
end process; |
|
end; |
/VHDL/t80/T80a.vhd
0,0 → 1,253
-- |
-- Z80 compatible microprocessor core, asynchronous top level |
-- |
-- Version : 0247 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First complete release |
-- |
-- 0211 : Fixed interrupt cycle |
-- |
-- 0235 : Updated for T80 interface change |
-- |
-- 0238 : Updated for T80 interface change |
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
-- 0247 : Fixed bus req/ack cycle |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80a is |
generic( |
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
MREQ_n : out std_logic; |
IORQ_n : out std_logic; |
RD_n : out std_logic; |
WR_n : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
D : inout std_logic_vector(7 downto 0) |
); |
end T80a; |
|
architecture rtl of T80a is |
|
signal CEN : std_logic; |
signal Reset_s : std_logic; |
signal IntCycle_n : std_logic; |
signal IORQ : std_logic; |
signal NoRead : std_logic; |
signal Write : std_logic; |
signal MREQ : std_logic; |
signal MReq_Inhibit : std_logic; |
signal Req_Inhibit : std_logic; |
signal RD : std_logic; |
signal MREQ_n_i : std_logic; |
signal IORQ_n_i : std_logic; |
signal RD_n_i : std_logic; |
signal WR_n_i : std_logic; |
signal RFSH_n_i : std_logic; |
signal BUSAK_n_i : std_logic; |
signal A_i : std_logic_vector(15 downto 0); |
signal DO : std_logic_vector(7 downto 0); |
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser |
signal Wait_s : std_logic; |
signal MCycle : std_logic_vector(2 downto 0); |
signal TState : std_logic_vector(2 downto 0); |
|
begin |
|
CEN <= '1'; |
|
BUSAK_n <= BUSAK_n_i; |
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); |
RD_n_i <= not RD or Req_Inhibit; |
|
MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; |
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; |
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; |
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; |
RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; |
A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); |
D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); |
|
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
Reset_s <= '0'; |
elsif CLK_n'event and CLK_n = '1' then |
Reset_s <= '1'; |
end if; |
end process; |
|
u0 : T80 |
generic map( |
Mode => Mode, |
IOWait => 1) |
port map( |
CEN => CEN, |
M1_n => M1_n, |
IORQ => IORQ, |
NoRead => NoRead, |
Write => Write, |
RFSH_n => RFSH_n_i, |
HALT_n => HALT_n, |
WAIT_n => Wait_s, |
INT_n => INT_n, |
NMI_n => NMI_n, |
RESET_n => Reset_s, |
BUSRQ_n => BUSRQ_n, |
BUSAK_n => BUSAK_n_i, |
CLK_n => CLK_n, |
A => A_i, |
DInst => D, |
DI => DI_Reg, |
DO => DO, |
MC => MCycle, |
TS => TState, |
IntCycle_n => IntCycle_n); |
|
process (CLK_n) |
begin |
if CLK_n'event and CLK_n = '0' then |
Wait_s <= WAIT_n; |
if TState = "011" and BUSAK_n_i = '1' then |
DI_Reg <= to_x01(D); |
end if; |
end if; |
end process; |
|
process (Reset_s,CLK_n) |
begin |
if Reset_s = '0' then |
WR_n_i <= '1'; |
elsif CLK_n'event and CLK_n = '1' then |
WR_n_i <= '1'; |
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! |
WR_n_i <= not Write; |
end if; |
end if; |
end process; |
|
process (Reset_s,CLK_n) |
begin |
if Reset_s = '0' then |
Req_Inhibit <= '0'; |
elsif CLK_n'event and CLK_n = '1' then |
if MCycle = "001" and TState = "010" then |
Req_Inhibit <= '1'; |
else |
Req_Inhibit <= '0'; |
end if; |
end if; |
end process; |
|
process (Reset_s,CLK_n) |
begin |
if Reset_s = '0' then |
MReq_Inhibit <= '0'; |
elsif CLK_n'event and CLK_n = '0' then |
if MCycle = "001" and TState = "010" then |
MReq_Inhibit <= '1'; |
else |
MReq_Inhibit <= '0'; |
end if; |
end if; |
end process; |
|
process(Reset_s,CLK_n) |
begin |
if Reset_s = '0' then |
RD <= '0'; |
IORQ_n_i <= '1'; |
MREQ <= '0'; |
elsif CLK_n'event and CLK_n = '0' then |
|
if MCycle = "001" then |
if TState = "001" then |
RD <= IntCycle_n; |
MREQ <= IntCycle_n; |
IORQ_n_i <= IntCycle_n; |
end if; |
if TState = "011" then |
RD <= '0'; |
IORQ_n_i <= '1'; |
MREQ <= '1'; |
end if; |
if TState = "100" then |
MREQ <= '0'; |
end if; |
else |
if TState = "001" and NoRead = '0' then |
RD <= not Write; |
IORQ_n_i <= not IORQ; |
MREQ <= not IORQ; |
end if; |
if TState = "011" then |
RD <= '0'; |
IORQ_n_i <= '1'; |
MREQ <= '0'; |
end if; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/SSRAMX.vhd
0,0 → 1,132
-- |
-- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes) |
-- |
-- Version : 0247 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0240 : Initial release |
-- |
-- 0242 : Changed RAMB4_S8 to map by name |
-- |
-- 0247 : Added RAMB4_S8 component declaration |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity SSRAM is |
generic( |
AddrWidth : integer := 11; |
DataWidth : integer := 8 |
); |
port( |
Clk : in std_logic; |
CE_n : in std_logic; |
WE_n : in std_logic; |
A : in std_logic_vector(AddrWidth - 1 downto 0); |
DIn : in std_logic_vector(DataWidth - 1 downto 0); |
DOut : out std_logic_vector(DataWidth - 1 downto 0) |
); |
end SSRAM; |
|
architecture rtl of SSRAM is |
|
component RAMB4_S8 |
port( |
DO : out std_logic_vector(7 downto 0); |
ADDR : in std_logic_vector(8 downto 0); |
CLK : in std_ulogic; |
DI : in std_logic_vector(7 downto 0); |
EN : in std_ulogic; |
RST : in std_ulogic; |
WE : in std_ulogic); |
end component; |
|
constant RAMs : integer := (2 ** AddrWidth) / 512; |
|
type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0); |
|
signal bRAMOut : bRAMOut_a; |
signal biA_r : integer; |
signal A_r : unsigned(A'left downto 0); |
-- signal A_i : std_logic_vector(8 downto 0); |
signal WEA : std_logic_vector(RAMs - 1 downto 0); |
|
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
A_r <= unsigned(A); |
end if; |
end process; |
|
biA_r <= to_integer(A_r(A'left downto 9)); |
-- A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0); |
|
bG1: for I in 0 to RAMs - 1 generate |
begin |
WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0'; |
BSSRAM : RAMB4_S8 |
port map( |
DI => DIn, |
EN => '1', |
WE => WEA(I), |
RST => '0', |
CLK => Clk, |
ADDR => A, |
DO => bRAMOut(I)); |
end generate; |
|
process (biA_r, bRAMOut) |
begin |
DOut <= bRAMOut(0); |
for I in 1 to RAMs - 1 loop |
if biA_r = I then |
DOut <= bRAMOut(I); |
end if; |
end loop; |
end process; |
|
end; |
/VHDL/t80/T80_MCode.vhd
0,0 → 1,1934
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First complete release |
-- |
-- 0211 : Fixed IM 1 |
-- |
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test |
-- |
-- 0235 : Added IM 2 fix by Mike Johnson |
-- |
-- 0238 : Added NoRead signal |
-- |
-- 0238b: Fixed instruction timing for POP and DJNZ |
-- |
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes |
-- |
-- 0242 : Fixed I/O instruction timing, cleanup |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T80_MCode is |
generic( |
Mode : integer := 0; |
Flag_C : integer := 0; |
Flag_N : integer := 1; |
Flag_P : integer := 2; |
Flag_X : integer := 3; |
Flag_H : integer := 4; |
Flag_Y : integer := 5; |
Flag_Z : integer := 6; |
Flag_S : integer := 7 |
); |
port( |
IR : in std_logic_vector(7 downto 0); |
ISet : in std_logic_vector(1 downto 0); |
MCycle : in std_logic_vector(2 downto 0); |
F : in std_logic_vector(7 downto 0); |
NMICycle : in std_logic; |
IntCycle : in std_logic; |
MCycles : out std_logic_vector(2 downto 0); |
TStates : out std_logic_vector(2 downto 0); |
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD |
Inc_PC : out std_logic; |
Inc_WZ : out std_logic; |
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc |
Read_To_Reg : out std_logic; |
Read_To_Acc : out std_logic; |
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F |
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 |
ALU_Op : out std_logic_vector(3 downto 0); |
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
Save_ALU : out std_logic; |
PreserveC : out std_logic; |
Arith16 : out std_logic; |
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI |
IORQ : out std_logic; |
Jump : out std_logic; |
JumpE : out std_logic; |
JumpXY : out std_logic; |
Call : out std_logic; |
RstP : out std_logic; |
LDZ : out std_logic; |
LDW : out std_logic; |
LDSPHL : out std_logic; |
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None |
ExchangeDH : out std_logic; |
ExchangeRp : out std_logic; |
ExchangeAF : out std_logic; |
ExchangeRS : out std_logic; |
I_DJNZ : out std_logic; |
I_CPL : out std_logic; |
I_CCF : out std_logic; |
I_SCF : out std_logic; |
I_RETN : out std_logic; |
I_BT : out std_logic; |
I_BC : out std_logic; |
I_BTR : out std_logic; |
I_RLD : out std_logic; |
I_RRD : out std_logic; |
I_INRC : out std_logic; |
SetDI : out std_logic; |
SetEI : out std_logic; |
IMode : out std_logic_vector(1 downto 0); |
Halt : out std_logic; |
NoRead : out std_logic; |
Write : out std_logic |
); |
end T80_MCode; |
|
architecture rtl of T80_MCode is |
|
constant aNone : std_logic_vector(2 downto 0) := "111"; |
constant aBC : std_logic_vector(2 downto 0) := "000"; |
constant aDE : std_logic_vector(2 downto 0) := "001"; |
constant aXY : std_logic_vector(2 downto 0) := "010"; |
constant aIOA : std_logic_vector(2 downto 0) := "100"; |
constant aSP : std_logic_vector(2 downto 0) := "101"; |
constant aZI : std_logic_vector(2 downto 0) := "110"; |
-- constant aNone : std_logic_vector(2 downto 0) := "000"; |
-- constant aXY : std_logic_vector(2 downto 0) := "001"; |
-- constant aIOA : std_logic_vector(2 downto 0) := "010"; |
-- constant aSP : std_logic_vector(2 downto 0) := "011"; |
-- constant aBC : std_logic_vector(2 downto 0) := "100"; |
-- constant aDE : std_logic_vector(2 downto 0) := "101"; |
-- constant aZI : std_logic_vector(2 downto 0) := "110"; |
|
function is_cc_true( |
F : std_logic_vector(7 downto 0); |
cc : bit_vector(2 downto 0) |
) return boolean is |
begin |
if Mode = 3 then |
case cc is |
when "000" => return F(7) = '0'; -- NZ |
when "001" => return F(7) = '1'; -- Z |
when "010" => return F(4) = '0'; -- NC |
when "011" => return F(4) = '1'; -- C |
when "100" => return false; |
when "101" => return false; |
when "110" => return false; |
when "111" => return false; |
end case; |
else |
case cc is |
when "000" => return F(6) = '0'; -- NZ |
when "001" => return F(6) = '1'; -- Z |
when "010" => return F(0) = '0'; -- NC |
when "011" => return F(0) = '1'; -- C |
when "100" => return F(2) = '0'; -- PO |
when "101" => return F(2) = '1'; -- PE |
when "110" => return F(7) = '0'; -- P |
when "111" => return F(7) = '1'; -- M |
end case; |
end if; |
end; |
|
begin |
|
process (IR, ISet, MCycle, F, NMICycle, IntCycle) |
variable DDD : std_logic_vector(2 downto 0); |
variable SSS : std_logic_vector(2 downto 0); |
variable DPair : std_logic_vector(1 downto 0); |
variable IRB : bit_vector(7 downto 0); |
begin |
DDD := IR(5 downto 3); |
SSS := IR(2 downto 0); |
DPair := IR(5 downto 4); |
IRB := to_bitvector(IR); |
|
MCycles <= "001"; |
if MCycle = "001" then |
TStates <= "100"; |
else |
TStates <= "011"; |
end if; |
Prefix <= "00"; |
Inc_PC <= '0'; |
Inc_WZ <= '0'; |
IncDec_16 <= "0000"; |
Read_To_Acc <= '0'; |
Read_To_Reg <= '0'; |
Set_BusB_To <= "0000"; |
Set_BusA_To <= "0000"; |
ALU_Op <= "0" & IR(5 downto 3); |
Save_ALU <= '0'; |
PreserveC <= '0'; |
Arith16 <= '0'; |
IORQ <= '0'; |
Set_Addr_To <= aNone; |
Jump <= '0'; |
JumpE <= '0'; |
JumpXY <= '0'; |
Call <= '0'; |
RstP <= '0'; |
LDZ <= '0'; |
LDW <= '0'; |
LDSPHL <= '0'; |
Special_LD <= "000"; |
ExchangeDH <= '0'; |
ExchangeRp <= '0'; |
ExchangeAF <= '0'; |
ExchangeRS <= '0'; |
I_DJNZ <= '0'; |
I_CPL <= '0'; |
I_CCF <= '0'; |
I_SCF <= '0'; |
I_RETN <= '0'; |
I_BT <= '0'; |
I_BC <= '0'; |
I_BTR <= '0'; |
I_RLD <= '0'; |
I_RRD <= '0'; |
I_INRC <= '0'; |
SetDI <= '0'; |
SetEI <= '0'; |
IMode <= "11"; |
Halt <= '0'; |
NoRead <= '0'; |
Write <= '0'; |
|
case ISet is |
when "00" => |
|
------------------------------------------------------------------------------ |
-- |
-- Unprefixed instructions |
-- |
------------------------------------------------------------------------------ |
|
case IRB is |
-- 8 BIT LOAD GROUP |
when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" |
|"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" |
|"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" |
|"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" |
|"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" |
|"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" |
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => |
-- LD r,r' |
Set_BusB_To(2 downto 0) <= SSS; |
ExchangeRp <= '1'; |
Set_BusA_To(2 downto 0) <= DDD; |
Read_To_Reg <= '1'; |
when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => |
-- LD r,n |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_BusA_To(2 downto 0) <= DDD; |
Read_To_Reg <= '1'; |
when others => null; |
end case; |
when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => |
-- LD r,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
Set_BusA_To(2 downto 0) <= DDD; |
Read_To_Reg <= '1'; |
when others => null; |
end case; |
when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => |
-- LD (HL),r |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
when 2 => |
Write <= '1'; |
when others => null; |
end case; |
when "00110110" => |
-- LD (HL),n |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_Addr_To <= aXY; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
when 3 => |
Write <= '1'; |
when others => null; |
end case; |
when "00001010" => |
-- LD A,(BC) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
when 2 => |
Read_To_Acc <= '1'; |
when others => null; |
end case; |
when "00011010" => |
-- LD A,(DE) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aDE; |
when 2 => |
Read_To_Acc <= '1'; |
when others => null; |
end case; |
when "00111010" => |
if Mode = 3 then |
-- LDD A,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
Read_To_Acc <= '1'; |
IncDec_16 <= "1110"; |
when others => null; |
end case; |
else |
-- LD A,(nn) |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
when 4 => |
Read_To_Acc <= '1'; |
when others => null; |
end case; |
end if; |
when "00000010" => |
-- LD (BC),A |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
Set_BusB_To <= "0111"; |
when 2 => |
Write <= '1'; |
when others => null; |
end case; |
when "00010010" => |
-- LD (DE),A |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aDE; |
Set_BusB_To <= "0111"; |
when 2 => |
Write <= '1'; |
when others => null; |
end case; |
when "00110010" => |
if Mode = 3 then |
-- LDD (HL),A |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
Set_BusB_To <= "0111"; |
when 2 => |
Write <= '1'; |
IncDec_16 <= "1110"; |
when others => null; |
end case; |
else |
-- LD (nn),A |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
Set_BusB_To <= "0111"; |
when 4 => |
Write <= '1'; |
when others => null; |
end case; |
end if; |
|
-- 16 BIT LOAD GROUP |
when "00000001"|"00010001"|"00100001"|"00110001" => |
-- LD dd,nn |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Read_To_Reg <= '1'; |
if DPAIR = "11" then |
Set_BusA_To(3 downto 0) <= "1000"; |
else |
Set_BusA_To(2 downto 1) <= DPAIR; |
Set_BusA_To(0) <= '1'; |
end if; |
when 3 => |
Inc_PC <= '1'; |
Read_To_Reg <= '1'; |
if DPAIR = "11" then |
Set_BusA_To(3 downto 0) <= "1001"; |
else |
Set_BusA_To(2 downto 1) <= DPAIR; |
Set_BusA_To(0) <= '0'; |
end if; |
when others => null; |
end case; |
when "00101010" => |
if Mode = 3 then |
-- LDI A,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
Read_To_Acc <= '1'; |
IncDec_16 <= "0110"; |
when others => null; |
end case; |
else |
-- LD HL,(nn) |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
when 4 => |
Set_BusA_To(2 downto 0) <= "101"; -- L |
Read_To_Reg <= '1'; |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
when 5 => |
Set_BusA_To(2 downto 0) <= "100"; -- H |
Read_To_Reg <= '1'; |
when others => null; |
end case; |
end if; |
when "00100010" => |
if Mode = 3 then |
-- LDI (HL),A |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
Set_BusB_To <= "0111"; |
when 2 => |
Write <= '1'; |
IncDec_16 <= "0110"; |
when others => null; |
end case; |
else |
-- LD (nn),HL |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
Set_BusB_To <= "0101"; -- L |
when 4 => |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
Write <= '1'; |
Set_BusB_To <= "0100"; -- H |
when 5 => |
Write <= '1'; |
when others => null; |
end case; |
end if; |
when "11111001" => |
-- LD SP,HL |
TStates <= "110"; |
LDSPHL <= '1'; |
when "11000101"|"11010101"|"11100101"|"11110101" => |
-- PUSH qq |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
IncDec_16 <= "1111"; |
Set_Addr_TO <= aSP; |
if DPAIR = "11" then |
Set_BusB_To <= "0111"; |
else |
Set_BusB_To(2 downto 1) <= DPAIR; |
Set_BusB_To(0) <= '0'; |
Set_BusB_To(3) <= '0'; |
end if; |
when 2 => |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
if DPAIR = "11" then |
Set_BusB_To <= "1011"; |
else |
Set_BusB_To(2 downto 1) <= DPAIR; |
Set_BusB_To(0) <= '1'; |
Set_BusB_To(3) <= '0'; |
end if; |
Write <= '1'; |
when 3 => |
Write <= '1'; |
when others => null; |
end case; |
when "11000001"|"11010001"|"11100001"|"11110001" => |
-- POP qq |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aSP; |
when 2 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
Read_To_Reg <= '1'; |
if DPAIR = "11" then |
Set_BusA_To(3 downto 0) <= "1011"; |
else |
Set_BusA_To(2 downto 1) <= DPAIR; |
Set_BusA_To(0) <= '1'; |
end if; |
when 3 => |
IncDec_16 <= "0111"; |
Read_To_Reg <= '1'; |
if DPAIR = "11" then |
Set_BusA_To(3 downto 0) <= "0111"; |
else |
Set_BusA_To(2 downto 1) <= DPAIR; |
Set_BusA_To(0) <= '0'; |
end if; |
when others => null; |
end case; |
|
-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP |
when "11101011" => |
if Mode /= 3 then |
-- EX DE,HL |
ExchangeDH <= '1'; |
end if; |
when "00001000" => |
if Mode = 3 then |
-- LD (nn),SP |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
Set_BusB_To <= "1000"; |
when 4 => |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
Write <= '1'; |
Set_BusB_To <= "1001"; |
when 5 => |
Write <= '1'; |
when others => null; |
end case; |
elsif Mode < 2 then |
-- EX AF,AF' |
ExchangeAF <= '1'; |
end if; |
when "11011001" => |
if Mode = 3 then |
-- RETI |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_TO <= aSP; |
when 2 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
LDZ <= '1'; |
when 3 => |
Jump <= '1'; |
IncDec_16 <= "0111"; |
I_RETN <= '1'; |
SetEI <= '1'; |
when others => null; |
end case; |
elsif Mode < 2 then |
-- EXX |
ExchangeRS <= '1'; |
end if; |
when "11100011" => |
if Mode /= 3 then |
-- EX (SP),HL |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aSP; |
when 2 => |
Read_To_Reg <= '1'; |
Set_BusA_To <= "0101"; |
Set_BusB_To <= "0101"; |
Set_Addr_To <= aSP; |
when 3 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
TStates <= "100"; |
Write <= '1'; |
when 4 => |
Read_To_Reg <= '1'; |
Set_BusA_To <= "0100"; |
Set_BusB_To <= "0100"; |
Set_Addr_To <= aSP; |
when 5 => |
IncDec_16 <= "1111"; |
TStates <= "101"; |
Write <= '1'; |
when others => null; |
end case; |
end if; |
|
-- 8 BIT ARITHMETIC AND LOGICAL GROUP |
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" |
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" |
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" |
|"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" |
|"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" |
|"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" |
|"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => |
-- ADD A,r |
-- ADC A,r |
-- SUB A,r |
-- SBC A,r |
-- AND A,r |
-- OR A,r |
-- XOR A,r |
-- CP A,r |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusA_To(2 downto 0) <= "111"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => |
-- ADD A,(HL) |
-- ADC A,(HL) |
-- SUB A,(HL) |
-- SBC A,(HL) |
-- AND A,(HL) |
-- OR A,(HL) |
-- XOR A,(HL) |
-- CP A,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusA_To(2 downto 0) <= "111"; |
when others => null; |
end case; |
when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => |
-- ADD A,n |
-- ADC A,n |
-- SUB A,n |
-- SBC A,n |
-- AND A,n |
-- OR A,n |
-- XOR A,n |
-- CP A,n |
MCycles <= "010"; |
if MCycle = "010" then |
Inc_PC <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusA_To(2 downto 0) <= "111"; |
end if; |
when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => |
-- INC r |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= DDD; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "0000"; |
when "00110100" => |
-- INC (HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
TStates <= "100"; |
Set_Addr_To <= aXY; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "0000"; |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= DDD; |
when 3 => |
Write <= '1'; |
when others => null; |
end case; |
when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => |
-- DEC r |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= DDD; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "0010"; |
when "00110101" => |
-- DEC (HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
when 2 => |
TStates <= "100"; |
Set_Addr_To <= aXY; |
ALU_Op <= "0010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= DDD; |
when 3 => |
Write <= '1'; |
when others => null; |
end case; |
|
-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS |
when "00100111" => |
-- DAA |
Set_BusA_To(2 downto 0) <= "111"; |
Read_To_Reg <= '1'; |
ALU_Op <= "1100"; |
Save_ALU <= '1'; |
when "00101111" => |
-- CPL |
I_CPL <= '1'; |
when "00111111" => |
-- CCF |
I_CCF <= '1'; |
when "00110111" => |
-- SCF |
I_SCF <= '1'; |
when "00000000" => |
if NMICycle = '1' then |
-- NMI |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1101"; |
when 2 => |
TStates <= "100"; |
Write <= '1'; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1100"; |
when 3 => |
TStates <= "100"; |
Write <= '1'; |
when others => null; |
end case; |
elsif IntCycle = '1' then |
-- INT (IM 2) |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
LDZ <= '1'; |
TStates <= "101"; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1101"; |
when 2 => |
TStates <= "100"; |
Write <= '1'; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1100"; |
when 3 => |
TStates <= "100"; |
Write <= '1'; |
when 4 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 5 => |
Jump <= '1'; |
when others => null; |
end case; |
else |
-- NOP |
end if; |
when "01110110" => |
-- HALT |
Halt <= '1'; |
when "11110011" => |
-- DI |
SetDI <= '1'; |
when "11111011" => |
-- EI |
SetEI <= '1'; |
|
-- 16 BIT ARITHMETIC GROUP |
when "00001001"|"00011001"|"00101001"|"00111001" => |
-- ADD HL,ss |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '1'; |
when others => |
Set_BusB_To <= "1000"; |
end case; |
TStates <= "100"; |
Arith16 <= '1'; |
when 3 => |
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0001"; |
Set_BusA_To(2 downto 0) <= "100"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
when others => |
Set_BusB_To <= "1001"; |
end case; |
Arith16 <= '1'; |
when others => |
end case; |
when "00000011"|"00010011"|"00100011"|"00110011" => |
-- INC ss |
TStates <= "110"; |
IncDec_16(3 downto 2) <= "01"; |
IncDec_16(1 downto 0) <= DPair; |
when "00001011"|"00011011"|"00101011"|"00111011" => |
-- DEC ss |
TStates <= "110"; |
IncDec_16(3 downto 2) <= "11"; |
IncDec_16(1 downto 0) <= DPair; |
|
-- ROTATE AND SHIFT GROUP |
when "00000111" |
-- RLCA |
|"00010111" |
-- RLA |
|"00001111" |
-- RRCA |
|"00011111" => |
-- RRA |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
|
-- JUMP GROUP |
when "11000011" => |
-- JP nn |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Inc_PC <= '1'; |
Jump <= '1'; |
when others => null; |
end case; |
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => |
if IR(5) = '1' and Mode = 3 then |
case IRB(4 downto 3) is |
when "00" => |
-- LD ($FF00+C),A |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
Set_BusB_To <= "0111"; |
when 2 => |
Write <= '1'; |
IORQ <= '1'; |
when others => |
end case; |
when "01" => |
-- LD (nn),A |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
Set_BusB_To <= "0111"; |
when 4 => |
Write <= '1'; |
when others => null; |
end case; |
when "10" => |
-- LD A,($FF00+C) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
when 2 => |
Read_To_Acc <= '1'; |
IORQ <= '1'; |
when others => |
end case; |
when "11" => |
-- LD A,(nn) |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
when 4 => |
Read_To_Acc <= '1'; |
when others => null; |
end case; |
end case; |
else |
-- JP cc,nn |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Inc_PC <= '1'; |
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
Jump <= '1'; |
end if; |
when others => null; |
end case; |
end if; |
when "00011000" => |
if Mode /= 2 then |
-- JR e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
when "00111000" => |
if Mode /= 2 then |
-- JR C,e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
if F(Flag_C) = '0' then |
MCycles <= "010"; |
end if; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
when "00110000" => |
if Mode /= 2 then |
-- JR NC,e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
if F(Flag_C) = '1' then |
MCycles <= "010"; |
end if; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
when "00101000" => |
if Mode /= 2 then |
-- JR Z,e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
if F(Flag_Z) = '0' then |
MCycles <= "010"; |
end if; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
when "00100000" => |
if Mode /= 2 then |
-- JR NZ,e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
if F(Flag_Z) = '1' then |
MCycles <= "010"; |
end if; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
when "11101001" => |
-- JP (HL) |
JumpXY <= '1'; |
when "00010000" => |
if Mode = 3 then |
I_DJNZ <= '1'; |
elsif Mode < 2 then |
-- DJNZ,e |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
I_DJNZ <= '1'; |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= "000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0010"; |
when 2 => |
I_DJNZ <= '1'; |
Inc_PC <= '1'; |
when 3 => |
NoRead <= '1'; |
JumpE <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end if; |
|
-- CALL AND RETURN GROUP |
when "11001101" => |
-- CALL nn |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
IncDec_16 <= "1111"; |
Inc_PC <= '1'; |
TStates <= "100"; |
Set_Addr_To <= aSP; |
LDW <= '1'; |
Set_BusB_To <= "1101"; |
when 4 => |
Write <= '1'; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1100"; |
when 5 => |
Write <= '1'; |
Call <= '1'; |
when others => null; |
end case; |
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => |
if IR(5) = '0' or Mode /= 3 then |
-- CALL cc,nn |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Inc_PC <= '1'; |
LDW <= '1'; |
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
IncDec_16 <= "1111"; |
Set_Addr_TO <= aSP; |
TStates <= "100"; |
Set_BusB_To <= "1101"; |
else |
MCycles <= "011"; |
end if; |
when 4 => |
Write <= '1'; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1100"; |
when 5 => |
Write <= '1'; |
Call <= '1'; |
when others => null; |
end case; |
end if; |
when "11001001" => |
-- RET |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
Set_Addr_TO <= aSP; |
when 2 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
LDZ <= '1'; |
when 3 => |
Jump <= '1'; |
IncDec_16 <= "0111"; |
when others => null; |
end case; |
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => |
if IR(5) = '1' and Mode = 3 then |
case IRB(4 downto 3) is |
when "00" => |
-- LD ($FF00+nn),A |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_Addr_To <= aIOA; |
Set_BusB_To <= "0111"; |
when 3 => |
Write <= '1'; |
when others => null; |
end case; |
when "01" => |
-- ADD SP,n |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
ALU_Op <= "0000"; |
Inc_PC <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To <= "1000"; |
Set_BusB_To <= "0110"; |
when 3 => |
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0001"; |
Set_BusA_To <= "1001"; |
Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! |
when others => |
end case; |
when "10" => |
-- LD A,($FF00+nn) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_Addr_To <= aIOA; |
when 3 => |
Read_To_Acc <= '1'; |
when others => null; |
end case; |
when "11" => |
-- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
when 4 => |
Set_BusA_To(2 downto 0) <= "101"; -- L |
Read_To_Reg <= '1'; |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
when 5 => |
Set_BusA_To(2 downto 0) <= "100"; -- H |
Read_To_Reg <= '1'; |
when others => null; |
end case; |
end case; |
else |
-- RET cc |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then |
Set_Addr_TO <= aSP; |
else |
MCycles <= "001"; |
end if; |
TStates <= "101"; |
when 2 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
LDZ <= '1'; |
when 3 => |
Jump <= '1'; |
IncDec_16 <= "0111"; |
when others => null; |
end case; |
end if; |
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => |
-- RST p |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1101"; |
when 2 => |
Write <= '1'; |
IncDec_16 <= "1111"; |
Set_Addr_To <= aSP; |
Set_BusB_To <= "1100"; |
when 3 => |
Write <= '1'; |
RstP <= '1'; |
when others => null; |
end case; |
|
-- INPUT AND OUTPUT GROUP |
when "11011011" => |
if Mode /= 3 then |
-- IN A,(n) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_Addr_To <= aIOA; |
when 3 => |
Read_To_Acc <= '1'; |
IORQ <= '1'; |
when others => null; |
end case; |
end if; |
when "11010011" => |
if Mode /= 3 then |
-- OUT (n),A |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
Set_Addr_To <= aIOA; |
Set_BusB_To <= "0111"; |
when 3 => |
Write <= '1'; |
IORQ <= '1'; |
when others => null; |
end case; |
end if; |
|
------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ |
-- MULTIBYTE INSTRUCTIONS |
------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ |
|
when "11001011" => |
if Mode /= 2 then |
Prefix <= "01"; |
end if; |
|
when "11101101" => |
if Mode < 2 then |
Prefix <= "10"; |
end if; |
|
when "11011101"|"11111101" => |
if Mode < 2 then |
Prefix <= "11"; |
end if; |
|
end case; |
|
when "01" => |
|
------------------------------------------------------------------------------ |
-- |
-- CB prefixed instructions |
-- |
------------------------------------------------------------------------------ |
|
Set_BusA_To(2 downto 0) <= IR(2 downto 0); |
Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
|
case IRB is |
when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" |
|"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" |
|"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" |
|"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" |
|"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" |
|"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" |
|"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" |
|"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => |
-- RLC r |
-- RL r |
-- RRC r |
-- RR r |
-- SLA r |
-- SRA r |
-- SRL r |
-- SLL r (Undocumented) / SWAP r |
if MCycle = "001" then |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => |
-- RLC (HL) |
-- RL (HL) |
-- RRC (HL) |
-- RR (HL) |
-- SRA (HL) |
-- SRL (HL) |
-- SLA (HL) |
-- SLL (HL) (Undocumented) / SWAP (HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
TStates <= "100"; |
when 3 => |
Write <= '1'; |
when others => |
end case; |
when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" |
|"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" |
|"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" |
|"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" |
|"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" |
|"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" |
|"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" |
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => |
-- BIT b,r |
if MCycle = "001" then |
Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
ALU_Op <= "1001"; |
end if; |
when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => |
-- BIT b,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
ALU_Op <= "1001"; |
TStates <= "100"; |
when others => |
end case; |
when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" |
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" |
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" |
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" |
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" |
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" |
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" |
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => |
-- SET b,r |
if MCycle = "001" then |
ALU_Op <= "1010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => |
-- SET b,(HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
ALU_Op <= "1010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
TStates <= "100"; |
when 3 => |
Write <= '1'; |
when others => |
end case; |
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" |
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" |
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" |
|"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" |
|"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" |
|"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" |
|"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => |
-- RES b,r |
if MCycle = "001" then |
ALU_Op <= "1011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => |
-- RES b,(HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
ALU_Op <= "1011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
TStates <= "100"; |
when 3 => |
Write <= '1'; |
when others => |
end case; |
end case; |
|
when others => |
|
------------------------------------------------------------------------------ |
-- |
-- ED prefixed instructions |
-- |
------------------------------------------------------------------------------ |
|
case IRB is |
when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" |
|"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" |
|"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" |
|"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" |
|"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" |
|"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" |
|"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" |
|"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" |
|
|
|"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" |
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" |
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" |
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" |
| "10100100"|"10100101"|"10100110"|"10100111" |
| "10101100"|"10101101"|"10101110"|"10101111" |
| "10110100"|"10110101"|"10110110"|"10110111" |
| "10111100"|"10111101"|"10111110"|"10111111" |
|"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" |
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" |
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" |
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" |
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" |
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" |
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" |
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => |
null; -- NOP, undocumented |
when "01111110"|"01111111" => |
-- NOP, undocumented |
null; |
-- 8 BIT LOAD GROUP |
when "01010111" => |
-- LD A,I |
Special_LD <= "100"; |
TStates <= "101"; |
when "01011111" => |
-- LD A,R |
Special_LD <= "101"; |
TStates <= "101"; |
when "01000111" => |
-- LD I,A |
Special_LD <= "110"; |
TStates <= "101"; |
when "01001111" => |
-- LD R,A |
Special_LD <= "111"; |
TStates <= "101"; |
-- 16 BIT LOAD GROUP |
when "01001011"|"01011011"|"01101011"|"01111011" => |
-- LD dd,(nn) |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
when 4 => |
Read_To_Reg <= '1'; |
if IR(5 downto 4) = "11" then |
Set_BusA_To <= "1000"; |
else |
Set_BusA_To(2 downto 1) <= IR(5 downto 4); |
Set_BusA_To(0) <= '1'; |
end if; |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
when 5 => |
Read_To_Reg <= '1'; |
if IR(5 downto 4) = "11" then |
Set_BusA_To <= "1001"; |
else |
Set_BusA_To(2 downto 1) <= IR(5 downto 4); |
Set_BusA_To(0) <= '0'; |
end if; |
when others => null; |
end case; |
when "01000011"|"01010011"|"01100011"|"01110011" => |
-- LD (nn),dd |
MCycles <= "101"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Inc_PC <= '1'; |
LDZ <= '1'; |
when 3 => |
Set_Addr_To <= aZI; |
Inc_PC <= '1'; |
LDW <= '1'; |
if IR(5 downto 4) = "11" then |
Set_BusB_To <= "1000"; |
else |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '1'; |
Set_BusB_To(3) <= '0'; |
end if; |
when 4 => |
Inc_WZ <= '1'; |
Set_Addr_To <= aZI; |
Write <= '1'; |
if IR(5 downto 4) = "11" then |
Set_BusB_To <= "1001"; |
else |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '0'; |
Set_BusB_To(3) <= '0'; |
end if; |
when 5 => |
Write <= '1'; |
when others => null; |
end case; |
when "10100000" | "10101000" | "10110000" | "10111000" => |
-- LDI, LDD, LDIR, LDDR |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
IncDec_16 <= "1100"; -- BC |
when 2 => |
Set_BusB_To <= "0110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "0000"; |
Set_Addr_To <= aDE; |
if IR(3) = '0' then |
IncDec_16 <= "0110"; -- IX |
else |
IncDec_16 <= "1110"; |
end if; |
when 3 => |
I_BT <= '1'; |
TStates <= "101"; |
Write <= '1'; |
if IR(3) = '0' then |
IncDec_16 <= "0101"; -- DE |
else |
IncDec_16 <= "1101"; |
end if; |
when 4 => |
NoRead <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
when "10100001" | "10101001" | "10110001" | "10111001" => |
-- CPI, CPD, CPIR, CPDR |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
IncDec_16 <= "1100"; -- BC |
when 2 => |
Set_BusB_To <= "0110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "0111"; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
if IR(3) = '0' then |
IncDec_16 <= "0110"; |
else |
IncDec_16 <= "1110"; |
end if; |
when 3 => |
NoRead <= '1'; |
I_BC <= '1'; |
TStates <= "101"; |
when 4 => |
NoRead <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => |
-- NEG |
Alu_OP <= "0010"; |
Set_BusB_To <= "0111"; |
Set_BusA_To <= "1010"; |
Read_To_Acc <= '1'; |
Save_ALU <= '1'; |
when "01000110"|"01001110"|"01100110"|"01101110" => |
-- IM 0 |
IMode <= "00"; |
when "01010110"|"01110110" => |
-- IM 1 |
IMode <= "01"; |
when "01011110"|"01110111" => |
-- IM 2 |
IMode <= "10"; |
-- 16 bit arithmetic |
when "01001010"|"01011010"|"01101010"|"01111010" => |
-- ADC HL,ss |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "0001"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '1'; |
when others => |
Set_BusB_To <= "1000"; |
end case; |
TStates <= "100"; |
when 3 => |
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0001"; |
Set_BusA_To(2 downto 0) <= "100"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '0'; |
when others => |
Set_BusB_To <= "1001"; |
end case; |
when others => |
end case; |
when "01000010"|"01010010"|"01100010"|"01110010" => |
-- SBC HL,ss |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "0011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
Set_BusB_To(0) <= '1'; |
when others => |
Set_BusB_To <= "1000"; |
end case; |
TStates <= "100"; |
when 3 => |
NoRead <= '1'; |
ALU_Op <= "0011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "100"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
Set_BusB_To(2 downto 1) <= IR(5 downto 4); |
when others => |
Set_BusB_To <= "1001"; |
end case; |
when others => |
end case; |
when "01101111" => |
-- RLD |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
Set_Addr_To <= aXY; |
when 3 => |
Read_To_Reg <= '1'; |
Set_BusB_To(2 downto 0) <= "110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "1101"; |
TStates <= "100"; |
Set_Addr_To <= aXY; |
Save_ALU <= '1'; |
when 4 => |
I_RLD <= '1'; |
Write <= '1'; |
when others => |
end case; |
when "01100111" => |
-- RRD |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
Set_Addr_To <= aXY; |
when 3 => |
Read_To_Reg <= '1'; |
Set_BusB_To(2 downto 0) <= "110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "1110"; |
TStates <= "100"; |
Set_Addr_To <= aXY; |
Save_ALU <= '1'; |
when 4 => |
I_RRD <= '1'; |
Write <= '1'; |
when others => |
end case; |
when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => |
-- RETI, RETN |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_TO <= aSP; |
when 2 => |
IncDec_16 <= "0111"; |
Set_Addr_To <= aSP; |
LDZ <= '1'; |
when 3 => |
Jump <= '1'; |
IncDec_16 <= "0111"; |
I_RETN <= '1'; |
when others => null; |
end case; |
when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => |
-- IN r,(C) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
when 2 => |
IORQ <= '1'; |
if IR(5 downto 3) /= "110" then |
Read_To_Reg <= '1'; |
Set_BusA_To(2 downto 0) <= IR(5 downto 3); |
end if; |
I_INRC <= '1'; |
when others => |
end case; |
when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => |
-- OUT (C),r |
-- OUT (C),0 |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
Set_BusB_To(2 downto 0) <= IR(5 downto 3); |
if IR(5 downto 3) = "110" then |
Set_BusB_To(3) <= '1'; |
end if; |
when 2 => |
Write <= '1'; |
IORQ <= '1'; |
when others => |
end case; |
when "10100010" | "10101010" | "10110010" | "10111010" => |
-- INI, IND, INIR, INDR |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aBC; |
Set_BusB_To <= "1010"; |
Set_BusA_To <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0010"; |
when 2 => |
IORQ <= '1'; |
Set_BusB_To <= "0110"; |
Set_Addr_To <= aXY; |
when 3 => |
if IR(3) = '0' then |
IncDec_16 <= "0010"; |
else |
IncDec_16 <= "1010"; |
end if; |
TStates <= "100"; |
Write <= '1'; |
I_BTR <= '1'; |
when 4 => |
NoRead <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
when "10100011" | "10101011" | "10110011" | "10111011" => |
-- OUTI, OUTD, OTIR, OTDR |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
Set_Addr_To <= aXY; |
Set_BusB_To <= "1010"; |
Set_BusA_To <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "0010"; |
when 2 => |
Set_BusB_To <= "0110"; |
Set_Addr_To <= aBC; |
when 3 => |
if IR(3) = '0' then |
IncDec_16 <= "0010"; |
else |
IncDec_16 <= "1010"; |
end if; |
IORQ <= '1'; |
Write <= '1'; |
I_BTR <= '1'; |
when 4 => |
NoRead <= '1'; |
TStates <= "101"; |
when others => null; |
end case; |
end case; |
|
end case; |
|
if Mode = 1 then |
if MCycle = "001" then |
-- TStates <= "100"; |
else |
TStates <= "011"; |
end if; |
end if; |
|
if Mode = 3 then |
if MCycle = "001" then |
-- TStates <= "100"; |
else |
TStates <= "100"; |
end if; |
end if; |
|
if Mode < 2 then |
if MCycle = "110" then |
Inc_PC <= '1'; |
if Mode = 1 then |
Set_Addr_To <= aXY; |
TStates <= "100"; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
end if; |
if IRB = "00110110" or IRB = "11001011" then |
Set_Addr_To <= aNone; |
end if; |
end if; |
if MCycle = "111" then |
if Mode = 0 then |
TStates <= "101"; |
end if; |
if ISet /= "01" then |
Set_Addr_To <= aXY; |
end if; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
if IRB = "00110110" or ISet = "01" then |
-- LD (HL),n |
Inc_PC <= '1'; |
else |
NoRead <= '1'; |
end if; |
end if; |
end if; |
|
end process; |
|
end; |
/VHDL/t80/SSRAM.vhd
0,0 → 1,92
-- |
-- Inferrable Synchronous SRAM for XST synthesis |
-- |
-- Version : 0220 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- 0208 : Initial release |
-- 0218 : Fixed data out at write |
-- 0220 : Added support for XST |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity SSRAM is |
generic( |
AddrWidth : integer := 11; |
DataWidth : integer := 8 |
); |
port( |
Clk : in std_logic; |
CE_n : in std_logic; |
WE_n : in std_logic; |
A : in std_logic_vector(AddrWidth - 1 downto 0); |
DIn : in std_logic_vector(DataWidth - 1 downto 0); |
DOut : out std_logic_vector(DataWidth - 1 downto 0) |
); |
end SSRAM; |
|
architecture behaviour of SSRAM is |
|
type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); |
signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); |
signal A_r : std_logic_vector(AddrWidth - 1 downto 0); |
|
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
if (CE_n nor WE_n) = '1' then |
RAM(to_integer(unsigned(A))) <= DIn; |
end if; |
A_r <= A; |
end if; |
end process; |
|
DOut <= RAM(to_integer(unsigned(A_r))) |
-- pragma translate_off |
when not is_x(A_r) else (others => '-') |
-- pragma translate_on |
; |
end; |
/VHDL/t80/T80s.vhd.bak
0,0 → 1,190
-- |
-- Z80 compatible microprocessor core, synchronous top level |
-- Different timing than the original z80 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First complete release |
-- |
-- 0210 : Fixed read with wait |
-- |
-- 0211 : Fixed interrupt cycle |
-- |
-- 0235 : Updated for T80 interface change |
-- |
-- 0236 : Added T2Write generic |
-- |
-- 0237 : Fixed T2Write with wait state |
-- |
-- 0238 : Updated for T80 interface change |
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80s is |
generic( |
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 |
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
MREQ_n : out std_logic; |
IORQ_n : out std_logic; |
RD_n : out std_logic; |
WR_n : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0) |
); |
end T80s; |
|
architecture rtl of T80s is |
|
signal CEN : std_logic; |
signal IntCycle_n : std_logic; |
signal NoRead : std_logic; |
signal Write : std_logic; |
signal IORQ : std_logic; |
signal DI_Reg : std_logic_vector(7 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal TState : std_logic_vector(2 downto 0); |
|
begin |
|
CEN <= '1'; |
|
u0 : T80 |
generic map( |
Mode => Mode, |
IOWait => IOWait) |
port map( |
CEN => CEN, |
M1_n => M1_n, |
IORQ => IORQ, |
NoRead => NoRead, |
Write => Write, |
RFSH_n => RFSH_n, |
HALT_n => HALT_n, |
WAIT_n => Wait_n, |
INT_n => INT_n, |
NMI_n => NMI_n, |
RESET_n => RESET_n, |
BUSRQ_n => BUSRQ_n, |
BUSAK_n => BUSAK_n, |
CLK_n => CLK_n, |
A => A, |
DInst => DI, |
DI => DI_Reg, |
DO => DO, |
MC => MCycle, |
TS => TState, |
IntCycle_n => IntCycle_n); |
|
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
DI_Reg <= "00000000"; |
elsif CLK_n'event and CLK_n = '1' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
if MCycle = "001" then |
if TState = "001" or (TState = "010" and Wait_n = '0') then |
RD_n <= not IntCycle_n; |
MREQ_n <= not IntCycle_n; |
IORQ_n <= IntCycle_n; |
end if; |
if TState = "011" then |
MREQ_n <= '0'; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then |
RD_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
if T2Write = 0 then |
if TState = "010" and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
end if; |
end if; |
if TState = "010" and Wait_n = '1' then |
DI_Reg <= DI; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/t80/DebugSystem.vhd
0,0 → 1,181
-- Z80, Monitor ROM, 4k RAM and two 16450 UARTs |
-- that can be synthesized and used with |
-- the NoICE debugger that can be found at |
-- http://www.noicedebugger.com/ |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
entity DebugSystem is |
port( |
Reset_n : in std_logic; |
Clk : in std_logic; |
NMI_n : in std_logic; |
RXD0 : in std_logic; |
CTS0 : in std_logic; |
DSR0 : in std_logic; |
RI0 : in std_logic; |
DCD0 : in std_logic; |
RXD1 : in std_logic; |
CTS1 : in std_logic; |
DSR1 : in std_logic; |
RI1 : in std_logic; |
DCD1 : in std_logic; |
TXD0 : out std_logic; |
RTS0 : out std_logic; |
DTR0 : out std_logic; |
TXD1 : out std_logic; |
RTS1 : out std_logic; |
DTR1 : out std_logic |
); |
end DebugSystem; |
|
architecture struct of DebugSystem is |
|
signal M1_n : std_logic; |
signal MREQ_n : std_logic; |
signal IORQ_n : std_logic; |
signal RD_n : std_logic; |
signal WR_n : std_logic; |
signal RFSH_n : std_logic; |
signal HALT_n : std_logic; |
signal WAIT_n : std_logic; |
signal INT_n : std_logic; |
signal RESET_s : std_logic; |
signal BUSRQ_n : std_logic; |
signal BUSAK_n : std_logic; |
signal A : std_logic_vector(15 downto 0); |
signal D : std_logic_vector(7 downto 0); |
signal ROM_D : std_logic_vector(7 downto 0); |
signal SRAM_D : std_logic_vector(7 downto 0); |
signal UART0_D : std_logic_vector(7 downto 0); |
signal UART1_D : std_logic_vector(7 downto 0); |
signal CPU_D : std_logic_vector(7 downto 0); |
|
signal Mirror : std_logic; |
|
signal IOWR_n : std_logic; |
signal RAMCS_n : std_logic; |
signal UART0CS_n : std_logic; |
signal UART1CS_n : std_logic; |
|
signal BaudOut0 : std_logic; |
signal BaudOut1 : std_logic; |
|
begin |
|
Wait_n <= '1'; |
BusRq_n <= '1'; |
INT_n <= '1'; |
|
process (Reset_n, Clk) |
begin |
if Reset_n = '0' then |
Reset_s <= '0'; |
Mirror <= '0'; |
elsif Clk'event and Clk = '1' then |
Reset_s <= '1'; |
if IORQ_n = '0' and A(7 downto 4) = "1111" then |
Mirror <= D(0); |
end if; |
end if; |
end process; |
|
IOWR_n <= WR_n or IORQ_n; |
RAMCS_n <= (not Mirror and not A(15)) or MREQ_n; |
UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1'; |
UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1'; |
|
CPU_D <= |
SRAM_D when RAMCS_n = '0' else |
UART0_D when UART0CS_n = '0' else |
UART1_D when UART1CS_n = '0' else |
ROM_D; |
|
u0 : entity work.T80s |
generic map(Mode => 1, T2Write => 1, IOWait => 0) |
port map( |
RESET_n => RESET_s, |
CLK_n => Clk, |
WAIT_n => WAIT_n, |
INT_n => INT_n, |
NMI_n => NMI_n, |
BUSRQ_n => BUSRQ_n, |
M1_n => M1_n, |
MREQ_n => MREQ_n, |
IORQ_n => IORQ_n, |
RD_n => RD_n, |
WR_n => WR_n, |
RFSH_n => RFSH_n, |
HALT_n => HALT_n, |
BUSAK_n => BUSAK_n, |
A => A, |
DI => CPU_D, |
DO => D); |
|
u1 : entity work.MonZ80 |
port map( |
Clk => Clk, |
A => A(10 downto 0), |
D => ROM_D); |
|
u2 : entity work.SSRAM |
generic map( |
AddrWidth => 12) |
port map( |
Clk => Clk, |
CE_n => RAMCS_n, |
WE_n => WR_n, |
A => A(11 downto 0), |
DIn => D, |
DOut => SRAM_D); |
|
u3 : entity work.T16450 |
port map( |
MR_n => Reset_s, |
XIn => Clk, |
RClk => BaudOut0, |
CS_n => UART0CS_n, |
Rd_n => RD_n, |
Wr_n => IOWR_n, |
A => A(2 downto 0), |
D_In => D, |
D_Out => UART0_D, |
SIn => RXD0, |
CTS_n => CTS0, |
DSR_n => DSR0, |
RI_n => RI0, |
DCD_n => DCD0, |
SOut => TXD0, |
RTS_n => RTS0, |
DTR_n => DTR0, |
OUT1_n => open, |
OUT2_n => open, |
BaudOut => BaudOut0, |
Intr => open); |
|
u4 : entity work.T16450 |
port map( |
MR_n => Reset_s, |
XIn => Clk, |
RClk => BaudOut1, |
CS_n => UART1CS_n, |
Rd_n => RD_n, |
Wr_n => IOWR_n, |
A => A(2 downto 0), |
D_In => D, |
D_Out => UART1_D, |
SIn => RXD1, |
CTS_n => CTS1, |
DSR_n => DSR1, |
RI_n => RI1, |
DCD_n => DCD1, |
SOut => TXD1, |
RTS_n => RTS1, |
DTR_n => DTR1, |
OUT1_n => open, |
OUT2_n => open, |
BaudOut => BaudOut1, |
Intr => open); |
|
end; |
/VHDL/t80/T80s.vhd
0,0 → 1,190
-- |
-- Z80 compatible microprocessor core, synchronous top level |
-- Different timing than the original z80 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0208 : First complete release |
-- |
-- 0210 : Fixed read with wait |
-- |
-- 0211 : Fixed interrupt cycle |
-- |
-- 0235 : Updated for T80 interface change |
-- |
-- 0236 : Added T2Write generic |
-- |
-- 0237 : Fixed T2Write with wait state |
-- |
-- 0238 : Updated for T80 interface change |
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80s is |
generic( |
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 |
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle |
); |
port( |
RESET_n : in std_logic; |
CLK_n : in std_logic; |
WAIT_n : in std_logic; |
INT_n : in std_logic; |
NMI_n : in std_logic; |
BUSRQ_n : in std_logic; |
M1_n : out std_logic; |
MREQ_n : out std_logic; |
IORQ_n : out std_logic; |
RD_n : out std_logic; |
WR_n : out std_logic; |
RFSH_n : out std_logic; |
HALT_n : out std_logic; |
BUSAK_n : out std_logic; |
A : out std_logic_vector(15 downto 0); |
DI : in std_logic_vector(7 downto 0); |
DO : out std_logic_vector(7 downto 0) |
); |
end T80s; |
|
architecture rtl of T80s is |
|
signal CEN : std_logic; |
signal IntCycle_n : std_logic; |
signal NoRead : std_logic; |
signal Write : std_logic; |
signal IORQ : std_logic; |
signal DI_Reg : std_logic_vector(7 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal TState : std_logic_vector(2 downto 0); |
|
begin |
|
CEN <= '1'; |
|
u0 : T80 |
generic map( |
Mode => Mode, |
IOWait => IOWait) |
port map( |
CEN => CEN, |
M1_n => M1_n, |
IORQ => IORQ, |
NoRead => NoRead, |
Write => Write, |
RFSH_n => RFSH_n, |
HALT_n => HALT_n, |
WAIT_n => Wait_n, |
INT_n => INT_n, |
NMI_n => NMI_n, |
RESET_n => RESET_n, |
BUSRQ_n => BUSRQ_n, |
BUSAK_n => BUSAK_n, |
CLK_n => CLK_n, |
A => A, |
DInst => DI, |
DI => DI_Reg, |
DO => DO, |
MC => MCycle, |
TS => TState, |
IntCycle_n => IntCycle_n); |
|
process (RESET_n, CLK_n) |
begin |
if RESET_n = '0' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
DI_Reg <= "00000000"; |
elsif CLK_n'event and CLK_n = '1' then |
RD_n <= '1'; |
WR_n <= '1'; |
IORQ_n <= '1'; |
MREQ_n <= '1'; |
if MCycle = "001" then |
if TState = "001" or (TState = "010" and Wait_n = '0') then |
RD_n <= not IntCycle_n; |
MREQ_n <= not IntCycle_n; |
IORQ_n <= IntCycle_n; |
end if; |
if TState = "011" then |
MREQ_n <= '0'; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then |
RD_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
if T2Write = 0 then |
if TState = "010" and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
else |
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then |
WR_n <= '0'; |
IORQ_n <= not IORQ; |
MREQ_n <= IORQ; |
end if; |
end if; |
end if; |
if TState = "010" and Wait_n = '1' then |
DI_Reg <= DI; |
end if; |
end if; |
end process; |
|
end; |
/VHDL/video_PLL.vhd
0,0 → 1,203
-- megafunction wizard: %ALTPLL% |
-- GENERATION: STANDARD |
-- VERSION: WM1.0 |
-- MODULE: altpll |
|
-- ============================================================ |
-- File Name: video_PLL.vhd |
-- Megafunction Name(s): |
-- altpll |
-- ============================================================ |
-- ************************************************************ |
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! |
-- |
-- 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition |
-- ************************************************************ |
|
|
--Copyright (C) 1991-2005 Altera Corporation |
--Your use of Altera Corporation's design tools, logic functions |
--and other software and tools, and its AMPP partner logic |
--functions, and any output files any of the foregoing |
--(including device programming or simulation files), and any |
--associated documentation or information are expressly subject |
--to the terms and conditions of the Altera Program License |
--Subscription Agreement, Altera MegaCore Function License |
--Agreement, or other applicable license agreement, including, |
--without limitation, that your use is for the sole purpose of |
--programming logic devices manufactured by Altera and sold by |
--Altera or its authorized distributors. Please refer to the |
--applicable agreement for further details. |
|
|
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
LIBRARY altera_mf; |
USE altera_mf.altera_mf_components.all; |
|
ENTITY video_PLL IS |
PORT |
( |
inclk0 : IN STD_LOGIC := '0'; |
c0 : OUT STD_LOGIC |
); |
END video_PLL; |
|
|
ARCHITECTURE SYN OF video_pll IS |
|
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0); |
SIGNAL sub_wire1 : STD_LOGIC ; |
SIGNAL sub_wire2 : STD_LOGIC ; |
SIGNAL sub_wire3 : STD_LOGIC_VECTOR (1 DOWNTO 0); |
SIGNAL sub_wire4_bv : BIT_VECTOR (0 DOWNTO 0); |
SIGNAL sub_wire4 : STD_LOGIC_VECTOR (0 DOWNTO 0); |
|
|
|
COMPONENT altpll |
GENERIC ( |
clk0_duty_cycle : NATURAL; |
lpm_type : STRING; |
clk0_multiply_by : NATURAL; |
inclk0_input_frequency : NATURAL; |
clk0_divide_by : NATURAL; |
pll_type : STRING; |
intended_device_family : STRING; |
operation_mode : STRING; |
compensate_clock : STRING; |
clk0_phase_shift : STRING |
); |
PORT ( |
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); |
clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0) |
); |
END COMPONENT; |
|
BEGIN |
sub_wire4_bv(0 DOWNTO 0) <= "0"; |
sub_wire4 <= To_stdlogicvector(sub_wire4_bv); |
sub_wire1 <= sub_wire0(0); |
c0 <= sub_wire1; |
sub_wire2 <= inclk0; |
sub_wire3 <= sub_wire4(0 DOWNTO 0) & sub_wire2; |
|
altpll_component : altpll |
GENERIC MAP ( |
clk0_duty_cycle => 50, |
lpm_type => "altpll", |
clk0_multiply_by => 1, |
inclk0_input_frequency => 20000, |
clk0_divide_by => 2, |
pll_type => "FAST", |
intended_device_family => "Cyclone II", |
operation_mode => "NORMAL", |
compensate_clock => "CLK0", |
clk0_phase_shift => "0" |
) |
PORT MAP ( |
inclk => sub_wire3, |
clk => sub_wire0 |
); |
|
|
|
END SYN; |
|
-- ============================================================ |
-- CNX file retrieval info |
-- ============================================================ |
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" |
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" |
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" |
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" |
-- Retrieval info: PRIVATE: SPREAD_USE STRING "0" |
-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" |
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" |
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" |
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" |
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" |
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" |
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1" |
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" |
-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" |
-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" |
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" |
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" |
-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" |
-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0" |
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "6" |
-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" |
-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0" |
-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" |
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" |
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" |
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1" |
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" |
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0" |
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" |
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" |
-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" |
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" |
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" |
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" |
-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" |
-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" |
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" |
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" |
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" |
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0" |
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" |
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" |
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" |
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" |
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" |
-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" |
-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" |
-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" |
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "500.000" |
-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" |
-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" |
-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0" |
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000" |
-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" |
-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" |
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.000" |
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" |
-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" |
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" |
-- Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone II" |
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" |
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" |
-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" |
-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1" |
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" |
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" |
-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" |
-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" |
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" |
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all |
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" |
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" |
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1" |
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000" |
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "2" |
-- Retrieval info: CONSTANT: PLL_TYPE STRING "FAST" |
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II" |
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" |
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" |
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" |
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0" |
-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]" |
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0" |
-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]" |
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT VCC "@inclk[1..0]" |
-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 |
-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 |
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 |
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.vhd TRUE FALSE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.inc FALSE FALSE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.cmp TRUE FALSE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.bsf FALSE FALSE |
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL_inst.vhd TRUE FALSE |