1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-18 17:06:57 +00:00

Merge pull request #94 from gyurco/master

Some component updates
This commit is contained in:
Marcel 2020-07-13 00:29:19 +02:00 committed by GitHub
commit 005b15b5ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 191 additions and 302 deletions

53
common/CPU/T80/README Normal file
View File

@ -0,0 +1,53 @@
--------------------------------------------------------------------------------
-- ****
-- T80(c) core. Attempt to finish all undocumented features and provide
-- accurate timings.
-- Version 350.
-- Copyright (c) 2018 Sorgelig
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
-- correct implementation is still unclear.
--
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
-- Ver 300 started tidyup.
--
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
-- Z80 compatible microprocessor core
--
-- Version : 0247
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--

View File

@ -79,8 +79,7 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.all;
use work.T80_Pack.all;
entity T80 is
generic(
@ -128,136 +127,6 @@ entity T80 is
end T80;
architecture rtl of T80 is
component T80_MCode
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
IR : in std_logic_vector(7 downto 0);
ISet : in std_logic_vector(1 downto 0);
MCycle : in std_logic_vector(2 downto 0);
F : in std_logic_vector(7 downto 0);
NMICycle : in std_logic;
IntCycle : in std_logic;
XY_State : in std_logic_vector(1 downto 0);
MCycles : out std_logic_vector(2 downto 0);
TStates : out std_logic_vector(2 downto 0);
Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD
Inc_PC : out std_logic;
Inc_WZ : out std_logic;
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
Read_To_Reg : out std_logic;
Read_To_Acc : out std_logic;
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
IORQ : out std_logic;
Jump : out std_logic;
JumpE : out std_logic;
JumpXY : out std_logic;
Call : out std_logic;
RstP : out std_logic;
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
I_SCF : out std_logic;
I_RETN : out std_logic;
I_BT : out std_logic;
I_BC : out std_logic;
I_BTR : out std_logic;
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetWZ : out std_logic_vector(1 downto 0);
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
XYbit_undoc : out std_logic
);
end component;
component T80_ALU
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
WZ : in std_logic_vector(15 downto 0);
XY_State : in std_logic_vector(1 downto 0);
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end component;
component T80_Reg
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0);
DOR : out std_logic_vector(127 downto 0);
DIRSet : in std_logic;
DIR : in std_logic_vector(127 downto 0)
);
end component;
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
-- Registers
signal ACC, F : std_logic_vector(7 downto 0);
@ -294,8 +163,8 @@ architecture rtl of T80 is
signal IntE_FF1 : std_logic;
signal IntE_FF2 : std_logic;
signal Halt_FF : std_logic;
signal BusReq_s : std_logic;
signal BusAck : std_logic;
signal BusReq_s : std_logic := '0';
signal BusAck : std_logic := '0';
signal ClkEn : std_logic;
signal NMI_s : std_logic;
signal IStatus : std_logic_vector(1 downto 0);
@ -1168,7 +1037,7 @@ begin
TS <= std_logic_vector(TState);
DI_Reg <= DI;
HALT_n <= not Halt_FF;
BUSAK_n <= not BusAck;
BUSAK_n <= not (BusAck and RESET_n);
IntCycle_n <= not IntCycle;
IntE <= IntE_FF1;
IORQ <= IORQ_i;
@ -1187,7 +1056,7 @@ begin
TState <= "000";
Pre_XY_F_M <= "000";
Halt_FF <= '0';
BusAck <= '0';
--BusAck <= '0';
NMICycle <= '0';
IntCycle <= '0';
IntE_FF1 <= '0';
@ -1196,7 +1065,7 @@ begin
Auto_Wait_t1 <= '0';
Auto_Wait_t2 <= '0';
M1_n <= '1';
BusReq_s <= '0';
--BusReq_s <= '0';
NMI_s <= '0';
elsif rising_edge(CLK_n) then
@ -1295,5 +1164,5 @@ begin
end if;
end process;
Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0';
Auto_Wait <= '1' when (IntCycle = '1' or NMICycle = '1') and MCycle = "001" else '0';
end;

View File

@ -74,6 +74,7 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T80_MCode is
generic(
@ -149,14 +150,6 @@ end T80_MCode;
architecture rtl of T80_MCode is
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
function is_cc_true(
F : std_logic_vector(7 downto 0);
cc : bit_vector(2 downto 0)

View File

@ -84,7 +84,7 @@ package T80_Pack is
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
@ -96,35 +96,42 @@ package T80_Pack is
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic
Stop : out std_logic;
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
DIRSet : in std_logic := '0';
DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
);
end component;
component T80_Reg
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
DOCL : out std_logic_vector(7 downto 0);
DOR : out std_logic_vector(127 downto 0);
DIRSet : in std_logic;
DIR : in std_logic_vector(127 downto 0)
);
end component;
@ -173,8 +180,6 @@ package T80_Pack is
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
LDHLSP : out std_logic;
ADDSPdd : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
@ -191,6 +196,7 @@ package T80_Pack is
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetWZ : out std_logic_vector(1 downto 0);
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
@ -216,6 +222,8 @@ package T80_Pack is
port(
Arith16 : in std_logic;
Z16 : in std_logic;
WZ : in std_logic_vector(15 downto 0);
XY_State : in std_logic_vector(1 downto 0);
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);

View File

@ -56,6 +56,7 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T80pa is
generic(
@ -89,50 +90,7 @@ entity T80pa is
end T80pa;
architecture rtl of T80pa is
component T80
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
IORQ : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
DIRSet : in std_logic := '0';
DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
);
end component;
signal IntCycle_n : std_logic;
signal IntCycleD_n : std_logic_vector(1 downto 0);
signal IORQ : std_logic;

View File

@ -69,6 +69,7 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.T80_Pack.all;
entity T80s is
generic(
@ -100,50 +101,6 @@ entity T80s is
end T80s;
architecture rtl of T80s is
component T80
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
IORQ : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
DIRSet : in std_logic := '0';
DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
);
end component;
signal IntCycle_n : std_logic;
signal NoRead : std_logic;

View File

@ -41,6 +41,7 @@ architecture struct of ctc_counter is
signal clk_trg_in : std_logic;
signal clk_trg_r : std_logic;
signal trigger : std_logic;
signal trigger_clk : std_logic;
signal count_ena : std_logic;
signal load_data_r : std_logic; -- make sure load_data toggles to get one new data
@ -52,7 +53,6 @@ prescale_max <=
X"FF"; -- timer mode prescale 256
clk_trg_in <= clk_trg xor control_word(4);
trigger <= '1' when clk_trg_in = '0' and clk_trg_r = '1' else '0';
d_out <= count_in(7 downto 0);
@ -74,8 +74,11 @@ begin
else
if rising_edge(clock) then
if clock_ena = '1' then
clk_trg_r <= clk_trg_in;
trigger <= '0';
trigger_clk <= '0';
if trigger_clk = '0' and trigger = '1' then
trigger_clk <= '1';
end if;
load_data_r <= load_data;
if (restart_on_next_trigger = '1' and trigger = '1') or (restart_on_next_clock = '1') then
@ -128,7 +131,7 @@ begin
-- counter
zc_to_in <= '0';
if ((control_word(6) = '1' and trigger = '1' ) or
if ((control_word(6) = '1' and trigger_clk = '0' and trigger = '1') or -- rising edge of trigger_clk
(control_word(6) = '0' and count_ena = '1') ) and time_constant_loaded = '1' then
if prescale_in = 0 then
prescale_in <= prescale_max;
@ -144,6 +147,14 @@ begin
end if;
end if;
-- detecting of trg input is asynchronous,
-- but eventually it's synchronized to the timer clock (clock_ena) via trigger_clk
clk_trg_r <= clk_trg_in;
if clk_trg_in = '0' and clk_trg_r = '1' then
trigger <= '1';
end if;
end if;
end if;
end process;

View File

@ -1,4 +1,3 @@
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) z80ctc_top.vhd ]
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ctc_controler.vhd ]
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ctc_counter.vhd ]
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) z80ctc_top.vhd ]

View File

@ -37,6 +37,7 @@ end z80ctc_top;
architecture struct of z80ctc_top is
signal cpu_int_ack_n : std_logic;
signal ctc_int_n : std_logic;
signal ctc_controler_we : std_logic;
signal ctc_controler_do : std_logic_vector(7 downto 0);
@ -87,13 +88,15 @@ ctc_counter_1_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n
ctc_counter_2_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "10" else '0';
ctc_counter_3_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "11" else '0';
dout <= ctc_controler_do when cpu_int_ack_n = '0' else
ctc_counter_0_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "00" else
ctc_counter_1_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "01" else
ctc_counter_2_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "10" else
ctc_counter_3_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "11" else
dout <= ctc_controler_do when cpu_int_ack_n = '0' and ctc_int_n = '0' else
ctc_counter_0_do when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "00" else
ctc_counter_1_do when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "01" else
ctc_counter_2_do when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "10" else
ctc_counter_3_do when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "11" else
x"FF";
int_n <= ctc_int_n;
-- CTC interrupt controler Z80-CTC (MK3882)
ctc_controler : entity work.ctc_controler
port map(
@ -112,7 +115,7 @@ port map(
int_pulse_3 => ctc_counter_3_int,
d_out => ctc_controler_do,
int_n => int_n
int_n => ctc_int_n
);
ctc_counter_0 : entity work.ctc_counter

View File

@ -62,7 +62,7 @@ library ieee;
entity YM2149 is
generic (
MIXER_VOLTABLE : std_logic := '0'
MIXER_VOLTABLE : std_logic := '0'
);
port (
-- data bus
@ -586,11 +586,12 @@ begin
vol_r <= vol_r + dac_amp;
when "00" => -- Channel A
if I_STEREO = '0' then
vol_mixer_l <= vol_l + dac_amp;
else
vol_mixer_l <= vol_l;
vol_r <= vol_r + dac_amp;
end if;
vol_mixer_r <= vol_r + dac_amp;
vol_l <= vol_l + dac_amp;
when "11" =>
vol_mixer_l <= vol_l;
vol_mixer_r <= vol_r;
when others => null;
end case;
end if;
@ -667,12 +668,12 @@ begin
ADDR_B => vol_table_in_r,
DATA_B => vol_table_out_r
);
end generate; -- VOLTABLE
end generate; -- VOLTABLE
NO_VOLTABLE: if MIXER_VOLTABLE = '0' generate
vol_table_out_l <= (others => '0');
vol_table_out_r <= (others => '0');
end generate;
end generate;
-- mixed audio output

33
common/mist/README.md Normal file
View File

@ -0,0 +1,33 @@
Common components for MiST board
================================
This repository contains common components, which should be used by almost all cores.
The modules:
- user_io.v - communicating with the IO controller.
- data_io.v - handling file uploads from the IO controller.
- mist_video.v - a video pipeline, which gives an optional scandoubler, OSD and rgb2ypbpr conversion.
- osd.v, scandoubler.v, rgb2ypbpr.sv, cofi.sv - these are used in mist_video, but can be used separately, too.
- sd_card.v - gives an SPI interface with SD-Card commands towards the IO-Controller, accessing .VHD and other mounted files.
- dac.vhd - a simple sigma-delta DAC for audio output.
- arcade_inputs.v - mostly for arcade-style games, gives access to the joysticks with MAME-style keyboard mapping.
- mist.vhd - VHDL component declarations for user_io and mist_video.
- mist_core.qip - collects the core components, which are needed in almost every case.
Usage hints
===========
All of these components should be clocked by a synchronous clock to the core. The data between the external SPI
interface and this internal clock are synchronized. However to make Quartus' job easier, you have to tell it to
don't try to optimize paths between the SPI and the system clock domain. Also you have to define the incoming
27 MHz and the SPI clocks. These lines in the .sdc file do that:
```
set sys_clk "your_system_clock"
create_clock -name {clk_27} -period 37.037 -waveform { 0.000 18.500 } [get_ports {CLOCK_27[0]}]
create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks $sys_clk]
```
Replace "your_system_clock" with the name of the pll clock, like "pll|altpll_component|auto_generated|pll1|clk[0]".

View File

@ -35,6 +35,8 @@ module data_io
// ARM -> FPGA download
output reg ioctl_download = 0, // signal indicating an active download
output reg [7:0] ioctl_index, // menu index used to upload the file ([7:6] - extension index, [5:0] - menu index)
// Note: this is also set for user_io mounts.
// Valid when ioctl_download = 1 or when img_mounted strobe is active in user_io.
output reg ioctl_wr, // strobe indicating ioctl_dout valid
output reg [24:0] ioctl_addr,
output reg [7:0] ioctl_dout,
@ -53,7 +55,6 @@ reg rclk = 0;
reg rclk2 = 0;
reg addr_reset = 0;
reg downloading_reg = 0;
reg [7:0] index_reg = 0;
localparam DIO_FILE_TX = 8'h53;
localparam DIO_FILE_TX_DAT = 8'h54;
@ -101,7 +102,7 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin : SPI_RECEIVER
end
// expose file (menu) index
if((cmd == DIO_FILE_INDEX) && (cnt == 15)) index_reg <= {sbuf, SPI_DI};
if((cmd == DIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI};
// receiving FAT directory entry (mist-firmware/fat.h - DIRENTRY)
if((cmd == DIO_FILE_INFO) && (cnt == 15)) begin
@ -193,7 +194,6 @@ always@(posedge clk_sys) begin : DATA_OUT
if(addr_resetD ^ addr_resetD2) begin
addr <= START_ADDR;
filepos <= 0;
ioctl_index <= index_reg;
ioctl_download <= 1;
end

View File

@ -51,6 +51,7 @@ parameter OSD_Y_OFFSET = 10'd0;
parameter SD_HCNT_WIDTH = 9;
parameter COLOR_DEPTH = 6; // 1-6
parameter OSD_AUTO_CE = 1'b1;
parameter SYNC_AND = 1'b0; // 0 - XOR, 1 - AND
wire [5:0] SD_R_O;
wire [5:0] SD_G_O;
@ -181,7 +182,7 @@ assign VGA_R = ypbpr?pr:cofi_r;
assign VGA_G = ypbpr? y:cofi_g;
assign VGA_B = ypbpr?pb:cofi_b;
wire cs = ~(cofi_hs ^ cofi_vs);
wire cs = SYNC_AND ? (cofi_hs & cofi_vs) : ~(cofi_hs ^ cofi_vs);
wire hs = cofi_hs;
wire vs = cofi_vs;

View File

@ -102,8 +102,8 @@ wire doublescan = (dsp_height>350);
reg auto_ce_pix;
always @(posedge clk_sys) begin
reg [15:0] cnt = 0;
reg [1:0] pixsz;
reg [1:0] pixcnt;
reg [2:0] pixsz;
reg [2:0] pixcnt;
reg hs;
cnt <= cnt + 1'd1;
@ -118,7 +118,9 @@ always @(posedge clk_sys) begin
if(cnt <= OSD_WIDTH_PADDED * 2) pixsz <= 0;
else if(cnt <= OSD_WIDTH_PADDED * 3) pixsz <= 1;
else if(cnt <= OSD_WIDTH_PADDED * 4) pixsz <= 2;
else pixsz <= 3;
else if(cnt <= OSD_WIDTH_PADDED * 5) pixsz <= 3;
else if(cnt <= OSD_WIDTH_PADDED * 6) pixsz <= 4;
else pixsz <= 5;
pixcnt <= 0;
auto_ce_pix <= 1;
@ -155,13 +157,15 @@ always @(posedge clk_sys) begin
// falling edge of VSync
if(!VSync && vsD) begin
v_cnt <= 0;
vs_high <= v_cnt;
// if the difference is only one line, that might be interlaced picture
if (vs_high != v_cnt + 1'd1) vs_high <= v_cnt;
end
// rising edge of VSync
else if(VSync && !vsD) begin
v_cnt <= 0;
vs_low <= v_cnt;
// if the difference is only one line, that might be interlaced picture
if (vs_low != v_cnt + 1'd1) vs_low <= v_cnt;
end
end
end

View File

@ -146,7 +146,7 @@ assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_kbd_r_inc;
always@(posedge clk_sys) begin
always@(posedge clk_sys) begin : ps2_kbd
reg ps2_clkD;
ps2_clkD <= ps2_clk;
@ -215,7 +215,7 @@ assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_mouse_r_inc;
always@(posedge clk_sys) begin
always@(posedge clk_sys) begin : ps2_mouse
reg ps2_clkD;
ps2_clkD <= ps2_clk;
@ -283,7 +283,7 @@ wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available};
// status[0] is reset signal from io controller and is thus used to flush
// the fifo
always @(posedge serial_strobe or posedge status[0]) begin
always @(posedge serial_strobe or posedge status[0]) begin : serial_out
if(status[0] == 1) begin
serial_out_wptr <= 0;
end else begin
@ -292,7 +292,7 @@ always @(posedge serial_strobe or posedge status[0]) begin
end
end
always@(negedge spi_sck or posedge status[0]) begin
always@(negedge spi_sck or posedge status[0]) begin : serial_in
if(status[0] == 1) begin
serial_out_rptr <= 0;
end else begin
@ -306,7 +306,7 @@ end
// SPI bit and byte counters
always@(posedge spi_sck or posedge SPI_SS_IO) begin
always@(posedge spi_sck or posedge SPI_SS_IO) begin : spi_counter
if(SPI_SS_IO == 1) begin
bit_cnt <= 0;
byte_cnt <= 0;
@ -321,7 +321,7 @@ end
// SPI transmitter FPGA -> IO
reg [7:0] spi_byte_out;
always@(negedge spi_sck or posedge SPI_SS_IO) begin
always@(negedge spi_sck or posedge SPI_SS_IO) begin : spi_byteout
if(SPI_SS_IO == 1) begin
SPI_MISO <= 1'bZ;
end else begin
@ -329,7 +329,7 @@ always@(negedge spi_sck or posedge SPI_SS_IO) begin
end
end
always@(posedge spi_sck or posedge SPI_SS_IO) begin
always@(posedge spi_sck or posedge SPI_SS_IO) begin : spi_transmitter
reg [31:0] sd_lba_r;
reg [7:0] drive_sel_r;
@ -357,10 +357,12 @@ always@(posedge spi_sck or posedge SPI_SS_IO) begin
// reading sd card write data
8'h18: spi_byte_out <= sd_din;
8'h1b:
// send alternating flag byte and data
if(byte_cnt[0]) spi_byte_out <= serial_out_status;
else spi_byte_out <= serial_out_byte;
endcase
end
end
@ -373,7 +375,7 @@ reg spi_transfer_end_r = 1;
reg [7:0] spi_byte_in;
// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
always@(posedge spi_sck or posedge SPI_SS_IO) begin
always@(posedge spi_sck or posedge SPI_SS_IO) begin : spi_receiver
if(SPI_SS_IO == 1) begin
spi_transfer_end_r <= 1;
@ -392,7 +394,7 @@ always@(posedge spi_sck or posedge SPI_SS_IO) begin
end
// Process bytes from SPI at the clk_sys domain
always @(posedge clk_sys) begin
always @(posedge clk_sys) begin : cmd_block
reg spi_receiver_strobe;
reg spi_transfer_end;
@ -417,7 +419,7 @@ always @(posedge clk_sys) begin
key_strobe <= 0;
mouse_strobe <= 0;
if (~spi_transfer_endD & spi_transfer_end) begin
if (spi_transfer_end) begin
abyte_cnt <= 8'd0;
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
@ -436,12 +438,12 @@ always @(posedge clk_sys) begin
8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h70,8'h71: begin
// store incoming ps2 mouse bytes
if (~acmd[0]) begin
// PS2 serial protocol for the first mouse only
// store incoming ps2 mouse bytes
if (abyte_cnt < 4) begin
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in;
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
end
if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in;
else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in;
else if (abyte_cnt == 3) mouse_y_r <= spi_byte_in;
@ -451,8 +453,8 @@ always @(posedge clk_sys) begin
mouse_x <= { mouse_flags_r[4], mouse_x_r };
mouse_y <= { mouse_flags_r[5], mouse_y_r };
mouse_z <= spi_byte_in[3:0];
mouse_strobe <= 1;
mouse_idx <= acmd[0];
mouse_strobe <= 1;
end
end
8'h05: begin
@ -466,7 +468,7 @@ always @(posedge clk_sys) begin
if (spi_byte_in == 8'he0) key_extended_r <= 1'b1;
else if (spi_byte_in == 8'hf0) key_pressed_r <= 1'b0;
else begin
key_extended <= key_extended_r;
key_extended <= key_extended_r && abyte_cnt != 1;
key_pressed <= key_pressed_r || abyte_cnt == 1;
key_code <= spi_byte_in;
key_strobe <= 1'b1;
@ -506,8 +508,9 @@ always @(posedge clk_sys) begin
end
end
// Process SD-card related bytes from SPI at the clk_sd domain
always @(posedge clk_sd) begin
always @(posedge clk_sd) begin : sd_block
reg spi_receiver_strobe;
reg spi_transfer_end;
@ -538,7 +541,7 @@ always @(posedge clk_sd) begin
img_mounted <= 0;
if (~spi_transfer_endD & spi_transfer_end) begin
if (spi_transfer_end) begin
abyte_cnt <= 8'd0;
sd_ack <= 1'b0;
sd_ack_conf <= 1'b0;
@ -558,6 +561,8 @@ always @(posedge clk_sd) begin
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end
if(spi_byte_in == 8'h19)
sd_ack_conf <= 1'b1;
if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
sd_ack <= 1'b1;
@ -565,7 +570,9 @@ always @(posedge clk_sd) begin
case(acmd)
// send sector IO -> FPGA
8'h17: begin
8'h17,
// send SD config IO -> FPGA
8'h19: begin
// flag that download begins
sd_dout_strobe <= 1'b1;
sd_dout <= spi_byte_in;
@ -579,14 +586,6 @@ always @(posedge clk_sd) begin
end
end
// send SD config IO -> FPGA
8'h19: begin
// flag that download begins
sd_dout_strobe <= 1'b1;
sd_ack_conf <= 1'b1;
sd_dout <= spi_byte_in;
end
8'h1c: img_mounted[spi_byte_in[0]] <= 1;
// send image info