1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-28 12:38:43 +00:00

First tests with zx spectrum core

This commit is contained in:
harbaum
2014-07-24 18:32:33 +00:00
parent 651dff2928
commit be79813325
22 changed files with 9021 additions and 0 deletions

1094
cores/spectrum/T80/T80.vhd Executable file

File diff suppressed because it is too large Load Diff

371
cores/spectrum/T80/T80_ALU.vhd Executable file
View File

@@ -0,0 +1,371 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- 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);
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
process (Carry_v, Carry7_v, Q_v)
begin
if(Mode=2) then
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
OverFlow_v <= Carry_v xor Carry7_v;
end if;
end process;
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;

2028
cores/spectrum/T80/T80_MCode.vhd Executable file

File diff suppressed because it is too large Load Diff

220
cores/spectrum/T80/T80_Pack.vhd Executable file
View File

@@ -0,0 +1,220 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- 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;
XY_State : in std_logic_vector(1 downto 0);
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;
XYbit_undoc : 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;

114
cores/spectrum/T80/T80_Reg.vhd Executable file
View File

@@ -0,0 +1,114 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- 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;

192
cores/spectrum/T80/T80se.vhd Executable file
View File

@@ -0,0 +1,192 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- 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 : 0240
--
-- 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;

View File

@@ -0,0 +1,583 @@
--
-- A simulation model of YM2149 (AY-3-8910 with bells on)
-- Copyright (c) MikeJ - Jan 2005
--
-- 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 CODE 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.
--
-- You are responsible for any legal issues arising from your use of this code.
--
-- The latest version of this file can be found at: www.fpgaarcade.com
--
-- Email support@fpgaarcade.com
--
-- Revision list
--
-- version 001 initial release
--
-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
--
-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
-- vol 15 .. 0
-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
-- to produced all the required values.
-- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
--
-- NOTE, this component uses a volume table for accurate mixing of the three analogue channels,
-- where the outputs are wired together - like in the Atari ST
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity YM2149 is
port (
-- data bus
I_DA : in std_logic_vector(7 downto 0);
O_DA : out std_logic_vector(7 downto 0);
O_DA_OE_L : out std_logic;
-- control
I_A9_L : in std_logic;
I_A8 : in std_logic;
I_BDIR : in std_logic;
I_BC2 : in std_logic;
I_BC1 : in std_logic;
I_SEL_L : in std_logic;
O_AUDIO : out std_logic_vector(7 downto 0);
-- port a
I_IOA : in std_logic_vector(7 downto 0);
O_IOA : out std_logic_vector(7 downto 0);
O_IOA_OE_L : out std_logic;
-- port b
I_IOB : in std_logic_vector(7 downto 0);
O_IOB : out std_logic_vector(7 downto 0);
O_IOB_OE_L : out std_logic;
--
ENA : in std_logic; -- clock enable for higher speed operation
RESET_L : in std_logic;
CLK : in std_logic -- note 6 Mhz
);
end;
architecture RTL of YM2149 is
component vol_table
port (
CLK : in std_logic;
ADDR : in std_logic_vector(11 downto 0);
DATA : out std_logic_vector(9 downto 0)
);
end component;
-- signals
type array_16x8 is array (0 to 15) of std_logic_vector(7 downto 0);
type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
signal noise_div : std_logic := '0';
signal ena_div : std_logic;
signal ena_div_noise : std_logic;
signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
-- registers
signal addr : std_logic_vector(7 downto 0);
signal busctrl_addr : std_logic;
signal busctrl_we : std_logic;
signal busctrl_re : std_logic;
signal reg : array_16x8;
signal env_reset : std_logic;
signal ioa_inreg : std_logic_vector(7 downto 0);
signal iob_inreg : std_logic_vector(7 downto 0);
signal noise_gen_cnt : std_logic_vector(4 downto 0);
signal noise_gen_op : std_logic;
signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
signal env_gen_cnt : std_logic_vector(15 downto 0);
signal env_ena : std_logic;
signal env_hold : std_logic;
signal env_inc : std_logic;
signal env_vol : std_logic_vector(4 downto 0);
signal vol_table_in : std_logic_vector(11 downto 0);
signal vol_table_out : std_logic_vector(9 downto 0);
begin
-- cpu i/f
p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
variable cs : std_logic;
variable sel : std_logic_vector(2 downto 0);
begin
-- BDIR BC2 BC1 MODE
-- 0 0 0 inactive
-- 0 0 1 address
-- 0 1 0 inactive
-- 0 1 1 read
-- 1 0 0 address
-- 1 0 1 inactive
-- 1 1 0 write
-- 1 1 1 read
busctrl_addr <= '0';
busctrl_we <= '0';
busctrl_re <= '0';
cs := '0';
if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
cs := '1';
end if;
sel := (I_BDIR & I_BC2 & I_BC1);
case sel is
when "000" => null;
when "001" => busctrl_addr <= '1';
when "010" => null;
when "011" => busctrl_re <= cs;
when "100" => busctrl_addr <= '1';
when "101" => null;
when "110" => busctrl_we <= cs;
when "111" => busctrl_addr <= '1';
when others => null;
end case;
end process;
p_oe : process(busctrl_re)
begin
-- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
O_DA_OE_L <= not (busctrl_re);
end process;
-- CLOCKED
--p_waddr : process
--begin
---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
--wait until rising_edge(CLK);
--if (RESET_L = '0') then
--addr <= (others => '0');
--else
--if (busctrl_addr = '1') then
--addr <= I_DA;
--end if;
--end if;
--end process;
--p_wdata : process
--begin
---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
--wait until rising_edge(CLK);
--env_reset <= '0';
--if (RESET_L = '0') then
--reg <= (others => (others => '0'));
--env_reset <= '1';
--else
--env_reset <= '0';
--if (busctrl_we = '1') then
--case addr(3 downto 0) is
--when x"0" => reg(0) <= I_DA;
--when x"1" => reg(1) <= I_DA;
--when x"2" => reg(2) <= I_DA;
--when x"3" => reg(3) <= I_DA;
--when x"4" => reg(4) <= I_DA;
--when x"5" => reg(5) <= I_DA;
--when x"6" => reg(6) <= I_DA;
--when x"7" => reg(7) <= I_DA;
--when x"8" => reg(8) <= I_DA;
--when x"9" => reg(9) <= I_DA;
--when x"A" => reg(10) <= I_DA;
--when x"B" => reg(11) <= I_DA;
--when x"C" => reg(12) <= I_DA;
--when x"D" => reg(13) <= I_DA; env_reset <= '1';
--when x"E" => reg(14) <= I_DA;
--when x"F" => reg(15) <= I_DA;
--when others => null;
--end case;
--end if;
--end if;
--end process;
-- LATCHED, useful when emulating a real chip in circuit. Nasty as gated clock.
p_waddr : process(reset_l, busctrl_addr)
begin
-- looks like registers are latches in real chip, but the address is caught at the end of the address state.
if (RESET_L = '0') then
addr <= (others => '0');
elsif falling_edge(busctrl_addr) then -- yuk
addr <= I_DA;
end if;
end process;
p_wdata : process(reset_l, busctrl_we, addr)
begin
if (RESET_L = '0') then
reg <= (others => (others => '0'));
elsif falling_edge(busctrl_we) then
case addr(3 downto 0) is
when x"0" => reg(0) <= I_DA;
when x"1" => reg(1) <= I_DA;
when x"2" => reg(2) <= I_DA;
when x"3" => reg(3) <= I_DA;
when x"4" => reg(4) <= I_DA;
when x"5" => reg(5) <= I_DA;
when x"6" => reg(6) <= I_DA;
when x"7" => reg(7) <= I_DA;
when x"8" => reg(8) <= I_DA;
when x"9" => reg(9) <= I_DA;
when x"A" => reg(10) <= I_DA;
when x"B" => reg(11) <= I_DA;
when x"C" => reg(12) <= I_DA;
when x"D" => reg(13) <= I_DA;
when x"E" => reg(14) <= I_DA;
when x"F" => reg(15) <= I_DA;
when others => null;
end case;
end if;
env_reset <= '0';
if (busctrl_we = '1') and (addr(3 downto 0) = x"D") then
env_reset <= '1';
end if;
end process;
p_rdata : process(busctrl_re, addr, reg)
begin
O_DA <= (others => '0'); -- 'X'
if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
case addr(3 downto 0) is
when x"0" => O_DA <= reg(0) ;
when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
when x"2" => O_DA <= reg(2) ;
when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
when x"4" => O_DA <= reg(4) ;
when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
when x"7" => O_DA <= reg(7) ;
when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
when x"B" => O_DA <= reg(11);
when x"C" => O_DA <= reg(12);
when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
when x"E" => if (reg(7)(6) = '0') then -- input
O_DA <= ioa_inreg;
else
O_DA <= reg(14); -- read output reg
end if;
when x"F" => if (Reg(7)(7) = '0') then
O_DA <= iob_inreg;
else
O_DA <= reg(15);
end if;
when others => null;
end case;
end if;
end process;
--
p_divider : process
begin
wait until rising_edge(CLK);
-- / 8 when SEL is high and /16 when SEL is low
if (ENA = '1') then
ena_div <= '0';
ena_div_noise <= '0';
if (cnt_div = "0000") then
cnt_div <= (not I_SEL_L) & "111";
ena_div <= '1';
noise_div <= not noise_div;
if (noise_div = '1') then
ena_div_noise <= '1';
end if;
else
cnt_div <= cnt_div - "1";
end if;
end if;
end process;
p_noise_gen : process
variable noise_gen_comp : std_logic_vector(4 downto 0);
variable poly17_zero : std_logic;
begin
wait until rising_edge(CLK);
if (reg(6)(4 downto 0) = "00000") then
noise_gen_comp := "00000";
else
noise_gen_comp := (reg(6)(4 downto 0) - "1");
end if;
poly17_zero := '0';
if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
if (ENA = '1') then
if (ena_div_noise = '1') then -- divider ena
if (noise_gen_cnt >= noise_gen_comp) then
noise_gen_cnt <= "00000";
poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
else
noise_gen_cnt <= (noise_gen_cnt + "1");
end if;
end if;
end if;
end process;
noise_gen_op <= poly17(0);
p_tone_gens : process
variable tone_gen_freq : array_3x12;
variable tone_gen_comp : array_3x12;
begin
wait until rising_edge(CLK);
-- looks like real chips count up - we need to get the Exact behaviour ..
tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
-- period 0 = period 1
for i in 1 to 3 loop
if (tone_gen_freq(i) = x"000") then
tone_gen_comp(i) := x"000";
else
tone_gen_comp(i) := (tone_gen_freq(i) - "1");
end if;
end loop;
if (ENA = '1') then
for i in 1 to 3 loop
if (ena_div = '1') then -- divider ena
if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
tone_gen_cnt(i) <= x"000";
tone_gen_op(i) <= not tone_gen_op(i);
else
tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
end if;
end if;
end loop;
end if;
end process;
p_envelope_freq : process
variable env_gen_freq : std_logic_vector(15 downto 0);
variable env_gen_comp : std_logic_vector(15 downto 0);
begin
wait until rising_edge(CLK);
env_gen_freq := reg(12) & reg(11);
-- envelope freqs 1 and 0 are the same.
if (env_gen_freq = x"0000") then
env_gen_comp := x"0000";
else
env_gen_comp := (env_gen_freq - "1");
end if;
if (ENA = '1') then
env_ena <= '0';
if (ena_div = '1') then -- divider ena
if (env_gen_cnt >= env_gen_comp) then
env_gen_cnt <= x"0000";
env_ena <= '1';
else
env_gen_cnt <= (env_gen_cnt + "1");
end if;
end if;
end if;
end process;
p_envelope_shape : process(env_reset, CLK)
variable is_bot : boolean;
variable is_bot_p1 : boolean;
variable is_top_m1 : boolean;
variable is_top : boolean;
begin
-- envelope shapes
-- C AtAlH
-- 0 0 x x \___
--
-- 0 1 x x /___
--
-- 1 0 0 0 \\\\
--
-- 1 0 0 1 \___
--
-- 1 0 1 0 \/\/
-- ___
-- 1 0 1 1 \
--
-- 1 1 0 0 ////
-- ___
-- 1 1 0 1 /
--
-- 1 1 1 0 /\/\
--
-- 1 1 1 1 /___
if (env_reset = '1') then
-- load initial state
if (reg(13)(2) = '0') then -- attack
env_vol <= "11111";
env_inc <= '0'; -- -1
else
env_vol <= "00000";
env_inc <= '1'; -- +1
end if;
env_hold <= '0';
elsif rising_edge(CLK) then
is_bot := (env_vol = "00000");
is_bot_p1 := (env_vol = "00001");
is_top_m1 := (env_vol = "11110");
is_top := (env_vol = "11111");
if (ENA = '1') then
if (env_ena = '1') then
if (env_hold = '0') then
if (env_inc = '1') then
env_vol <= (env_vol + "00001");
else
env_vol <= (env_vol + "11111");
end if;
end if;
-- envelope shape control.
if (reg(13)(3) = '0') then
if (env_inc = '0') then -- down
if is_bot_p1 then env_hold <= '1'; end if;
else
if is_top then env_hold <= '1'; end if;
end if;
else
if (reg(13)(0) = '1') then -- hold = 1
if (env_inc = '0') then -- down
if (reg(13)(1) = '1') then -- alt
if is_bot then env_hold <= '1'; end if;
else
if is_bot_p1 then env_hold <= '1'; end if;
end if;
else
if (reg(13)(1) = '1') then -- alt
if is_top then env_hold <= '1'; end if;
else
if is_top_m1 then env_hold <= '1'; end if;
end if;
end if;
elsif (reg(13)(1) = '1') then -- alternate
if (env_inc = '0') then -- down
if is_bot_p1 then env_hold <= '1'; end if;
if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
else
if is_top_m1 then env_hold <= '1'; end if;
if is_top then env_hold <= '0'; env_inc <= '0'; end if;
end if;
end if;
end if;
end if;
end if;
end if;
end process;
p_chan_mixer_table : process
variable chan_mixed : std_logic_vector(2 downto 0);
begin
wait until rising_edge(CLK);
if (ENA = '1') then
chan_mixed(0) := (reg(7)(0) or tone_gen_op(1)) and (reg(7)(3) or noise_gen_op);
chan_mixed(1) := (reg(7)(1) or tone_gen_op(2)) and (reg(7)(4) or noise_gen_op);
chan_mixed(2) := (reg(7)(2) or tone_gen_op(3)) and (reg(7)(5) or noise_gen_op);
vol_table_in <= x"000";
if (chan_mixed(0) = '1') then
if (reg(8)(4) = '0') then
vol_table_in(3 downto 0) <= reg(8)(3 downto 0);
else
vol_table_in(3 downto 0) <= env_vol(4 downto 1);
end if;
end if;
if (chan_mixed(1) = '1') then
if (reg(9)(4) = '0') then
vol_table_in(7 downto 4) <= reg(9)(3 downto 0);
else
vol_table_in(7 downto 4) <= env_vol(4 downto 1);
end if;
end if;
if (chan_mixed(2) = '1') then
if (reg(10)(4) = '0') then
vol_table_in(11 downto 8) <= reg(10)(3 downto 0);
else
vol_table_in(11 downto 8) <= env_vol(4 downto 1);
end if;
end if;
end if;
end process;
u_vol_table : vol_table
port map (
CLK => clk,
ADDR => vol_table_in,
DATA => vol_table_out
);
p_op_mixer : process
variable chan_mixed : std_logic;
variable chan_amp : std_logic_vector(4 downto 0);
begin
wait until rising_edge(CLK);
if (RESET_L = '0') then
O_AUDIO(7 downto 0) <= "00000000";
else
O_AUDIO(7 downto 0) <= vol_table_out(9 downto 2);
end if;
end process;
p_io_ports : process(reg)
begin
-- input low
O_IOA <= reg(14);
O_IOA_OE_L <= not reg(7)(6);
O_IOB <= reg(15);
O_IOB_OE_L <= not reg(7)(7);
end process;
p_io_ports_inreg : process
begin
wait until rising_edge(CLK);
ioa_inreg <= I_IOA;
iob_inreg <= I_IOB;
end process;
end architecture RTL;

View File

@@ -0,0 +1,540 @@
-- generated with tablegen by MikeJ
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity vol_table is
port (
CLK : in std_logic;
ADDR : in std_logic_vector(11 downto 0);
DATA : out std_logic_vector(9 downto 0)
);
end;
architecture RTL of vol_table is
type ROM_ARRAY is array(0 to 4095) of std_logic_vector(11 downto 0);
constant ROM : ROM_ARRAY := (
x"000",x"002",x"004",x"006",x"009",x"00D",x"014",x"01B", -- 0x0000
x"027",x"036",x"050",x"06D",x"0A5",x"0EB",x"17D",x"24D", -- 0x0008
x"002",x"005",x"007",x"009",x"00D",x"010",x"016",x"01D", -- 0x0010
x"02A",x"038",x"051",x"06F",x"0A7",x"0ED",x"17E",x"24D", -- 0x0018
x"004",x"007",x"009",x"00B",x"00E",x"012",x"018",x"020", -- 0x0020
x"02B",x"03A",x"054",x"071",x"0A9",x"0EF",x"17E",x"24D", -- 0x0028
x"006",x"009",x"00B",x"00D",x"011",x"014",x"01A",x"021", -- 0x0030
x"02E",x"03C",x"055",x"073",x"0AB",x"0F0",x"17F",x"24D", -- 0x0038
x"009",x"00D",x"00E",x"011",x"014",x"018",x"01D",x"024", -- 0x0040
x"031",x"03F",x"058",x"076",x"0AD",x"0F3",x"180",x"24D", -- 0x0048
x"00D",x"010",x"012",x"014",x"018",x"01B",x"021",x"028", -- 0x0050
x"035",x"042",x"05C",x"079",x"0B0",x"0F5",x"182",x"24D", -- 0x0058
x"014",x"016",x"018",x"01A",x"01D",x"021",x"027",x"02F", -- 0x0060
x"03A",x"049",x"062",x"07E",x"0B5",x"0FA",x"184",x"24D", -- 0x0068
x"01B",x"01D",x"020",x"021",x"024",x"028",x"02F",x"035", -- 0x0070
x"042",x"050",x"068",x"085",x"0BB",x"0FE",x"188",x"24D", -- 0x0078
x"027",x"02A",x"02B",x"02E",x"031",x"035",x"03A",x"042", -- 0x0080
x"04D",x"05C",x"073",x"091",x"0C5",x"108",x"18E",x"24D", -- 0x0088
x"036",x"038",x"03A",x"03C",x"03F",x"042",x"049",x"050", -- 0x0090
x"05C",x"06A",x"082",x"09D",x"0D2",x"114",x"19A",x"24D", -- 0x0098
x"050",x"051",x"054",x"055",x"058",x"05C",x"062",x"068", -- 0x00A0
x"073",x"082",x"098",x"0B4",x"0E7",x"128",x"1AB",x"254", -- 0x00A8
x"06D",x"06F",x"071",x"073",x"076",x"079",x"07E",x"085", -- 0x00B0
x"091",x"09D",x"0B4",x"0D0",x"102",x"142",x"1C1",x"264", -- 0x00B8
x"0A5",x"0A7",x"0A9",x"0AB",x"0AD",x"0B0",x"0B5",x"0BB", -- 0x00C0
x"0C5",x"0D2",x"0E7",x"102",x"133",x"172",x"1ED",x"27C", -- 0x00C8
x"0EB",x"0ED",x"0EF",x"0F0",x"0F3",x"0F5",x"0FA",x"0FE", -- 0x00D0
x"108",x"114",x"128",x"142",x"172",x"1AF",x"21D",x"2AB", -- 0x00D8
x"17D",x"17E",x"17E",x"17F",x"180",x"182",x"184",x"188", -- 0x00E0
x"18E",x"19A",x"1AB",x"1C1",x"1ED",x"21D",x"284",x"30A", -- 0x00E8
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x00F0
x"24D",x"24D",x"254",x"264",x"27C",x"2AB",x"30A",x"379", -- 0x00F8
x"002",x"005",x"006",x"009",x"00C",x"010",x"016",x"01D", -- 0x0100
x"02A",x"038",x"052",x"06F",x"0A7",x"0ED",x"17E",x"24E", -- 0x0108
x"005",x"007",x"009",x"00B",x"00F",x"012",x"018",x"01F", -- 0x0110
x"02C",x"03A",x"053",x"071",x"0A9",x"0EF",x"17F",x"24E", -- 0x0118
x"006",x"009",x"00B",x"00D",x"011",x"014",x"01B",x"022", -- 0x0120
x"02E",x"03D",x"056",x"073",x"0AB",x"0F0",x"180",x"24E", -- 0x0128
x"009",x"00B",x"00D",x"010",x"013",x"016",x"01C",x"023", -- 0x0130
x"030",x"03E",x"057",x"075",x"0AD",x"0F2",x"181",x"24E", -- 0x0138
x"00C",x"00F",x"011",x"013",x"016",x"01A",x"01F",x"027", -- 0x0140
x"033",x"041",x"05B",x"078",x"0AF",x"0F4",x"181",x"24E", -- 0x0148
x"010",x"012",x"014",x"016",x"01A",x"01D",x"023",x"02A", -- 0x0150
x"037",x"044",x"05E",x"07B",x"0B2",x"0F7",x"183",x"24E", -- 0x0158
x"016",x"018",x"01B",x"01C",x"01F",x"023",x"02A",x"031", -- 0x0160
x"03D",x"04B",x"064",x"080",x"0B7",x"0FB",x"185",x"24E", -- 0x0168
x"01D",x"01F",x"022",x"023",x"027",x"02A",x"031",x"037", -- 0x0170
x"044",x"052",x"06A",x"087",x"0BD",x"100",x"189",x"24E", -- 0x0178
x"02A",x"02C",x"02E",x"030",x"033",x"037",x"03D",x"044", -- 0x0180
x"04F",x"05E",x"075",x"092",x"0C7",x"10A",x"190",x"24E", -- 0x0188
x"038",x"03A",x"03D",x"03E",x"041",x"044",x"04B",x"052", -- 0x0190
x"05E",x"06C",x"083",x"09F",x"0D4",x"115",x"19B",x"24E", -- 0x0198
x"052",x"053",x"056",x"057",x"05B",x"05E",x"064",x"06A", -- 0x01A0
x"075",x"083",x"09A",x"0B6",x"0E9",x"12A",x"1AD",x"256", -- 0x01A8
x"06F",x"071",x"073",x"075",x"078",x"07B",x"080",x"087", -- 0x01B0
x"092",x"09F",x"0B6",x"0D1",x"104",x"143",x"1C2",x"265", -- 0x01B8
x"0A7",x"0A9",x"0AB",x"0AD",x"0AF",x"0B2",x"0B7",x"0BD", -- 0x01C0
x"0C7",x"0D4",x"0E9",x"104",x"135",x"174",x"1EE",x"27D", -- 0x01C8
x"0ED",x"0EF",x"0F0",x"0F2",x"0F4",x"0F7",x"0FB",x"100", -- 0x01D0
x"10A",x"115",x"12A",x"143",x"174",x"1B0",x"21E",x"2AC", -- 0x01D8
x"17E",x"17F",x"180",x"181",x"181",x"183",x"185",x"189", -- 0x01E0
x"190",x"19B",x"1AD",x"1C2",x"1EE",x"21E",x"285",x"30B", -- 0x01E8
x"24E",x"24E",x"24E",x"24E",x"24E",x"24E",x"24E",x"24E", -- 0x01F0
x"24E",x"24E",x"256",x"265",x"27D",x"2AC",x"30B",x"379", -- 0x01F8
x"004",x"006",x"008",x"00A",x"00D",x"011",x"018",x"01F", -- 0x0200
x"02B",x"039",x"053",x"070",x"0A8",x"0EE",x"17F",x"24F", -- 0x0208
x"006",x"009",x"00B",x"00D",x"011",x"014",x"01A",x"021", -- 0x0210
x"02E",x"03C",x"055",x"073",x"0AB",x"0F0",x"180",x"24F", -- 0x0218
x"008",x"00B",x"00D",x"00F",x"012",x"016",x"01C",x"023", -- 0x0220
x"02F",x"03E",x"057",x"074",x"0AC",x"0F2",x"181",x"24F", -- 0x0228
x"00A",x"00D",x"00F",x"011",x"014",x"018",x"01E",x"025", -- 0x0230
x"031",x"040",x"059",x"077",x"0AE",x"0F3",x"182",x"24F", -- 0x0238
x"00D",x"011",x"012",x"014",x"018",x"01B",x"021",x"028", -- 0x0240
x"035",x"043",x"05C",x"079",x"0B0",x"0F5",x"183",x"24F", -- 0x0248
x"011",x"014",x"016",x"018",x"01B",x"01F",x"025",x"02C", -- 0x0250
x"039",x"046",x"05F",x"07C",x"0B3",x"0F8",x"184",x"24F", -- 0x0258
x"018",x"01A",x"01C",x"01E",x"021",x"025",x"02B",x"032", -- 0x0260
x"03E",x"04C",x"065",x"082",x"0B8",x"0FD",x"186",x"24F", -- 0x0268
x"01F",x"021",x"023",x"025",x"028",x"02C",x"032",x"039", -- 0x0270
x"045",x"053",x"06C",x"088",x"0BE",x"101",x"18A",x"24F", -- 0x0278
x"02B",x"02E",x"02F",x"031",x"035",x"039",x"03E",x"045", -- 0x0280
x"051",x"05F",x"077",x"094",x"0C8",x"10B",x"191",x"24F", -- 0x0288
x"039",x"03C",x"03E",x"040",x"043",x"046",x"04C",x"053", -- 0x0290
x"05F",x"06D",x"085",x"0A0",x"0D5",x"116",x"19C",x"24F", -- 0x0298
x"053",x"055",x"057",x"059",x"05C",x"05F",x"065",x"06C", -- 0x02A0
x"077",x"085",x"09B",x"0B7",x"0EA",x"12B",x"1AE",x"256", -- 0x02A8
x"070",x"073",x"074",x"077",x"079",x"07C",x"082",x"088", -- 0x02B0
x"094",x"0A0",x"0B7",x"0D3",x"105",x"144",x"1C3",x"266", -- 0x02B8
x"0A8",x"0AB",x"0AC",x"0AE",x"0B0",x"0B3",x"0B8",x"0BE", -- 0x02C0
x"0C8",x"0D5",x"0EA",x"105",x"136",x"175",x"1EF",x"27E", -- 0x02C8
x"0EE",x"0F0",x"0F2",x"0F3",x"0F5",x"0F8",x"0FC",x"101", -- 0x02D0
x"10B",x"116",x"12B",x"144",x"175",x"1B1",x"21F",x"2AD", -- 0x02D8
x"17F",x"180",x"181",x"182",x"183",x"184",x"186",x"18A", -- 0x02E0
x"191",x"19C",x"1AE",x"1C3",x"1EF",x"21F",x"285",x"30B", -- 0x02E8
x"24E",x"24E",x"24E",x"24E",x"24E",x"24E",x"24E",x"24E", -- 0x02F0
x"24E",x"24E",x"256",x"266",x"27E",x"2AD",x"30B",x"37A", -- 0x02F8
x"006",x"009",x"00A",x"00D",x"010",x"014",x"01A",x"021", -- 0x0300
x"02D",x"03B",x"055",x"072",x"0AA",x"0F0",x"181",x"250", -- 0x0308
x"009",x"00B",x"00D",x"00F",x"013",x"016",x"01C",x"023", -- 0x0310
x"030",x"03E",x"057",x"075",x"0AD",x"0F2",x"182",x"250", -- 0x0318
x"00A",x"00D",x"00F",x"011",x"014",x"018",x"01F",x"026", -- 0x0320
x"031",x"040",x"059",x"076",x"0AE",x"0F3",x"183",x"250", -- 0x0328
x"00D",x"00F",x"011",x"014",x"017",x"01A",x"020",x"027", -- 0x0330
x"034",x"042",x"05B",x"079",x"0B0",x"0F5",x"183",x"250", -- 0x0338
x"010",x"013",x"014",x"017",x"01A",x"01E",x"023",x"02A", -- 0x0340
x"037",x"045",x"05E",x"07B",x"0B2",x"0F7",x"184",x"250", -- 0x0348
x"014",x"016",x"018",x"01A",x"01E",x"021",x"027",x"02E", -- 0x0350
x"03B",x"048",x"061",x"07E",x"0B5",x"0FA",x"186",x"250", -- 0x0358
x"01A",x"01C",x"01F",x"020",x"023",x"027",x"02D",x"034", -- 0x0360
x"040",x"04E",x"067",x"084",x"0BA",x"0FE",x"188",x"250", -- 0x0368
x"021",x"023",x"026",x"027",x"02A",x"02E",x"034",x"03B", -- 0x0370
x"047",x"055",x"06E",x"08A",x"0C0",x"103",x"18C",x"250", -- 0x0378
x"02D",x"030",x"031",x"034",x"037",x"03B",x"040",x"047", -- 0x0380
x"053",x"061",x"079",x"096",x"0CA",x"10C",x"192",x"250", -- 0x0388
x"03B",x"03E",x"040",x"042",x"045",x"048",x"04E",x"055", -- 0x0390
x"061",x"06F",x"087",x"0A2",x"0D7",x"118",x"19E",x"250", -- 0x0398
x"055",x"057",x"059",x"05B",x"05E",x"061",x"067",x"06E", -- 0x03A0
x"079",x"087",x"09D",x"0B9",x"0EC",x"12C",x"1AF",x"258", -- 0x03A8
x"072",x"075",x"076",x"079",x"07B",x"07E",x"084",x"08A", -- 0x03B0
x"096",x"0A2",x"0B9",x"0D4",x"106",x"145",x"1C4",x"267", -- 0x03B8
x"0AA",x"0AD",x"0AE",x"0B0",x"0B2",x"0B5",x"0BA",x"0C0", -- 0x03C0
x"0CA",x"0D7",x"0EC",x"106",x"137",x"176",x"1F0",x"27F", -- 0x03C8
x"0F0",x"0F2",x"0F3",x"0F5",x"0F7",x"0FA",x"0FE",x"103", -- 0x03D0
x"10C",x"118",x"12C",x"145",x"176",x"1B2",x"220",x"2AE", -- 0x03D8
x"181",x"182",x"183",x"183",x"184",x"186",x"188",x"18C", -- 0x03E0
x"192",x"19E",x"1AF",x"1C4",x"1F0",x"220",x"286",x"30C", -- 0x03E8
x"250",x"250",x"250",x"250",x"250",x"250",x"250",x"250", -- 0x03F0
x"250",x"250",x"257",x"267",x"27F",x"2AE",x"30C",x"37A", -- 0x03F8
x"009",x"00C",x"00D",x"010",x"013",x"017",x"01D",x"024", -- 0x0400
x"030",x"03E",x"058",x"075",x"0AD",x"0F3",x"183",x"251", -- 0x0408
x"00C",x"00E",x"010",x"012",x"016",x"019",x"01F",x"026", -- 0x0410
x"033",x"041",x"05A",x"077",x"0AF",x"0F4",x"184",x"251", -- 0x0418
x"00D",x"010",x"012",x"014",x"017",x"01B",x"022",x"029", -- 0x0420
x"034",x"043",x"05C",x"079",x"0B1",x"0F6",x"185",x"251", -- 0x0428
x"010",x"012",x"014",x"017",x"01A",x"01D",x"023",x"02A", -- 0x0430
x"037",x"045",x"05E",x"07B",x"0B2",x"0F7",x"185",x"251", -- 0x0438
x"013",x"016",x"017",x"01A",x"01D",x"021",x"026",x"02D", -- 0x0440
x"03A",x"048",x"061",x"07E",x"0B4",x"0FA",x"186",x"251", -- 0x0448
x"017",x"019",x"01B",x"01D",x"021",x"024",x"02A",x"031", -- 0x0450
x"03E",x"04B",x"064",x"081",x"0B8",x"0FC",x"188",x"251", -- 0x0458
x"01D",x"01F",x"022",x"023",x"026",x"02A",x"030",x"037", -- 0x0460
x"043",x"051",x"06A",x"086",x"0BC",x"101",x"18A",x"251", -- 0x0468
x"024",x"026",x"029",x"02A",x"02D",x"031",x"037",x"03E", -- 0x0470
x"04A",x"058",x"070",x"08C",x"0C2",x"105",x"18E",x"251", -- 0x0478
x"030",x"033",x"034",x"037",x"03A",x"03E",x"043",x"04A", -- 0x0480
x"056",x"064",x"07B",x"098",x"0CD",x"10F",x"194",x"251", -- 0x0488
x"03E",x"041",x"043",x"045",x"048",x"04B",x"051",x"058", -- 0x0490
x"064",x"072",x"089",x"0A4",x"0D9",x"11A",x"1A0",x"251", -- 0x0498
x"058",x"05A",x"05C",x"05E",x"061",x"064",x"06A",x"070", -- 0x04A0
x"07B",x"089",x"0A0",x"0BB",x"0EE",x"12E",x"1B1",x"259", -- 0x04A8
x"075",x"077",x"079",x"07B",x"07E",x"081",x"086",x"08C", -- 0x04B0
x"098",x"0A4",x"0BB",x"0D6",x"109",x"147",x"1C6",x"269", -- 0x04B8
x"0AD",x"0AF",x"0B1",x"0B2",x"0B4",x"0B8",x"0BC",x"0C2", -- 0x04C0
x"0CD",x"0D9",x"0EE",x"109",x"139",x"178",x"1F2",x"280", -- 0x04C8
x"0F3",x"0F4",x"0F6",x"0F7",x"0FA",x"0FC",x"101",x"105", -- 0x04D0
x"10E",x"11A",x"12E",x"147",x"178",x"1B3",x"221",x"2AF", -- 0x04D8
x"183",x"184",x"185",x"185",x"186",x"188",x"18A",x"18E", -- 0x04E0
x"194",x"1A0",x"1B1",x"1C6",x"1F1",x"221",x"287",x"30D", -- 0x04E8
x"251",x"251",x"251",x"251",x"251",x"251",x"251",x"251", -- 0x04F0
x"251",x"251",x"259",x"269",x"280",x"2AF",x"30D",x"37B", -- 0x04F8
x"00D",x"010",x"011",x"014",x"017",x"01B",x"021",x"028", -- 0x0500
x"034",x"042",x"05C",x"078",x"0B0",x"0F6",x"186",x"254", -- 0x0508
x"010",x"012",x"014",x"016",x"01A",x"01D",x"023",x"02A", -- 0x0510
x"036",x"044",x"05D",x"07B",x"0B2",x"0F7",x"187",x"254", -- 0x0518
x"011",x"014",x"016",x"018",x"01B",x"01F",x"025",x"02C", -- 0x0520
x"038",x"047",x"05F",x"07C",x"0B4",x"0F9",x"187",x"254", -- 0x0528
x"014",x"016",x"018",x"01B",x"01E",x"021",x"027",x"02E", -- 0x0530
x"03A",x"048",x"061",x"07F",x"0B5",x"0FA",x"188",x"254", -- 0x0538
x"017",x"01A",x"01B",x"01E",x"021",x"025",x"02A",x"031", -- 0x0540
x"03D",x"04B",x"064",x"081",x"0B8",x"0FD",x"189",x"254", -- 0x0548
x"01B",x"01D",x"01F",x"021",x"025",x"028",x"02E",x"035", -- 0x0550
x"041",x"04E",x"067",x"084",x"0BB",x"0FF",x"18A",x"254", -- 0x0558
x"021",x"023",x"025",x"027",x"02A",x"02E",x"034",x"03B", -- 0x0560
x"047",x"055",x"06D",x"089",x"0BF",x"104",x"18D",x"254", -- 0x0568
x"028",x"02A",x"02C",x"02E",x"031",x"035",x"03B",x"041", -- 0x0570
x"04E",x"05B",x"074",x"090",x"0C6",x"108",x"191",x"254", -- 0x0578
x"034",x"036",x"038",x"03A",x"03D",x"041",x"047",x"04E", -- 0x0580
x"059",x"067",x"07E",x"09B",x"0D0",x"112",x"197",x"254", -- 0x0588
x"042",x"044",x"047",x"048",x"04B",x"04E",x"055",x"05B", -- 0x0590
x"067",x"075",x"08C",x"0A8",x"0DC",x"11D",x"1A2",x"254", -- 0x0598
x"05C",x"05D",x"05F",x"061",x"064",x"067",x"06D",x"074", -- 0x05A0
x"07E",x"08C",x"0A3",x"0BE",x"0F1",x"131",x"1B3",x"25B", -- 0x05A8
x"078",x"07B",x"07C",x"07F",x"081",x"084",x"089",x"090", -- 0x05B0
x"09B",x"0A8",x"0BE",x"0D9",x"10B",x"14A",x"1C8",x"26B", -- 0x05B8
x"0B0",x"0B2",x"0B4",x"0B5",x"0B8",x"0BB",x"0BF",x"0C6", -- 0x05C0
x"0D0",x"0DC",x"0F1",x"10B",x"13C",x"17A",x"1F4",x"282", -- 0x05C8
x"0F6",x"0F7",x"0F9",x"0FA",x"0FD",x"0FF",x"103",x"108", -- 0x05D0
x"111",x"11D",x"131",x"14A",x"17A",x"1B6",x"223",x"2B0", -- 0x05D8
x"186",x"187",x"187",x"188",x"189",x"18A",x"18D",x"191", -- 0x05E0
x"197",x"1A2",x"1B3",x"1C8",x"1F4",x"223",x"289",x"30E", -- 0x05E8
x"253",x"253",x"253",x"253",x"253",x"253",x"253",x"253", -- 0x05F0
x"253",x"253",x"25B",x"26B",x"282",x"2B0",x"30E",x"37C", -- 0x05F8
x"014",x"016",x"018",x"01A",x"01D",x"021",x"027",x"02E", -- 0x0600
x"03A",x"048",x"061",x"07E",x"0B5",x"0FA",x"18A",x"256", -- 0x0608
x"016",x"018",x"01B",x"01C",x"020",x"023",x"029",x"030", -- 0x0610
x"03C",x"04A",x"063",x"080",x"0B7",x"0FC",x"18B",x"256", -- 0x0618
x"018",x"01B",x"01C",x"01E",x"021",x"025",x"02B",x"032", -- 0x0620
x"03E",x"04C",x"065",x"081",x"0B9",x"0FD",x"18B",x"256", -- 0x0628
x"01A",x"01C",x"01E",x"021",x"024",x"027",x"02D",x"034", -- 0x0630
x"040",x"04E",x"066",x"084",x"0BA",x"0FF",x"18C",x"256", -- 0x0638
x"01D",x"020",x"021",x"024",x"027",x"02B",x"030",x"037", -- 0x0640
x"043",x"051",x"069",x"086",x"0BC",x"101",x"18D",x"256", -- 0x0648
x"021",x"023",x"025",x"027",x"02B",x"02E",x"034",x"03B", -- 0x0650
x"047",x"054",x"06D",x"089",x"0C0",x"104",x"18E",x"256", -- 0x0658
x"027",x"029",x"02B",x"02D",x"030",x"034",x"03A",x"041", -- 0x0660
x"04C",x"05A",x"073",x"08E",x"0C4",x"108",x"191",x"256", -- 0x0668
x"02E",x"030",x"032",x"034",x"037",x"03B",x"041",x"047", -- 0x0670
x"053",x"061",x"079",x"094",x"0CA",x"10D",x"194",x"256", -- 0x0678
x"03A",x"03C",x"03E",x"040",x"043",x"047",x"04C",x"053", -- 0x0680
x"05F",x"06C",x"083",x"0A0",x"0D4",x"116",x"19B",x"256", -- 0x0688
x"048",x"04A",x"04C",x"04E",x"051",x"054",x"05A",x"061", -- 0x0690
x"06C",x"07A",x"091",x"0AC",x"0E0",x"121",x"1A6",x"256", -- 0x0698
x"061",x"063",x"065",x"066",x"069",x"06D",x"073",x"079", -- 0x06A0
x"083",x"091",x"0A7",x"0C3",x"0F5",x"135",x"1B7",x"25E", -- 0x06A8
x"07E",x"080",x"081",x"084",x"086",x"089",x"08E",x"094", -- 0x06B0
x"0A0",x"0AC",x"0C3",x"0DE",x"10F",x"14E",x"1CB",x"26D", -- 0x06B8
x"0B5",x"0B7",x"0B9",x"0BA",x"0BC",x"0C0",x"0C4",x"0CA", -- 0x06C0
x"0D4",x"0E0",x"0F5",x"10F",x"13F",x"17E",x"1F6",x"284", -- 0x06C8
x"0FA",x"0FC",x"0FD",x"0FF",x"101",x"103",x"108",x"10C", -- 0x06D0
x"116",x"121",x"135",x"14E",x"17D",x"1B8",x"226",x"2B2", -- 0x06D8
x"18A",x"18B",x"18B",x"18C",x"18D",x"18E",x"191",x"194", -- 0x06E0
x"19B",x"1A6",x"1B7",x"1CB",x"1F6",x"226",x"28B",x"30F", -- 0x06E8
x"256",x"256",x"256",x"256",x"256",x"256",x"256",x"256", -- 0x06F0
x"256",x"256",x"25E",x"26D",x"284",x"2B2",x"30F",x"37D", -- 0x06F8
x"01B",x"01D",x"01F",x"021",x"024",x"028",x"02E",x"034", -- 0x0700
x"041",x"04E",x"067",x"084",x"0BB",x"100",x"18E",x"25A", -- 0x0708
x"01D",x"01F",x"022",x"023",x"027",x"02A",x"030",x"037", -- 0x0710
x"043",x"050",x"069",x"086",x"0BD",x"101",x"18F",x"25A", -- 0x0718
x"01F",x"022",x"023",x"025",x"028",x"02C",x"032",x"039", -- 0x0720
x"044",x"053",x"06B",x"087",x"0BE",x"103",x"190",x"25A", -- 0x0728
x"021",x"023",x"025",x"028",x"02B",x"02E",x"034",x"03B", -- 0x0730
x"047",x"054",x"06D",x"08A",x"0C0",x"104",x"191",x"25A", -- 0x0738
x"024",x"027",x"028",x"02B",x"02E",x"031",x"037",x"03E", -- 0x0740
x"04A",x"057",x"070",x"08C",x"0C2",x"107",x"191",x"25A", -- 0x0748
x"028",x"02A",x"02C",x"02E",x"031",x"034",x"03B",x"041", -- 0x0750
x"04D",x"05A",x"073",x"08F",x"0C5",x"109",x"193",x"25A", -- 0x0758
x"02E",x"030",x"032",x"034",x"037",x"03B",x"041",x"047", -- 0x0760
x"053",x"060",x"079",x"094",x"0CA",x"10D",x"195",x"25A", -- 0x0768
x"034",x"037",x"039",x"03B",x"03E",x"041",x"047",x"04D", -- 0x0770
x"059",x"067",x"07F",x"09A",x"0D0",x"112",x"199",x"25A", -- 0x0778
x"041",x"043",x"044",x"047",x"04A",x"04D",x"053",x"059", -- 0x0780
x"065",x"072",x"089",x"0A5",x"0D9",x"11B",x"19F",x"25A", -- 0x0788
x"04E",x"050",x"053",x"054",x"057",x"05A",x"060",x"067", -- 0x0790
x"072",x"080",x"097",x"0B2",x"0E6",x"126",x"1AA",x"25A", -- 0x0798
x"067",x"069",x"06B",x"06D",x"070",x"073",x"079",x"07F", -- 0x07A0
x"089",x"097",x"0AD",x"0C8",x"0FA",x"13A",x"1BB",x"262", -- 0x07A8
x"084",x"086",x"087",x"08A",x"08C",x"08F",x"094",x"09A", -- 0x07B0
x"0A5",x"0B2",x"0C8",x"0E3",x"114",x"152",x"1CF",x"271", -- 0x07B8
x"0BB",x"0BD",x"0BE",x"0C0",x"0C2",x"0C5",x"0CA",x"0D0", -- 0x07C0
x"0D9",x"0E6",x"0FA",x"114",x"144",x"182",x"1FA",x"287", -- 0x07C8
x"0FF",x"101",x"102",x"104",x"106",x"108",x"10D",x"112", -- 0x07D0
x"11B",x"126",x"13A",x"152",x"181",x"1BC",x"229",x"2B5", -- 0x07D8
x"18E",x"18F",x"190",x"191",x"191",x"193",x"195",x"199", -- 0x07E0
x"19F",x"1AA",x"1BB",x"1CF",x"1F9",x"229",x"28D",x"312", -- 0x07E8
x"25A",x"25A",x"25A",x"25A",x"25A",x"25A",x"25A",x"25A", -- 0x07F0
x"25A",x"25A",x"261",x"270",x"287",x"2B5",x"312",x"37F", -- 0x07F8
x"027",x"02A",x"02B",x"02D",x"030",x"034",x"03A",x"041", -- 0x0800
x"04C",x"05A",x"072",x"08E",x"0C5",x"109",x"197",x"261", -- 0x0808
x"02A",x"02C",x"02E",x"030",x"033",x"036",x"03C",x"043", -- 0x0810
x"04F",x"05C",x"074",x"090",x"0C7",x"10B",x"198",x"261", -- 0x0818
x"02B",x"02E",x"030",x"032",x"035",x"038",x"03E",x"045", -- 0x0820
x"050",x"05E",x"076",x"092",x"0C8",x"10C",x"198",x"261", -- 0x0828
x"02D",x"030",x"032",x"034",x"037",x"03A",x"040",x"046", -- 0x0830
x"052",x"060",x"078",x"094",x"0CA",x"10E",x"199",x"261", -- 0x0838
x"030",x"033",x"035",x"037",x"03A",x"03E",x"043",x"049", -- 0x0840
x"055",x"062",x"07B",x"096",x"0CC",x"110",x"19A",x"261", -- 0x0848
x"034",x"036",x"038",x"03A",x"03E",x"041",x"046",x"04D", -- 0x0850
x"059",x"065",x"07E",x"099",x"0CF",x"112",x"19B",x"261", -- 0x0858
x"03A",x"03C",x"03E",x"040",x"043",x"046",x"04C",x"053", -- 0x0860
x"05E",x"06B",x"083",x"09E",x"0D3",x"117",x"19E",x"261", -- 0x0868
x"041",x"043",x"045",x"046",x"049",x"04D",x"053",x"059", -- 0x0870
x"065",x"072",x"089",x"0A4",x"0D9",x"11B",x"1A1",x"261", -- 0x0878
x"04C",x"04F",x"050",x"052",x"055",x"059",x"05E",x"065", -- 0x0880
x"070",x"07D",x"094",x"0AF",x"0E3",x"124",x"1A7",x"261", -- 0x0888
x"05A",x"05C",x"05E",x"060",x"062",x"065",x"06B",x"072", -- 0x0890
x"07D",x"08A",x"0A1",x"0BB",x"0EF",x"12F",x"1B2",x"261", -- 0x0898
x"072",x"074",x"076",x"078",x"07B",x"07E",x"083",x"089", -- 0x08A0
x"094",x"0A1",x"0B6",x"0D1",x"103",x"142",x"1C2",x"268", -- 0x08A8
x"08E",x"090",x"092",x"094",x"096",x"099",x"09E",x"0A4", -- 0x08B0
x"0AF",x"0BB",x"0D1",x"0EB",x"11C",x"15A",x"1D6",x"277", -- 0x08B8
x"0C5",x"0C7",x"0C8",x"0CA",x"0CC",x"0CF",x"0D3",x"0D9", -- 0x08C0
x"0E3",x"0EF",x"103",x"11C",x"14B",x"189",x"200",x"28D", -- 0x08C8
x"109",x"10A",x"10C",x"10D",x"110",x"112",x"116",x"11B", -- 0x08D0
x"123",x"12F",x"142",x"15A",x"189",x"1C3",x"22F",x"2BA", -- 0x08D8
x"197",x"198",x"198",x"199",x"19A",x"19B",x"19E",x"1A1", -- 0x08E0
x"1A7",x"1B2",x"1C2",x"1D6",x"200",x"22F",x"292",x"315", -- 0x08E8
x"260",x"260",x"260",x"260",x"260",x"260",x"260",x"260", -- 0x08F0
x"260",x"260",x"268",x"276",x"28C",x"2BA",x"315",x"382", -- 0x08F8
x"036",x"038",x"039",x"03B",x"03E",x"042",x"048",x"04E", -- 0x0900
x"05A",x"067",x"07F",x"09A",x"0D0",x"114",x"1A1",x"268", -- 0x0908
x"038",x"03A",x"03C",x"03E",x"041",x"044",x"04A",x"050", -- 0x0910
x"05C",x"069",x"080",x"09C",x"0D2",x"116",x"1A1",x"268", -- 0x0918
x"039",x"03C",x"03E",x"040",x"043",x"046",x"04C",x"052", -- 0x0920
x"05D",x"06B",x"083",x"09E",x"0D4",x"117",x"1A2",x"268", -- 0x0928
x"03B",x"03E",x"040",x"042",x"045",x"048",x"04D",x"054", -- 0x0930
x"05F",x"06C",x"084",x"0A0",x"0D5",x"119",x"1A3",x"268", -- 0x0938
x"03E",x"041",x"043",x"045",x"048",x"04B",x"050",x"057", -- 0x0940
x"062",x"06F",x"087",x"0A2",x"0D7",x"11B",x"1A3",x"268", -- 0x0948
x"042",x"044",x"046",x"048",x"04B",x"04E",x"054",x"05A", -- 0x0950
x"066",x"072",x"08A",x"0A5",x"0DA",x"11D",x"1A5",x"268", -- 0x0958
x"048",x"04A",x"04C",x"04D",x"050",x"054",x"05A",x"060", -- 0x0960
x"06B",x"078",x"090",x"0AA",x"0DF",x"121",x"1A7",x"268", -- 0x0968
x"04E",x"050",x"052",x"054",x"057",x"05A",x"060",x"066", -- 0x0970
x"071",x"07E",x"095",x"0B0",x"0E4",x"126",x"1AB",x"268", -- 0x0978
x"05A",x"05C",x"05D",x"05F",x"062",x"066",x"06B",x"071", -- 0x0980
x"07C",x"089",x"09F",x"0BB",x"0EE",x"12E",x"1B0",x"268", -- 0x0988
x"067",x"069",x"06B",x"06C",x"06F",x"072",x"078",x"07E", -- 0x0990
x"089",x"096",x"0AC",x"0C6",x"0F9",x"139",x"1BB",x"268", -- 0x0998
x"07F",x"080",x"083",x"084",x"087",x"08A",x"090",x"095", -- 0x09A0
x"09F",x"0AC",x"0C1",x"0DC",x"10D",x"14C",x"1CB",x"26F", -- 0x09A8
x"09A",x"09C",x"09E",x"0A0",x"0A2",x"0A5",x"0AA",x"0B0", -- 0x09B0
x"0BB",x"0C6",x"0DC",x"0F6",x"126",x"163",x"1DE",x"27E", -- 0x09B8
x"0D0",x"0D2",x"0D4",x"0D5",x"0D7",x"0DA",x"0DF",x"0E4", -- 0x09C0
x"0EE",x"0F9",x"10D",x"126",x"154",x"192",x"207",x"293", -- 0x09C8
x"114",x"115",x"117",x"118",x"11A",x"11C",x"121",x"125", -- 0x09D0
x"12E",x"138",x"14C",x"163",x"191",x"1CA",x"235",x"2BF", -- 0x09D8
x"1A1",x"1A1",x"1A2",x"1A3",x"1A3",x"1A5",x"1A7",x"1AB", -- 0x09E0
x"1B0",x"1BB",x"1CB",x"1DE",x"207",x"235",x"298",x"31A", -- 0x09E8
x"268",x"268",x"268",x"268",x"268",x"268",x"268",x"268", -- 0x09F0
x"268",x"268",x"26F",x"27D",x"293",x"2BF",x"31A",x"386", -- 0x09F8
x"050",x"052",x"053",x"055",x"058",x"05B",x"061",x"067", -- 0x0A00
x"072",x"07E",x"096",x"0B0",x"0E5",x"128",x"1B1",x"275", -- 0x0A08
x"052",x"054",x"056",x"057",x"05B",x"05D",x"063",x"069", -- 0x0A10
x"074",x"080",x"097",x"0B2",x"0E7",x"129",x"1B2",x"275", -- 0x0A18
x"053",x"056",x"057",x"059",x"05C",x"05F",x"065",x"06B", -- 0x0A20
x"075",x"082",x"099",x"0B4",x"0E8",x"12B",x"1B3",x"275", -- 0x0A28
x"055",x"057",x"059",x"05B",x"05E",x"061",x"066",x"06C", -- 0x0A30
x"077",x"084",x"09B",x"0B6",x"0EA",x"12C",x"1B4",x"275", -- 0x0A38
x"058",x"05B",x"05C",x"05E",x"061",x"064",x"069",x"06F", -- 0x0A40
x"07A",x"086",x"09D",x"0B8",x"0EC",x"12E",x"1B4",x"275", -- 0x0A48
x"05B",x"05D",x"05F",x"061",x"064",x"067",x"06C",x"073", -- 0x0A50
x"07E",x"089",x"0A0",x"0BA",x"0EE",x"130",x"1B6",x"275", -- 0x0A58
x"061",x"063",x"065",x"066",x"069",x"06C",x"072",x"078", -- 0x0A60
x"082",x"08F",x"0A5",x"0BF",x"0F3",x"134",x"1B8",x"275", -- 0x0A68
x"067",x"069",x"06B",x"06C",x"06F",x"073",x"078",x"07E", -- 0x0A70
x"088",x"095",x"0AB",x"0C5",x"0F8",x"138",x"1BB",x"275", -- 0x0A78
x"072",x"074",x"075",x"077",x"07A",x"07E",x"082",x"088", -- 0x0A80
x"093",x"09F",x"0B5",x"0CF",x"101",x"141",x"1C0",x"275", -- 0x0A88
x"07E",x"080",x"082",x"084",x"086",x"089",x"08F",x"095", -- 0x0A90
x"09F",x"0AB",x"0C1",x"0DA",x"10C",x"14B",x"1CB",x"275", -- 0x0A98
x"096",x"097",x"099",x"09B",x"09D",x"0A0",x"0A5",x"0AB", -- 0x0AA0
x"0B5",x"0C1",x"0D5",x"0EF",x"11F",x"15D",x"1DA",x"27C", -- 0x0AA8
x"0B0",x"0B2",x"0B4",x"0B6",x"0B8",x"0BA",x"0BF",x"0C5", -- 0x0AB0
x"0CF",x"0DA",x"0EF",x"108",x"136",x"172",x"1EC",x"28A", -- 0x0AB8
x"0E5",x"0E7",x"0E8",x"0EA",x"0EC",x"0EE",x"0F3",x"0F8", -- 0x0AC0
x"101",x"10C",x"11E",x"136",x"164",x"1A0",x"213",x"29E", -- 0x0AC8
x"127",x"128",x"12A",x"12B",x"12D",x"12F",x"133",x"137", -- 0x0AD0
x"140",x"14A",x"15D",x"172",x"19F",x"1D7",x"240",x"2C8", -- 0x0AD8
x"1B1",x"1B2",x"1B3",x"1B4",x"1B4",x"1B6",x"1B8",x"1BB", -- 0x0AE0
x"1C0",x"1CB",x"1DA",x"1EC",x"212",x"240",x"2A1",x"320", -- 0x0AE8
x"274",x"274",x"274",x"274",x"274",x"274",x"274",x"274", -- 0x0AF0
x"274",x"274",x"27B",x"288",x"29D",x"2C8",x"320",x"38B", -- 0x0AF8
x"06D",x"06F",x"070",x"072",x"075",x"078",x"07D",x"082", -- 0x0B00
x"08C",x"097",x"0AE",x"0C6",x"0F9",x"13B",x"1C0",x"27D", -- 0x0B08
x"06F",x"071",x"073",x"074",x"077",x"079",x"07E",x"084", -- 0x0B10
x"08E",x"099",x"0AF",x"0C8",x"0FB",x"13C",x"1C1",x"27D", -- 0x0B18
x"070",x"073",x"074",x"076",x"078",x"07B",x"080",x"086", -- 0x0B20
x"08F",x"09B",x"0B1",x"0CA",x"0FD",x"13D",x"1C1",x"27D", -- 0x0B28
x"072",x"074",x"076",x"078",x"07A",x"07D",x"082",x"087", -- 0x0B30
x"091",x"09C",x"0B2",x"0CB",x"0FE",x"13F",x"1C2",x"27D", -- 0x0B38
x"075",x"077",x"078",x"07A",x"07D",x"080",x"084",x"08A", -- 0x0B40
x"094",x"09F",x"0B5",x"0CD",x"100",x"141",x"1C2",x"27D", -- 0x0B48
x"078",x"079",x"07B",x"07D",x"080",x"082",x"087",x"08D", -- 0x0B50
x"097",x"0A1",x"0B7",x"0D0",x"102",x"142",x"1C4",x"27D", -- 0x0B58
x"07D",x"07E",x"080",x"082",x"084",x"087",x"08C",x"092", -- 0x0B60
x"09B",x"0A6",x"0BC",x"0D4",x"106",x"146",x"1C6",x"27D", -- 0x0B68
x"082",x"084",x"086",x"087",x"08A",x"08D",x"092",x"097", -- 0x0B70
x"0A1",x"0AC",x"0C1",x"0D9",x"10B",x"14A",x"1C9",x"27D", -- 0x0B78
x"08C",x"08E",x"08F",x"091",x"094",x"097",x"09B",x"0A1", -- 0x0B80
x"0AA",x"0B5",x"0CA",x"0E3",x"113",x"151",x"1CE",x"27D", -- 0x0B88
x"097",x"099",x"09B",x"09C",x"09F",x"0A1",x"0A6",x"0AC", -- 0x0B90
x"0B5",x"0C1",x"0D5",x"0ED",x"11D",x"15B",x"1D7",x"27D", -- 0x0B98
x"0AE",x"0AF",x"0B1",x"0B2",x"0B5",x"0B7",x"0BC",x"0C1", -- 0x0BA0
x"0CA",x"0D5",x"0E7",x"100",x"12F",x"16B",x"1E5",x"283", -- 0x0BA8
x"0C6",x"0C8",x"0CA",x"0CB",x"0CD",x"0D0",x"0D4",x"0D9", -- 0x0BB0
x"0E3",x"0ED",x"100",x"118",x"145",x"17F",x"1F6",x"290", -- 0x0BB8
x"0F9",x"0FB",x"0FD",x"0FE",x"100",x"102",x"106",x"10B", -- 0x0BC0
x"113",x"11D",x"12E",x"145",x"170",x"1AB",x"21A",x"2A2", -- 0x0BC8
x"139",x"13A",x"13C",x"13D",x"13F",x"141",x"144",x"148", -- 0x0BD0
x"150",x"159",x"16B",x"17F",x"1A9",x"1DF",x"245",x"2CA", -- 0x0BD8
x"1C0",x"1C1",x"1C1",x"1C2",x"1C2",x"1C4",x"1C6",x"1C9", -- 0x0BE0
x"1CE",x"1D7",x"1E5",x"1F6",x"219",x"245",x"2A2",x"31E", -- 0x0BE8
x"27B",x"27B",x"27B",x"27B",x"27B",x"27B",x"27B",x"27B", -- 0x0BF0
x"27B",x"27B",x"282",x"28E",x"2A1",x"2CA",x"31E",x"386", -- 0x0BF8
x"0A5",x"0A7",x"0A8",x"0A9",x"0AB",x"0AE",x"0B2",x"0B7", -- 0x0C00
x"0C0",x"0C9",x"0DD",x"0F3",x"123",x"162",x"1E0",x"292", -- 0x0C08
x"0A7",x"0A8",x"0AA",x"0AB",x"0AE",x"0B0",x"0B4",x"0B9", -- 0x0C10
x"0C1",x"0CB",x"0DE",x"0F5",x"125",x"163",x"1E1",x"292", -- 0x0C18
x"0A8",x"0AA",x"0AB",x"0AD",x"0AF",x"0B1",x"0B6",x"0BA", -- 0x0C20
x"0C2",x"0CC",x"0E0",x"0F6",x"126",x"164",x"1E1",x"292", -- 0x0C28
x"0A9",x"0AB",x"0AD",x"0AE",x"0B0",x"0B2",x"0B7",x"0BB", -- 0x0C30
x"0C4",x"0CD",x"0E1",x"0F8",x"127",x"165",x"1E2",x"292", -- 0x0C38
x"0AB",x"0AE",x"0AF",x"0B0",x"0B2",x"0B5",x"0B9",x"0BD", -- 0x0C40
x"0C6",x"0CF",x"0E3",x"0F9",x"129",x"167",x"1E2",x"292", -- 0x0C48
x"0AE",x"0B0",x"0B1",x"0B2",x"0B5",x"0B7",x"0BB",x"0C0", -- 0x0C50
x"0C9",x"0D2",x"0E5",x"0FB",x"12B",x"168",x"1E3",x"292", -- 0x0C58
x"0B2",x"0B4",x"0B6",x"0B7",x"0B9",x"0BB",x"0C0",x"0C4", -- 0x0C60
x"0CC",x"0D6",x"0E9",x"0FF",x"12E",x"16C",x"1E5",x"292", -- 0x0C68
x"0B7",x"0B9",x"0BA",x"0BB",x"0BD",x"0C0",x"0C4",x"0C9", -- 0x0C70
x"0D1",x"0DB",x"0EE",x"103",x"132",x"16F",x"1E8",x"292", -- 0x0C78
x"0C0",x"0C1",x"0C2",x"0C4",x"0C6",x"0C9",x"0CC",x"0D1", -- 0x0C80
x"0D9",x"0E2",x"0F5",x"10B",x"139",x"175",x"1EC",x"292", -- 0x0C88
x"0C9",x"0CB",x"0CC",x"0CD",x"0CF",x"0D2",x"0D6",x"0DB", -- 0x0C90
x"0E2",x"0EC",x"0FF",x"114",x"142",x"17D",x"1F4",x"292", -- 0x0C98
x"0DD",x"0DE",x"0E0",x"0E1",x"0E3",x"0E5",x"0E9",x"0EE", -- 0x0CA0
x"0F5",x"0FF",x"10E",x"126",x"152",x"18B",x"1FF",x"298", -- 0x0CA8
x"0F3",x"0F5",x"0F6",x"0F8",x"0F9",x"0FB",x"0FF",x"103", -- 0x0CB0
x"10B",x"114",x"126",x"13B",x"164",x"19C",x"20E",x"2A2", -- 0x0CB8
x"123",x"125",x"126",x"127",x"129",x"12B",x"12E",x"132", -- 0x0CC0
x"139",x"142",x"150",x"164",x"18D",x"1C4",x"22E",x"2B2", -- 0x0CC8
x"160",x"161",x"162",x"163",x"164",x"166",x"169",x"16C", -- 0x0CD0
x"173",x"17A",x"18B",x"19C",x"1C2",x"1F4",x"256",x"2D5", -- 0x0CD8
x"1E0",x"1E1",x"1E1",x"1E2",x"1E2",x"1E3",x"1E5",x"1E8", -- 0x0CE0
x"1EC",x"1F4",x"1FF",x"20E",x"22B",x"256",x"2AD",x"324", -- 0x0CE8
x"290",x"290",x"290",x"290",x"290",x"290",x"290",x"290", -- 0x0CF0
x"290",x"290",x"295",x"2A0",x"2B0",x"2D5",x"324",x"388", -- 0x0CF8
x"0EB",x"0ED",x"0EE",x"0EF",x"0F1",x"0F3",x"0F7",x"0FB", -- 0x0D00
x"103",x"10B",x"11E",x"132",x"160",x"19D",x"217",x"2C2", -- 0x0D08
x"0ED",x"0EE",x"0F0",x"0F1",x"0F3",x"0F5",x"0F8",x"0FD", -- 0x0D10
x"104",x"10C",x"11F",x"134",x"162",x"19E",x"217",x"2C2", -- 0x0D18
x"0EE",x"0F0",x"0F1",x"0F2",x"0F4",x"0F6",x"0FA",x"0FE", -- 0x0D20
x"105",x"10E",x"120",x"135",x"163",x"19F",x"217",x"2C2", -- 0x0D28
x"0EF",x"0F1",x"0F2",x"0F3",x"0F5",x"0F7",x"0FB",x"0FF", -- 0x0D30
x"106",x"10F",x"121",x"136",x"164",x"1A0",x"218",x"2C2", -- 0x0D38
x"0F1",x"0F3",x"0F4",x"0F5",x"0F7",x"0F9",x"0FD",x"101", -- 0x0D40
x"108",x"111",x"123",x"137",x"165",x"1A1",x"218",x"2C2", -- 0x0D48
x"0F3",x"0F5",x"0F6",x"0F7",x"0F9",x"0FB",x"0FF",x"103", -- 0x0D50
x"10B",x"113",x"125",x"139",x"167",x"1A3",x"219",x"2C2", -- 0x0D58
x"0F7",x"0F8",x"0FA",x"0FB",x"0FD",x"0FF",x"103",x"107", -- 0x0D60
x"10E",x"116",x"128",x"13C",x"16A",x"1A6",x"21B",x"2C2", -- 0x0D68
x"0FB",x"0FD",x"0FE",x"0FF",x"101",x"103",x"107",x"10B", -- 0x0D70
x"112",x"11A",x"12C",x"140",x"16D",x"1A8",x"21D",x"2C2", -- 0x0D78
x"103",x"104",x"105",x"106",x"108",x"10B",x"10E",x"112", -- 0x0D80
x"119",x"121",x"133",x"147",x"173",x"1AE",x"221",x"2C2", -- 0x0D88
x"10B",x"10C",x"10E",x"10F",x"111",x"113",x"116",x"11A", -- 0x0D90
x"121",x"12A",x"13B",x"14F",x"17B",x"1B5",x"228",x"2C2", -- 0x0D98
x"11E",x"11F",x"120",x"121",x"123",x"125",x"128",x"12C", -- 0x0DA0
x"133",x"13B",x"149",x"15F",x"18B",x"1C1",x"232",x"2C6", -- 0x0DA8
x"132",x"134",x"135",x"136",x"137",x"139",x"13C",x"140", -- 0x0DB0
x"147",x"14F",x"15F",x"173",x"19A",x"1D0",x"23F",x"2D0", -- 0x0DB8
x"160",x"162",x"163",x"164",x"165",x"167",x"16A",x"16D", -- 0x0DC0
x"173",x"17B",x"187",x"19A",x"1C1",x"1F7",x"25C",x"2DE", -- 0x0DC8
x"19A",x"19B",x"19C",x"19D",x"19E",x"1A0",x"1A2",x"1A5", -- 0x0DD0
x"1AB",x"1B2",x"1C1",x"1D0",x"1F3",x"224",x"282",x"2FD", -- 0x0DD8
x"217",x"217",x"217",x"218",x"218",x"219",x"21B",x"21D", -- 0x0DE0
x"221",x"228",x"232",x"23F",x"259",x"282",x"2D5",x"348", -- 0x0DE8
x"2BE",x"2BE",x"2BE",x"2BE",x"2BE",x"2BE",x"2BE",x"2BE", -- 0x0DF0
x"2BE",x"2BE",x"2C3",x"2CC",x"2DA",x"2FD",x"348",x"3AA", -- 0x0DF8
x"17D",x"17E",x"17E",x"17F",x"181",x"183",x"185",x"188", -- 0x0E00
x"18E",x"194",x"1A4",x"1B5",x"1DF",x"218",x"288",x"325", -- 0x0E08
x"17E",x"17F",x"180",x"180",x"182",x"184",x"186",x"189", -- 0x0E10
x"18F",x"195",x"1A4",x"1B6",x"1E0",x"219",x"288",x"325", -- 0x0E18
x"17E",x"180",x"180",x"182",x"183",x"185",x"187",x"18A", -- 0x0E20
x"18F",x"196",x"1A5",x"1B6",x"1E0",x"219",x"289",x"325", -- 0x0E28
x"17F",x"180",x"182",x"183",x"184",x"185",x"188",x"18B", -- 0x0E30
x"190",x"197",x"1A6",x"1B7",x"1E1",x"21A",x"289",x"325", -- 0x0E38
x"181",x"182",x"183",x"184",x"185",x"187",x"189",x"18C", -- 0x0E40
x"192",x"198",x"1A7",x"1B8",x"1E2",x"21B",x"289",x"325", -- 0x0E48
x"183",x"184",x"185",x"185",x"187",x"188",x"18B",x"18E", -- 0x0E50
x"194",x"199",x"1A9",x"1BA",x"1E4",x"21C",x"28A",x"325", -- 0x0E58
x"185",x"186",x"187",x"188",x"189",x"18B",x"18E",x"191", -- 0x0E60
x"196",x"19C",x"1AB",x"1BC",x"1E6",x"21E",x"28B",x"325", -- 0x0E68
x"188",x"189",x"18A",x"18B",x"18C",x"18E",x"191",x"194", -- 0x0E70
x"199",x"19F",x"1AE",x"1BF",x"1E8",x"220",x"28D",x"325", -- 0x0E78
x"18E",x"18F",x"18F",x"190",x"192",x"194",x"196",x"199", -- 0x0E80
x"19E",x"1A4",x"1B3",x"1C4",x"1ED",x"224",x"290",x"325", -- 0x0E88
x"194",x"195",x"196",x"197",x"198",x"199",x"19C",x"19F", -- 0x0E90
x"1A4",x"1AA",x"1B9",x"1C9",x"1F2",x"229",x"295",x"325", -- 0x0E98
x"1A4",x"1A4",x"1A5",x"1A6",x"1A7",x"1A9",x"1AB",x"1AE", -- 0x0EA0
x"1B3",x"1B9",x"1C3",x"1D8",x"200",x"232",x"29C",x"328", -- 0x0EA8
x"1B5",x"1B6",x"1B6",x"1B7",x"1B8",x"1BA",x"1BC",x"1BF", -- 0x0EB0
x"1C4",x"1C9",x"1D8",x"1E8",x"20B",x"23D",x"2A5",x"32F", -- 0x0EB8
x"1DF",x"1E0",x"1E0",x"1E1",x"1E2",x"1E4",x"1E6",x"1E8", -- 0x0EC0
x"1ED",x"1F2",x"1FB",x"20B",x"22E",x"260",x"2BD",x"339", -- 0x0EC8
x"214",x"214",x"215",x"216",x"217",x"218",x"21A",x"21C", -- 0x0ED0
x"220",x"225",x"232",x"23D",x"25B",x"287",x"2DF",x"352", -- 0x0ED8
x"288",x"288",x"289",x"289",x"289",x"28A",x"28B",x"28D", -- 0x0EE0
x"290",x"295",x"29C",x"2A5",x"2B8",x"2DF",x"32B",x"396", -- 0x0EE8
x"320",x"320",x"320",x"320",x"320",x"320",x"320",x"320", -- 0x0EF0
x"320",x"320",x"324",x"32B",x"335",x"352",x"396",x"3F3", -- 0x0EF8
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F00
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F08
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F10
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F18
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F20
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F28
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F30
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F38
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F40
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F48
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F50
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F58
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F60
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F68
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F70
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F78
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F80
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F88
x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D",x"24D", -- 0x0F90
x"24D",x"24D",x"254",x"25C",x"27C",x"2AB",x"302",x"379", -- 0x0F98
x"254",x"254",x"254",x"254",x"254",x"254",x"254",x"254", -- 0x0FA0
x"254",x"254",x"254",x"264",x"284",x"2AB",x"302",x"379", -- 0x0FA8
x"25C",x"25C",x"25C",x"25C",x"25C",x"25C",x"25C",x"25C", -- 0x0FB0
x"25C",x"25C",x"264",x"26C",x"284",x"2AB",x"302",x"379", -- 0x0FB8
x"27C",x"27C",x"27C",x"27C",x"27C",x"27C",x"27C",x"27C", -- 0x0FC0
x"27C",x"27C",x"27C",x"284",x"29C",x"2C3",x"30A",x"379", -- 0x0FC8
x"2A3",x"2A3",x"2A3",x"2A3",x"2A3",x"2A3",x"2A3",x"2A3", -- 0x0FD0
x"2A3",x"2A3",x"2AB",x"2AB",x"2BB",x"2DB",x"322",x"381", -- 0x0FD8
x"302",x"302",x"302",x"302",x"302",x"302",x"302",x"302", -- 0x0FE0
x"302",x"302",x"302",x"302",x"302",x"322",x"359",x"3B0", -- 0x0FE8
x"371",x"371",x"371",x"371",x"371",x"371",x"371",x"371", -- 0x0FF0
x"371",x"371",x"371",x"371",x"371",x"381",x"3B0",x"3FF" -- 0x0FF8
);
begin
p_rom : process
begin
wait until rising_edge(CLK);
DATA <= ROM(to_integer(unsigned(ADDR)))(9 downto 0);
end process;
end RTL;

86
cores/spectrum/clocks.vhd Executable file
View File

@@ -0,0 +1,86 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity clocks is
port (
-- 28 MHz master clock
CLK : in std_logic;
-- Master reset
nRESET : in std_logic;
-- 1.75 MHz clock enable for sound
CLKEN_PSG : out std_logic;
-- 3.5 MHz clock enable (1 in 8)
CLKEN_CPU : out std_logic;
-- 3.5 MHz clock enable (1 in 8) for cpu memory access
CLKEN_MEM : out std_logic;
-- 14 MHz clock enable (out of phase with CPU)
CLKEN_VID : out std_logic
);
end clocks;
-- Clock enables for uncontended VRAM access
-- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-- CPU VID VID VID VID VID VID VID VID
-- PSG
architecture clocks_arch of clocks is
signal counter : unsigned(3 downto 0);
begin
-- X000
CLKEN_CPU <= '1' when counter = "1000" or counter = "1100" else '0';
-- X011
CLKEN_MEM <= '1' when counter = "1001" or counter = "1101" else '0';
-- XXX1
CLKEN_VID <= '1' when counter(0) = '1' else '0';
-- 1111
CLKEN_PSG <= '1' when counter = "1111" else '0';
process(nRESET,CLK)
begin
if nRESET = '0' then
counter <= (others => '0');
elsif falling_edge(CLK) then
counter <= counter + 1;
end if;
end process;
end clocks_arch;

215
cores/spectrum/keyboard.vhd Executable file
View File

@@ -0,0 +1,215 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
-- PS/2 scancode to Spectrum matrix conversion
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity keyboard is
port (
CLK : in std_logic;
nRESET : in std_logic;
-- PS/2 interface
PS2_CLK : in std_logic;
PS2_DATA : in std_logic;
-- CPU address bus (row)
A : in std_logic_vector(15 downto 0);
-- Column outputs to ULA
KEYB : out std_logic_vector(4 downto 0)
);
end keyboard;
architecture rtl of keyboard is
-- PS/2 interface
component ps2_intf is
generic (filter_length : positive := 8);
port(
CLK : in std_logic;
nRESET : in std_logic;
-- PS/2 interface (could be bi-dir)
PS2_CLK : in std_logic;
PS2_DATA : in std_logic;
-- Byte-wide data interface - only valid for one clock
-- so must be latched externally if required
DATA : out std_logic_vector(7 downto 0);
VALID : out std_logic;
ERROR : out std_logic
);
end component;
-- Interface to PS/2 block
signal keyb_data : std_logic_vector(7 downto 0);
signal keyb_valid : std_logic;
signal keyb_error : std_logic;
-- Internal signals
type key_matrix is array (7 downto 0) of std_logic_vector(4 downto 0);
signal keys : key_matrix;
signal release : std_logic;
signal extended : std_logic;
begin
ps2 : ps2_intf port map (
CLK, nRESET,
PS2_CLK, PS2_DATA,
keyb_data, keyb_valid, keyb_error
);
-- Output addressed row to ULA
KEYB <= keys(0) when A(8) = '0' else
keys(1) when A(9) = '0' else
keys(2) when A(10) = '0' else
keys(3) when A(11) = '0' else
keys(4) when A(12) = '0' else
keys(5) when A(13) = '0' else
keys(6) when A(14) = '0' else
keys(7) when A(15) = '0' else
(others => '1');
process(nRESET,CLK)
begin
if nRESET = '0' then
release <= '0';
extended <= '0';
keys(0) <= (others => '1');
keys(1) <= (others => '1');
keys(2) <= (others => '1');
keys(3) <= (others => '1');
keys(4) <= (others => '1');
keys(5) <= (others => '1');
keys(6) <= (others => '1');
keys(7) <= (others => '1');
elsif rising_edge(CLK) then
if keyb_valid = '1' then
if keyb_data = X"e0" then
-- Extended key code follows
extended <= '1';
elsif keyb_data = X"f0" then
-- Release code follows
release <= '1';
else
-- Cancel extended/release flags for next time
release <= '0';
extended <= '0';
case keyb_data is
when X"12" => keys(0)(0) <= release; -- Left shift (CAPS SHIFT)
when X"59" => keys(0)(0) <= release; -- Right shift (CAPS SHIFT)
when X"1a" => keys(0)(1) <= release; -- Z
when X"22" => keys(0)(2) <= release; -- X
when X"21" => keys(0)(3) <= release; -- C
when X"2a" => keys(0)(4) <= release; -- V
when X"1c" => keys(1)(0) <= release; -- A
when X"1b" => keys(1)(1) <= release; -- S
when X"23" => keys(1)(2) <= release; -- D
when X"2b" => keys(1)(3) <= release; -- F
when X"34" => keys(1)(4) <= release; -- G
when X"15" => keys(2)(0) <= release; -- Q
when X"1d" => keys(2)(1) <= release; -- W
when X"24" => keys(2)(2) <= release; -- E
when X"2d" => keys(2)(3) <= release; -- R
when X"2c" => keys(2)(4) <= release; -- T
when X"16" => keys(3)(0) <= release; -- 1
when X"1e" => keys(3)(1) <= release; -- 2
when X"26" => keys(3)(2) <= release; -- 3
when X"25" => keys(3)(3) <= release; -- 4
when X"2e" => keys(3)(4) <= release; -- 5
when X"45" => keys(4)(0) <= release; -- 0
when X"46" => keys(4)(1) <= release; -- 9
when X"3e" => keys(4)(2) <= release; -- 8
when X"3d" => keys(4)(3) <= release; -- 7
when X"36" => keys(4)(4) <= release; -- 6
when X"4d" => keys(5)(0) <= release; -- P
when X"44" => keys(5)(1) <= release; -- O
when X"43" => keys(5)(2) <= release; -- I
when X"3c" => keys(5)(3) <= release; -- U
when X"35" => keys(5)(4) <= release; -- Y
when X"5a" => keys(6)(0) <= release; -- ENTER
when X"4b" => keys(6)(1) <= release; -- L
when X"42" => keys(6)(2) <= release; -- K
when X"3b" => keys(6)(3) <= release; -- J
when X"33" => keys(6)(4) <= release; -- H
when X"29" => keys(7)(0) <= release; -- SPACE
when X"14" => keys(7)(1) <= release; -- CTRL (Symbol Shift)
when X"3a" => keys(7)(2) <= release; -- M
when X"31" => keys(7)(3) <= release; -- N
when X"32" => keys(7)(4) <= release; -- B
-- Cursor keys - these are actually extended (E0 xx), but
-- the scancodes for the numeric keypad cursor keys are
-- are the same but without the extension, so we'll accept
-- the codes whether they are extended or not
when X"6B" => keys(0)(0) <= release; -- Left (CAPS 5)
keys(3)(4) <= release;
when X"72" => keys(0)(0) <= release; -- Down (CAPS 6)
keys(4)(4) <= release;
when X"75" => keys(0)(0) <= release; -- Up (CAPS 7)
keys(4)(3) <= release;
when X"74" => keys(0)(0) <= release; -- Right (CAPS 8)
keys(4)(2) <= release;
-- Other special keys sent to the ULA as key combinations
when X"66" => keys(0)(0) <= release; -- Backspace (CAPS 0)
keys(4)(0) <= release;
when X"58" => keys(0)(0) <= release; -- Caps lock (CAPS 2)
keys(3)(1) <= release;
when X"76" => keys(0)(0) <= release; -- Escape (CAPS SPACE)
keys(7)(0) <= release;
when others =>
null;
end case;
end if;
end if;
end if;
end process;
end architecture;

182
cores/spectrum/osd.v Normal file
View File

@@ -0,0 +1,182 @@
// A simple OSD implementation. Can be hooked up between a cores
// VGA output and the physical VGA pins
module osd (
// OSDs pixel clock, should be synchronous to cores pixel clock to
// avoid jitter.
input pclk,
// SPI interface
input sck,
input ss,
input sdi,
// VGA signals coming from core
input [5:0] red_in,
input [5:0] green_in,
input [5:0] blue_in,
input hs_in,
input vs_in,
// VGA signals going to video connector
output [5:0] red_out,
output [5:0] green_out,
output [5:0] blue_out,
output hs_out,
output vs_out
);
parameter OSD_X_OFFSET = 10'd0;
parameter OSD_Y_OFFSET = 10'd0;
parameter OSD_COLOR = 3'd0;
localparam OSD_WIDTH = 10'd256;
localparam OSD_HEIGHT = 10'd128;
// *********************************************************************************
// spi client
// *********************************************************************************
// this core supports only the display related OSD commands
// of the minimig
reg [7:0] sbuf;
reg [7:0] cmd;
reg [4:0] cnt;
reg [10:0] bcnt;
reg osd_enable;
reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself
// the OSD has its own SPI interface to the io controller
always@(posedge sck, posedge ss) begin
if(ss == 1'b1) begin
cnt <= 5'd0;
bcnt <= 11'd0;
end else begin
sbuf <= { sbuf[6:0], sdi};
// 0:7 is command, rest payload
if(cnt < 15)
cnt <= cnt + 4'd1;
else
cnt <= 4'd8;
if(cnt == 7) begin
cmd <= {sbuf[6:0], sdi};
// lower three command bits are line address
bcnt <= { sbuf[1:0], sdi, 8'h00};
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
if(sbuf[6:3] == 4'b0100)
osd_enable <= sdi;
end
// command 0x20: OSDCMDWRITE
if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
osd_buffer[bcnt] <= {sbuf[6:0], sdi};
bcnt <= bcnt + 11'd1;
end
end
end
// *********************************************************************************
// video timing and sync polarity anaylsis
// *********************************************************************************
// horizontal counter
reg [9:0] h_cnt;
reg hsD, hsD2;
reg [9:0] hs_low, hs_high;
wire hs_pol = hs_high < hs_low;
wire [9:0] h_dsp_width = hs_pol?hs_low:hs_high;
wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] };
always @(posedge pclk) begin
// bring hsync into local clock domain
hsD <= hs_in;
hsD2 <= hsD;
// falling edge of hs_in
if(!hsD && hsD2) begin
h_cnt <= 10'd0;
hs_high <= h_cnt;
end
// rising edge of hs_in
else if(hsD && !hsD2) begin
h_cnt <= 10'd0;
hs_low <= h_cnt;
end
else
h_cnt <= h_cnt + 10'd1;
end
// vertical counter
reg [9:0] v_cnt;
reg vsD, vsD2;
reg [9:0] vs_low, vs_high;
wire vs_pol = vs_high < vs_low;
wire [9:0] v_dsp_width = vs_pol?vs_low:vs_high;
wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_width[9:1] };
always @(posedge hs_in) begin
// bring vsync into local clock domain
vsD <= vs_in;
vsD2 <= vsD;
// falling edge of vs_in
if(!vsD && vsD2) begin
v_cnt <= 10'd0;
vs_high <= v_cnt;
end
// rising edge of vs_in
else if(vsD && !vsD2) begin
v_cnt <= 10'd0;
vs_low <= v_cnt;
end
else
v_cnt <= v_cnt + 10'd1;
end
// area in which OSD is being displayed
wire [9:0] h_osd_start = h_dsp_ctr + OSD_X_OFFSET - (OSD_WIDTH >> 1);
wire [9:0] h_osd_end = h_dsp_ctr + OSD_X_OFFSET + (OSD_WIDTH >> 1) - 1;
wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (OSD_HEIGHT >> 1);
wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (OSD_HEIGHT >> 1) - 1;
reg h_osd_active, v_osd_active;
always @(posedge pclk) begin
if(hs_in != hs_pol) begin
if(h_cnt == h_osd_start) h_osd_active <= 1'b1;
if(h_cnt == h_osd_end) h_osd_active <= 1'b0;
end
if(vs_in != vs_pol) begin
if(v_cnt == v_osd_start) v_osd_active <= 1'b1;
if(v_cnt == v_osd_end) v_osd_active <= 1'b0;
end
end
wire osd_de = osd_enable && h_osd_active && v_osd_active;
wire [7:0] osd_hcnt = h_cnt - h_osd_start + 7'd1; // one pixel offset for osd_byte register
wire [6:0] osd_vcnt = v_cnt - v_osd_start;
wire osd_pixel = osd_byte[osd_vcnt[3:1]];
reg [7:0] osd_byte;
always @(posedge pclk)
osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}];
wire [2:0] osd_color = OSD_COLOR;
assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] };
assign green_out = !osd_de?green_in:{osd_pixel, osd_pixel, osd_color[1], green_in[5:3]};
assign blue_out = !osd_de?blue_in: {osd_pixel, osd_pixel, osd_color[0], blue_in[5:3] };
assign hs_out = hs_in;
assign vs_out = vs_in;
endmodule

397
cores/spectrum/pll_main.vhd Executable file
View File

@@ -0,0 +1,397 @@
-- megafunction wizard: %ALTPLL%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altpll
-- ============================================================
-- File Name: pll_main.vhd
-- Megafunction Name(s):
-- altpll
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 13.1.4 Build 182 03/12/2014 SJ Web Edition
-- ************************************************************
--Copyright (C) 1991-2014 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 pll_main IS
PORT
(
areset : IN STD_LOGIC := '0';
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC ;
c1 : OUT STD_LOGIC ;
locked : OUT STD_LOGIC
);
END pll_main;
ARCHITECTURE SYN OF pll_main IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC ;
SIGNAL sub_wire2 : STD_LOGIC ;
SIGNAL sub_wire3 : STD_LOGIC ;
SIGNAL sub_wire4 : STD_LOGIC ;
SIGNAL sub_wire5 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire6_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire6 : STD_LOGIC_VECTOR (0 DOWNTO 0);
COMPONENT altpll
GENERIC (
bandwidth_type : STRING;
clk0_divide_by : NATURAL;
clk0_duty_cycle : NATURAL;
clk0_multiply_by : NATURAL;
clk0_phase_shift : STRING;
clk1_divide_by : NATURAL;
clk1_duty_cycle : NATURAL;
clk1_multiply_by : NATURAL;
clk1_phase_shift : STRING;
compensate_clock : STRING;
inclk0_input_frequency : NATURAL;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
operation_mode : STRING;
pll_type : STRING;
port_activeclock : STRING;
port_areset : STRING;
port_clkbad0 : STRING;
port_clkbad1 : STRING;
port_clkloss : STRING;
port_clkswitch : STRING;
port_configupdate : STRING;
port_fbin : STRING;
port_inclk0 : STRING;
port_inclk1 : STRING;
port_locked : STRING;
port_pfdena : STRING;
port_phasecounterselect : STRING;
port_phasedone : STRING;
port_phasestep : STRING;
port_phaseupdown : STRING;
port_pllena : STRING;
port_scanaclr : STRING;
port_scanclk : STRING;
port_scanclkena : STRING;
port_scandata : STRING;
port_scandataout : STRING;
port_scandone : STRING;
port_scanread : STRING;
port_scanwrite : STRING;
port_clk0 : STRING;
port_clk1 : STRING;
port_clk2 : STRING;
port_clk3 : STRING;
port_clk4 : STRING;
port_clk5 : STRING;
port_clkena0 : STRING;
port_clkena1 : STRING;
port_clkena2 : STRING;
port_clkena3 : STRING;
port_clkena4 : STRING;
port_clkena5 : STRING;
port_extclk0 : STRING;
port_extclk1 : STRING;
port_extclk2 : STRING;
port_extclk3 : STRING;
self_reset_on_loss_lock : STRING;
width_clock : NATURAL
);
PORT (
areset : IN STD_LOGIC ;
clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
locked : OUT STD_LOGIC
);
END COMPONENT;
BEGIN
sub_wire6_bv(0 DOWNTO 0) <= "0";
sub_wire6 <= To_stdlogicvector(sub_wire6_bv);
sub_wire3 <= sub_wire0(0);
sub_wire1 <= sub_wire0(1);
c1 <= sub_wire1;
locked <= sub_wire2;
c0 <= sub_wire3;
sub_wire4 <= inclk0;
sub_wire5 <= sub_wire6(0 DOWNTO 0) & sub_wire4;
altpll_component : altpll
GENERIC MAP (
bandwidth_type => "AUTO",
clk0_divide_by => 27,
clk0_duty_cycle => 50,
clk0_multiply_by => 112,
clk0_phase_shift => "0",
clk1_divide_by => 27,
clk1_duty_cycle => 50,
clk1_multiply_by => 112,
clk1_phase_shift => "-2500",
compensate_clock => "CLK0",
inclk0_input_frequency => 37037,
intended_device_family => "Cyclone III",
lpm_hint => "CBX_MODULE_PREFIX=pll_main",
lpm_type => "altpll",
operation_mode => "NORMAL",
pll_type => "AUTO",
port_activeclock => "PORT_UNUSED",
port_areset => "PORT_USED",
port_clkbad0 => "PORT_UNUSED",
port_clkbad1 => "PORT_UNUSED",
port_clkloss => "PORT_UNUSED",
port_clkswitch => "PORT_UNUSED",
port_configupdate => "PORT_UNUSED",
port_fbin => "PORT_UNUSED",
port_inclk0 => "PORT_USED",
port_inclk1 => "PORT_UNUSED",
port_locked => "PORT_USED",
port_pfdena => "PORT_UNUSED",
port_phasecounterselect => "PORT_UNUSED",
port_phasedone => "PORT_UNUSED",
port_phasestep => "PORT_UNUSED",
port_phaseupdown => "PORT_UNUSED",
port_pllena => "PORT_UNUSED",
port_scanaclr => "PORT_UNUSED",
port_scanclk => "PORT_UNUSED",
port_scanclkena => "PORT_UNUSED",
port_scandata => "PORT_UNUSED",
port_scandataout => "PORT_UNUSED",
port_scandone => "PORT_UNUSED",
port_scanread => "PORT_UNUSED",
port_scanwrite => "PORT_UNUSED",
port_clk0 => "PORT_USED",
port_clk1 => "PORT_USED",
port_clk2 => "PORT_UNUSED",
port_clk3 => "PORT_UNUSED",
port_clk4 => "PORT_UNUSED",
port_clk5 => "PORT_UNUSED",
port_clkena0 => "PORT_UNUSED",
port_clkena1 => "PORT_UNUSED",
port_clkena2 => "PORT_UNUSED",
port_clkena3 => "PORT_UNUSED",
port_clkena4 => "PORT_UNUSED",
port_clkena5 => "PORT_UNUSED",
port_extclk0 => "PORT_UNUSED",
port_extclk1 => "PORT_UNUSED",
port_extclk2 => "PORT_UNUSED",
port_extclk3 => "PORT_UNUSED",
self_reset_on_loss_lock => "OFF",
width_clock => 5
)
PORT MAP (
areset => areset,
inclk => sub_wire5,
clk => sub_wire0,
locked => sub_wire2
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "39"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "112.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "112.000000"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "40"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "40"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "112.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "112.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "-2500.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_main.mif"
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK1 STRING "1"
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "27"
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "112"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27"
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "112"
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "-2500"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
-- Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
-- Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
-- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 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: c1 0 0 0 0 @clk 0 0 1 1
-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main.ppf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_main_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
-- Retrieval info: CBX_MODULE_PREFIX: ON

158
cores/spectrum/ps2_intf.vhd Executable file
View File

@@ -0,0 +1,158 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
-- PS/2 interface (input only)
-- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- This is input-only for the time being
entity ps2_intf is
generic (filter_length : positive := 8);
port(
CLK : in std_logic;
nRESET : in std_logic;
-- PS/2 interface (could be bi-dir)
PS2_CLK : in std_logic;
PS2_DATA : in std_logic;
-- Byte-wide data interface - only valid for one clock
-- so must be latched externally if required
DATA : out std_logic_vector(7 downto 0);
VALID : out std_logic;
ERROR : out std_logic
);
end ps2_intf;
architecture ps2_intf_arch of ps2_intf is
subtype filter_t is std_logic_vector(filter_length-1 downto 0);
signal clk_filter : filter_t;
signal ps2_clk_in : std_logic;
signal ps2_dat_in : std_logic;
-- Goes high when a clock falling edge is detected
signal clk_edge : std_logic;
signal bit_count : unsigned (3 downto 0);
signal shiftreg : std_logic_vector(8 downto 0);
signal parity : std_logic;
begin
-- Register input signals
process(nRESET,CLK)
begin
if nRESET = '0' then
ps2_clk_in <= '1';
ps2_dat_in <= '1';
clk_filter <= (others => '1');
clk_edge <= '0';
elsif rising_edge(CLK) then
-- Register inputs (and filter clock)
ps2_dat_in <= PS2_DATA;
clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1);
clk_edge <= '0';
if clk_filter = filter_t'(others => '1') then
-- Filtered clock is high
ps2_clk_in <= '1';
elsif clk_filter = filter_t'(others => '0') then
-- Filter clock is low, check for edge
if ps2_clk_in = '1' then
clk_edge <= '1';
end if;
ps2_clk_in <= '0';
end if;
end if;
end process;
-- Shift in keyboard data
process(nRESET,CLK)
begin
if nRESET = '0' then
bit_count <= (others => '0');
shiftreg <= (others => '0');
parity <= '0';
DATA <= (others => '0');
VALID <= '0';
ERROR <= '0';
elsif rising_edge(CLK) then
-- Clear flags
VALID <= '0';
ERROR <= '0';
if clk_edge = '1' then
-- We have a new bit from the keyboard for processing
if bit_count = 0 then
-- Idle state, check for start bit (0) only and don't
-- start counting bits until we get it
parity <= '0';
if ps2_dat_in = '0' then
-- This is a start bit
bit_count <= bit_count + 1;
end if;
else
-- Running. 8-bit data comes in LSb first followed by
-- a single stop bit (1)
if bit_count < 10 then
-- Shift in data and parity (9 bits)
bit_count <= bit_count + 1;
shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
parity <= parity xor ps2_dat_in; -- Calculate parity
elsif ps2_dat_in = '1' then
-- Valid stop bit received
bit_count <= (others => '0'); -- back to idle
if parity = '1' then
-- Parity correct, submit data to host
DATA <= shiftreg(7 downto 0);
VALID <= '1';
else
-- Error
ERROR <= '1';
end if;
else
-- Invalid stop bit
bit_count <= (others => '0'); -- back to idle
ERROR <= '1';
end if;
end if;
end if;
end if;
end process;
end ps2_intf_arch;

143
cores/spectrum/rom48.vhd Normal file
View File

@@ -0,0 +1,143 @@
-- megafunction wizard: %ROM: 1-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: rom48.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 13.1.4 Build 182 03/12/2014 SJ Web Edition
-- ************************************************************
--Copyright (C) 1991-2014 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.altera_mf_components.all;
ENTITY rom48 IS
PORT
(
address : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
clock : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END rom48;
ARCHITECTURE SYN OF rom48 IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
q <= sub_wire0(7 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "48.hex",
intended_device_family => "Cyclone III",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 16384,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
widthad_a => 14,
width_a => 8,
width_byteena_a => 1
)
PORT MAP (
address_a => address,
clock0 => clock,
q_a => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clken NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "48.hex"
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "14"
-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: INIT_FILE STRING "48.hex"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
-- Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL rom48.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL rom48.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL rom48.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL rom48.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL rom48_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf

176
cores/spectrum/sdram.v Normal file
View File

@@ -0,0 +1,176 @@
//
// sdram.v
//
// sdram controller implementation for the MiST board
// http://code.google.com/p/mist-board/
//
// Copyright (c) 2013 Till Harbaum <till@harbaum.org>
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module sdram (
// interface to the MT48LC16M16 chip
inout [15:0] sd_data, // 16 bit bidirectional data bus
output reg [12:0] sd_addr, // 13 bit multiplexed address bus
output reg [1:0] sd_dqm, // two byte masks
output reg [1:0] sd_ba, // two banks
output sd_cs, // a single chip select
output sd_we, // write enable
output sd_ras, // row address select
output sd_cas, // columns address select
// cpu/chipset interface
input init, // init signal after FPGA config to initialize RAM
input clk, // sdram is accessed at up to 128MHz
input clkref, // reference clock to sync to
input [7:0] din, // data input from chipset/cpu
output [7:0] dout, // data output to chipset/cpu
input [24:0] addr, // 25 bit byte address
input oe, // cpu/chipset requests read
input we // cpu/chipset requests write
);
// falling edge on oe/we/rfsh starts state machine
// no burst configured
localparam RASCAS_DELAY = 3'd3; // tRCD=20ns -> 3 cycles@128MHz
localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
localparam CAS_LATENCY = 3'd3; // 2/3 allowed
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
// ---------------------------------------------------------------------
// ------------------------ cycle state machine ------------------------
// ---------------------------------------------------------------------
localparam STATE_IDLE = 3'd0; // first state in cycle
localparam STATE_CMD_START = 3'd0; // state in which a new command can be started
localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY; // 4 command can be continued
localparam STATE_LAST = 3'd7; // last state in cycle
reg [2:0] q /* synthesis noprune */;
always @(posedge clk) begin
// 112Mhz counter synchronous to 14 Mhz clock
// force counter to pass state 5->6 exactly after the rising edge of clkref
// since clkref is two clocks early
if(((q == 5) && ( clkref == 0)) ||
((q == 6) && ( clkref == 1)) ||
((q != 5) && (q != 6)))
q <= q + 3'd1;
end
// ---------------------------------------------------------------------
// --------------------------- startup/reset ---------------------------
// ---------------------------------------------------------------------
// wait 1ms (32 8Mhz cycles) after FPGA config is done before going
// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
reg [4:0] reset;
always @(posedge clk) begin
if(init) reset <= 5'h1f;
else if((q == STATE_LAST) && (reset != 0))
reset <= reset - 5'd1;
end
// ---------------------------------------------------------------------
// ------------------ generate ram control signals ---------------------
// ---------------------------------------------------------------------
// all possible commands
localparam CMD_INHIBIT = 4'b1111;
localparam CMD_NOP = 4'b0111;
localparam CMD_ACTIVE = 4'b0011;
localparam CMD_READ = 4'b0101;
localparam CMD_WRITE = 4'b0100;
localparam CMD_BURST_TERMINATE = 4'b0110;
localparam CMD_PRECHARGE = 4'b0010;
localparam CMD_AUTO_REFRESH = 4'b0001;
localparam CMD_LOAD_MODE = 4'b0000;
reg [3:0] sd_cmd; // current command sent to sd ram
// drive control signals according to current command
assign sd_cs = sd_cmd[3];
assign sd_ras = sd_cmd[2];
assign sd_cas = sd_cmd[1];
assign sd_we = sd_cmd[0];
// drive ram data lines when writing, set them as inputs otherwise
// the eight bits are sent on both bytes ports. Which one's actually
// written depends on the state of dqm of which only one is active
// at a time when writing
assign sd_data = we?{din, din}:16'bZZZZZZZZZZZZZZZZ;
assign dout = addr[0]?sd_data[7:0]:sd_data[15:8];
always @(posedge clk) begin
sd_cmd <= CMD_INHIBIT; // default: idle
if(reset != 0) begin
// initialization takes place at the end of the reset phase
if(q == STATE_CMD_START) begin
if(reset == 13) begin
sd_cmd <= CMD_PRECHARGE;
sd_addr[10] <= 1'b1; // precharge all banks
end
if(reset == 2) begin
sd_cmd <= CMD_LOAD_MODE;
sd_addr <= MODE;
end
end
end else begin
// normal operation
// ------------------- cpu/chipset read/write ----------------------
if(we || oe) begin
// RAS phase
if(q == STATE_CMD_START) begin
sd_cmd <= CMD_ACTIVE;
sd_addr <= addr[21:9];
sd_ba <= addr[23:22];
// always return both bytes in a read. Only the correct byte
// is being stored during read. On write only one of the two
// bytes is enabled
if(!we) sd_dqm <= 2'b00;
else sd_dqm <= { addr[0], ~addr[0] };
end
// CAS phase
if(q == STATE_CMD_CONT) begin
sd_cmd <= we?CMD_WRITE:CMD_READ;
sd_addr <= { 4'b0010, addr[24], addr[8:1] }; // auto precharge
end
end
// ------------------------ no access --------------------------
else begin
if(q == STATE_CMD_START)
sd_cmd <= CMD_AUTO_REFRESH;
end
end
end
endmodule

30
cores/spectrum/spectrum.qpf Executable file
View File

@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2009 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.
#
# -------------------------------------------------------------------------- #
#
# Quartus II
# Version 9.1 Build 222 10/21/2009 SJ Web Edition
# Date created = 21:43:01 February 24, 2010
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "9.1"
DATE = "21:43:01 February 24, 2010"
# Revisions
PROJECT_REVISION = "spectrum"

577
cores/spectrum/spectrum.qsf Executable file
View File

@@ -0,0 +1,577 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2014 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.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 32-bit
# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
# Date created = 21:40:24 May 17, 2014
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# zx01_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
# 2) Altera recommends that you do not modify this file. This
# file is updated automatically by the Quartus II software
# and any changes you make may be lost or overwritten.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY "Cyclone III"
set_global_assignment -name DEVICE EP3C25E144C8
set_global_assignment -name TOP_LEVEL_ENTITY spectrum_mist
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name GENERATE_RBF_FILE ON
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
set_location_assignment PIN_7 -to LED
set_location_assignment PIN_22 -to CLOCK_50[0]
set_location_assignment PIN_23 -to CLOCK_50[1]
set_location_assignment PIN_128 -to CLOCK_32[0]
set_location_assignment PIN_129 -to CLOCK_32[1]
set_location_assignment PIN_54 -to CLOCK_27[0]
set_location_assignment PIN_55 -to CLOCK_27[1]
set_location_assignment PIN_144 -to VGA_R[5]
set_location_assignment PIN_143 -to VGA_R[4]
set_location_assignment PIN_142 -to VGA_R[3]
set_location_assignment PIN_141 -to VGA_R[2]
set_location_assignment PIN_137 -to VGA_R[1]
set_location_assignment PIN_135 -to VGA_R[0]
set_location_assignment PIN_133 -to VGA_B[5]
set_location_assignment PIN_132 -to VGA_B[4]
set_location_assignment PIN_125 -to VGA_B[3]
set_location_assignment PIN_121 -to VGA_B[2]
set_location_assignment PIN_120 -to VGA_B[1]
set_location_assignment PIN_115 -to VGA_B[0]
set_location_assignment PIN_114 -to VGA_G[5]
set_location_assignment PIN_113 -to VGA_G[4]
set_location_assignment PIN_112 -to VGA_G[3]
set_location_assignment PIN_111 -to VGA_G[2]
set_location_assignment PIN_110 -to VGA_G[1]
set_location_assignment PIN_106 -to VGA_G[0]
set_location_assignment PIN_136 -to VGA_VS
set_location_assignment PIN_119 -to VGA_HS
set_location_assignment PIN_65 -to AUDIO_L
set_location_assignment PIN_80 -to AUDIO_R
set_location_assignment PIN_46 -to UART_TX
set_location_assignment PIN_31 -to UART_RX
set_location_assignment PIN_105 -to SPI_DO
set_location_assignment PIN_88 -to SPI_DI
set_location_assignment PIN_126 -to SPI_SCK
set_location_assignment PIN_127 -to SPI_SS2
set_location_assignment PIN_91 -to SPI_SS3
set_location_assignment PIN_90 -to SPI_SS4
set_location_assignment PIN_13 -to CONF_DATA0
set_location_assignment PIN_49 -to SDRAM_A[0]
set_location_assignment PIN_44 -to SDRAM_A[1]
set_location_assignment PIN_42 -to SDRAM_A[2]
set_location_assignment PIN_39 -to SDRAM_A[3]
set_location_assignment PIN_4 -to SDRAM_A[4]
set_location_assignment PIN_6 -to SDRAM_A[5]
set_location_assignment PIN_8 -to SDRAM_A[6]
set_location_assignment PIN_10 -to SDRAM_A[7]
set_location_assignment PIN_11 -to SDRAM_A[8]
set_location_assignment PIN_28 -to SDRAM_A[9]
set_location_assignment PIN_50 -to SDRAM_A[10]
set_location_assignment PIN_30 -to SDRAM_A[11]
set_location_assignment PIN_32 -to SDRAM_A[12]
set_location_assignment PIN_83 -to SDRAM_DQ[0]
set_location_assignment PIN_79 -to SDRAM_DQ[1]
set_location_assignment PIN_77 -to SDRAM_DQ[2]
set_location_assignment PIN_76 -to SDRAM_DQ[3]
set_location_assignment PIN_72 -to SDRAM_DQ[4]
set_location_assignment PIN_71 -to SDRAM_DQ[5]
set_location_assignment PIN_69 -to SDRAM_DQ[6]
set_location_assignment PIN_68 -to SDRAM_DQ[7]
set_location_assignment PIN_86 -to SDRAM_DQ[8]
set_location_assignment PIN_87 -to SDRAM_DQ[9]
set_location_assignment PIN_98 -to SDRAM_DQ[10]
set_location_assignment PIN_99 -to SDRAM_DQ[11]
set_location_assignment PIN_100 -to SDRAM_DQ[12]
set_location_assignment PIN_101 -to SDRAM_DQ[13]
set_location_assignment PIN_103 -to SDRAM_DQ[14]
set_location_assignment PIN_104 -to SDRAM_DQ[15]
set_location_assignment PIN_58 -to SDRAM_BA[0]
set_location_assignment PIN_51 -to SDRAM_BA[1]
set_location_assignment PIN_85 -to SDRAM_DQMH
set_location_assignment PIN_67 -to SDRAM_DQML
set_location_assignment PIN_60 -to SDRAM_nRAS
set_location_assignment PIN_64 -to SDRAM_nCAS
set_location_assignment PIN_66 -to SDRAM_nWE
set_location_assignment PIN_59 -to SDRAM_nCS
set_location_assignment PIN_33 -to SDRAM_CKE
set_location_assignment PIN_43 -to SDRAM_CLK
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_NCE_PIN OFF
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name ENABLE_SIGNALTAP ON
set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp
set_global_assignment -name SLD_NODE_CREATOR_ID 110 -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_ENTITY_NAME sld_signaltap -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=AUTO" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_INFO=805334528" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_POWER_UP_TRIGGER=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ATTRIBUTE_MEM_MODE=OFF" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_FLOW_USE_GENERATED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_BITS=11" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_BUFFER_FULL_STOP=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_CURRENT_RESOURCE_WIDTH=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_IN_ENABLED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ADVANCED_TRIGGER_ENTITY=basic,1," -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL_PIPELINE=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ENABLE_ADVANCED_TRIGGER=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH=0" -section_id auto_signaltap_0
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name GLOBAL_SIGNAL "GLOBAL CLOCK" -to clk_8
set_instance_assignment -name GLOBAL_SIGNAL "GLOBAL CLOCK" -to clk_128
set_instance_assignment -name GLOBAL_SIGNAL "GLOBAL CLOCK" -to SDRAM_CLK
set_instance_assignment -name GLOBAL_SIGNAL "GLOBAL CLOCK" -to SPI_SCK
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQML
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQMH
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nRAS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCAS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nWE
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CKE
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CLK
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[0]
set_global_assignment -name VERILOG_FILE osd.v
set_global_assignment -name VERILOG_FILE user_io.v
set_global_assignment -name VHDL_FILE YM2149/YM2149_volmix.vhd
set_global_assignment -name VHDL_FILE YM2149/vol_table_array.vhd
set_global_assignment -name VHDL_FILE T80/T80se.vhd
set_global_assignment -name VHDL_FILE T80/T80_Reg.vhd
set_global_assignment -name VHDL_FILE T80/T80_Pack.vhd
set_global_assignment -name VHDL_FILE T80/T80_MCode.vhd
set_global_assignment -name VHDL_FILE T80/T80_ALU.vhd
set_global_assignment -name VHDL_FILE T80/T80.vhd
set_global_assignment -name VHDL_FILE clocks.vhd
set_global_assignment -name VHDL_FILE debugger.vhd
set_global_assignment -name VHDL_FILE keyboard.vhd
set_global_assignment -name QIP_FILE pll_main.qip
set_global_assignment -name VHDL_FILE ps2_intf.vhd
set_global_assignment -name VHDL_FILE spectrum_mist.vhd
set_global_assignment -name VHDL_FILE ula_port.vhd
set_global_assignment -name VHDL_FILE video.vhd
set_global_assignment -name VHDL_FILE zxmmc.vhd
set_global_assignment -name SIGNALTAP_FILE stp1.stp
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_clk -to "pll_main:pll|altpll:altpll_component|clk[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[0] -to SDRAM_A[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[1] -to SDRAM_A[10] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[2] -to SDRAM_A[11] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[3] -to SDRAM_A[12] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[4] -to SDRAM_A[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[5] -to SDRAM_A[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[6] -to SDRAM_A[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[7] -to SDRAM_A[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[8] -to SDRAM_A[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[9] -to SDRAM_A[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[10] -to SDRAM_A[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[11] -to SDRAM_A[8] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[12] -to SDRAM_A[9] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[13] -to SDRAM_nCAS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[14] -to SDRAM_nCS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[15] -to SDRAM_nRAS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[16] -to SDRAM_nWE -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[0] -to SDRAM_A[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[1] -to SDRAM_A[10] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[2] -to SDRAM_A[11] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[3] -to SDRAM_A[12] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[4] -to SDRAM_A[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[5] -to SDRAM_A[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[6] -to SDRAM_A[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[7] -to SDRAM_A[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[8] -to SDRAM_A[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[9] -to SDRAM_A[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[10] -to SDRAM_A[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[11] -to SDRAM_A[8] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[12] -to SDRAM_A[9] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[13] -to SDRAM_nCAS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[14] -to SDRAM_nCS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[15] -to SDRAM_nRAS -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[16] -to SDRAM_nWE -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[17] -to "T80se:cpu|A[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[18] -to "T80se:cpu|A[10]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[19] -to "T80se:cpu|A[11]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[20] -to "T80se:cpu|A[12]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[21] -to "T80se:cpu|A[13]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[22] -to "T80se:cpu|A[14]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[23] -to "T80se:cpu|A[15]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[24] -to "T80se:cpu|A[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[25] -to "T80se:cpu|A[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[26] -to "T80se:cpu|A[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[27] -to "T80se:cpu|A[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[28] -to "T80se:cpu|A[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[29] -to "T80se:cpu|A[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[30] -to "T80se:cpu|A[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[31] -to "T80se:cpu|A[8]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[32] -to "T80se:cpu|A[9]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[33] -to "T80se:cpu|CLKEN" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[34] -to "T80se:cpu|CLK_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[35] -to "T80se:cpu|DI[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[36] -to "T80se:cpu|DI[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[37] -to "T80se:cpu|DI[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[38] -to "T80se:cpu|DI[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[39] -to "T80se:cpu|DI[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[40] -to "T80se:cpu|DI[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[41] -to "T80se:cpu|DI[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[42] -to "T80se:cpu|DI[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[43] -to "T80se:cpu|DO[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[44] -to "T80se:cpu|DO[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[45] -to "T80se:cpu|DO[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[46] -to "T80se:cpu|DO[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[47] -to "T80se:cpu|DO[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[48] -to "T80se:cpu|DO[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[49] -to "T80se:cpu|DO[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[50] -to "T80se:cpu|DO[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[51] -to "T80se:cpu|RD_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[52] -to "T80se:cpu|WR_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[53] -to "clocks:clken|CLKEN_CPU" -section_id auto_signaltap_0
set_global_assignment -name QIP_FILE rom48.qip
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[116] -to ula_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[117] -to "video:vid|nRESET" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[118] -to "video:vid|nVID_RD" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[116] -to ula_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[117] -to "video:vid|nRESET" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[118] -to "video:vid|nVID_RD" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_DATA_BITS=119" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_BITS=119" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[17] -to "T80se:cpu|A[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[18] -to "T80se:cpu|A[10]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[19] -to "T80se:cpu|A[11]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[20] -to "T80se:cpu|A[12]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[21] -to "T80se:cpu|A[13]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[22] -to "T80se:cpu|A[14]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[23] -to "T80se:cpu|A[15]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[24] -to "T80se:cpu|A[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[25] -to "T80se:cpu|A[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[26] -to "T80se:cpu|A[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[27] -to "T80se:cpu|A[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[28] -to "T80se:cpu|A[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[29] -to "T80se:cpu|A[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[30] -to "T80se:cpu|A[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[31] -to "T80se:cpu|A[8]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[32] -to "T80se:cpu|A[9]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[33] -to "T80se:cpu|CLKEN" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[34] -to "T80se:cpu|CLK_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[35] -to "T80se:cpu|DI[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[36] -to "T80se:cpu|DI[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[37] -to "T80se:cpu|DI[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[38] -to "T80se:cpu|DI[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[39] -to "T80se:cpu|DI[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[40] -to "T80se:cpu|DI[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[41] -to "T80se:cpu|DI[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[42] -to "T80se:cpu|DI[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[43] -to "T80se:cpu|DO[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[44] -to "T80se:cpu|DO[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[45] -to "T80se:cpu|DO[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[46] -to "T80se:cpu|DO[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[47] -to "T80se:cpu|DO[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[48] -to "T80se:cpu|DO[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[49] -to "T80se:cpu|DO[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[50] -to "T80se:cpu|DO[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[51] -to "T80se:cpu|RD_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[52] -to "T80se:cpu|WR_n" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[53] -to "clocks:clken|CLKEN_CPU" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[54] -to "clocks:clken|CLKEN_PSG" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[55] -to "clocks:clken|CLKEN_VID" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[56] -to cpu_cycle -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[57] -to int_ram_write -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[58] -to mem_do[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[59] -to mem_do[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[60] -to mem_do[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[61] -to mem_do[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[62] -to mem_do[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[63] -to mem_do[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[64] -to mem_do[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[65] -to mem_do[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[66] -to ram_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[67] -to rom_do[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[68] -to rom_do[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[69] -to rom_do[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[70] -to rom_do[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[71] -to rom_do[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[72] -to rom_do[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[73] -to rom_do[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[74] -to rom_do[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[75] -to rom_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[76] -to "sdram:sdr|addr[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[77] -to "sdram:sdr|addr[10]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[78] -to "sdram:sdr|addr[11]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[79] -to "sdram:sdr|addr[12]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[80] -to "sdram:sdr|addr[13]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[81] -to "sdram:sdr|addr[14]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[82] -to "sdram:sdr|addr[15]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[83] -to "sdram:sdr|addr[16]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[84] -to "sdram:sdr|addr[17]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[85] -to "sdram:sdr|addr[18]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[86] -to "sdram:sdr|addr[19]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[87] -to "sdram:sdr|addr[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[88] -to "sdram:sdr|addr[20]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[89] -to "sdram:sdr|addr[21]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[90] -to "sdram:sdr|addr[22]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[91] -to "sdram:sdr|addr[23]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[92] -to "sdram:sdr|addr[24]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[93] -to "sdram:sdr|addr[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[94] -to "sdram:sdr|addr[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[95] -to "sdram:sdr|addr[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[96] -to "sdram:sdr|addr[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[97] -to "sdram:sdr|addr[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[98] -to "sdram:sdr|addr[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[99] -to "sdram:sdr|addr[8]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[100] -to "sdram:sdr|addr[9]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[101] -to "sdram:sdr|dout[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[102] -to "sdram:sdr|dout[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[103] -to "sdram:sdr|dout[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[104] -to "sdram:sdr|dout[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[105] -to "sdram:sdr|dout[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[106] -to "sdram:sdr|dout[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[107] -to "sdram:sdr|dout[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[108] -to "sdram:sdr|dout[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[109] -to "sdram:sdr|oe" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[110] -to "sdram:sdr|q[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[111] -to "sdram:sdr|q[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[112] -to "sdram:sdr|q[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[113] -to "sdram:sdr|we" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[114] -to sdram_oe -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[115] -to sdram_we -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[54] -to "clocks:clken|CLKEN_PSG" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[55] -to "clocks:clken|CLKEN_VID" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[56] -to cpu_cycle -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[57] -to int_ram_write -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[58] -to mem_do[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[59] -to mem_do[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[60] -to mem_do[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[61] -to mem_do[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[62] -to mem_do[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[63] -to mem_do[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[64] -to mem_do[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[65] -to mem_do[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[66] -to ram_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[67] -to rom_do[0] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[68] -to rom_do[1] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[69] -to rom_do[2] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[70] -to rom_do[3] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[71] -to rom_do[4] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[72] -to rom_do[5] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[73] -to rom_do[6] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[74] -to rom_do[7] -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[75] -to rom_enable -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[76] -to "sdram:sdr|addr[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[77] -to "sdram:sdr|addr[10]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[78] -to "sdram:sdr|addr[11]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[79] -to "sdram:sdr|addr[12]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[80] -to "sdram:sdr|addr[13]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[81] -to "sdram:sdr|addr[14]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[82] -to "sdram:sdr|addr[15]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[83] -to "sdram:sdr|addr[16]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[84] -to "sdram:sdr|addr[17]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[85] -to "sdram:sdr|addr[18]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[86] -to "sdram:sdr|addr[19]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[87] -to "sdram:sdr|addr[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[88] -to "sdram:sdr|addr[20]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[89] -to "sdram:sdr|addr[21]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[90] -to "sdram:sdr|addr[22]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[91] -to "sdram:sdr|addr[23]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[92] -to "sdram:sdr|addr[24]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[93] -to "sdram:sdr|addr[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[94] -to "sdram:sdr|addr[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[95] -to "sdram:sdr|addr[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[96] -to "sdram:sdr|addr[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[97] -to "sdram:sdr|addr[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[98] -to "sdram:sdr|addr[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[99] -to "sdram:sdr|addr[8]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[100] -to "sdram:sdr|addr[9]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[101] -to "sdram:sdr|dout[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[102] -to "sdram:sdr|dout[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[103] -to "sdram:sdr|dout[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[104] -to "sdram:sdr|dout[3]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[105] -to "sdram:sdr|dout[4]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[106] -to "sdram:sdr|dout[5]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[107] -to "sdram:sdr|dout[6]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[108] -to "sdram:sdr|dout[7]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[109] -to "sdram:sdr|oe" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[110] -to "sdram:sdr|q[0]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[111] -to "sdram:sdr|q[1]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[112] -to "sdram:sdr|q[2]" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[113] -to "sdram:sdr|we" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[114] -to sdram_oe -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[115] -to sdram_we -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_LOWORD=20707" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LENGTH=380" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SEGMENT_SIZE=512" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_HIWORD=40338" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SAMPLE_DEPTH=512" -section_id auto_signaltap_0
set_global_assignment -name SLD_FILE db/stp1_auto_stripped.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

1077
cores/spectrum/spectrum_mist.vhd Executable file

File diff suppressed because it is too large Load Diff

95
cores/spectrum/ula_port.vhd Executable file
View File

@@ -0,0 +1,95 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ula_port is
port (
CLK : in std_logic;
nRESET : in std_logic;
-- CPU interface with separate read/write buses
D_IN : in std_logic_vector(7 downto 0);
D_OUT : out std_logic_vector(7 downto 0);
ENABLE : in std_logic;
nWR : in std_logic;
BORDER_OUT : out std_logic_vector(2 downto 0);
EAR_OUT : out std_logic;
MIC_OUT : out std_logic;
KEYB_IN : in std_logic_vector(4 downto 0);
EAR_IN : in std_logic
);
end ula_port;
architecture ula_port_arch of ula_port is
begin
process(CLK,nRESET)
begin
if nRESET = '0' then
-- Output register
-- 7,6,5 = N/C
-- 4 = EAR
-- 3 = MIC
-- 2,1,0 = BORDER (G, R, B)
EAR_OUT <= '0';
MIC_OUT <= '0';
BORDER_OUT <= (others => '0');
-- Input register
D_OUT <= (others => '0');
elsif rising_edge(CLK) then
-- Register inputs
-- 7 = N/C
-- 6 = EAR
-- 5 = N/C
-- 4-0 = Keyboard
D_OUT <= '0' & EAR_IN & '0' & KEYB_IN;
if ENABLE = '1' and nWR = '0' then
-- Latch input data to output register
EAR_OUT <= D_IN(4);
MIC_OUT <= D_IN(3);
BORDER_OUT <= D_IN(2 downto 0);
end if;
end if;
end process;
end ula_port_arch;

189
cores/spectrum/user_io.v Normal file
View File

@@ -0,0 +1,189 @@
//
// user_io.v
//
// user_io for the MiST board
// http://code.google.com/p/mist-board/
//
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// parameter STRLEN and the actual length of conf_str have to match
module user_io #(parameter STRLEN=0) (
input [(8*STRLEN)-1:0] conf_str,
input SPI_CLK,
input SPI_SS_IO,
output reg SPI_MISO,
input SPI_MOSI,
output [5:0] JOY0,
output [5:0] JOY1,
output [1:0] BUTTONS,
output [1:0] SWITCHES,
output reg [7:0] status,
input clk,
output ps2_clk,
output reg ps2_data
);
reg [6:0] sbuf;
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [7:0] byte_cnt; // counts bytes
reg [5:0] joystick0;
reg [5:0] joystick1;
reg [3:0] but_sw;
assign JOY0 = joystick0;
assign JOY1 = joystick1;
assign BUTTONS = but_sw[1:0];
assign SWITCHES = but_sw[3:2];
// this variant of user_io is for 8 bit cores (type == a4) only
wire [7:0] core_type = 8'ha4;
// drive MISO only when transmitting core id
always@(negedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
SPI_MISO <= 1'bZ;
end else begin
// first byte returned is always core type, further bytes are
// command dependent
if(byte_cnt == 0) begin
SPI_MISO <= core_type[~bit_cnt];
end else begin
// reading config string
if(cmd == 8'h14) begin
// returning a byte from string
if(byte_cnt < STRLEN + 1)
SPI_MISO <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
else
SPI_MISO <= 1'b0;
end
end
end
end
// 8 byte fifo to store ps2 bytes
localparam PS2_FIFO_BITS = 3;
reg [7:0] ps2_fifo [(2**PS2_FIFO_BITS)-1:0];
reg [PS2_FIFO_BITS-1:0] ps2_wptr;
reg [PS2_FIFO_BITS-1:0] ps2_rptr;
// ps2 transmitter state machine
reg [3:0] ps2_tx_state;
reg [7:0] ps2_tx_byte;
reg ps2_parity;
assign ps2_clk = clk || (ps2_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_r_inc;
always@(posedge clk) begin
ps2_r_inc <= 1'b0;
if(ps2_r_inc)
ps2_rptr <= ps2_rptr + 1;
// transmitter is idle?
if(ps2_tx_state == 0) begin
// data in fifo present?
if(ps2_wptr != ps2_rptr) begin
// load tx register from fifo
ps2_tx_byte <= ps2_fifo[ps2_rptr];
ps2_r_inc <= 1'b1;
// reset parity
ps2_parity <= 1'b1;
// start transmitter
ps2_tx_state <= 4'd1;
// put start bit on data line
ps2_data <= 1'b0; // start bit is 0
end
end else begin
// transmission of 8 data bits
if((ps2_tx_state >= 1)&&(ps2_tx_state < 9)) begin
ps2_data <= ps2_tx_byte[0]; // data bits
ps2_tx_byte[6:0] <= ps2_tx_byte[7:1]; // shift down
if(ps2_tx_byte[0])
ps2_parity <= !ps2_parity;
end
// transmission of parity
if(ps2_tx_state == 9)
ps2_data <= ps2_parity;
// transmission of stop bit
if(ps2_tx_state == 10)
ps2_data <= 1'b1; // stop bit is 1
// advance state machine
if(ps2_tx_state < 11)
ps2_tx_state <= ps2_tx_state + 4'd1;
else
ps2_tx_state <= 4'd0;
end
end
// SPI receiver
always@(posedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
bit_cnt <= 3'd0;
byte_cnt <= 8'd0;
end else begin
sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
bit_cnt <= bit_cnt + 3'd1;
if(bit_cnt == 7) byte_cnt <= byte_cnt + 8'd1;
// finished reading command byte
if(bit_cnt == 7) begin
if(byte_cnt == 0)
cmd <= { sbuf, SPI_MOSI};
if(byte_cnt != 0) begin
if(cmd == 8'h01)
but_sw <= { sbuf[2:0], SPI_MOSI };
if(cmd == 8'h02)
joystick0 <= { sbuf[4:0], SPI_MOSI };
if(cmd == 8'h03)
joystick1 <= { sbuf[4:0], SPI_MOSI };
if(cmd == 8'h05) begin
// store incoming keyboard bytes in
ps2_fifo[ps2_wptr] <= { sbuf, SPI_MOSI };
ps2_wptr <= ps2_wptr + 1;
end
if(cmd == 8'h15) begin
status <= { sbuf[4:0], SPI_MOSI };
end
end
end
end
end
endmodule

384
cores/spectrum/video.vhd Executable file
View File

@@ -0,0 +1,384 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity video is
port(
-- Master clock (28 MHz)
CLK : in std_logic;
-- Video domain clock enable (14 MHz)
CLKEN : in std_logic;
-- Master reset
nRESET : in std_logic;
-- Mode
VGA : in std_logic;
-- Memory interface
VID_A : out std_logic_vector(12 downto 0);
VID_D_IN : in std_logic_vector(7 downto 0);
nVID_RD : out std_logic;
nWAIT : out std_logic;
-- IO interface
BORDER_IN : in std_logic_vector(2 downto 0);
-- Video outputs
R : out std_logic_vector(3 downto 0);
G : out std_logic_vector(3 downto 0);
B : out std_logic_vector(3 downto 0);
nVSYNC : out std_logic;
nHSYNC : out std_logic;
nCSYNC : out std_logic;
nHCSYNC : out std_logic;
IS_BORDER : out std_logic;
IS_VALID : out std_logic;
-- Clock outputs, might be useful
PIXCLK : out std_logic;
FLASHCLK : out std_logic;
-- Interrupt to CPU (asserted for 32 T-states, 64 ticks)
nIRQ : out std_logic
);
end video;
architecture video_arch of video is
signal pixels : std_logic_vector(9 downto 0);
signal attr : std_logic_vector(7 downto 0);
-- Video logic runs at 14 MHz so hcounter has an additonal LSb which is
-- skipped if running in VGA scan-doubled mode. The value of this
-- extra bit is 1/2 for the purposes of timing calculations bit 1 is
-- assumed to have a value of 1.
signal hcounter : std_logic_vector(9 downto 0);
-- vcounter has an extra LSb as well except this is skipped if running
-- in PAL mode. By not skipping it in VGA mode we get the required
-- double-scanning of each line. This extra bit has a value 1/2 as well.
signal vcounter : std_logic_vector(9 downto 0);
signal flashcounter : std_logic_vector(4 downto 0);
signal vblanking : std_logic;
signal hblanking : std_logic;
signal hpicture : std_logic;
signal vpicture : std_logic;
signal picture : std_logic;
signal blanking : std_logic;
signal hsync : std_logic;
signal vsync : std_logic;
signal red : std_logic;
signal green : std_logic;
signal blue : std_logic;
signal bright : std_logic;
signal dot : std_logic;
begin
-- The first 256 pixels of each line are valid picture
picture <= hpicture and vpicture;
blanking <= hblanking or vblanking;
-- Generate clocks and enables from internal signals
FLASHCLK <= flashcounter(4);
IS_VALID <= not blanking;
IS_BORDER <= not picture;
-- FIXME: This needs to be halved for PAL mode
PIXCLK <= CLK and CLKEN and nRESET;
-- Output syncs
nVSYNC <= not vsync;
nHSYNC <= not hsync;
nCSYNC <= not (vsync xor hsync);
-- Combined HSYNC/CSYNC. Feeds HSYNC to VGA HSYNC in VGA mode,
-- or CSYNC to the same pin in PAL mode
nHCSYNC <= not (vsync xor hsync) when VGA = '0' else
not hsync;
-- Determine the pixel colour
dot <= pixels(9) xor (flashcounter(4) and attr(7)); -- Combine delayed pixel with FLASH attr and clock state
red <= attr(1) when picture = '1' and dot = '1' else
attr(4) when picture = '1' and dot = '0' else
BORDER_IN(1) when blanking = '0' else
'0';
green <= attr(2) when picture = '1' and dot = '1' else
attr(5) when picture = '1' and dot = '0' else
BORDER_IN(2) when blanking = '0' else
'0';
blue <= attr(0) when picture = '1' and dot = '1' else
attr(3) when picture = '1' and dot = '0' else
BORDER_IN(0) when blanking = '0' else
'0';
bright <= attr(6) when picture = '1' else
'0';
-- Re-register video output to DACs to clean up edges
process(nRESET,CLK)
begin
if nRESET = '0' then
-- Asynchronous clear
R <= (others => '0');
G <= (others => '0');
B <= (others => '0');
elsif rising_edge(CLK) then
-- Output video to DACs
R <= (3 => red, others => bright and red);
G <= (3 => green, others => bright and green);
B <= (3 => blue, others => bright and blue);
end if;
end process;
-- This is what the contention model is supposed to look like.
-- We may need to emulate this to ensure proper compatibility.
--
-- At vcounter = 0 and hcounter = 0 we are at
-- 14336*T since the falling edge of the vsync.
-- This is where we start contending RAM access.
-- The contention pattern repeats every 8 T states, with
-- CPU clock held during the first 6 of every 8 T states
-- (where one T state is two ticks of the horizontal counter).
-- Two screen bytes are fetched consecutively, display first
-- followed by attribute. The cycle looks like this:
-- hcounter[3..1] = 000 Fetch data 1 nWAIT = 0
-- 001 Fetch attr 1 0
-- 010 Fetch data 2 0
-- 011 Fetch attr 2 0
-- 100 1
-- 101 1
-- 110 0
-- 111 0
-- What we actually do is the following, interleaved with CPU RAM access
-- so that we don't need any contention:
-- hcounter[2..0] = 000 Fetch data (LOAD)
-- 001 Fetch data (STORE)
-- 010 Fetch attr (LOAD)
-- 011 Fetch attr (STORE)
-- 100 Idle
-- 101 Idle
-- 110 Idle
-- 111 Idle
-- The load/store pairs take place over two clock enables. In VGA mode
-- there is one picture/attribute pair fetch per CPU clock enable. In PAL
-- mode every other tick is ignored, so the picture/attribute fetches occur
-- on alternate CPU clocks. At no time must a CPU cycle be allowed to split
-- a LOAD/STORE pair, as the bus routing logic will disconnect the memory from
-- the CPU during this time.
-- RAM address is generated continuously from the counter values
-- Pixel fetch takes place when hcounter(2) = 0, attribute when = 1
VID_A(12 downto 0) <=
-- Picture
vcounter(8 downto 7) & vcounter(3 downto 1) & vcounter(6 downto 4) & hcounter(8 downto 4)
when hcounter(2) = '0' else
-- Attribute
"110" & vcounter(8 downto 7) & vcounter(6 downto 4) & hcounter(8 downto 4);
-- This timing model is completely uncontended. CPU runs all the time.
nWAIT <= '1';
-- First 192 lines are picture
vpicture <= not (vcounter(9) or (vcounter(8) and vcounter(7)));
process(nRESET,CLK,CLKEN,hcounter,vcounter)
begin
if nRESET = '0' then
-- Asynchronous master reset
hcounter <= (others => '0');
vcounter <= (others => '0');
flashcounter <= (others => '0');
vblanking <= '0';
hblanking <= '0';
hpicture <= '1';
hsync <= '0';
vsync <= '0';
nIRQ <= '1';
nVID_RD <= '1';
pixels <= (others => '0');
attr <= (others => '0');
elsif rising_edge(CLK) and CLKEN = '1' then
-- Most functions are only performed when hcounter(0) is clear.
-- This is the 'half' bit inserted to allow for scan-doubled VGA output.
-- In VGA mode the counter will be stepped through the even values only,
-- so the rest of the logic remains the same.
if vpicture = '1' and hcounter(0) = '0' then
-- Pump pixel shift register - this is two pixels longer
-- than a byte to delay the pixels back into alignment with
-- the attribute byte, stored two ticks later
pixels(9 downto 1) <= pixels(8 downto 0);
if hcounter(9) = '0' and hcounter(3) = '0' then
-- Handle the fetch cycle
-- 3210
-- 0000 PICTURE LOAD
-- 0010 PICTURE STORE
-- 0100 ATTR LOAD
-- 0110 ATTR STORE
if hcounter(1) = '0' then
-- LOAD
-- Assert the read strobe during the active picture in the
-- first and third pixel of every 8. This splits a picture/attribute
-- fetch pair across two CPU cycles in PAL mode, or both in one cycle
-- in VGA mode
nVID_RD <= '0';
else
-- STORE
if hcounter(2) = '0' then
-- PICTURE
pixels(7 downto 0) <= VID_D_IN;
else
-- ATTR
attr <= VID_D_IN;
end if;
nVID_RD <= '1';
end if;
end if;
-- Delay horizontal picture enable until the end of the first fetch cycle
-- This also allows for the re-registration of the outputs
if hcounter(9) = '0' and hcounter(2 downto 1) = "11" then
hpicture <= '1';
end if;
if hcounter(9) = '1' and hcounter(2 downto 1) = "11" then
hpicture <= '0';
end if;
end if;
-- Step the horizontal counter and check for wrap
if VGA = '1' then
-- Counter wraps after 894 in VGA mode
if hcounter = "1101111110" then
hcounter <= (others => '0');
-- Increment vertical counter by ones for VGA so that
-- lines are double-scanned
vcounter <= vcounter + '1';
else
-- Increment horizontal counter
-- Even values only for VGA mode
hcounter <= hcounter + "10";
hcounter(0) <= '0';
end if;
else
-- Counter wraps after 895 in PAL mode
if hcounter = "1101111111" then
hcounter <= (others => '0');
-- Increment vertical counter by even values for PAL
vcounter <= vcounter + "10";
vcounter(0) <= '0';
else
-- Increment horizontal counter
-- All values for PAL mode
hcounter <= hcounter + '1';
end if;
end if;
--------------------
-- HORIZONTAL
--------------------
-- Each line comprises the following:
-- 256 pixels of active image
-- 48 pixels right border
-- 24 pixels front porch
-- 32 pixels sync
-- 40 pixels back porch
-- 48 pixels left border
-- Generate timing signals during inactive region
-- (when hcounter(9) = 1)
case hcounter(9 downto 4) is
-- Blanking starts at 304
when "100110" => hblanking <= '1';
-- Sync starts at 328
when "101001" => hsync <= '1';
-- Sync ends at 360
when "101101" => hsync <= '0';
-- Blanking ends at 400
when "110010" => hblanking <= '0';
when others =>
null;
end case;
-- Clear interrupt after 32T
if hcounter(7) = '1' then
nIRQ <= '1';
end if;
----------------
-- VERTICAL
----------------
case vcounter(9 downto 3) is
when "0111110" =>
-- Start of blanking and vsync(line 248)
vblanking <= '1';
vsync <= '1';
-- Assert vsync interrupt
nIRQ <= '0';
when "0111111" =>
-- End of vsync after 4 lines (line 252)
vsync <= '0';
when "1000000" =>
-- End of blanking and start of top border (line 256)
-- Should be line 264 but this is simpler and doesn't really make
-- any difference
vblanking <= '0';
when others =>
null;
end case;
-- Wrap vertical counter at line 312-1,
-- Top counter value is 623 for VGA, 622 for PAL
if vcounter(9 downto 1) = "100110111" then
if (VGA = '1' and vcounter(0) = '1') or VGA = '0' then
-- Start of picture area
vcounter <= (others => '0');
-- Increment the flash counter once per frame
flashcounter <= flashcounter + '1';
end if;
end if;
end if;
end process;
end video_arch;

170
cores/spectrum/zxmmc.vhd Executable file
View File

@@ -0,0 +1,170 @@
-- ZX Spectrum for Altera DE1
--
-- Copyright (c) 2009-2011 Mike Stirling
--
-- 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 agreement from the author.
--
-- * License is granted for non-commercial use only. A fee may not be charged
-- for redistributions as source code or in synthesized/hardware form without
-- specific prior written agreement from the author.
--
-- 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.
--
-- Emulation of ZXMMC+ interface
--
-- (C) 2011 Mike Stirling
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity zxmmc is
port (
CLOCK : in std_logic;
nRESET : in std_logic;
CLKEN : in std_logic;
-- Bus interface
ENABLE : in std_logic;
-- 0 - W - Card chip selects (active low)
-- 1 - RW - SPI tx/rx data register
-- 2 - Not used
-- 3 - RW - Paging control register
RS : in std_logic_vector(1 downto 0);
nWR : in std_logic;
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
-- SD card interface
SD_CS0 : out std_logic;
SD_CS1 : out std_logic;
SD_CLK : out std_logic;
SD_MOSI : out std_logic;
SD_MISO : in std_logic;
-- Paging control for external RAM/ROM banks
EXT_WR_EN : out std_logic; -- Enable writes to external RAM/ROM
EXT_RD_EN : out std_logic; -- Enable reads from external RAM/ROM (overlay internal ROM)
EXT_ROM_nRAM : out std_logic; -- Select external ROM or RAM banks
EXT_BANK : out std_logic_vector(4 downto 0); -- Selected bank number
-- DIP switches (reset values for corresponding bits above)
INIT_RD_EN : in std_logic;
INIT_ROM_nRAM : in std_logic
);
end entity;
architecture rtl of zxmmc is
signal counter : unsigned(3 downto 0);
-- Shift register has an extra bit because we write on the
-- falling edge and read on the rising edge
signal shift_reg : std_logic_vector(8 downto 0);
signal in_reg : std_logic_vector(7 downto 0);
signal paging_reg : std_logic_vector(7 downto 0);
begin
-- Input register read when RS=1
DO <=
in_reg when RS="01" else
paging_reg when RS="11" else
(others => '1');
-- Paging control outputs from register
EXT_WR_EN <= paging_reg(7);
EXT_RD_EN <= paging_reg(6);
EXT_ROM_nRAM <= paging_reg(5);
EXT_BANK <= paging_reg(4 downto 0);
-- SD card outputs from clock divider and shift register
SD_CLK <= counter(0);
SD_MOSI <= shift_reg(8);
-- Chip selects
process(CLOCK,nRESET)
begin
if nRESET = '0' then
SD_CS0 <= '1';
SD_CS1 <= '1';
elsif rising_edge(CLOCK) and CLKEN = '1' then
if ENABLE = '1' and RS = "00" and nWR = '0' then
-- The two chip select outputs are controlled directly
-- by writes to the lowest two bits of the control register
SD_CS0 <= DI(0);
SD_CS1 <= DI(1);
end if;
end if;
end process;
-- Paging register writes
process(CLOCK,nRESET)
begin
if nRESET = '0' then
paging_reg <= "0" & INIT_RD_EN & INIT_ROM_nRAM & "00000";
elsif rising_edge(CLOCK) and CLKEN = '1' then
if ENABLE = '1' and RS = "11" and nWR = '0' then
paging_reg <= DI;
end if;
end if;
end process;
-- SPI write
process(CLOCK,nRESET)
begin
if nRESET = '0' then
shift_reg <= (others => '1');
in_reg <= (others => '1');
counter <= "1111"; -- Idle
elsif rising_edge(CLOCK) and CLKEN = '1' then
if counter = "1111" then
-- Store previous shift register value in input register
in_reg <= shift_reg(7 downto 0);
-- Idle - check for a bus access
if ENABLE = '1' and RS = "01" then
-- Write loads shift register with data
-- Read loads it with all 1s
if nWR = '1' then
shift_reg <= (others => '1');
else
shift_reg <= DI & '1';
end if;
counter <= "0000"; -- Initiates transfer
end if;
else
-- Transfer in progress
counter <= counter + 1;
if counter(0) = '0' then
-- Input next bit on rising edge
shift_reg(0) <= SD_MISO;
else
-- Output next bit on falling edge
shift_reg <= shift_reg(7 downto 0) & '1';
end if;
end if;
end if;
end process;
end architecture;