Añado core Kyp

This commit is contained in:
antoniovillena 2016-10-02 21:18:17 +02:00
parent 87dbbbc14e
commit ca2814fb53
50 changed files with 1992 additions and 1691 deletions

View File

@ -3,7 +3,7 @@ SET speed=3
SET ruta_ucf=..\src\Atomic
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=2
SET ruta_ucf=..\src\AcornElectron
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=..\source\apple2
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=a2601
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=..\src\bbc_micro
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=2
SET ruta_ucf=jupiter_ace
SET ruta_bat=..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -0,0 +1,336 @@
-- #####################################################################################
--
-- #### #### #####
-- ## ## ## ##
-- ## ## ##### ## ## ##### ## ###### ##### ##### ##### ## ##
-- ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
-- ## ## ## ## ## ## ## ## ##### ## ## ## ## ## ## ## ##
-- ## ## ## ## ## ## ###### ## ###### ###### ## ## ######
-- ## ## ## ## ## ## ## ## ## ## ## ## ##
-- ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ##
-- #### ######## ##### # ##### ##### ## ##### ##### ##### #####
--
-- #####################################################################################
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity ay8910 is
port( -----------------------------------------
CLK : in std_logic; -- System Clock
CLC : in std_logic; -- PSG Clock
RESET : in std_logic; -- Chip Reset (set all Registers to '0', active low)
BDIR : in std_logic; -- Bus Direction (0 - read , 1 - write)
CS : in std_logic; -- Chip Select (active low)
BC : in std_logic; -- Bus control
DI : in std_logic_vector(7 downto 0); -- Data In
DO : out std_logic_vector(7 downto 0); -- Data Out
OUT_A : out std_logic_vector(7 downto 0); -- PSG Output channel A
OUT_B : out std_logic_vector(7 downto 0); -- PSG Output channel B
OUT_C : out std_logic_vector(7 downto 0) -- PSG Output channel C
); -----------------------------------------
end ay8910;
architecture rtl of ay8910 is
signal ClockDiv : unsigned (3 downto 0); -- Divide CLC
----------------------- AY Registers ----------------------
signal Period_A : std_logic_vector (11 downto 0); -- Channel A Tone Period (R1:R0)
signal Period_B : std_logic_vector (11 downto 0); -- Channel B Tone Period (R3:R2)
signal Period_C : std_logic_vector (11 downto 0); -- Channel C Tone Period (R5:R4)
signal Period_N : std_logic_vector (4 downto 0); -- Noise Period (R6)
signal Enable : std_logic_vector (7 downto 0); -- Enable (R7)
signal Volume_A : std_logic_vector (4 downto 0); -- Channel A Amplitude (R10)
signal Volume_B : std_logic_vector (4 downto 0); -- Channel B Amplitude (R11)
signal Volume_C : std_logic_vector (4 downto 0); -- Channel C Amplitude (R12)
signal Period_E : std_logic_vector (15 downto 0); -- Envelope Period (R14:R13)
signal Shape : std_logic_vector (3 downto 0); -- Envelope Shape/Cycle (R15)
signal Port_A : std_logic_vector (7 downto 0); -- I/O Port A Data Store (R16)
signal Port_B : std_logic_vector (7 downto 0); -- I/O Port B Data Store (R17)
-----------------------------------------------------------
signal Address : std_logic_vector (3 downto 0); -- Selected Register
alias Continue : std_logic is Shape(3); ------------- Envelope Control
alias Attack : std_logic is Shape(2); --
alias Alternate : std_logic is Shape(1); --
alias Hold : std_logic is Shape(0); -------------
signal Reset_Req : std_logic; ------------------------- Envelope Reset Required
signal Reset_Ack : std_logic; ------------------------- Envelope Reset Acknoledge
signal Volume_E : std_logic_vector (3 downto 0); -- Envelope Volume
signal Freq_A : std_logic; -- Tone Generator A Output
signal Freq_B : std_logic; -- Tone Generator B Output
signal Freq_C : std_logic; -- Tone Generator C Output
signal Freq_N : std_logic; -- Noise Generator Output
function VolumeTable (value : std_logic_vector(3 downto 0)) return std_logic_vector is
variable result : std_logic_vector (7 downto 0);
begin
case value is ----------------------------------- Volume Table
when "1111" => result := "11111111";
when "1110" => result := "10110100";
when "1101" => result := "01111111";
when "1100" => result := "01011010";
when "1011" => result := "00111111";
when "1010" => result := "00101101";
when "1001" => result := "00011111";
when "1000" => result := "00010110";
when "0111" => result := "00001111";
when "0110" => result := "00001011";
when "0101" => result := "00000111";
when "0100" => result := "00000101";
when "0011" => result := "00000011";
when "0010" => result := "00000010";
when "0001" => result := "00000001";
when "0000" => result := "00000000";
when others => null;---------------------------
end case;
return result;
end VolumeTable;
begin
------------------------- Write to AY ---------------------
process (RESET , CLK)
begin
if RESET = '0' then
Address <= "0000";
Period_A <= "000000000000";
Period_B <= "000000000000";
Period_C <= "000000000000";
Period_N <= "00000";
Enable <= "00000000";
Volume_A <= "00000";
Volume_B <= "00000";
Volume_C <= "00000";
Period_E <= "0000000000000000";
Shape <= "0000";
Port_A <= "00000000";
Port_B <= "00000000";
Reset_Req <= '0';
elsif rising_edge(CLK) then
if CS = '0' and BDIR = '1' then
if BC = '1' then
Address <= DI (3 downto 0); ----------------- Latch Address
else
case Address is ------------------------------- Latch Registers
when "0000" => Period_A (7 downto 0) <= DI;
when "0001" => Period_A (11 downto 8) <= DI (3 downto 0);
when "0010" => Period_B (7 downto 0) <= DI;
when "0011" => Period_B (11 downto 8) <= DI (3 downto 0);
when "0100" => Period_C (7 downto 0) <= DI;
when "0101" => Period_C (11 downto 8) <= DI (3 downto 0);
when "0110" => Period_N <= DI (4 downto 0);
when "0111" => Enable <= DI;
when "1000" => Volume_A <= DI (4 downto 0);
when "1001" => Volume_B <= DI (4 downto 0);
when "1010" => Volume_C <= DI (4 downto 0);
when "1011" => Period_E (7 downto 0) <= DI;
when "1100" => Period_E (15 downto 8) <= DI;
when "1101" => Shape <= DI (3 downto 0);
Reset_Req <= not Reset_Ack; -- Reset Envelope Generator
when "1110" => Port_A <= DI;
when "1111" => Port_B <= DI;
when others => null;
end case;
end if;
end if;
end if;
end process;
------------------------- Read from AY --------------------
DO <= Period_A (7 downto 0) when Address = "0000" and CS = '0' and BDIR = '0' and BC = '1' else
"0000" & Period_A (11 downto 8) when Address = "0001" and CS = '0' and BDIR = '0' and BC = '1' else
Period_B (7 downto 0) when Address = "0010" and CS = '0' and BDIR = '0' and BC = '1' else
"0000" & Period_B (11 downto 8) when Address = "0011" and CS = '0' and BDIR = '0' and BC = '1' else
Period_C (7 downto 0) when Address = "0100" and CS = '0' and BDIR = '0' and BC = '1' else
"0000" & Period_C (11 downto 8) when Address = "0101" and CS = '0' and BDIR = '0' and BC = '1' else
"000" & Period_N when Address = "0110" and CS = '0' and BDIR = '0' and BC = '1' else
Enable when Address = "0111" and CS = '0' and BDIR = '0' and BC = '1' else
"000" & Volume_A when Address = "1000" and CS = '0' and BDIR = '0' and BC = '1' else
"000" & Volume_B when Address = "1001" and CS = '0' and BDIR = '0' and BC = '1' else
"000" & Volume_C when Address = "1010" and CS = '0' and BDIR = '0' and BC = '1' else
Period_E (7 downto 0) when Address = "1011" and CS = '0' and BDIR = '0' and BC = '1' else
Period_E (15 downto 8) when Address = "1100" and CS = '0' and BDIR = '0' and BC = '1' else
"0000" & Shape when Address = "1101" and CS = '0' and BDIR = '0' and BC = '1' else
-- Port_A when Address = "1110" and CS = '0' and BDIR = '0' and BC = '1' else
-- Port_B when Address = "1111" and CS = '0' and BDIR = '0' and BC = '1' else
"11111111";
-------------------------- Divide CLC ---------------------
process (RESET , CLK)
begin
if RESET = '0' then
ClockDiv <= "0000";
elsif rising_edge(CLK) then
if CLC = '1' then
ClockDiv <= ClockDiv - 1;
end if;
end if;
end process;
------------------------ Tone Generator -------------------
process (RESET , CLK)
variable Counter_A : unsigned (11 downto 0);
variable Counter_B : unsigned (11 downto 0);
variable Counter_C : unsigned (11 downto 0);
begin
if RESET = '0' then
Counter_A := "000000000000";
Counter_B := "000000000000";
Counter_C := "000000000000";
Freq_A <= '0';
Freq_B <= '0';
Freq_C <= '0';
elsif rising_edge(CLK) then
if ClockDiv(2 downto 0) = "000" and CLC = '1' then
-- Channel A Counter
if (Counter_A /= X"000") then
Counter_A := Counter_A - 1;
elsif (Period_A /= X"000") then
Counter_A := unsigned(Period_A) - 1;
end if;
if (Counter_A = X"000") then
Freq_A <= not Freq_A;
end if;
-- Channel B Counter
if (Counter_B /= X"000") then
Counter_B := Counter_B - 1;
elsif (Period_B /= X"000") then
Counter_B := unsigned(Period_B) - 1;
end if;
if (Counter_B = X"000") then
Freq_B <= not Freq_B;
end if;
-- Channel C Counter
if (Counter_C /= X"000") then
Counter_C := Counter_C - 1;
elsif (Period_C /= X"000") then
Counter_C := unsigned(Period_C) - 1;
end if;
if (Counter_C = X"000") then
Freq_C <= not Freq_C;
end if;
end if;
end if;
end process;
----------------------- Noise Generator -------------------
process (RESET , CLK)
variable NoiseShift : unsigned (16 downto 0);
variable Counter_N : unsigned (4 downto 0);
begin
if RESET = '0' then
Counter_N := "00000";
NoiseShift := "00000000000000001";
elsif rising_edge(CLK) then
if ClockDiv(2 downto 0) = "000" and CLC = '1' then
if (Counter_N /= "00000") then
Counter_N := Counter_N - 1;
elsif (Period_N /= "00000") then
Counter_N := unsigned(Period_N) - 1;
end if;
if Counter_N = "00000" then
NoiseShift := (NoiseShift(0) xor NoiseShift(2)) & NoiseShift(16 downto 1);
end if;
Freq_N <= NoiseShift(0);
end if;
end if;
end process;
---------------------- Envelope Generator -----------------
process (RESET , CLK)
variable EnvCounter : unsigned(15 downto 0);
variable EnvWave : unsigned(4 downto 0);
begin
if RESET = '0' then
EnvCounter := "0000000000000000";
EnvWave := "11111";
Volume_E <= "0000";
Reset_Ack <= '0';
elsif rising_edge(CLK) then
if ClockDiv = "0000" and CLC = '1' then
------------ Envelope Period Counter -----------
if (EnvCounter /= X"0000" and Reset_Req = Reset_Ack) then
EnvCounter := EnvCounter - 1;
elsif (Period_E /= X"0000") then
EnvCounter := unsigned(Period_E) - 1;
end if;
------------ Envelope Phase Counter ------------
if (Reset_Req /= Reset_Ack) then
EnvWave := (others => '1');
elsif (EnvCounter = X"0000" and (EnvWave(4) = '1' or (Hold = '0' and Continue = '1'))) then
EnvWave := EnvWave - 1;
end if;
---------- Envelope Amplitude Counter ----------
for I in 3 downto 0 loop
if (EnvWave(4) = '0' and Continue = '0') then
Volume_E(I) <= '0';
elsif (EnvWave(4) = '1' or (Alternate xor Hold) = '0') then
Volume_E(I) <= EnvWave(I) xor Attack;
else
Volume_E(I) <= EnvWave(I) xor Attack xor '1';
end if;
end loop;
Reset_Ack <= Reset_Req;
end if;
end if;
end process;
--------------------------- Mixer -------------------------
process (RESET , CLK)
begin
if RESET = '0' then
OUT_A <= "00000000";
OUT_B <= "00000000";
OUT_C <= "00000000";
elsif rising_edge(CLK) then
if CLC = '1' then
if (((Enable(0) or Freq_A) and (Enable(3) or Freq_N)) = '0') then
OUT_A <= "00000000";
elsif (Volume_A(4) = '0') then
OUT_A <= VolumeTable(Volume_A(3 downto 0));
else
OUT_A <= VolumeTable(Volume_E);
end if;
if (((Enable(1) or Freq_B) and (Enable(4) or Freq_N)) = '0') then
OUT_B <= "00000000";
elsif (Volume_B(4) = '0') then
OUT_B <= VolumeTable(Volume_B(3 downto 0));
else
OUT_B <= VolumeTable(Volume_E);
end if;
if (((Enable(2) or Freq_C) and (Enable(5) or Freq_N)) = '0') then
OUT_C <= "00000000";
elsif (Volume_C(4) = '0') then
OUT_C <= VolumeTable(Volume_C(3 downto 0));
else
OUT_C <= VolumeTable(Volume_E);
end if;
end if;
end if;
end process;
end rtl;

View File

@ -7,92 +7,56 @@ library unisim;
entity clock is
port
(
clock32 : in std_logic;
clockCPU : out std_logic;
clockVGA : out std_logic;
clockPS2 : out std_logic;
clockDAC : out std_logic;
clockAY : out std_logic
clock50 : in std_logic;
clock14 : out std_logic; -- 14.000 MHz
clock70 : out std_logic; -- 7.000 MHz
clock35 : out std_logic -- 3.500 Mhz
);
end;
architecture behavioral of clock is
signal ci32 : std_logic;
signal c1fb : std_logic;
signal c2fb : std_logic;
signal co25 : std_logic;
signal co14 : std_logic;
signal cfb : std_logic;
signal c50 : std_logic;
signal c14 : std_logic;
signal count : std_logic_vector(1 downto 0);
begin
Uibufg : ibufg port map(i => clock32, o => ci32);
IbufgVGA : bufg port map(i => co25, o => clockVGA);
IbufgPS2 : bufg port map(i => ci32, o => clockPS2);
IbufgDAC : bufg port map(i => co14, o => clockDAC);
IbufgCPU : bufg port map(i => count(1), o => clockCPU);
IbufgAY : bufg port map(i => count(1), o => clockAY);
Uibufg : ibufg port map(i => clock50, o => c50);
Uclock14 : bufg port map(i => c14, o => clock14);
Uclock70 : bufg port map(i => count(0), o => clock70);
Uclock35 : bufg port map(i => count(1), o => clock35);
Uclock1 : pll_base -- clkout0 = 25.143 MHz
uclock : pll_base
generic map
(
bandwidth => "optimized",
clk_feedback => "clkfbout",
compensation => "system_synchronous",
compensation => "internal",
clkin_period => 20.000,
ref_jitter => 0.010,
divclk_divide => 1,
clkfbout_mult => 22,
clkfbout_mult => 14,
clkfbout_phase => 0.000,
clkout0_divide => 28,
clkout0_divide => 50,
clkout0_phase => 0.000,
clkout0_duty_cycle => 0.500,
clkin_period => 31.250,
ref_jitter => 0.010
clkout0_duty_cycle => 0.500
)
port map
(
rst => '0',
clkin => ci32,
clkfbin => c1fb,
clkout0 => co25,
clkfbin => cfb,
clkfbout => cfb,
clkin => c50,
clkout0 => c14,
clkout1 => open,
clkout2 => open,
clkout3 => open,
clkout4 => open,
clkout5 => open,
locked => open,
clkfbout => c1fb
locked => open
);
Uclock2 : pll_base -- clkout0 = 14 MHz
generic map
(
bandwidth => "optimized",
clk_feedback => "clkfbout",
compensation => "system_synchronous",
divclk_divide => 1,
clkfbout_mult => 28,
clkfbout_phase => 0.000,
clkout0_divide => 64,
clkout0_phase => 0.000,
clkout0_duty_cycle => 0.500,
clkin_period => 31.250,
ref_jitter => 0.010
)
port map
(
rst => '0',
clkin => ci32,
clkfbin => c2fb,
clkout0 => co14,
clkout1 => open,
clkout2 => open,
clkout3 => open,
clkout4 => open,
clkout5 => open,
locked => open,
clkfbout => c2fb
);
count <= count+1 when rising_edge(co14);
count <= count+1 when falling_edge(c14);
end;

34
cores/KypSpectrum/dac.v Normal file
View File

@ -0,0 +1,34 @@
`define MSBI 9 // Most significant Bit of DAC input
// this is a delta-sigma digital to analog converter
module dac (o, i, clock, reset);
output o; // this is the average output that feeds low pass filter
input [`MSBI:0] i; // dac input (excess 2**msbi)
input clock;
input reset;
reg o; // for optimum performance, ensure that this ff is in IOB
reg [`MSBI+2:0] DeltaAdder; // Output of Delta adder
reg [`MSBI+2:0] SigmaAdder; // Output of Sigma adder
reg [`MSBI+2:0] SigmaLatch = 1'b1 << (`MSBI+1); // Latches output of Sigma adder
reg [`MSBI+2:0] DeltaB; // B input of Delta adder
always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1);
always @(i or DeltaB) DeltaAdder = i + DeltaB;
always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch;
always @(posedge clock or posedge reset)
begin
if(reset)
begin
SigmaLatch <= #1 1'b1 << (`MSBI+1);
o <= #1 1'b0;
end
else
begin
SigmaLatch <= #1 SigmaAdder;
o <= #1 SigmaLatch[`MSBI+2];
end
end
endmodule

View File

@ -23,7 +23,7 @@ entity dac is
generic
(
msbi : integer := 9
msbi : integer := 7
);
port
(
@ -42,12 +42,25 @@ architecture rtl of dac is
begin
process(clock, reset)
begin
if reset = '0' then
s <= to_unsigned(2**(msbi+1), s'length);
o <= '0';
elsif rising_edge(clock) then
s <= s+unsigned(s(msbi+2)&s(msbi+2)&i);
o <= s(msbi+2);
-- if reset = '0' then
-- s <= to_unsigned(2**(msbi+1), s'length);
-- o <= '0';
-- elsif rising_edge(clock) then
-- s <= s+unsigned(s(msbi+2)&s(msbi+2)&i);
-- o <= s(msbi+2);
-- end if;
if rising_edge(clock)
then
if reset = '0'
then
s <= to_unsigned(2**(msbi+1), s'length);
o <= '0';
else
s <= s+unsigned(s(msbi+2)&s(msbi+2)&i);
o <= s(msbi+2);
end if;
end if;
end process seq;
end;

67
cores/KypSpectrum/div.vhd Normal file
View File

@ -0,0 +1,67 @@
library ieee;
use ieee.std_logic_1164.all;
entity div is
port
(
clock : in std_logic;
reset : in std_logic;
mreq : in std_logic;
iorq : in std_logic;
m1 : in std_logic;
rd : in std_logic;
wr : in std_logic;
di : in std_logic_vector( 7 downto 0);
a : in std_logic_vector(15 downto 0);
--
automap : out std_logic;
conmem : out std_logic;
mapram : out std_logic;
page : out std_logic_vector( 3 downto 0)
);
end;
architecture behavioral of div is
signal m1on : std_logic := '0';
begin
process(clock)
begin
if rising_edge(clock)
then
if reset = '0'
then
m1on <= '0';
automap <= '0';
conmem <= '0';
mapram <= '0';
page <= (others => '0');
else
if iorq = '0' and wr = '0' and a(7 downto 0) = x"E3"
then
conmem <= di(7);
mapram <= di(6);-- or mapram;
page <= di(3 downto 0);
end if;
if mreq = '0' and m1 = '0'
then
if a = x"0000" or a = x"0008" or a = x"0038" or a = x"0066" or a = x"04C6" or a = x"0562"
then
m1on <= '1'; -- activate automapper after this cycle
elsif a(15 downto 3) = x"1ff"&'1'
then
m1on <= '0'; -- deactivate automapper after this cycle
elsif a(15 downto 8) = x"3D"
then
automap <= '1';
m1on <= '1'; -- activate automapper immediately
end if;
end if;
if m1 = '1' then automap <= m1on; end if;
end if;
end if;
end process;
end;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,140 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2016 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file drom.vhd when simulating
-- the core, drom. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY drom IS
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END drom;
ARCHITECTURE drom_a OF drom IS
-- synthesis translate_off
COMPONENT wrapped_drom
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_drom USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 13,
c_addrb_width => 13,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "FF",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 1,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "drom.mif",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 1,
c_mem_type => 3,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 8192,
c_read_depth_b => 8192,
c_read_width_a => 8,
c_read_width_b => 8,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 1,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 8192,
c_write_depth_b => 8192,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 8,
c_write_width_b => 8,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_drom
PORT MAP (
clka => clka,
ena => ena,
addra => addra,
douta => douta
);
-- synthesis translate_on
END drom_a;

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2015 Xilinx, Inc. --
-- (c) Copyright 1995-2016 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,152 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2016 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file vram.vhd when simulating
-- the core, vram. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY vram IS
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END vram;
ARCHITECTURE vram_a OF vram IS
-- synthesis translate_off
COMPONENT wrapped_vram
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_vram USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 13,
c_addrb_width => 13,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 1,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 8192,
c_read_depth_b => 8192,
c_read_width_a => 8,
c_read_width_b => 8,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 8192,
c_write_depth_b => 8192,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 8,
c_write_width_b => 8,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_vram
PORT MAP (
clka => clka,
ena => ena,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END vram_a;

View File

@ -4,17 +4,19 @@ library ieee;
entity keyboard is
port
(
boot : out std_logic;
reset : out std_logic;
nmi : out std_logic;
received : in std_logic;
scancode : in std_logic_vector(7 downto 0);
rows : in std_logic_vector(7 downto 0);
cols : out std_logic_vector(4 downto 0);
reset : out std_logic
cols : out std_logic_vector(4 downto 0)
);
end;
architecture behavioral of keyboard is
type matrix is array (53 downto 0) of std_logic;
type matrix is array (57 downto 0) of std_logic;
signal keys : matrix := (others => '1');
signal pressed : std_logic := '0';
@ -93,6 +95,11 @@ begin
when x"49" => keys(45) <= pressed; -- .
when x"41" => keys(46) <= pressed; -- ,
when x"03" => keys(54) <= pressed; -- F5
when x"78" => keys(57) <= pressed; -- F11
when x"07" => keys(55) <= pressed; -- F12
when x"76" => keys(56) <= pressed; -- ESCAPE
when others => null;
end case;
else
@ -113,66 +120,70 @@ begin
end process;
cols(0) <= ( keys( 0) or rows(0) ) and -- CS
( keys( 5) or rows(1) ) and -- A
( keys(10) or rows(2) ) and -- Q
( keys(15) or rows(3) ) and -- 1
( keys(20) or rows(4) ) and -- 0
( keys(25) or rows(5) ) and -- P
( keys(30) or rows(6) ) and -- ENTER
( keys(35) or rows(7) ) and -- SPACE
( keys(43) or rows(0) ) and -- DELETE(CS)
( keys(43) or rows(4) ) and -- DELETE(0)
( keys(50) or rows(0) ) and -- UP(CS)
( keys(51) or rows(0) ) and -- DOWN(CS)
( keys(52) or rows(0) ) and -- LEFT(CS)
( keys(53) or rows(0) ); -- RIGHT(CS)
( keys( 5) or rows(1) ) and -- A
( keys(10) or rows(2) ) and -- Q
( keys(15) or rows(3) ) and -- 1
( keys(20) or rows(4) ) and -- 0
( keys(25) or rows(5) ) and -- P
( keys(30) or rows(6) ) and -- ENTER
( keys(35) or rows(7) ) and -- SPACE
( keys(43) or rows(0) ) and -- DELETE(CS)
( keys(43) or rows(4) ) and -- DELETE(0)
( keys(50) or rows(0) ) and -- UP(CS)
( keys(51) or rows(0) ) and -- DOWN(CS)
( keys(52) or rows(0) ) and -- LEFT(CS)
( keys(53) or rows(0) ) and -- RIGHT(CS)
( keys(56) or rows(0) ) and -- ESC
( keys(56) or rows(7) ); -- ESC
cols(1) <= ( keys( 1) or rows(0) ) and -- Z
( keys( 6) or rows(1) ) and -- S
( keys(11) or rows(2) ) and -- W
( keys(16) or rows(3) ) and -- 2
( keys(21) or rows(4) ) and -- 9
( keys(26) or rows(5) ) and -- O
( keys(31) or rows(6) ) and -- L
( keys(36) or rows(7) ) and -- SS
( keys(44) or rows(7) ) and -- -(SS)
( keys(45) or rows(7) ) and -- .(SS)
( keys(46) or rows(7) ); -- ,(SS)
( keys( 6) or rows(1) ) and -- S
( keys(11) or rows(2) ) and -- W
( keys(16) or rows(3) ) and -- 2
( keys(21) or rows(4) ) and -- 9
( keys(26) or rows(5) ) and -- O
( keys(31) or rows(6) ) and -- L
( keys(36) or rows(7) ) and -- SS
( keys(44) or rows(7) ) and -- -(SS)
( keys(45) or rows(7) ) and -- .(SS)
( keys(46) or rows(7) ); -- ,(SS)
cols(2) <= ( keys( 2) or rows(0) ) and -- X
( keys( 7) or rows(1) ) and -- D
( keys(12) or rows(2) ) and -- E
( keys(17) or rows(3) ) and -- 3
( keys(22) or rows(4) ) and -- 8
( keys(27) or rows(5) ) and -- I
( keys(32) or rows(6) ) and -- K
( keys(37) or rows(7) ) and -- M
( keys(45) or rows(7) ) and -- .(M)
( keys(53) or rows(4) ); -- RIGHT(8)
( keys( 7) or rows(1) ) and -- D
( keys(12) or rows(2) ) and -- E
( keys(17) or rows(3) ) and -- 3
( keys(22) or rows(4) ) and -- 8
( keys(27) or rows(5) ) and -- I
( keys(32) or rows(6) ) and -- K
( keys(37) or rows(7) ) and -- M
( keys(45) or rows(7) ) and -- .(M)
( keys(53) or rows(4) ); -- RIGHT(8)
cols(3) <= ( keys( 3) or rows(0) ) and -- C
( keys( 8) or rows(1) ) and -- F
( keys(13) or rows(2) ) and -- R
( keys(18) or rows(3) ) and -- 4
( keys(23) or rows(4) ) and -- 7
( keys(28) or rows(5) ) and -- U
( keys(33) or rows(6) ) and -- J
( keys(38) or rows(7) ) and -- N
( keys(44) or rows(6) ) and -- -(J)
( keys(46) or rows(7) ) and -- ,(N)
( keys(50) or rows(4) ); -- UP(7)
( keys( 8) or rows(1) ) and -- F
( keys(13) or rows(2) ) and -- R
( keys(18) or rows(3) ) and -- 4
( keys(23) or rows(4) ) and -- 7
( keys(28) or rows(5) ) and -- U
( keys(33) or rows(6) ) and -- J
( keys(38) or rows(7) ) and -- N
( keys(44) or rows(6) ) and -- -(J)
( keys(46) or rows(7) ) and -- ,(N)
( keys(50) or rows(4) ); -- UP(7)
cols(4) <= ( keys( 4) or rows(0) ) and -- V
( keys( 9) or rows(1) ) and -- G
( keys(14) or rows(2) ) and -- T
( keys(19) or rows(3) ) and -- 5
( keys(24) or rows(4) ) and -- 6
( keys(29) or rows(5) ) and -- Y
( keys(34) or rows(6) ) and -- H
( keys(39) or rows(7) ) and -- B
( keys(52) or rows(3) ) and -- LEFT(5)
( keys(51) or rows(4) ); -- DOWN(7)
( keys( 9) or rows(1) ) and -- G
( keys(14) or rows(2) ) and -- T
( keys(19) or rows(3) ) and -- 5
( keys(24) or rows(4) ) and -- 6
( keys(29) or rows(5) ) and -- Y
( keys(34) or rows(6) ) and -- H
( keys(39) or rows(7) ) and -- B
( keys(52) or rows(3) ) and -- LEFT(5)
( keys(51) or rows(4) ); -- DOWN(7)
reset <= not ((keys(40) and keys(47)) or (keys(41) and keys(48)) or (keys(42) and keys(49)));
nmi <= keys(54);
boot <= keys(57);
reset <= keys(55) and ((keys(40) and keys(47)) or (keys(41) and keys(48)) or (keys(42) and keys(49)));
end;

View File

@ -1,356 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.mapa_es.all;
entity keyboard is
port
(
clock : in std_logic;
ps2c : in std_logic;
ps2d : in std_logic;
rows : in std_logic_vector(7 downto 0);
cols : out std_logic_vector(4 downto 0)
);
end;
architecture behavioral of keyboard is
type key_matrix is array (7 downto 0) of std_logic_vector(4 downto 0);
signal keys : key_matrix;
signal pressed : std_logic;
-- signal isctrl : std_logic;
signal isshift : std_logic;
-- signal isalt : std_logic;
signal isextend : std_logic;
signal lastclk : std_logic_vector(4 downto 0);
signal bit_count : unsigned (3 downto 0);
signal shiftreg : std_logic_vector(8 downto 0);
signal parity : std_logic;
begin
process(clock)
begin
if rising_edge(clock) then
-- rst <= '1';
-- nmi <= '1';
-- mrst <= '1';
lastclk <= lastclk(3 downto 0) & ps2c;
if lastclk = "11100" and ps2c = '0' then -- detector de flanco de bajada de PS2CLK
if bit_count = 0 then
parity <= '0';
if ps2d = '0' then bit_count <= bit_count+1; end if;
else
if bit_count < 10 then
bit_count <= bit_count+1;
shiftreg <= ps2d&shiftreg(8 downto 1);
parity <= parity xor ps2d;
elsif ps2d = '1' then
bit_count <= (others => '0');
if parity = '1' then -- nueva pulsacion completa en shiftreg.
pressed <= '1';
-- scancode <= shiftreg(7 downto 0);
if isextend = '1' and shiftreg(7 downto 0) = KEY_RELEASED then isextend <= '1'; else isextend <= '0'; end if; -- procesar la secuencia E0 F0 key
case shiftreg(7 downto 0) is -- detectar secuencias especiales: tecla soltada y tecla extendida
when KEY_RELEASED => pressed <= '0';
when KEY_EXTENDED => isextend <= '1';
when others =>
end case;
if isextend='0' then -- teclas no extendidas
case shiftreg(7 downto 0) is
when KEY_LSHIFT |
KEY_RSHIFT => isshift <= pressed;
-- when KEY_ALTI => isalt <= pressed;
-- joy(4) <= pressed; -- dato entregado por el joystick
when KEY_CTRLI => keys(0)(0) <= pressed; -- Ctrl izquierdo: (CAPS SHIFT)
-- isctrl <= pressed;
-- joy(4) <= pressed; -- dato entregado por el joystick
when KEY_Z => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(0)(1) <= pressed; -- Z
when KEY_X => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(0)(2) <= pressed; -- X
when KEY_C => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(0)(3) <= pressed; -- C
when KEY_V => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(0)(4) <= pressed; -- V
when KEY_A => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(1)(0) <= pressed; -- A
when KEY_S => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(1)(1) <= pressed; -- S
when KEY_D => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(1)(2) <= pressed; -- D
when KEY_F => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(1)(3) <= pressed; -- F
when KEY_G => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(1)(4) <= pressed; -- G
when KEY_Q => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(2)(0) <= pressed; -- Q
when KEY_W => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(2)(1) <= pressed; -- W
when KEY_E => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(2)(2) <= pressed; -- E
when KEY_R => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(2)(3) <= pressed; -- R
when KEY_T => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(2)(4) <= pressed; -- T
when KEY_1 => if isshift='0' then
keys(3)(0) <= pressed; -- 1
else
keys(7)(1) <= pressed;
keys(3)(0) <= pressed; -- !
end if;
when KEY_2 => if isshift='0' then
keys(3)(1) <= pressed; -- 2
else
keys(7)(1) <= pressed;
keys(5)(0) <= pressed; -- "
end if;
when KEY_3 => if isshift='0' then
keys(3)(2) <= pressed; -- 3
else
keys(7)(1) <= pressed;
keys(3)(2) <= pressed; -- #
end if;
when KEY_4 => if isshift='0' then
keys(3)(3) <= pressed; -- 4
else
keys(7)(1) <= pressed;
keys(3)(3) <= pressed; -- $
end if;
when KEY_5 => if isshift='0' then
keys(3)(4) <= pressed; -- 5
else
keys(7)(1) <= pressed;
keys(3)(4) <= pressed; -- $
end if;
when KEY_0 => if isshift='0' then
keys(4)(0) <= pressed; -- 0
else
keys(7)(1) <= pressed;
keys(6)(1) <= pressed; -- =
end if;
when KEY_9 => if isshift='0' then
keys(4)(1) <= pressed; -- 9
else
keys(7)(1) <= pressed;
keys(4)(1) <= pressed; -- )
end if;
when KEY_8 => if isshift='0' then
keys(4)(2) <= pressed; -- 8
else
keys(7)(1) <= pressed;
keys(4)(2) <= pressed; -- (
end if;
when KEY_7 => if isshift='0' then
keys(4)(3) <= pressed; -- 7
else
keys(7)(1) <= pressed;
keys(0)(4) <= pressed; -- /
end if;
when KEY_6 => if isshift='0' then
keys(4)(4) <= pressed; -- 6
else
keys(7)(1) <= pressed;
keys(4)(4) <= pressed; -- &
end if;
when KEY_P => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(5)(0) <= pressed; -- P
when KEY_O => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(5)(1) <= pressed; -- O
when KEY_I => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(5)(2) <= pressed; -- I
when KEY_U => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(5)(3) <= pressed; -- U
when KEY_Y => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(5)(4) <= pressed; -- Y
when KEY_ENTER => keys(6)(0) <= pressed; -- ENTER
when KEY_L => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(6)(1) <= pressed; -- L
when KEY_K => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(6)(2) <= pressed; -- K
when KEY_J => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(6)(3) <= pressed; -- J
when KEY_H => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(6)(4) <= pressed; -- H
when KEY_SPACE => keys(7)(0) <= pressed; -- SPACE
when KEY_M => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(7)(2) <= pressed; -- M
when KEY_N => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(7)(3) <= pressed; -- N
when KEY_B => if isshift='1' then
keys(0)(0) <= pressed;
end if;
keys(7)(4) <= pressed; -- B
when KEY_BKSP => keys(0)(0) <= pressed; -- Backspace (Caps 0)
keys(4)(0) <= pressed;
-- if isctrl='1' and isalt='1' then
-- mrst <= '0';
-- end if;
when KEY_CPSLK => keys(0)(0) <= pressed; -- Caps lock (Caps 2)
keys(3)(1) <= pressed;
when KEY_ESC => keys(0)(0) <= pressed; -- Break (Caps Space)
keys(7)(0) <= pressed;
when KEY_F2 => keys(0)(0) <= pressed;
keys(3)(0) <= pressed; -- EDIT
when KEY_BL => keys(7)(1) <= pressed;
keys(1)(2) <= pressed; -- usado con EXT, da \
when KEY_APOS => keys(7)(1) <= pressed;
if isshift='0' then
keys(4)(3) <= pressed; -- apostrofe '
else
keys(0)(3) <= pressed; -- tecla ?
end if;
when KEY_TAB => keys(0)(0) <= pressed;
keys(7)(1) <= pressed; -- modo extendido
when KEY_CORCHA => keys(7)(1) <= pressed;
keys(6)(4) <= pressed; -- simbolo ^
when KEY_CORCHC => keys(7)(1) <= pressed;
if isshift='0' then
keys(6)(2) <= pressed; -- simbolo +
else
keys(7)(4) <= pressed; -- simbolo *
end if;
when KEY_LLAVA => keys(7)(1) <= pressed;
keys(1)(3) <= pressed; -- llave abierta, con EXT
when KEY_LLAVC => keys(7)(1) <= pressed;
keys(5)(0) <= pressed; -- copyright
when KEY_LT => keys(7)(1) <= pressed;
if isshift='0' then
keys(2)(3) <= pressed; -- símbolo <
else
keys(2)(4) <= pressed; -- símbolo >
end if;
when KEY_COMA => keys(7)(1) <= pressed;
if isshift='0' then
keys(7)(3) <= pressed; -- símbolo ,
else
keys(5)(1) <= pressed; -- símbolo ;
end if;
when KEY_PUNTO => keys(7)(1) <= pressed;
if isshift='0' then
keys(7)(2) <= pressed; -- símbolo .
else
keys(0)(1) <= pressed; -- símbolo :
end if;
when KEY_MENOS => keys(7)(1) <= pressed;
if isshift='0' then
keys(6)(3) <= pressed; -- símbolo -
else
keys(4)(0) <= pressed; -- tecla _ (guion bajo)
end if;
-- when KEY_F5 => if isctrl='1' and isalt='1' then
-- nmi <= '0'; -- NMI
-- end if;
-- when KEY_KPPUNTO => if isctrl='1' and isalt='1' then
-- rst <= '0'; -- reset al hacer ctrl-alt-supr
-- end if;
-- when KEY_KP4 => joy(1) <= pressed; -- dato entregado por el joystick: izquierda
-- when KEY_KP6 => joy(0) <= pressed; -- dato entregado por el joystick: derecha
-- when KEY_KP8 => joy(3) <= pressed; -- dato entregado por el joystick: arriba
-- when KEY_KP5 => joy(2) <= pressed; -- dato entregado por el joystick: abajo
when others=> null;
end case;
else -- process extended keys
case shiftreg(7 downto 0) is
when KEY_CTRLD => keys(7)(1) <= pressed; -- Ctrl derecho -> symbol shift
-- isctrl <= pressed;
-- joy(4) <= pressed; -- dato entregado por el joystick
-- when KEY_ALTGR => keys(0)(0) <= pressed;
-- keys(4)(1) <= pressed; -- Modo gráfico
-- isalt <= '1';
-- joy(4) <= pressed; -- dato entregado por el joystick
when KEY_LEFT => keys(0)(0) <= pressed; -- Left (Caps 5)
keys(3)(4) <= pressed;
when KEY_DOWN => keys(0)(0) <= pressed; -- Down (Caps 6)
keys(4)(4) <= pressed;
when KEY_UP => keys(0)(0) <= pressed; -- Up (Caps 7)
keys(4)(3) <= pressed;
when KEY_RIGHT => keys(0)(0) <= pressed; -- Right (Caps 8)
keys(4)(2) <= pressed;
-- when KEY_SUP => if isctrl='1' and isalt='1' then
-- rst <= '0'; -- reset al hacer ctrl-alt-supr
-- end if;
when others => null;
end case;
end if;
end if;
else
bit_count <= (others => '0');
end if;
end if;
end if;
end if;
end process;
process(keys, rows)
variable tmp: std_logic;
begin
for i in 0 to 4 loop
tmp := '0';
for j in 0 to 7 loop tmp := tmp or (keys(j)(i) and not rows(j)); end loop;
cols(i) <= not tmp;
end loop;
end process;
end;

View File

@ -1,9 +0,0 @@
SET machine=zxpp
SET speed=2
SET ruta_ucf=papilio
SET ruta_bat=..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
rem call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
call %ruta_bat%generar.bat Pa

View File

@ -7,10 +7,9 @@ entity mixer is
(
clock : in std_logic;
reset : in std_logic;
speaker : in std_logic;
ear : in std_logic;
mic : in std_logic;
ay : in std_logic_vector(7 downto 0);
speaker : in std_logic;
l : out std_logic;
r : out std_logic
);
@ -18,35 +17,45 @@ end;
architecture behavioral of mixer is
signal tmp : std_logic_vector(2 downto 0);
signal src : std_logic_vector(2 downto 0);
signal ula : std_logic_vector(7 downto 0);
signal sum : std_logic_vector(9 downto 0);
signal mix : std_logic_vector(9 downto 0);
signal o : std_logic;
signal mix : std_logic_vector(7 downto 0);
begin
tmp <= ear&mic&speaker;
ula <= x"11" when tmp = "000"
else x"24" when tmp = "010"
else x"B8" when tmp = "001"
else x"C0" when tmp = "011"
else x"16" when tmp = "100"
else x"30" when tmp = "110"
else x"F4" when tmp = "101"
process(clock)
variable tmp : std_logic_vector(3 downto 0) := (others => '0');
begin
if falling_edge(clock)
then
tmp := tmp+1;
if tmp = 0 then mix <= ula; else mix <= (others => '0'); end if;
end if;
end process;
src <= ear&mic&speaker;
ula <= x"11" when src = "000"
else x"24" when src = "010"
else x"B8" when src = "001"
else x"C0" when src = "011"
else x"16" when src = "100"
else x"30" when src = "110"
else x"F4" when src = "101"
else x"FF";
sum <= ("00"&ay)+("00"&ula);
mix <= sum when rising_edge(clock);
Udac: entity work.dac port map
UdacL: entity work.dac port map
(
clock => clock,
reset => reset,
i => mix,
o => o
o => l
);
UdacR: entity work.dac port map
(
clock => clock,
reset => reset,
i => mix,
o => r
);
l <= o;
r <= o;
end;

View File

@ -0,0 +1,307 @@
module multiboot (
input wire clk_icap, // WARNING: this clock must not be greater than 20MHz (50ns period)
input wire mrst_n
);
reg [4:0] q = 5'b00000;
reg reboot_ff = 1'b0;
always @(posedge clk_icap) begin
q[0] <= ~mrst_n;
q[1] <= q[0];
q[2] <= q[1];
q[3] <= q[2];
q[4] <= q[3];
reboot_ff <= (q[4] && (!q[3]) && (!q[2]) && (!q[1]) );
end
multiboot_spartan6 hacer_multiboot (
.CLK(clk_icap),
.MBT_RESET(1'b0),
.MBT_REBOOT(reboot_ff),
.spi_addr(24'h000000)
);
endmodule
module multiboot_spartan6 (
input wire CLK,
input wire MBT_RESET,
input wire MBT_REBOOT,
input wire [23:0] spi_addr
);
reg [15:0] icap_din;
reg icap_ce;
reg icap_wr;
reg [15:0] ff_icap_din_reversed;
reg ff_icap_ce;
reg ff_icap_wr;
ICAP_SPARTAN6 ICAP_SPARTAN6_inst (
.CE (ff_icap_ce), // Clock enable input
.CLK (CLK), // Clock input
.I (ff_icap_din_reversed), // 16-bit data input
.WRITE (ff_icap_wr) // Write input
);
// -------------------------------------------------
// -- State Machine for ICAP_SPARTAN6 MultiBoot --
// -------------------------------------------------
parameter IDLE = 0,
SYNC_H = 1,
SYNC_L = 2,
CWD_H = 3,
CWD_L = 4,
GEN1_H = 5,
GEN1_L = 6,
GEN2_H = 7,
GEN2_L = 8,
GEN3_H = 9,
GEN3_L = 10,
GEN4_H = 11,
GEN4_L = 12,
GEN5_H = 13,
GEN5_L = 14,
NUL_H = 15,
NUL_L = 16,
MOD_H = 17,
MOD_L = 18,
HCO_H = 19,
HCO_L = 20,
RBT_H = 21,
RBT_L = 22,
NOOP_0 = 23,
NOOP_1 = 24,
NOOP_2 = 25,
NOOP_3 = 26;
reg [4:0] state;
reg [4:0] next_state;
always @*
begin: COMB
case (state)
IDLE:
begin
if (MBT_REBOOT)
begin
next_state = SYNC_H;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'hAA99; // Sync word 1
end
else
begin
next_state = IDLE;
icap_ce = 1;
icap_wr = 1;
icap_din = 16'hFFFF; // Null
end
end
SYNC_H:
begin
next_state = SYNC_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h5566; // Sync word 2
end
SYNC_L:
begin
next_state = NUL_H;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h30A1; // Write to Command Register....
end
NUL_H:
begin
// next_state = NUL_L;
next_state = GEN1_H;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h0000; // Null Command issued.... value = 0x0000
end
//Q
GEN1_H:
begin
next_state = GEN1_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h3261; // Escritura a reg GENERAL_1 (bit boot en caliente)
end
GEN1_L:
begin
next_state = GEN2_H;
icap_ce = 0;
icap_wr = 0;
icap_din = spi_addr[15:0]; //16'hC000; // dreccion SPI BAJA
end
GEN2_H:
begin
next_state = GEN2_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h3281; // Escritura a reg GENERAL_2
end
GEN2_L:
begin
next_state = MOD_H;
icap_ce = 0;
icap_wr = 0;
icap_din = {8'h6B, spi_addr[23:16]}; // 16'h030A; // 03 lectura SPI opcode + direccion SPI ALTA (03 = 1x, 6B = 4x)
end
/////// Registro MODE (para carga a 4x tras reboot)
MOD_H:
begin
next_state = MOD_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h3301; // Escritura a reg MODE
end
MOD_L:
begin
next_state = NUL_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h3100; // Activamos bit de lectura a modo 4x en el proceso de Config
end
/////
NUL_L:
begin
next_state = RBT_H;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h30A1; // Write to Command Register....
end
RBT_H:
begin
next_state = RBT_L;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h000E; // REBOOT Command 0x000E
end
//--------------------
RBT_L:
begin
next_state = NOOP_0;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h2000; // NOOP
end
NOOP_0:
begin
next_state = NOOP_1;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h2000; // NOOP
end
NOOP_1:
begin
next_state = NOOP_2;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h2000; // NOOP
end
NOOP_2:
begin
next_state = NOOP_3;
icap_ce = 0;
icap_wr = 0;
icap_din = 16'h2000; // NOOP
end
//--------------------
NOOP_3:
begin
next_state = IDLE;
icap_ce = 1;
icap_wr = 1;
icap_din = 16'h1111; // NULL value
end
default:
begin
next_state = IDLE;
icap_ce = 1;
icap_wr = 1;
icap_din = 16'h1111; // 16'h1111"
end
endcase
end
always @(posedge CLK)
begin: SEQ
if (MBT_RESET)
state <= IDLE;
else
state <= next_state;
end
always @(posedge CLK)
begin: ICAP_FF
ff_icap_din_reversed[0] <= icap_din[7]; //need to reverse bits to ICAP module since D0 bit is read first
ff_icap_din_reversed[1] <= icap_din[6];
ff_icap_din_reversed[2] <= icap_din[5];
ff_icap_din_reversed[3] <= icap_din[4];
ff_icap_din_reversed[4] <= icap_din[3];
ff_icap_din_reversed[5] <= icap_din[2];
ff_icap_din_reversed[6] <= icap_din[1];
ff_icap_din_reversed[7] <= icap_din[0];
ff_icap_din_reversed[8] <= icap_din[15];
ff_icap_din_reversed[9] <= icap_din[14];
ff_icap_din_reversed[10] <= icap_din[13];
ff_icap_din_reversed[11] <= icap_din[12];
ff_icap_din_reversed[12] <= icap_din[11];
ff_icap_din_reversed[13] <= icap_din[10];
ff_icap_din_reversed[14] <= icap_din[9];
ff_icap_din_reversed[15] <= icap_din[8];
ff_icap_ce <= icap_ce;
ff_icap_wr <= icap_wr;
end
endmodule

View File

@ -1,63 +0,0 @@
# UCF file for the Papilio Pro board
# Generated by pin_converter, written by Kevin Lindsey
# https://github.com/thelonious/papilio_pins/tree/development/pin_converter
# Main board wing pin [] to FPGA pin Pxx map
# -------C------- -------B------- -------A-------
# [GND] [C00] P114 [GND] [B00] P99 P100 [A15]
# [2V5] [C01] P115 [2V5] [B01] P97 P98 [A14]
# [3V3] [C02] P116 [3V3] [B02] P92 P93 [A13]
# [5V0] [C03] P117 [5V0] [B03] P87 P88 [A12]
# [C04] P118 [B04] P84 P85 [A11] [5V0]
# [C05] P119 [B05] P82 P83 [A10] [3V3]
# [C06] P120 [B06] P80 P81 [A09] [2V5]
# [C07] P121 [B07] P78 P79 [A08] [GND]
# [GND] [C08] P123 [GND] [B08] P74 P75 [A07]
# [2V5] [C09] P124 [2V5] [B09] P95 P67 [A06]
# [3V3] [C10] P126 [3V3] [B10] P62 P66 [A05]
# [5V0] [C11] P127 [5V0] [B11] P59 P61 [A04]
# [C12] P131 [B12] P57 P58 [A03] [5V0]
# [C13] P132 [B13] P55 P56 [A02] [3V3]
# [C14] P133 [B14] P50 P51 [A01] [2V5]
# [C15] P134 [B15] P47 P48 [A00] [GND]
## Prohibit the automatic placement of pins that are connected to VCC or GND for configuration.
CONFIG PROHIBIT=P144;
CONFIG PROHIBIT=P69;
CONFIG PROHIBIT=P60;
NET netCLK LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK
NET netRST LOC="P85" | IOSTANDARD=LVTTL | PULLDOWN; # A11
NET netNMI LOC="P95" | IOSTANDARD=LVTTL | PULLDOWN; # B9 -- SW(2)
NET ps2CLK LOC="P115" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C1
NET ps2DAT LOC="P114" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C0
NET joyBTN(0) LOC="P123" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C8 -- JOYSTICK A1
NET joyBTN(1) LOC="P126" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C10 -- JOYSTICK A2
NET joyBTN(2) LOC="P127" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C11 -- JOYSTICK A3
NET joyBTN(3) LOC="P132" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C13 -- JOYSTICK A4
NET joyBTN(4) LOC="P124" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # C9 -- JOYSTICK A6
# joy+5 # -- JOYSTICK A7
NET joyGND LOC="P131" | IOSTANDARD=LVTTL; # C12 -- JOYSTICK A8
NET audioL LOC="P98" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # A14
NET audioR LOC="P100" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # A15
NET audioEAR LOC="P57" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B12 -- JOYSTICK B1
NET audioGND LOC="P48" | IOSTANDARD=LVTTL; # C12 -- JOYSTICK B8
# audio+5 # -- JOYSTICK B7
NET videoV LOC="P116" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C2
NET videoH LOC="P117" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C3
NET videoR(0) LOC="P118" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C4
NET videoR(1) LOC="P119" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C5
NET videoR(2) LOC="P120" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C6
NET videoR(3) LOC="P121" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C7
NET videoG(0) LOC="P84" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B4
NET videoG(1) LOC="P82" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B5
NET videoG(2) LOC="P80" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B6
NET videoG(3) LOC="P78" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B7
NET videoB(0) LOC="P99" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B0
NET videoB(1) LOC="P97" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B1
NET videoB(2) LOC="P92" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B2
NET videoB(3) LOC="P87" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B3

View File

@ -5,9 +5,9 @@ library ieee;
entity ps2 is
port
(
clock : in std_logic;
ps2c : inout std_logic;
ps2d : inout std_logic;
clockPs2 : in std_logic;
clock : inout std_logic;
data : inout std_logic;
received : out std_logic;
scancode : out std_logic_vector(7 downto 0)
);
@ -20,8 +20,8 @@ architecture behavioral of ps2 is
constant state_waiting : std_logic_vector(1 downto 0) := "10";
constant state_received : std_logic_vector(1 downto 0) := "11";
constant minClockPulseLen : natural := 30*32; -- 30us @ 32MHz
constant maxClockPulseLen : natural := 50*32; -- 50us @ 32MHz
constant minClockPulseLen : natural := 30*7; -- 30us @ 7 MHz
constant maxClockPulseLen : natural := 50*7; -- 50us @ 7 MHz
type reg is
record
@ -57,13 +57,15 @@ architecture behavioral of ps2 is
);
begin
ps2c <= 'Z';
ps2d <= 'Z';
clock <= 'Z';
data <= 'Z';
received <= r.dataReceived;
scancode <= r.scancode;
process(r, ps2d, ps2c)
r <= n when rising_edge(clockPs2);
process(r, clock, data)
begin
n <= r;
@ -72,7 +74,7 @@ begin
n.ps2lastClkDeglitched <= r.ps2clkDeglitched;
-- Deglitch the clock signal
if ps2c = '1' then
if clock = '1' then
if r.ps2clkDeglitch < 31 then
n.ps2clkDeglitch <= r.ps2clkDeglitch+1;
else
@ -89,7 +91,7 @@ begin
end if;
-- Deglitch the data signal
if ps2d = '1' then
if data = '1' then
if r.ps2dataDeglitch < 31 then
n.ps2dataDeglitch <= r.ps2dataDeglitch+1;
else
@ -153,9 +155,4 @@ begin
end case;
end process;
process(clock, n)
begin
if rising_edge(clock) then r <= n; end if;
end process;
end;

27
cores/KypSpectrum/ram.vhd Normal file
View File

@ -0,0 +1,27 @@
library ieee;
use ieee.std_logic_1164.all;
entity ram is
port
(
wr : in std_logic;
di : in std_logic_vector( 7 downto 0);
do : out std_logic_vector( 7 downto 0);
a : in std_logic_vector(18 downto 0);
--
sramWr : out std_logic;
sramData : inout std_logic_vector( 7 downto 0);
sramAddr : out std_logic_vector(18 downto 0)
);
end;
architecture structural of ram is
begin
sramWr <= wr;
sramData <= di when wr = '0' else (others => 'Z');
sramAddr <= a;
do <= sramData;
end;

57
cores/KypSpectrum/sd.vhd Normal file
View File

@ -0,0 +1,57 @@
library ieee;
use ieee.std_logic_1164.all;
entity sd is
port
(
clock : in std_logic;
pause : out std_logic;
iorq : in std_logic;
rd : in std_logic;
wr : in std_logic;
oe : out std_logic;
di : in std_logic_vector( 7 downto 0);
do : out std_logic_vector( 7 downto 0);
a : in std_logic_vector(15 downto 0);
--
sdClock : out std_logic;
sdCs : out std_logic;
sdDi : out std_logic;
sdDo : in std_logic
);
end;
architecture behavioral of sd is
signal rx : std_logic;
signal tx : std_logic;
begin
process(clock)
begin
if rising_edge(clock)
then
if iorq = '0' and wr = '0' and (a(7 downto 0) = x"1F" or a(7 downto 0) = x"E7") then sdCs <= di(0); end if;
end if;
end process;
rx <= '1' when iorq = '0' and rd = '0' and (a(7 downto 0) = x"3F" or a(7 downto 0) = x"EB") else '0';
tx <= '1' when iorq = '0' and wr = '0' and (a(7 downto 0) = x"3F" or a(7 downto 0) = x"EB") else '0';
Uspi : entity work.spi port map
(
clk => clock,
enviar_dato => tx,
recibir_dato => rx,
din => di,
dout => do,
oe_n => oe,
wait_n => pause,
--
spi_clk => sdClock,
spi_di => sdDi,
spi_do => sdDo
);
end;

111
cores/KypSpectrum/spi.v Normal file
View File

@ -0,0 +1,111 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 20:24:47 03/04/2014
// Design Name:
// Module Name: spi
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module spi (
input wire clk, // 7MHz
input wire enviar_dato, // a 1 para indicar que queremos enviar un dato por SPI
input wire recibir_dato,// a 1 para indicar que queremos recibir un dato
input wire [7:0] din, // del bus de datos de salida de la CPU
output reg [7:0] dout, // al bus de datos de entrada de la CPU
output reg oe_n, // el dato en dout es válido
output reg wait_n,
output wire spi_clk, // Interface SPI
output wire spi_di, //
input wire spi_do //
);
// Modulo SPI.
reg ciclo_lectura = 1'b0; // ciclo de lectura en curso
reg ciclo_escritura = 1'b0; // ciclo de escritura en curso
reg [4:0] contador = 5'b00000; // contador del FSM (ciclos)
reg [7:0] data_to_spi; // dato a enviar a la spi por DI
reg [7:0] data_from_spi; // dato a recibir desde la spi
reg [7:0] data_to_cpu; // ultimo dato recibido correctamente
assign spi_clk = contador[0]; // spi_CLK es la mitad que el reloj del módulo
assign spi_di = data_to_spi[7]; // la transmisión es del bit 7 al 0
initial wait_n = 1'b1;
always @(posedge clk) begin
if (enviar_dato && !ciclo_escritura) begin // si ha sido señalizado, iniciar ciclo de escritura
ciclo_escritura <= 1'b1;
ciclo_lectura <= 1'b0;
contador <= 5'b00000;
data_to_spi <= din;
wait_n <= 1'b0;
end
else if (recibir_dato && !ciclo_lectura) begin // si no, si mirar si hay que iniciar ciclo de lectura
ciclo_lectura <= 1'b1;
ciclo_escritura <= 1'b0;
contador <= 5'b00000;
data_to_cpu <= data_from_spi;
data_from_spi <= 8'h00;
data_to_spi <= 8'hFF; // mientras leemos, MOSI debe estar a nivel alto!
wait_n <= 1'b0;
end
// FSM para enviar un dato a la spi
else if (ciclo_escritura==1'b1) begin
if (contador!=5'b10000) begin
if (contador == 5'b01000)
wait_n <= 1'b1;
if (spi_clk==1'b1) begin
data_to_spi <= {data_to_spi[6:0],1'b0};
data_from_spi <= {data_from_spi[6:0],spi_do};
end
contador <= contador + 1;
end
else begin
if (!enviar_dato)
ciclo_escritura <= 1'b0;
end
end
// FSM para leer un dato de la spi
else if (ciclo_lectura==1'b1) begin
if (contador!=5'b10000) begin
if (contador == 5'b01000)
wait_n <= 1'b1;
if (spi_clk==1'b1)
data_from_spi <= {data_from_spi[6:0],spi_do};
contador <= contador + 1;
end
else begin
if (!recibir_dato)
ciclo_lectura <= 1'b0;
end
end
end
always @* begin
if (recibir_dato) begin
dout = data_to_cpu;
oe_n = 1'b0;
end
else begin
dout = 8'hZZ;
oe_n = 1'b1;
end
end
endmodule

View File

@ -1,65 +1,178 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ula is
port
(
clockVGA : in std_logic;
clockCPU : in std_logic;
keys : in std_logic_vector( 4 downto 0);
iorq : in std_logic;
int : out std_logic;
rd : in std_logic;
wr : in std_logic;
a0 : in std_logic;
di : in std_logic_vector( 7 downto 0);
do : out std_logic_vector( 7 downto 0);
ear : in std_logic;
mic : out std_logic;
speaker : out std_logic;
va : out std_logic_vector(12 downto 0);
vd : in std_logic_vector( 7 downto 0);
hs : out std_logic;
vs : out std_logic;
rgb : out std_logic_vector(11 downto 0)
cpuClock : in std_logic;
iorq : in std_logic;
rd : in std_logic;
wr : in std_logic;
a0 : in std_logic;
di : in std_logic_vector( 7 downto 0);
do : out std_logic_vector( 7 downto 0);
--
vramClock : in std_logic;
vramData : in std_logic_vector( 7 downto 0);
vramAddr : out std_logic_vector(12 downto 0);
int : out std_logic;
v : out std_logic;
h : out std_logic;
r : out std_logic;
g : out std_logic;
b : out std_logic;
i : out std_logic;
--
ear : in std_logic;
mic : out std_logic;
speaker : out std_logic;
--
rows : in std_logic_vector(15 downto 8);
boot : out std_logic;
reset : out std_logic;
nmi : out std_logic;
ps2 : inout std_logic_vector(1 downto 0)
);
end;
architecture behavioral of ula is
signal portFF : std_logic_vector(2 downto 0);
signal received : std_logic;
signal scancode : std_logic_vector(7 downto 0);
signal keys : std_logic_vector(4 downto 0);
signal rows : std_logic_vector(7 downto 0);
signal cols : std_logic_vector(4 downto 0);
signal border : std_logic_vector(2 downto 0);
signal hCount : std_logic_vector(8 downto 0) := (others => '0');
signal vCount : std_logic_vector(8 downto 0) := (others => '0');
signal fCount : std_logic_vector(4 downto 0) := (others => '0');
signal hSync : std_logic;
signal vSync : std_logic;
signal dataInp : std_logic_vector(7 downto 0);
signal dataOut : std_logic_vector(7 downto 0);
signal attrInp : std_logic_vector(7 downto 0);
signal attrMux : std_logic_vector(7 downto 3);
signal attrOut : std_logic_vector(7 downto 0);
signal dataEnable : std_logic;
signal videoBlank : std_logic;
signal videoEnable : std_logic;
signal dataInpLoad : std_logic;
signal dataOutLoad : std_logic;
signal attrInpLoad : std_logic;
signal attrOutLoad : std_logic;
signal dataSelect : std_logic;
begin
Uvga: entity work.vga port map
Ups2 : entity work.ps2 port map
(
clockVGA => clockVGA,
border => portFF(2 downto 0),
va => va,
vd => vd,
hs => hs,
vs => vs,
rgb => rgb
clockPs2 => vramClock, -- 7 MHz
clock => ps2(0),
data => ps2(1),
received => received,
scancode => scancode
);
Uvideo: entity work.video port map
Ukeyboard : entity work.keyboard port map
(
clockCPU => clockCPU,
int => int
received => received,
scancode => scancode,
boot => boot,
reset => reset,
nmi => nmi,
cols => keys,
rows => rows
);
process(clockCPU)
process(cpuClock)
begin
if rising_edge(clockCPU) then
if iorq = '0' and rd = '0' and a0 = '0' then do <= '0'&ear&'0'&keys; end if;
if iorq = '0' and wr = '0' and a0 = '0' then
portFF <= di(2 downto 0);
mic <= di(3);
speaker <= di(4);
if falling_edge(cpuClock)
then
do <= attrOut;
if iorq = '0' and a0 = '0'
then
if wr = '0'
then
border <= di(2 downto 0);
mic <= di(3);
speaker <= di(4);
elsif rd = '0'
then
do <= '0'&ear&'0'&keys;
end if;
end if;
end if;
end process;
process(vramClock)
begin
if falling_edge(vramClock)
then
if hCount < 447
then
hCount <= hCount+1;
else
hCount <= (others => '0');
if vCount < 311
then
vCount <= vCount+1;
else
vCount <= (others => '0');
fCount <= fCount+1;
end if;
end if;
if hCount >= 344 and hCount <= 375 then hSync <= '0'; else hSync <= '1'; end if;
if vCount >= 248 and vCount <= 251 then vSync <= '0'; else vSync <= '1'; end if;
if vCount = 248 and hCount >= 2 and hCount <= 65 then int <= '0'; else int <= '1'; end if;
end if;
end process;
process(vramClock)
begin
if falling_edge(vramClock)
then
dataInpLoad <= hCount(0) and not hCount(1) and hCount(3) and videoEnable;
dataOutLoad <= not hCount(0) and not hCount(1) and hCount(2) and videoEnable;
attrInpLoad <= hCount(0) and hCount(1) and hCount(3) and videoEnable;
attrOutLoad <= hCount(0) and not hCount(1) and hCount(2);
dataSelect <= dataOut(7) xor (fCount(4) and attrOut(7));
if hCount(3) = '1' then videoEnable <= dataEnable; end if;
if hCount < 256 and vCount < 192 then dataEnable <= '1'; else dataEnable <= '0'; end if;
if (hCount >= 320 and hCount <= 415) or (vCount >= 248 and vCount <= 255) then videoBlank <= '1'; else videoBlank <= '0'; end if;
if dataInpLoad = '1' then dataInp <= vramData; end if;
if dataOutLoad = '1' then dataOut <= dataInp; else dataOut <= dataOut(6 downto 0)&'0'; end if;
if attrInpLoad = '1' then attrInp <= vramData; end if;
if attrOutLoad = '1' then attrOut <= attrMux&attrInp(2 downto 0); end if;
if videoEnable = '1' then attrMux(7 downto 3) <= attrInp(7 downto 3); else attrMux(7 downto 3) <= "00"&border; end if;
vramAddr( 7 downto 0) <= vCount(5 downto 3)&hCount(7 downto 4)&hCount(2);
if hCount(1) = '0' then vramAddr(12 downto 8) <= vCount(7 downto 6)&vCount(2 downto 0); else vramAddr(12 downto 8) <= "110"&vCount(7 downto 6); end if;
end if;
end process;
v <= vSync;
h <= hSync;
r <= '0' when videoBlank = '1' else attrOut(1) when dataSelect = '1' else attrOut(4);
g <= '0' when videoBlank = '1' else attrOut(2) when dataSelect = '1' else attrOut(5);
b <= '0' when videoBlank = '1' else attrOut(0) when dataSelect = '1' else attrOut(3);
i <= '0' when videoBlank = '1' else attrOut(6);
end;

View File

@ -1,94 +0,0 @@
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- |VGA 640x480 | Horizontal| Vertical|
-- +------------+-----------+-----------+
-- |Visible area| 0-639:640| 0-479:480|
-- |Front porch |640-655: 16|480-489: 10|
-- |Sync pulse |656-751: 96|490-491: 2|
-- |Back porch |752-799: 48|492-524: 33|
-- |Whole line | 800| 525|
entity vga is
port
(
clockVGA : in std_logic;
border : in std_logic_vector( 2 downto 0);
va : out std_logic_vector(12 downto 0);
vd : in std_logic_vector( 7 downto 0);
hs : out std_logic;
vs : out std_logic;
rgb : out std_logic_vector(11 downto 0)
);
end;
architecture behavioral of vga is
signal xy : std_logic_vector(17 downto 0);
signal x : std_logic_vector( 9 downto 0) := std_logic_vector(to_unsigned(512-20, 10));
signal y : std_logic_vector( 9 downto 0) := std_logic_vector(to_unsigned(383, 10));
signal f : std_logic_vector( 5 downto 0);
signal bmap : std_logic_vector( 7 downto 0);
signal attr : std_logic_vector( 7 downto 0);
type tpalette is array (0 to 15) of std_logic_vector(11 downto 0);
constant palette : tpalette := ( x"000", x"007", x"700", x"707", x"070", x"077", x"770", x"777", x"000", x"00f", x"f00", x"f0f", x"0f0", x"0ff", x"ff0", x"fff" );
begin
process(clockVGA)
variable bpre : std_logic_vector(7 downto 0);
variable apre : std_logic_vector(7 downto 0);
variable i, p : std_logic_vector(2 downto 0);
variable b, c : integer;
begin
if rising_edge(clockVGA) then
if x < 799 then x <= x+1;
else
x <= (others => '0');
if y < 524 then y <= y+1;
else
y <= (others => '0');
f <= f+1;
end if;
end if;
if x >= 640+16 and x < 640+16+96 then hs <= '0'; else hs <= '1'; end if;
if y >= 480+10 and y < 480+10+ 2 then vs <= '0'; else vs <= '1'; end if;
if x >= 64 and x < 64+512 and y >= 48 and y < 48+384 then
if x = 64+512-16 and y = 48+383 then xy <= (others => '0'); else xy <= xy+1; end if;
if xy(3 downto 0) = "0000" then va <= xy(17 downto 16)&xy(12 downto 10)&xy(15 downto 13)&xy(8 downto 4); end if;
if xy(3 downto 0) = "1000" then va <= "110"&xy(17 downto 13)&xy( 8 downto 4); end if;
if xy(3 downto 0) = "0010" then bpre := vd; end if;
if xy(3 downto 0) = "1010" then apre := vd; end if;
if xy(3 downto 0) = "1110" then bmap <= bpre; attr <= apre; end if;
b := 7-to_integer(unsigned(x(3 downto 1)));
i := attr(2 downto 0);
p := attr(5 downto 3);
if attr(7) = '1' then
if f(5) = '1' then
if bmap(b) = '0' then c := to_integer(unsigned(i)); else c := to_integer(unsigned(p)); end if;
else
if bmap(b) = '0' then c := to_integer(unsigned(p)); else c := to_integer(unsigned(i)); end if;
end if;
else
if bmap(b) = '1' then c := to_integer(unsigned(i)); else c := to_integer(unsigned(p)); end if;
end if;
if attr(6) = '1' then c := c+8; end if;
rgb <= palette(c);
elsif x < 640 and y < 480 then
rgb <= palette(to_integer(unsigned(border)));
else
rgb <= x"000";
end if;
end if;
end process;
end;

View File

@ -1,26 +0,0 @@
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity video is
port
(
clockCPU : in std_logic;
int : out std_logic
);
end;
architecture behavioral of video is
begin
process(clockCPU)
variable c : std_logic_vector(17 downto 0) := (others => '0');
begin
if rising_edge(clockCPU) then
if c < 69887 then c := c+1; else c := (others => '0'); end if;
if c >= 16 and c < 48 then int <= '0'; else int <= '1'; end if;
end if;
end process;
end;

View File

@ -0,0 +1,9 @@
SET machine=zxkyp
SET speed=2
SET ruta_ucf=..\zxkyp
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -0,0 +1,20 @@
vhdl work "../ipcore_dir/rom.vhd"
vhdl work "../ipcore_dir/vram.vhd"
vhdl work "../ipcore_dir/drom.vhd"
verilog work "../tv80_reg.v"
verilog work "../tv80_mcode.v"
verilog work "../tv80_alu.v"
verilog work "../tv80_core.v"
verilog work "../spi.v"
vhdl work "../ps2.vhd"
vhdl work "../keyboard.vhd"
vhdl work "../dac.vhd"
vhdl work "../ula.vhd"
verilog work "../tv80n.v"
vhdl work "../sd.vhd"
vhdl work "../ram.vhd"
verilog work "../multiboot.v"
vhdl work "../mixer.vhd"
vhdl work "../div.vhd"
vhdl work "../clock.vhd"
vhdl work "../zxkyp.vhd"

View File

@ -1,6 +1,5 @@
-w
-g DebugBitstream:No
-g Compress
-g Binary:no
-g CRC:Enable
-g Reset_on_err:No

View File

@ -1,11 +1,11 @@
set -tmpdir "xst/projnav.tmp"
set -xsthdpdir "xst"
run
-ifn zxpp.prj
-ofn zxpp
-ifn zxkyp.prj
-ofn zxkyp
-ofmt NGC
-p xc6slx9-2-tqg144
-top zxpp
-top zxkyp
-opt_mode Speed
-opt_level 1
-power NO
@ -15,7 +15,7 @@ run
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-sd {"ipcore_dir" }
-sd {"../ipcore_dir" }
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /

View File

@ -1,623 +0,0 @@
--
-- 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 LINEAR mixing of the three analogue channels, and is only
-- accurate for designs where the outputs are buffered and not simply wired together.
-- The ouput level is more complex in that case and requires a larger table.
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
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 tone_ena_l : std_logic;
signal tone_src : std_logic;
signal noise_ena_l : std_logic;
signal chan_vol : std_logic_vector(4 downto 0);
signal dac_amp : std_logic_vector(7 downto 0);
signal audio_mix : std_logic_vector(9 downto 0);
signal audio_final : 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 address
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 : process(cnt_div, reg, tone_gen_op)
begin
tone_ena_l <= '1'; tone_src <= '1';
noise_ena_l <= '1'; chan_vol <= "00000";
case cnt_div(1 downto 0) is
when "00" =>
tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
noise_ena_l <= reg(7)(3);
when "01" =>
tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
noise_ena_l <= reg(7)(4);
when "10" =>
tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
noise_ena_l <= reg(7)(5);
when "11" => null; -- tone gen outputs become valid on this clock
when others => null;
end case;
end process;
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 (ENA = '1') then
chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
chan_amp := (others => '0');
if (chan_mixed = '1') then
if (chan_vol(4) = '0') then
if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
chan_amp := "00000";
else
chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
end if;
else
chan_amp := env_vol(4 downto 0);
end if;
end if;
dac_amp <= x"00";
case chan_amp is
when "11111" => dac_amp <= x"FF";
when "11110" => dac_amp <= x"D9";
when "11101" => dac_amp <= x"BA";
when "11100" => dac_amp <= x"9F";
when "11011" => dac_amp <= x"88";
when "11010" => dac_amp <= x"74";
when "11001" => dac_amp <= x"63";
when "11000" => dac_amp <= x"54";
when "10111" => dac_amp <= x"48";
when "10110" => dac_amp <= x"3D";
when "10101" => dac_amp <= x"34";
when "10100" => dac_amp <= x"2C";
when "10011" => dac_amp <= x"25";
when "10010" => dac_amp <= x"1F";
when "10001" => dac_amp <= x"1A";
when "10000" => dac_amp <= x"16";
when "01111" => dac_amp <= x"13";
when "01110" => dac_amp <= x"10";
when "01101" => dac_amp <= x"0D";
when "01100" => dac_amp <= x"0B";
when "01011" => dac_amp <= x"09";
when "01010" => dac_amp <= x"08";
when "01001" => dac_amp <= x"07";
when "01000" => dac_amp <= x"06";
when "00111" => dac_amp <= x"05";
when "00110" => dac_amp <= x"04";
when "00101" => dac_amp <= x"03";
when "00100" => dac_amp <= x"03";
when "00011" => dac_amp <= x"02";
when "00010" => dac_amp <= x"02";
when "00001" => dac_amp <= x"01";
when "00000" => dac_amp <= x"00";
when others => null;
end case;
if (cnt_div(1 downto 0) = "10") then
audio_mix <= (others => '0');
audio_final <= audio_mix;
else
audio_mix <= audio_mix + ("00" & dac_amp);
end if;
if (RESET_L = '0') then
O_AUDIO(7 downto 0) <= "00000000";
else
if (audio_final(9) = '0') then
O_AUDIO(7 downto 0) <= audio_final(8 downto 1);
else -- clip
O_AUDIO(7 downto 0) <= x"FF";
end if;
end if;
end if;
end process;
p_io_ports : process(reg)
begin
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;

264
cores/KypSpectrum/zxkyp.vhd Normal file
View File

@ -0,0 +1,264 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity zxkyp is
port
(
clock50 : in std_logic;
led : out std_logic;
--
sramWr : out std_logic;
sramData : inout std_logic_vector( 7 downto 0);
sramAddr : out std_logic_vector(18 downto 0);
--
videoRgb : out std_logic_vector( 8 downto 0);
videoSync : out std_logic_vector( 1 downto 0);
videoStdn : out std_logic_vector( 1 downto 0);
--
ear : in std_logic;
audio : out std_logic_vector(1 downto 0);
--
ps2 : inout std_logic_vector(1 downto 0);
--
sdClock : out std_logic;
sdCs : out std_logic;
sdDi : out std_logic;
sdDo : in std_logic
);
end;
architecture structural of zxkyp is
signal clock14 : std_logic;
signal clock70 : std_logic;
signal clock35 : std_logic;
signal boot : std_logic;
signal reset : std_logic;
signal pause : std_logic;
signal mreq : std_logic;
signal iorq : std_logic;
signal nmi : std_logic;
signal int : std_logic;
signal m1 : std_logic;
signal rd : std_logic;
signal wr : std_logic;
signal data : std_logic_vector( 7 downto 0);
signal addr : std_logic_vector(15 downto 0);
signal v : std_logic;
signal h : std_logic;
signal r : std_logic;
signal g : std_logic;
signal b : std_logic;
signal i : std_logic;
signal mic : std_logic;
signal speaker : std_logic;
signal automap : std_logic;
signal conmem : std_logic;
signal mapram : std_logic;
signal page : std_logic_vector( 3 downto 0);
signal cpuData : std_logic_vector( 7 downto 0);
signal ulaData : std_logic_vector( 7 downto 0);
signal romCs : std_logic;
signal romData : std_logic_vector( 7 downto 0);
signal ramCs : std_logic;
signal ramWr : std_logic;
signal ramData : std_logic_vector( 7 downto 0);
signal ramAddr : std_logic_vector(18 downto 0);
signal vramCs : std_logic;
signal vramWe : std_logic;
signal vramAddr : std_logic_vector(12 downto 0);
signal vramData : std_logic_vector( 7 downto 0);
signal dromCs : std_logic;
signal dromData : std_logic_vector( 7 downto 0);
signal sdOe : std_logic;
signal sdAc : std_logic;
signal sdData : std_logic_vector( 7 downto 0);
begin
Umultiboot : entity work.multiboot port map
(
clk_icap => clock14,
mrst_n => boot
);
Uclock : entity work.clock port map
(
clock50 => clock50,
clock14 => clock14,
clock70 => clock70,
clock35 => clock35
);
Ucpu : entity work.tv80n port map
(
clk => clock35,
reset_n => reset,
wait_n => pause,
mreq_n => mreq,
iorq_n => iorq,
nmi_n => nmi,
int_n => int,
m1_n => m1,
rd_n => rd,
wr_n => wr,
dout => cpuData,
di => data,
a => addr,
busrq_n => '1',
busak_n => open,
halt_n => open,
rfsh_n => open
);
Uula : entity work.ula port map
(
cpuClock => clock35,
iorq => iorq,
rd => rd,
wr => wr,
a0 => addr(0),
di => cpuData,
do => ulaData,
--
vramClock => clock70,
vramData => vramData,
vramAddr => vramAddr,
int => int,
v => v,
h => h,
r => r,
g => g,
b => b,
i => i,
--
ear => ear,
mic => mic,
speaker => speaker,
--
rows => addr(15 downto 8),
boot => boot,
reset => reset,
nmi => nmi,
ps2 => ps2
);
Udiv : entity work.div port map
(
clock => clock35,
reset => reset,
mreq => mreq,
iorq => iorq,
m1 => m1,
rd => rd,
wr => wr,
di => cpuData,
a => addr,
--
automap => automap,
conmem => conmem,
mapram => mapram,
page => page
);
Umixer: entity work.mixer port map
(
clock => clock35,
reset => reset,
speaker => speaker,
ear => ear,
mic => mic,
l => audio(0),
r => audio(1)
);
Urom : entity work.rom port map
(
clka => clock35,
ena => romCs,
douta => romData,
addra => addr(13 downto 0)
);
Udrom : entity work.drom port map
(
clka => clock35,
ena => dromCs,
douta => dromData,
addra => addr(12 downto 0)
);
Uram : entity work.ram port map
(
wr => ramWr,
di => cpuData,
do => ramData,
a => ramAddr,
--
sramWr => sramWr,
sramData => sramData,
sramAddr => sramAddr
);
Uvram : entity work.vram port map
(
clka => clock35,
ena => vramCs,
wea(0) => vramWe,
dina => cpuData,
addra => addr(12 downto 0),
--
clkb => clock70,
doutb => vramData,
addrb => vramAddr
);
Usd : entity work.sd port map
(
clock => clock14,
pause => pause,
iorq => iorq,
rd => rd,
wr => wr,
oe => sdOe,
di => cpuData,
do => sdData,
a => addr,
--
sdClock => sdClock,
sdCs => sdAc,
sdDi => sdDi,
sdDo => sdDo
);
sdCs <= sdAc;
led <= not sdAc;
vramCs <= '1' when mreq = '0' and addr(15 downto 13) = "010" else '0';
dromCs <= '1' when mreq = '0' and addr(15 downto 13) = "000" and (conmem = '1' or automap = '1') and mapram = '0' else '0';
romCs <= '1' when mreq = '0' and addr(15 downto 14) = "00" and conmem = '0' and automap = '0' else '0';
ramCs <= '1' when (mreq = '0' and addr(15 downto 13) = "000" and (conmem = '1' or automap = '1') and mapram = '1')
or (mreq = '0' and addr(15 downto 13) = "001" and (conmem = '1' or automap = '1'))
or (mreq = '0' and addr(15 downto 14) = "01")
or (mreq = '0' and addr(15) = '1')
else '0';
vramWe <= not (mreq or wr) when addr(15 downto 13) = "010" else '0';
ramWr <= mreq or wr;
ramAddr <= "01"&x"3"&addr(12 downto 0) when mreq = '0' and addr(15 downto 13) = "000" and (conmem = '1' or automap = '1') and mapram = '1'
else "01"&page&addr(12 downto 0) when mreq = '0' and addr(15 downto 13) = "001" and (conmem = '1' or automap = '1')
else "00"&"0"&addr;
data <= sdData when iorq = '0' and sdOe = '0'
else ramData when ramCs = '1'
else romData when romCs = '1'
else dromData when dromCs = '1'
else ulaData;
videoRgb <= (r&'0'&r)&(g&'0'&g)&(b&'0'&b) when i = '0' else (r&r&r)&(g&g&g)&(b&b&b);
videoSync <= '1'&(v and h);
videoStdn <= "01";
end;

View File

@ -0,0 +1,93 @@
#
#
#
# LED #########################################################################
NET "led" LOC="P11" | IOSTANDARD = LVCMOS33;
# Clock #######################################################################
NET "clock50" LOC="P55" | IOSTANDARD = LVCMOS33 | PERIOD=20ns;
# SRAM ########################################################################
NET "sramWr" LOC="P121" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<7>" LOC="P126" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<6>" LOC="P119" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<5>" LOC="P117" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<4>" LOC="P115" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<3>" LOC="P123" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<2>" LOC="P124" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<1>" LOC="P127" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramData<0>" LOC="P132" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "sramAddr<20>" LOC="P143" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "sramAddr<19>" LOC="P105" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<18>" LOC="P142" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<17>" LOC="P140" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<16>" LOC="P138" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<15>" LOC="P131" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<14>" LOC="P111" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<13>" LOC="P100" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<12>" LOC="P101" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<11>" LOC="P102" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<10>" LOC="P104" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<9>" LOC="P112" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<8>" LOC="P114" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<7>" LOC="P116" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<6>" LOC="P118" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<5>" LOC="P120" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<4>" LOC="P133" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<3>" LOC="P134" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<2>" LOC="P137" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<1>" LOC="P139" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "sramAddr<0>" LOC="P141" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
# Video #######################################################################
NET "videoRgb<8>" LOC="P81" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<7>" LOC="P80" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<6>" LOC="P79" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<5>" LOC="P84" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<4>" LOC="P83" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<3>" LOC="P82" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<2>" LOC="P93" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<1>" LOC="P92" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoRgb<0>" LOC="P88" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "videoSync<1>" LOC="P85" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # vs
NET "videoSync<0>" LOC="P87" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # hs
NET "videoStdn<1>" LOC="P66" | IOSTANDARD = LVCMOS33; # stdn <= "10" NTSC
NET "videoStdn<0>" LOC="P67" | IOSTANDARD = LVCMOS33; # stdn <= "01" PAL
# Audio #######################################################################
NET "ear" LOC="P94" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
NET "audio<0>" LOC="P10" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # left
NET "audio<1>" LOC="P9" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # right
# PS/2 ########################################################################
NET "ps2<0>" LOC="P99" | IOSTANDARD = LVCMOS33 | SLEW=FAST | PULLUP; # keyboard clock
NET "ps2<1>" LOC="P98" | IOSTANDARD = LVCMOS33 | SLEW=FAST | PULLUP; # keyboard data
# SD/MMC ######################################################################
NET "sdClock" LOC="P75" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # clock
NET "sdCs" LOC="P59" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # cs
NET "sdDi" LOC="P74" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # di
NET "sdDo" LOC="P78" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # do
# SPI Flash ###################################################################
#NET "flash_clk" LOC="P70" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "flash_cs" LOC="P38" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "flash_si" LOC="P64" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "flash_so" LOC="P65" | IOSTANDARD = LVCMOS33 | SLEW=FAST;
#NET "flash_ext1" LOC="P62" | IOSTANDARD = LVCMOS33;
#NET "flash_ext2" LOC="P61" | IOSTANDARD = LVCMOS33;

View File

@ -1,18 +0,0 @@
vhdl work "ipcore_dir/hiram.vhd"
vhdl work "ipcore_dir/loram.vhd"
vhdl work "ipcore_dir/rom.vhd"
verilog work "tv80_reg.v"
verilog work "tv80_mcode.v"
verilog work "tv80_alu.v"
vhdl work "video.vhd"
vhdl work "vga.vhd"
verilog work "tv80_core.v"
vhdl work "dac.vhd"
vhdl work "ym2149.vhd"
vhdl work "ula.vhd"
verilog work "tv80n.v"
vhdl work "ps2.vhd"
vhdl work "mixer.vhd"
vhdl work "keyboard.vhd"
vhdl work "clock.vhd"
vhdl work "zxpp.vhd"

View File

@ -1,240 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
entity zxpp is
port
(
netCLK : in std_logic;
netRST : in std_logic;
netNMI : in std_logic;
--
ps2CLK : inout std_logic;
ps2DAT : inout std_logic;
--
joyBTN : in std_logic_vector(4 downto 0);
joyGND : out std_logic;
--
audioL : out std_logic;
audioR : out std_logic;
audioEAR : in std_logic;
audioGND : out std_logic;
--
videoV : out std_logic;
videoH : out std_logic;
videoR : out std_logic_vector(3 downto 0);
videoG : out std_logic_vector(3 downto 0);
videoB : out std_logic_vector(3 downto 0)
);
end;
architecture structural of zxpp is
signal clockVGA : std_logic;
signal clockCPU : std_logic;
signal clockPS2 : std_logic;
signal clockDAC : std_logic;
signal clockAY : std_logic;
--
signal reset : std_logic;
signal kreset : std_logic;
--
signal iorq : std_logic;
signal mreq : std_logic;
signal nmi : std_logic;
signal int : std_logic;
signal rd : std_logic;
signal wr : std_logic;
signal a : std_logic_vector(15 downto 0);
signal d : std_logic_vector( 7 downto 0);
signal dcpu : std_logic_vector( 7 downto 0);
--
signal ear : std_logic;
signal mic : std_logic;
signal speaker : std_logic;
signal va : std_logic_vector(12 downto 0);
signal vd : std_logic_vector( 7 downto 0);
signal dula : std_logic_vector( 7 downto 0);
--
signal rps2 : std_logic;
signal dps2 : std_logic_vector( 7 downto 0);
signal keys : std_logic_vector( 4 downto 0);
--
signal erom : std_logic;
signal drom : std_logic_vector( 7 downto 0);
--
signal eloram : std_logic;
signal wloram : std_logic;
signal dloram : std_logic_vector( 7 downto 0);
--
signal ehiram : std_logic;
signal whiram : std_logic;
signal dhiram : std_logic_vector( 7 downto 0);
--
signal aybdir : std_logic;
signal aybc1 : std_logic;
signal ayoe : std_logic;
signal aydata : std_logic_vector( 7 downto 0);
signal ayaudio : std_logic_vector( 7 downto 0);
--
signal kempston : std_logic_vector( 7 downto 0);
begin
Uclock: entity work.clock port map
(
clock32 => netCLK,
clockVGA => clockVGA,
clockCPU => clockCPU,
clockPS2 => clockPS2,
clockDAC => clockDAC,
clockAY => clockAY
);
Ucpu: entity work.tv80n port map
(
clk => clockCPU,
reset_n => reset,
busrq_n => '1',
wait_n => '1',
busak_n => open,
halt_n => open,
rfsh_n => open,
m1_n => open,
mreq_n => mreq,
iorq_n => iorq,
nmi_n => nmi,
int_n => int,
rd_n => rd,
wr_n => wr,
a => a,
di => d,
dout => dcpu
);
Uula: entity work.ula port map
(
clockVGA => clockVGA,
clockCPU => clockCPU,
keys => keys,
iorq => iorq,
int => int,
rd => rd,
wr => wr,
a0 => a(0),
di => dcpu,
do => dula,
ear => audioEAR,
mic => mic,
speaker => speaker,
va => va,
vd => vd,
hs => videoH,
vs => videoV,
rgb(11 downto 8) => videoR,
rgb( 7 downto 4) => videoG,
rgb( 3 downto 0) => videoB
);
Ups2: entity work.ps2 port map
(
clock => clockPS2,
ps2c => ps2CLK,
ps2d => ps2DAT,
received => rps2,
scancode => dps2
);
Ukeyboard: entity work.keyboard port map
(
received => rps2,
scancode => dps2,
rows => a(15 downto 8),
cols => keys,
reset => kreset
);
Urom: entity work.rom port map
(
clka => clockCPU,
ena => erom,
addra => a(13 downto 0),
douta => drom
);
Uloram: entity work.loram port map
(
clka => clockCPU,
ena => eloram,
wea(0) => wloram,
addra => a(13 downto 0),
dina => dcpu,
douta => dloram,
clkb => clockVGA,
web(0) => '0',
addrb(13) => '0',
addrb(12 downto 0) => va,
dinb => (others => '0'),
doutb => vd
);
Uhiram: entity work.hiram port map
(
clka => clockCPU,
ena => ehiram,
wea(0) => whiram,
addra => a(14 downto 0),
dina => dcpu,
douta => dhiram
);
Uym2149: entity work.ym2149 port map
(
clk => clockAY,
ena => '1',
reset_l => reset,
i_da => dcpu,
o_da => aydata,
o_da_oe_l => ayoe,
i_a9_l => '0',
i_a8 => '1',
i_bc2 => '1',
i_bc1 => aybc1,
i_bdir => aybdir,
i_sel_l => '0',
o_audio => ayaudio,
i_ioa => (others => '0'),
o_ioa => open,
o_ioa_oe_l => open,
i_iob => (others => '0'),
o_iob => open,
o_iob_oe_l => open
);
Umixer: entity work.mixer port map
(
clock => clockDAC,
reset => reset,
speaker => speaker,
ear => audioEAR,
mic => mic,
ay => ayaudio,
l => audioL,
r => audioR
);
reset <= not (netRST or kreset);
nmi <= not netNMI;
audioGND <= '0';
joyGND <= '0';
kempston <= not ("111"&joyBTN(4)&joyBTN(0)&joyBTN(1)&joyBTN(2)&joyBTN(3));
erom <= '1' when mreq = '0' and a(15 downto 14) = "00" else '0';
eloram <= '1' when mreq = '0' and a(15 downto 14) = "01" else '0';
ehiram <= '1' when mreq = '0' and a(15) = '1' else '0';
wloram <= not wr;
whiram <= not wr;
aybdir <= '1' when iorq = '0' and wr = '0' and a(15) = '1' and a(1 downto 0) = "01" else '0';
aybc1 <= '1' when iorq = '0' and a(15 downto 14) = "11" and a(1 downto 0) = "01" else '0';
d <= dhiram when ehiram = '1' and rd = '0'
else dloram when eloram = '1' and rd = '0'
else drom when erom = '1' and rd = '0'
else kempston when iorq = '0' and rd = '0' and a(7 downto 5) = "000"
else aydata when ayoe = '0'
else dula;
end;

View File

@ -3,7 +3,7 @@ SET speed=3
SET ruta_ucf=src\sms
SET ruta_bat=..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=..\src\nes
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=3
SET ruta_ucf=..\source\oric
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=SamCoupe
SET ruta_bat=..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=pines
SET ruta_bat=..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=3
SET ruta_ucf=..\source\vic20
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -4,3 +4,4 @@ call %ruta_bat%par -intstyle ise -w -ol high -mt 4 %machine%_map.ncd %machi
call %ruta_bat%trce -intstyle ise -v 3 -s %speed% -n 3 -fastpaths -xml %machine%.twx %machine%.ncd -o %machine%.twr %machine%.pcf
call %ruta_bat%bitgen -intstyle ise -f %machine%.ut %machine%.ncd
copy /y %machine%.bit %machine%.%1.bit
%ruta_bat%..\firmware\bit2bin %machine%.bit COREn.%2

View File

@ -3,6 +3,6 @@ SET speed=2
SET ruta_ucf=pines
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=2
SET ruta_ucf=pines
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,6 +3,6 @@ SET speed=2
SET ruta_ucf=pines
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2_v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2_v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA

View File

@ -3,7 +3,7 @@ SET speed=2
SET ruta_ucf=pines
SET ruta_bat=..\..\
call %ruta_bat%genxst.bat
rem call %ruta_bat%generar.bat v2
rem call %ruta_bat%generar.bat v3
call %ruta_bat%generar.bat v4
rem call %ruta_bat%generar.bat Ap
rem call %ruta_bat%generar.bat v2 ZZ2
rem call %ruta_bat%generar.bat v3 ZZ3
call %ruta_bat%generar.bat v4 ZX1
rem call %ruta_bat%generar.bat Ap ZZA