mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-01-28 04:37:12 +00:00
Added QL source code
This commit is contained in:
918
cores/ql/TG68K_ALU.vhd
Normal file
918
cores/ql/TG68K_ALU.vhd
Normal file
@@ -0,0 +1,918 @@
|
||||
------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (c) 2009-2011 Tobias Gubener --
|
||||
-- Subdesign fAMpIGA by TobiFlex --
|
||||
-- --
|
||||
-- This source file is free software: you can redistribute it and/or modify --
|
||||
-- it under the terms of the GNU General Public License as published --
|
||||
-- by the Free Software Foundation, either version 3 of the License, or --
|
||||
-- (at your option) any later version. --
|
||||
-- --
|
||||
-- This source file is distributed in the hope that it will be useful, --
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
|
||||
-- GNU General Public License for more details. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License --
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.TG68K_Pack.all;
|
||||
|
||||
entity TG68K_ALU is
|
||||
generic(
|
||||
MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
||||
DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
|
||||
);
|
||||
port(clk : in std_logic;
|
||||
Reset : in std_logic;
|
||||
clkena_lw : in std_logic:='1';
|
||||
execOPC : in bit;
|
||||
exe_condition : in std_logic;
|
||||
exec_tas : in std_logic;
|
||||
long_start : in bit;
|
||||
movem_presub : in bit;
|
||||
set_stop : in bit;
|
||||
Z_error : in bit;
|
||||
rot_bits : in std_logic_vector(1 downto 0);
|
||||
exec : in bit_vector(lastOpcBit downto 0);
|
||||
OP1out : in std_logic_vector(31 downto 0);
|
||||
OP2out : in std_logic_vector(31 downto 0);
|
||||
reg_QA : in std_logic_vector(31 downto 0);
|
||||
reg_QB : in std_logic_vector(31 downto 0);
|
||||
opcode : in std_logic_vector(15 downto 0);
|
||||
datatype : in std_logic_vector(1 downto 0);
|
||||
exe_opcode : in std_logic_vector(15 downto 0);
|
||||
exe_datatype : in std_logic_vector(1 downto 0);
|
||||
sndOPC : in std_logic_vector(15 downto 0);
|
||||
last_data_read : in std_logic_vector(15 downto 0);
|
||||
data_read : in std_logic_vector(15 downto 0);
|
||||
FlagsSR : in std_logic_vector(7 downto 0);
|
||||
micro_state : in micro_states;
|
||||
bf_ext_in : in std_logic_vector(7 downto 0);
|
||||
bf_ext_out : out std_logic_vector(7 downto 0);
|
||||
bf_shift : in std_logic_vector(5 downto 0);
|
||||
bf_width : in std_logic_vector(5 downto 0);
|
||||
bf_loffset : in std_logic_vector(4 downto 0);
|
||||
|
||||
set_V_Flag : buffer bit;
|
||||
Flags : buffer std_logic_vector(7 downto 0);
|
||||
c_out : buffer std_logic_vector(2 downto 0);
|
||||
addsub_q : buffer std_logic_vector(31 downto 0);
|
||||
ALUout : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end TG68K_ALU;
|
||||
|
||||
architecture logic of TG68K_ALU is
|
||||
-----------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
-- ALU and more
|
||||
-----------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
signal OP1in : std_logic_vector(31 downto 0);
|
||||
signal addsub_a : std_logic_vector(31 downto 0);
|
||||
signal addsub_b : std_logic_vector(31 downto 0);
|
||||
signal notaddsub_b : std_logic_vector(33 downto 0);
|
||||
signal add_result : std_logic_vector(33 downto 0);
|
||||
signal addsub_ofl : std_logic_vector(2 downto 0);
|
||||
signal opaddsub : bit;
|
||||
signal c_in : std_logic_vector(3 downto 0);
|
||||
signal flag_z : std_logic_vector(2 downto 0);
|
||||
signal set_Flags : std_logic_vector(3 downto 0); --NZVC
|
||||
signal CCRin : std_logic_vector(7 downto 0);
|
||||
|
||||
signal niba_l : std_logic_vector(5 downto 0);
|
||||
signal niba_h : std_logic_vector(5 downto 0);
|
||||
signal niba_lc : std_logic;
|
||||
signal niba_hc : std_logic;
|
||||
signal bcda_lc : std_logic;
|
||||
signal bcda_hc : std_logic;
|
||||
signal nibs_l : std_logic_vector(5 downto 0);
|
||||
signal nibs_h : std_logic_vector(5 downto 0);
|
||||
signal nibs_lc : std_logic;
|
||||
signal nibs_hc : std_logic;
|
||||
|
||||
signal bcd_a : std_logic_vector(8 downto 0);
|
||||
signal bcd_s : std_logic_vector(8 downto 0);
|
||||
signal result_mulu : std_logic_vector(63 downto 0);
|
||||
signal result_div : std_logic_vector(63 downto 0);
|
||||
signal set_mV_Flag : std_logic;
|
||||
signal V_Flag : bit;
|
||||
|
||||
signal rot_rot : std_logic;
|
||||
signal rot_lsb : std_logic;
|
||||
signal rot_msb : std_logic;
|
||||
signal rot_X : std_logic;
|
||||
signal rot_C : std_logic;
|
||||
signal rot_out : std_logic_vector(31 downto 0);
|
||||
signal asl_VFlag : std_logic;
|
||||
signal bit_bits : std_logic_vector(1 downto 0);
|
||||
signal bit_number : std_logic_vector(4 downto 0);
|
||||
signal bits_out : std_logic_vector(31 downto 0);
|
||||
signal one_bit_in : std_logic;
|
||||
signal bchg : std_logic;
|
||||
signal bset : std_logic;
|
||||
|
||||
signal mulu_sign : std_logic;
|
||||
signal mulu_signext : std_logic_vector(16 downto 0);
|
||||
signal muls_msb : std_logic;
|
||||
signal mulu_reg : std_logic_vector(63 downto 0);
|
||||
signal FAsign : std_logic;
|
||||
signal faktorA : std_logic_vector(31 downto 0);
|
||||
signal faktorB : std_logic_vector(31 downto 0);
|
||||
|
||||
signal div_reg : std_logic_vector(63 downto 0);
|
||||
signal div_quot : std_logic_vector(63 downto 0);
|
||||
signal div_ovl : std_logic;
|
||||
signal div_neg : std_logic;
|
||||
signal div_bit : std_logic;
|
||||
signal div_sub : std_logic_vector(32 downto 0);
|
||||
signal div_over : std_logic_vector(32 downto 0);
|
||||
signal nozero : std_logic;
|
||||
signal div_qsign : std_logic;
|
||||
signal divisor : std_logic_vector(63 downto 0);
|
||||
signal divs : std_logic;
|
||||
signal signedOP : std_logic;
|
||||
signal OP1_sign : std_logic;
|
||||
signal OP2_sign : std_logic;
|
||||
signal OP2outext : std_logic_vector(15 downto 0);
|
||||
|
||||
signal in_offset : std_logic_vector(5 downto 0);
|
||||
-- signal in_width : std_logic_vector(5 downto 0);
|
||||
signal datareg : std_logic_vector(31 downto 0);
|
||||
signal insert : std_logic_vector(31 downto 0);
|
||||
-- signal bf_result : std_logic_vector(31 downto 0);
|
||||
-- signal bf_offset : std_logic_vector(5 downto 0);
|
||||
-- signal bf_width : std_logic_vector(5 downto 0);
|
||||
-- signal bf_firstbit : std_logic_vector(5 downto 0);
|
||||
signal bf_datareg : std_logic_vector(31 downto 0);
|
||||
-- signal bf_out : std_logic_vector(31 downto 0);
|
||||
signal result : std_logic_vector(39 downto 0);
|
||||
signal result_tmp : std_logic_vector(39 downto 0);
|
||||
signal sign : std_logic_vector(31 downto 0);
|
||||
signal bf_set1 : std_logic_vector(39 downto 0);
|
||||
signal inmux0 : std_logic_vector(39 downto 0);
|
||||
signal inmux1 : std_logic_vector(39 downto 0);
|
||||
signal inmux2 : std_logic_vector(39 downto 0);
|
||||
signal inmux3 : std_logic_vector(31 downto 0);
|
||||
signal copymux0 : std_logic_vector(39 downto 0);
|
||||
signal copymux1 : std_logic_vector(39 downto 0);
|
||||
signal copymux2 : std_logic_vector(39 downto 0);
|
||||
signal copymux3 : std_logic_vector(31 downto 0);
|
||||
signal bf_set2 : std_logic_vector(31 downto 0);
|
||||
-- signal bf_set3 : std_logic_vector(31 downto 0);
|
||||
signal shift : std_logic_vector(39 downto 0);
|
||||
signal copy : std_logic_vector(39 downto 0);
|
||||
-- signal offset : std_logic_vector(5 downto 0);
|
||||
-- signal width : std_logic_vector(5 downto 0);
|
||||
signal bf_firstbit : std_logic_vector(5 downto 0);
|
||||
signal mux : std_logic_vector(3 downto 0);
|
||||
signal bitnr : std_logic_vector(4 downto 0);
|
||||
signal mask : std_logic_vector(31 downto 0);
|
||||
signal bf_bset : std_logic;
|
||||
signal bf_NFlag : std_logic;
|
||||
signal bf_bchg : std_logic;
|
||||
signal bf_ins : std_logic;
|
||||
signal bf_exts : std_logic;
|
||||
signal bf_fffo : std_logic;
|
||||
signal bf_d32 : std_logic;
|
||||
signal bf_s32 : std_logic;
|
||||
signal index : std_logic_vector(4 downto 0);
|
||||
-- signal i : integer range 0 to 31;
|
||||
-- signal i : integer range 0 to 31;
|
||||
-- signal i : std_logic_vector(5 downto 0);
|
||||
BEGIN
|
||||
-----------------------------------------------------------------------------
|
||||
-- set OP1in
|
||||
-----------------------------------------------------------------------------
|
||||
PROCESS (OP2out, reg_QB, opcode, OP1out, OP1in, exe_datatype, addsub_q, execOPC, exec,
|
||||
bcd_a, bcd_s, result_mulu, result_div, exe_condition, bf_shift,
|
||||
Flags, FlagsSR, bits_out, exec_tas, rot_out, exe_opcode, result, bf_fffo, bf_firstbit, bf_datareg)
|
||||
BEGIN
|
||||
ALUout <= OP1in;
|
||||
ALUout(7) <= OP1in(7) OR exec_tas;
|
||||
IF exec(opcBFwb)='1' THEN
|
||||
ALUout <= result(31 downto 0);
|
||||
IF bf_fffo='1' THEN
|
||||
ALUout <= (OTHERS =>'0');
|
||||
ALUout(5 downto 0) <= bf_firstbit + bf_shift;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
OP1in <= addsub_q;
|
||||
IF exec(opcABCD)='1' THEN
|
||||
OP1in(7 downto 0) <= bcd_a(7 downto 0);
|
||||
ELSIF exec(opcSBCD)='1' THEN
|
||||
OP1in(7 downto 0) <= bcd_s(7 downto 0);
|
||||
ELSIF exec(opcMULU)='1' AND MUL_Mode/=3 THEN
|
||||
IF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN
|
||||
OP1in <= result_mulu(31 downto 0);
|
||||
ELSE
|
||||
OP1in <= result_mulu(63 downto 32);
|
||||
END IF;
|
||||
ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN
|
||||
IF exe_opcode(15)='1' OR DIV_Mode=0 THEN
|
||||
-- IF exe_opcode(15)='1' THEN
|
||||
OP1in <= result_div(47 downto 32)&result_div(15 downto 0);
|
||||
ELSE --64bit
|
||||
IF exec(write_reminder)='1' THEN
|
||||
OP1in <= result_div(63 downto 32);
|
||||
ELSE
|
||||
OP1in <= result_div(31 downto 0);
|
||||
END IF;
|
||||
END IF;
|
||||
ELSIF exec(opcOR)='1' THEN
|
||||
OP1in <= OP2out OR OP1out;
|
||||
ELSIF exec(opcAND)='1' THEN
|
||||
OP1in <= OP2out AND OP1out;
|
||||
ELSIF exec(opcScc)='1' THEN
|
||||
OP1in(7 downto 0) <= (others=>exe_condition);
|
||||
ELSIF exec(opcEOR)='1' THEN
|
||||
OP1in <= OP2out XOR OP1out;
|
||||
ELSIF exec(opcMOVE)='1' OR exec(exg)='1' THEN
|
||||
-- OP1in <= OP2out(31 downto 8)&(OP2out(7)OR exec_tas)&OP2out(6 downto 0);
|
||||
OP1in <= OP2out;
|
||||
ELSIF exec(opcROT)='1' THEN
|
||||
OP1in <= rot_out;
|
||||
ELSIF exec(opcSWAP)='1' THEN
|
||||
OP1in <= OP1out(15 downto 0)& OP1out(31 downto 16);
|
||||
ELSIF exec(opcBITS)='1' THEN
|
||||
OP1in <= bits_out;
|
||||
ELSIF exec(opcBF)='1' THEN
|
||||
OP1in <= bf_datareg;
|
||||
ELSIF exec(opcMOVESR)='1' THEN
|
||||
OP1in(7 downto 0) <= Flags;
|
||||
IF exe_datatype="00" THEN
|
||||
OP1in(15 downto 8) <= "00000000";
|
||||
ELSE
|
||||
OP1in(15 downto 8) <= FlagsSR;
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- addsub
|
||||
-----------------------------------------------------------------------------
|
||||
PROCESS (OP1out, OP2out, execOPC, datatype, Flags, long_start, movem_presub, exe_datatype, exec, addsub_a, addsub_b, opaddsub,
|
||||
notaddsub_b, add_result, c_in, sndOPC)
|
||||
BEGIN
|
||||
addsub_a <= OP1out;
|
||||
IF exec(get_bfoffset)='1' THEN
|
||||
IF sndOPC(11)='1' THEN
|
||||
addsub_a <= OP1out(31)&OP1out(31)&OP1out(31)&OP1out(31 downto 3);
|
||||
ELSE
|
||||
addsub_a <= "000000000000000000000000000000"&sndOPC(10 downto 9);
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF exec(subidx)='1' THEN
|
||||
opaddsub <= '1';
|
||||
ELSE
|
||||
opaddsub <= '0';
|
||||
END IF;
|
||||
|
||||
c_in(0) <='0';
|
||||
addsub_b <= OP2out;
|
||||
IF execOPC='0' AND exec(OP2out_one)='0' AND exec(get_bfoffset)='0'THEN
|
||||
IF long_start='0' AND datatype="00" AND exec(use_SP)='0' THEN
|
||||
addsub_b <= "00000000000000000000000000000001";
|
||||
ELSIF long_start='0' AND exe_datatype="10" AND (exec(presub) OR exec(postadd) OR movem_presub)='1' THEN
|
||||
IF exec(movem_action)='1' THEN
|
||||
addsub_b <= "00000000000000000000000000000110";
|
||||
ELSE
|
||||
addsub_b <= "00000000000000000000000000000100";
|
||||
END IF;
|
||||
ELSE
|
||||
addsub_b <= "00000000000000000000000000000010";
|
||||
END IF;
|
||||
ELSE
|
||||
IF (exec(use_XZFlag)='1' AND Flags(4)='1') OR exec(opcCHK)='1' THEN
|
||||
c_in(0) <= '1';
|
||||
END IF;
|
||||
opaddsub <= exec(addsub);
|
||||
END IF;
|
||||
|
||||
IF opaddsub='0' OR long_start='1' THEN --ADD
|
||||
notaddsub_b <= '0'&addsub_b&c_in(0);
|
||||
ELSE --SUB
|
||||
notaddsub_b <= NOT ('0'&addsub_b&c_in(0));
|
||||
END IF;
|
||||
add_result <= (('0'&addsub_a¬addsub_b(0))+notaddsub_b);
|
||||
c_in(1) <= add_result(9) XOR addsub_a(8) XOR addsub_b(8);
|
||||
c_in(2) <= add_result(17) XOR addsub_a(16) XOR addsub_b(16);
|
||||
c_in(3) <= add_result(33);
|
||||
addsub_q <= add_result(32 downto 1);
|
||||
addsub_ofl(0) <= (c_in(1) XOR add_result(8) XOR addsub_a(7) XOR addsub_b(7)); --V Byte
|
||||
addsub_ofl(1) <= (c_in(2) XOR add_result(16) XOR addsub_a(15) XOR addsub_b(15)); --V Word
|
||||
addsub_ofl(2) <= (c_in(3) XOR add_result(32) XOR addsub_a(31) XOR addsub_b(31)); --V Long
|
||||
c_out <= c_in(3 downto 1);
|
||||
END PROCESS;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--ALU
|
||||
------------------------------------------------------------------------------
|
||||
PROCESS (OP1out, OP2out, niba_hc, niba_h, niba_l, niba_lc, nibs_hc, nibs_h, nibs_l, nibs_lc, Flags)
|
||||
BEGIN
|
||||
--BCD_ARITH-------------------------------------------------------------------
|
||||
--ADC
|
||||
bcd_a <= niba_hc&(niba_h(4 downto 1)+('0',niba_hc,niba_hc,'0'))&(niba_l(4 downto 1)+('0',niba_lc,niba_lc,'0'));
|
||||
niba_l <= ('0'&OP1out(3 downto 0)&'1') + ('0'&OP2out(3 downto 0)&Flags(4));
|
||||
niba_lc <= niba_l(5) OR (niba_l(4) AND niba_l(3)) OR (niba_l(4) AND niba_l(2));
|
||||
|
||||
niba_h <= ('0'&OP1out(7 downto 4)&'1') + ('0'&OP2out(7 downto 4)&niba_lc);
|
||||
niba_hc <= niba_h(5) OR (niba_h(4) AND niba_h(3)) OR (niba_h(4) AND niba_h(2));
|
||||
--SBC
|
||||
bcd_s <= nibs_hc&(nibs_h(4 downto 1)-('0',nibs_hc,nibs_hc,'0'))&(nibs_l(4 downto 1)-('0',nibs_lc,nibs_lc,'0'));
|
||||
nibs_l <= ('0'&OP1out(3 downto 0)&'0') - ('0'&OP2out(3 downto 0)&Flags(4));
|
||||
nibs_lc <= nibs_l(5);
|
||||
|
||||
nibs_h <= ('0'&OP1out(7 downto 4)&'0') - ('0'&OP2out(7 downto 4)&nibs_lc);
|
||||
nibs_hc <= nibs_h(5);
|
||||
END PROCESS;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Bits
|
||||
-----------------------------------------------------------------------------
|
||||
PROCESS (clk, exe_opcode, OP1out, OP2out, one_bit_in, bchg, bset, bit_Number, sndOPC)
|
||||
BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena_lw = '1' THEN
|
||||
bchg <= '0';
|
||||
bset <= '0';
|
||||
CASE opcode(7 downto 6) IS
|
||||
WHEN "01" => --bchg
|
||||
bchg <= '1';
|
||||
WHEN "11" => --bset
|
||||
bset <= '1';
|
||||
WHEN OTHERS => NULL;
|
||||
END CASE;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF exe_opcode(8)='0' THEN
|
||||
IF exe_opcode(5 downto 4)="00" THEN
|
||||
bit_number <= sndOPC(4 downto 0);
|
||||
ELSE
|
||||
bit_number <= "00"&sndOPC(2 downto 0);
|
||||
END IF;
|
||||
ELSE
|
||||
IF exe_opcode(5 downto 4)="00" THEN
|
||||
bit_number <= reg_QB(4 downto 0);
|
||||
ELSE
|
||||
bit_number <= "00"®_QB(2 downto 0);
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
one_bit_in <= OP1out(to_integer(unsigned(bit_Number)));
|
||||
bits_out <= OP1out;
|
||||
bits_out(to_integer(unsigned(bit_Number))) <= (bchg AND NOT one_bit_in) OR bset ;
|
||||
END PROCESS;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Bit Field
|
||||
-----------------------------------------------------------------------------
|
||||
PROCESS (clk, mux, mask, bitnr, bf_ins, bf_bchg, bf_bset, bf_exts, bf_shift, inmux0, inmux1, inmux2, inmux3, bf_set2, OP1out, OP2out, result_tmp, bf_ext_in,
|
||||
shift, datareg, bf_NFlag, result, reg_QB, sign, bf_d32, bf_s32, copy, bf_loffset, copymux0, copymux1, copymux2, copymux3, bf_width)
|
||||
BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena_lw = '1' THEN
|
||||
bf_bset <= '0';
|
||||
bf_bchg <= '0';
|
||||
bf_ins <= '0';
|
||||
bf_exts <= '0';
|
||||
bf_fffo <= '0';
|
||||
bf_d32 <= '0';
|
||||
bf_s32 <= '0';
|
||||
CASE opcode(10 downto 8) IS
|
||||
WHEN "010" => bf_bchg <= '1'; --BFCHG
|
||||
WHEN "011" => bf_exts <= '1'; --BFEXTS
|
||||
-- WHEN "100" => insert <= (OTHERS =>'0'); --BFCLR
|
||||
WHEN "101" => bf_fffo <= '1'; --BFFFO
|
||||
WHEN "110" => bf_bset <= '1'; --BFSET
|
||||
WHEN "111" => bf_ins <= '1'; --BFINS
|
||||
bf_s32 <= '1';
|
||||
WHEN OTHERS => NULL;
|
||||
END CASE;
|
||||
IF opcode(4 downto 3)="00" THEN
|
||||
bf_d32 <= '1';
|
||||
END IF;
|
||||
bf_ext_out <= result(39 downto 32);
|
||||
END IF;
|
||||
END IF;
|
||||
shift <= bf_ext_in&OP2out;
|
||||
IF bf_s32='1' THEN
|
||||
shift(39 downto 32) <= OP2out(7 downto 0);
|
||||
END IF;
|
||||
|
||||
IF bf_shift(0)='1' THEN
|
||||
inmux0 <= shift(0)&shift(39 downto 1);
|
||||
ELSE
|
||||
inmux0 <= shift;
|
||||
END IF;
|
||||
IF bf_shift(1)='1' THEN
|
||||
inmux1 <= inmux0(1 downto 0)&inmux0(39 downto 2);
|
||||
ELSE
|
||||
inmux1 <= inmux0;
|
||||
END IF;
|
||||
IF bf_shift(2)='1' THEN
|
||||
inmux2 <= inmux1(3 downto 0)&inmux1(39 downto 4);
|
||||
ELSE
|
||||
inmux2 <= inmux1;
|
||||
END IF;
|
||||
IF bf_shift(3)='1' THEN
|
||||
inmux3 <= inmux2(7 downto 0)&inmux2(31 downto 8);
|
||||
ELSE
|
||||
inmux3 <= inmux2(31 downto 0);
|
||||
END IF;
|
||||
IF bf_shift(4)='1' THEN
|
||||
bf_set2(31 downto 0) <= inmux3(15 downto 0)&inmux3(31 downto 16);
|
||||
ELSE
|
||||
bf_set2(31 downto 0) <= inmux3;
|
||||
END IF;
|
||||
|
||||
IF bf_loffset(4)='1' THEN
|
||||
copymux3 <= sign(15 downto 0)&sign(31 downto 16);
|
||||
ELSE
|
||||
copymux3 <= sign;
|
||||
END IF;
|
||||
IF bf_loffset(3)='1' THEN
|
||||
copymux2(31 downto 0) <= copymux3(23 downto 0)©mux3(31 downto 24);
|
||||
ELSE
|
||||
copymux2(31 downto 0) <= copymux3;
|
||||
END IF;
|
||||
IF bf_d32='1' THEN
|
||||
copymux2(39 downto 32) <= copymux3(7 downto 0);
|
||||
ELSE
|
||||
copymux2(39 downto 32) <= "11111111";
|
||||
END IF;
|
||||
IF bf_loffset(2)='1' THEN
|
||||
copymux1 <= copymux2(35 downto 0)©mux2(39 downto 36);
|
||||
ELSE
|
||||
copymux1 <= copymux2;
|
||||
END IF;
|
||||
IF bf_loffset(1)='1' THEN
|
||||
copymux0 <= copymux1(37 downto 0)©mux1(39 downto 38);
|
||||
ELSE
|
||||
copymux0 <= copymux1;
|
||||
END IF;
|
||||
IF bf_loffset(0)='1' THEN
|
||||
copy <= copymux0(38 downto 0)©mux0(39);
|
||||
ELSE
|
||||
copy <= copymux0;
|
||||
END IF;
|
||||
|
||||
result_tmp <= bf_ext_in&OP1out;
|
||||
IF bf_ins='1' THEN
|
||||
datareg <= reg_QB;
|
||||
ELSE
|
||||
datareg <= bf_set2;
|
||||
END IF;
|
||||
IF bf_ins='1' THEN
|
||||
result(31 downto 0) <= bf_set2;
|
||||
result(39 downto 32) <= bf_set2(7 downto 0);
|
||||
ELSIF bf_bchg='1' THEN
|
||||
result(31 downto 0) <= NOT OP1out;
|
||||
result(39 downto 32) <= NOT bf_ext_in;
|
||||
ELSE
|
||||
result <= (OTHERS => '0');
|
||||
END IF;
|
||||
IF bf_bset='1' THEN
|
||||
result <= (OTHERS => '1');
|
||||
END IF;
|
||||
|
||||
sign <= (OTHERS => '0');
|
||||
bf_NFlag <= datareg(to_integer(unsigned(bf_width)));
|
||||
FOR i in 0 to 31 LOOP
|
||||
IF i>bf_width(4 downto 0) THEN
|
||||
datareg(i) <= '0';
|
||||
sign(i) <= '1';
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
FOR i in 0 to 39 LOOP
|
||||
IF copy(i)='1' THEN
|
||||
result(i) <= result_tmp(i);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
IF bf_exts='1' AND bf_NFlag='1' THEN
|
||||
bf_datareg <= datareg OR sign;
|
||||
ELSE
|
||||
bf_datareg <= datareg;
|
||||
END IF;
|
||||
-- bf_datareg <= copy(31 downto 0);
|
||||
-- result(31 downto 0)<=datareg;
|
||||
--BFFFO
|
||||
mask <= datareg;
|
||||
bf_firstbit <= '0'&bitnr;
|
||||
bitnr <= "11111";
|
||||
IF mask(31 downto 28)="0000" THEN
|
||||
IF mask(27 downto 24)="0000" THEN
|
||||
IF mask(23 downto 20)="0000" THEN
|
||||
IF mask(19 downto 16)="0000" THEN
|
||||
bitnr(4) <= '0';
|
||||
IF mask(15 downto 12)="0000" THEN
|
||||
IF mask(11 downto 8)="0000" THEN
|
||||
bitnr(3) <= '0';
|
||||
IF mask(7 downto 4)="0000" THEN
|
||||
bitnr(2) <= '0';
|
||||
mux <= mask(3 downto 0);
|
||||
ELSE
|
||||
mux <= mask(7 downto 4);
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(11 downto 8);
|
||||
bitnr(2) <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(15 downto 12);
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(19 downto 16);
|
||||
bitnr(3) <= '0';
|
||||
bitnr(2) <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(23 downto 20);
|
||||
bitnr(3) <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(27 downto 24);
|
||||
bitnr(2) <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
mux <= mask(31 downto 28);
|
||||
END IF;
|
||||
|
||||
IF mux(3 downto 2)="00" THEN
|
||||
bitnr(1) <= '0';
|
||||
IF mux(1)='0' THEN
|
||||
bitnr(0) <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
IF mux(3)='0' THEN
|
||||
bitnr(0) <= '0';
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Rotation
|
||||
-----------------------------------------------------------------------------
|
||||
PROCESS (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_rot, exec)
|
||||
BEGIN
|
||||
CASE exe_opcode(7 downto 6) IS
|
||||
WHEN "00" => --Byte
|
||||
rot_rot <= OP1out(7);
|
||||
WHEN "01"|"11" => --Word
|
||||
rot_rot <= OP1out(15);
|
||||
WHEN "10" => --Long
|
||||
rot_rot <= OP1out(31);
|
||||
WHEN OTHERS => NULL;
|
||||
END CASE;
|
||||
|
||||
CASE rot_bits IS
|
||||
WHEN "00" => --ASL, ASR
|
||||
rot_lsb <= '0';
|
||||
rot_msb <= rot_rot;
|
||||
WHEN "01" => --LSL, LSR
|
||||
rot_lsb <= '0';
|
||||
rot_msb <= '0';
|
||||
WHEN "10" => --ROXL, ROXR
|
||||
rot_lsb <= Flags(4);
|
||||
rot_msb <= Flags(4);
|
||||
WHEN "11" => --ROL, ROR
|
||||
rot_lsb <= rot_rot;
|
||||
rot_msb <= OP1out(0);
|
||||
WHEN OTHERS => NULL;
|
||||
END CASE;
|
||||
|
||||
IF exec(rot_nop)='1' THEN
|
||||
rot_out <= OP1out;
|
||||
rot_X <= Flags(4);
|
||||
IF rot_bits="10" THEN --ROXL, ROXR
|
||||
rot_C <= Flags(4);
|
||||
ELSE
|
||||
rot_C <= '0';
|
||||
END IF;
|
||||
ELSE
|
||||
IF exe_opcode(8)='1' THEN --left
|
||||
rot_out <= OP1out(30 downto 0)&rot_lsb;
|
||||
rot_X <= rot_rot;
|
||||
rot_C <= rot_rot;
|
||||
ELSE --right
|
||||
rot_X <= OP1out(0);
|
||||
rot_C <= OP1out(0);
|
||||
rot_out <= rot_msb&OP1out(31 downto 1);
|
||||
CASE exe_opcode(7 downto 6) IS
|
||||
WHEN "00" => --Byte
|
||||
rot_out(7) <= rot_msb;
|
||||
WHEN "01"|"11" => --Word
|
||||
rot_out(15) <= rot_msb;
|
||||
WHEN OTHERS => NULL;
|
||||
END CASE;
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--CCR op
|
||||
------------------------------------------------------------------------------
|
||||
PROCESS (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, flag_z, OP1IN, c_out, addsub_ofl,
|
||||
bcd_s, bcd_a, exec)
|
||||
BEGIN
|
||||
IF exec(andiSR)='1' THEN
|
||||
CCRin <= Flags AND last_data_read(7 downto 0);
|
||||
ELSIF exec(eoriSR)='1' THEN
|
||||
CCRin <= Flags XOR last_data_read(7 downto 0);
|
||||
ELSIF exec(oriSR)='1' THEN
|
||||
CCRin <= Flags OR last_data_read(7 downto 0);
|
||||
ELSE
|
||||
CCRin <= OP2out(7 downto 0);
|
||||
END IF;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--Flags
|
||||
------------------------------------------------------------------------------
|
||||
flag_z <= "000";
|
||||
IF exec(use_XZFlag)='1' AND flags(2)='0' THEN
|
||||
flag_z <= "000";
|
||||
ELSIF OP1in(7 downto 0)="00000000" THEN
|
||||
flag_z(0) <= '1';
|
||||
IF OP1in(15 downto 8)="00000000" THEN
|
||||
flag_z(1) <= '1';
|
||||
IF OP1in(31 downto 16)="0000000000000000" THEN
|
||||
flag_z(2) <= '1';
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- --Flags NZVC
|
||||
IF exe_datatype="00" THEN --Byte
|
||||
set_flags <= OP1IN(7)&flag_z(0)&addsub_ofl(0)&c_out(0);
|
||||
IF exec(opcABCD)='1' THEN
|
||||
set_flags(0) <= bcd_a(8);
|
||||
ELSIF exec(opcSBCD)='1' THEN
|
||||
set_flags(0) <= bcd_s(8);
|
||||
END IF;
|
||||
ELSIF exe_datatype="10" OR exec(opcCPMAW)='1' THEN --Long
|
||||
set_flags <= OP1IN(31)&flag_z(2)&addsub_ofl(2)&c_out(2);
|
||||
ELSE --Word
|
||||
set_flags <= OP1IN(15)&flag_z(1)&addsub_ofl(1)&c_out(1);
|
||||
END IF;
|
||||
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena_lw = '1' THEN
|
||||
IF exec(directSR)='1' OR set_stop='1' THEN
|
||||
Flags(7 downto 0) <= data_read(7 downto 0);
|
||||
END IF;
|
||||
IF exec(directCCR)='1' THEN
|
||||
Flags(7 downto 0) <= data_read(7 downto 0);
|
||||
END IF;
|
||||
|
||||
IF exec(opcROT)='1' THEN
|
||||
asl_VFlag <= ((set_flags(3) XOR rot_rot) OR asl_VFlag);
|
||||
ELSE
|
||||
asl_VFlag <= '0';
|
||||
END IF;
|
||||
IF exec(to_CCR)='1' THEN
|
||||
Flags(7 downto 0) <= CCRin(7 downto 0); --CCR
|
||||
ELSIF Z_error='1' THEN
|
||||
IF exe_opcode(8)='0' THEN
|
||||
Flags(3 downto 0) <= reg_QA(31)&"000";
|
||||
ELSE
|
||||
Flags(3 downto 0) <= "0100";
|
||||
END IF;
|
||||
ELSIF exec(no_Flags)='0' THEN
|
||||
IF exec(opcADD)='1' THEN
|
||||
Flags(4) <= set_flags(0);
|
||||
ELSIF exec(opcROT)='1' AND rot_bits/="11" AND exec(rot_nop)='0' THEN
|
||||
Flags(4) <= rot_X;
|
||||
END IF;
|
||||
|
||||
IF (exec(opcADD) OR exec(opcCMP))='1' THEN
|
||||
Flags(3 downto 0) <= set_flags;
|
||||
ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN
|
||||
IF V_Flag='1' THEN
|
||||
Flags(3 downto 0) <= "1010";
|
||||
ELSE
|
||||
Flags(3 downto 0) <= OP1IN(15)&flag_z(1)&"00";
|
||||
END IF;
|
||||
ELSIF exec(write_reminder)='1' AND MUL_Mode/=3 THEN -- z-flag MULU.l
|
||||
Flags(3) <= set_flags(3);
|
||||
Flags(2) <= set_flags(2) AND Flags(2);
|
||||
Flags(1) <= '0';
|
||||
Flags(0) <= '0';
|
||||
ELSIF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN -- flag MULU.l
|
||||
Flags(3) <= set_flags(3);
|
||||
Flags(2) <= set_flags(2);
|
||||
Flags(1) <= set_mV_Flag; --V
|
||||
Flags(0) <= '0';
|
||||
ELSIF exec(opcOR)='1' OR exec(opcAND)='1' OR exec(opcEOR)='1' OR exec(opcMOVE)='1' OR exec(opcMOVEQ)='1' OR exec(opcSWAP)='1' OR exec(opcBF)='1' OR (exec(opcMULU)='1' AND MUL_Mode/=3) THEN
|
||||
Flags(1 downto 0) <= "00";
|
||||
Flags(3 downto 2) <= set_flags(3 downto 2);
|
||||
IF exec(opcBF)='1' THEN
|
||||
Flags(3) <= bf_NFlag;
|
||||
END IF;
|
||||
ELSIF exec(opcROT)='1' THEN
|
||||
Flags(3 downto 2) <= set_flags(3 downto 2);
|
||||
Flags(0) <= rot_C;
|
||||
IF rot_bits="00" AND ((set_flags(3) XOR rot_rot) OR asl_VFlag)='1' THEN --ASL/ASR
|
||||
Flags(1) <= '1';
|
||||
ELSE
|
||||
Flags(1) <= '0';
|
||||
END IF;
|
||||
ELSIF exec(opcBITS)='1' THEN
|
||||
Flags(2) <= NOT one_bit_in;
|
||||
ELSIF exec(opcCHK)='1' THEN
|
||||
IF exe_datatype="01" THEN --Word
|
||||
Flags(3) <= OP1out(15);
|
||||
ELSE
|
||||
Flags(3) <= OP1out(31);
|
||||
END IF;
|
||||
IF OP1out(15 downto 0)=X"0000" AND (exe_datatype="01" OR OP1out(31 downto 16)=X"0000") THEN
|
||||
Flags(2) <='1';
|
||||
ELSE
|
||||
Flags(2) <='0';
|
||||
END IF;
|
||||
Flags(1 downto 0) <= "00";
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
Flags(7 downto 5) <= "000";
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
---- MULU/MULS
|
||||
-------------------------------------------------------------------------------
|
||||
PROCESS (exe_opcode, OP2out, muls_msb, mulu_reg, FAsign, mulu_sign, reg_QA, faktorB, result_mulu, signedOP)
|
||||
BEGIN
|
||||
IF (signedOP='1' AND faktorB(31)='1') OR FAsign='1' THEN
|
||||
muls_msb <= mulu_reg(63);
|
||||
ELSE
|
||||
muls_msb <= '0';
|
||||
END IF;
|
||||
|
||||
IF signedOP='1' AND faktorB(31)='1' THEN
|
||||
mulu_sign <= '1';
|
||||
ELSE
|
||||
mulu_sign <= '0';
|
||||
END IF;
|
||||
|
||||
IF MUL_Mode=0 THEN -- 16 Bit
|
||||
result_mulu(63 downto 32) <= muls_msb&mulu_reg(63 downto 33);
|
||||
result_mulu(15 downto 0) <= 'X'&mulu_reg(15 downto 1);
|
||||
IF mulu_reg(0)='1' THEN
|
||||
IF FAsign='1' THEN
|
||||
result_mulu(63 downto 47) <= (muls_msb&mulu_reg(63 downto 48)-(mulu_sign&faktorB(31 downto 16)));
|
||||
ELSE
|
||||
result_mulu(63 downto 47) <= (muls_msb&mulu_reg(63 downto 48)+(mulu_sign&faktorB(31 downto 16)));
|
||||
END IF;
|
||||
END IF;
|
||||
ELSE -- 32 Bit
|
||||
result_mulu <= muls_msb&mulu_reg(63 downto 1);
|
||||
IF mulu_reg(0)='1' THEN
|
||||
IF FAsign='1' THEN
|
||||
result_mulu(63 downto 31) <= (muls_msb&mulu_reg(63 downto 32)-(mulu_sign&faktorB));
|
||||
ELSE
|
||||
result_mulu(63 downto 31) <= (muls_msb&mulu_reg(63 downto 32)+(mulu_sign&faktorB));
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
IF exe_opcode(15)='1' OR MUL_Mode=0 THEN
|
||||
faktorB(31 downto 16) <= OP2out(15 downto 0);
|
||||
faktorB(15 downto 0) <= (OTHERS=>'0');
|
||||
ELSE
|
||||
faktorB <= OP2out;
|
||||
END IF;
|
||||
IF (result_mulu(63 downto 32)=X"00000000" AND (signedOP='0' OR result_mulu(31)='0')) OR
|
||||
(result_mulu(63 downto 32)=X"FFFFFFFF" AND signedOP='1' AND result_mulu(31)='1') THEN
|
||||
set_mV_Flag <= '0';
|
||||
ELSE
|
||||
set_mV_Flag <= '1';
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (clk)
|
||||
BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena_lw='1' THEN
|
||||
IF micro_state=mul1 THEN
|
||||
mulu_reg(63 downto 32) <= (OTHERS=>'0');
|
||||
IF divs='1' AND ((exe_opcode(15)='1' AND reg_QA(15)='1') OR (exe_opcode(15)='0' AND reg_QA(31)='1')) THEN --MULS Neg faktor
|
||||
FAsign <= '1';
|
||||
mulu_reg(31 downto 0) <= 0-reg_QA;
|
||||
ELSE
|
||||
FAsign <= '0';
|
||||
mulu_reg(31 downto 0) <= reg_QA;
|
||||
END IF;
|
||||
ELSIF exec(opcMULU)='0' THEN
|
||||
mulu_reg <= result_mulu;
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
---- DIVU/DIVS
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
PROCESS (execOPC, OP1out, OP2out, div_reg, div_neg, div_bit, div_sub, div_quot, OP1_sign, div_over, result_div, reg_QA, opcode, sndOPC, divs, exe_opcode, reg_QB,
|
||||
signedOP, nozero, div_qsign, OP2outext)
|
||||
BEGIN
|
||||
divs <= (opcode(15) AND opcode(8)) OR (NOT opcode(15) AND sndOPC(11));
|
||||
divisor(15 downto 0) <= (OTHERS=> '0');
|
||||
divisor(63 downto 32) <= (OTHERS=> divs AND reg_QA(31));
|
||||
IF exe_opcode(15)='1' OR DIV_Mode=0 THEN
|
||||
divisor(47 downto 16) <= reg_QA;
|
||||
ELSE
|
||||
divisor(31 downto 0) <= reg_QA;
|
||||
IF exe_opcode(14)='1' AND sndOPC(10)='1' THEN
|
||||
divisor(63 downto 32) <= reg_QB;
|
||||
END IF;
|
||||
END IF;
|
||||
IF signedOP='1' OR opcode(15)='0' THEN
|
||||
OP2outext <= OP2out(31 downto 16);
|
||||
ELSE
|
||||
OP2outext <= (OTHERS=> '0');
|
||||
END IF;
|
||||
IF signedOP='1' AND OP2out(31) ='1' THEN
|
||||
div_sub <= (div_reg(63 downto 31))+('1'&OP2out(31 downto 0));
|
||||
ELSE
|
||||
div_sub <= (div_reg(63 downto 31))-('0'&OP2outext(15 downto 0)&OP2out(15 downto 0));
|
||||
END IF;
|
||||
IF DIV_Mode=0 THEN
|
||||
div_bit <= div_sub(16);
|
||||
ELSE
|
||||
div_bit <= div_sub(32);
|
||||
END IF;
|
||||
IF div_bit='1' THEN
|
||||
div_quot(63 downto 32) <= div_reg(62 downto 31);
|
||||
ELSE
|
||||
div_quot(63 downto 32) <= div_sub(31 downto 0);
|
||||
END IF;
|
||||
div_quot(31 downto 0) <= div_reg(30 downto 0)&NOT div_bit;
|
||||
|
||||
|
||||
IF ((nozero='1' AND signedOP='1' AND (OP2out(31) XOR OP1_sign XOR div_neg XOR div_qsign)='1' ) --Overflow DIVS
|
||||
OR (signedOP='0' AND div_over(32)='0')) AND DIV_Mode/=3 THEN --Overflow DIVU
|
||||
set_V_Flag <= '1';
|
||||
ELSE
|
||||
set_V_Flag <= '0';
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (clk)
|
||||
BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena_lw='1' THEN
|
||||
V_Flag <= set_V_Flag;
|
||||
signedOP <= divs;
|
||||
IF micro_state=div1 THEN
|
||||
nozero <= '0';
|
||||
IF divs='1' AND divisor(63)='1' THEN -- Neg divisor
|
||||
OP1_sign <= '1';
|
||||
div_reg <= 0-divisor;
|
||||
ELSE
|
||||
OP1_sign <= '0';
|
||||
div_reg <= divisor;
|
||||
END IF;
|
||||
ELSE
|
||||
div_reg <= div_quot;
|
||||
nozero <= NOT div_bit OR nozero;
|
||||
END IF;
|
||||
IF micro_state=div2 THEN
|
||||
div_qsign <= NOT div_bit;
|
||||
div_neg <= signedOP AND (OP2out(31) XOR OP1_sign);
|
||||
IF DIV_Mode=0 THEN
|
||||
div_over(32 downto 16) <= ('0'&div_reg(47 downto 32))-('0'&OP2out(15 downto 0));
|
||||
ELSE
|
||||
div_over <= ('0'&div_reg(63 downto 32))-('0'&OP2out);
|
||||
END IF;
|
||||
END IF;
|
||||
IF exec(write_reminder)='0' THEN
|
||||
-- IF exec_DIVU='0' THEN
|
||||
IF div_neg='1' THEN
|
||||
result_div(31 downto 0) <= 0-div_quot(31 downto 0);
|
||||
ELSE
|
||||
result_div(31 downto 0) <= div_quot(31 downto 0);
|
||||
END IF;
|
||||
|
||||
IF OP1_sign='1' THEN
|
||||
result_div(63 downto 32) <= 0-div_quot(63 downto 32);
|
||||
ELSE
|
||||
result_div(63 downto 32) <= div_quot(63 downto 32);
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
END;
|
||||
165
cores/ql/TG68K_Pack.vhd
Normal file
165
cores/ql/TG68K_Pack.vhd
Normal file
@@ -0,0 +1,165 @@
|
||||
------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (c) 2009-2013 Tobias Gubener --
|
||||
-- Subdesign fAMpIGA by TobiFlex --
|
||||
-- --
|
||||
-- This source file is free software: you can redistribute it and/or modify --
|
||||
-- it under the terms of the GNU General Public License as published --
|
||||
-- by the Free Software Foundation, either version 3 of the License, or --
|
||||
-- (at your option) any later version. --
|
||||
-- --
|
||||
-- This source file is distributed in the hope that it will be useful, --
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
|
||||
-- GNU General Public License for more details. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License --
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package TG68K_Pack is
|
||||
|
||||
type micro_states is (idle, nop, ld_nn, st_nn, ld_dAn1, ld_AnXn1, ld_AnXn2, st_dAn1, ld_AnXnbd1, ld_AnXnbd2, ld_AnXnbd3,
|
||||
ld_229_1, ld_229_2, ld_229_3, ld_229_4, st_229_1, st_229_2, st_229_3, st_229_4,
|
||||
st_AnXn1, st_AnXn2, bra1, bsr1, bsr2, nopnop, dbcc1, movem1, movem2, movem3,
|
||||
andi, op_AxAy, cmpm, link1, link2, unlink1, unlink2, int1, int2, int3, int4, rte1, rte2, rte3, trap0, trap1, trap2, trap3,
|
||||
trap4, trap5, trap6, movec1, movep1, movep2, movep3, movep4, movep5, rota1, bf1,
|
||||
mul1, mul2, mul_end1, mul_end2, div1, div2, div3, div4, div_end1, div_end2);
|
||||
|
||||
constant opcMOVE : integer := 0; --
|
||||
constant opcMOVEQ : integer := 1; --
|
||||
constant opcMOVESR : integer := 2; --
|
||||
constant opcADD : integer := 3; --
|
||||
constant opcADDQ : integer := 4; --
|
||||
constant opcOR : integer := 5; --
|
||||
constant opcAND : integer := 6; --
|
||||
constant opcEOR : integer := 7; --
|
||||
constant opcCMP : integer := 8; --
|
||||
constant opcROT : integer := 9; --
|
||||
constant opcCPMAW : integer := 10;
|
||||
constant opcEXT : integer := 11; --
|
||||
constant opcABCD : integer := 12; --
|
||||
constant opcSBCD : integer := 13; --
|
||||
constant opcBITS : integer := 14; --
|
||||
constant opcSWAP : integer := 15; --
|
||||
constant opcScc : integer := 16; --
|
||||
constant andiSR : integer := 17; --
|
||||
constant eoriSR : integer := 18; --
|
||||
constant oriSR : integer := 19; --
|
||||
constant opcMULU : integer := 20; --
|
||||
constant opcDIVU : integer := 21; --
|
||||
constant dispouter : integer := 22; --
|
||||
constant rot_nop : integer := 23; --
|
||||
constant ld_rot_cnt : integer := 24; --
|
||||
constant writePC_add : integer := 25; --
|
||||
constant ea_data_OP1 : integer := 26; --
|
||||
constant ea_data_OP2 : integer := 27; --
|
||||
constant use_XZFlag : integer := 28; --
|
||||
constant get_bfoffset : integer := 29; --
|
||||
constant save_memaddr : integer := 30; --
|
||||
constant opcCHK : integer := 31; --
|
||||
constant movec_rd : integer := 32; --
|
||||
constant movec_wr : integer := 33; --
|
||||
constant Regwrena : integer := 34; --
|
||||
constant update_FC : integer := 35; --
|
||||
constant linksp : integer := 36; --
|
||||
constant movepl : integer := 37; --
|
||||
constant update_ld : integer := 38; --
|
||||
constant OP1addr : integer := 39; --
|
||||
constant write_reg : integer := 40; --
|
||||
constant changeMode : integer := 41; --
|
||||
constant ea_build : integer := 42; --
|
||||
constant trap_chk : integer := 43; --
|
||||
constant store_ea_data : integer := 44; --
|
||||
constant addrlong : integer := 45; --
|
||||
constant postadd : integer := 46; --
|
||||
constant presub : integer := 47; --
|
||||
constant subidx : integer := 48; --
|
||||
constant no_Flags : integer := 49; --
|
||||
constant use_SP : integer := 50; --
|
||||
constant to_CCR : integer := 51; --
|
||||
constant to_SR : integer := 52; --
|
||||
constant OP2out_one : integer := 53; --
|
||||
constant OP1out_zero : integer := 54; --
|
||||
constant mem_addsub : integer := 55; --
|
||||
constant addsub : integer := 56; --
|
||||
constant directPC : integer := 57; --
|
||||
constant direct_delta : integer := 58; --
|
||||
constant directSR : integer := 59; --
|
||||
constant directCCR : integer := 60; --
|
||||
constant exg : integer := 61; --
|
||||
constant get_ea_now : integer := 62; --
|
||||
constant ea_to_pc : integer := 63; --
|
||||
constant hold_dwr : integer := 64; --
|
||||
constant to_USP : integer := 65; --
|
||||
constant from_USP : integer := 66; --
|
||||
constant write_lowlong : integer := 67; --
|
||||
constant write_reminder : integer := 68; --
|
||||
constant movem_action : integer := 69; --
|
||||
constant briefext : integer := 70; --
|
||||
constant get_2ndOPC : integer := 71; --
|
||||
constant mem_byte : integer := 72; --
|
||||
constant longaktion : integer := 73; --
|
||||
constant opcRESET : integer := 74; --
|
||||
constant opcBF : integer := 75; --
|
||||
constant opcBFwb : integer := 76; --
|
||||
constant s2nd_hbits : integer := 77; --
|
||||
-- constant : integer := 75; --
|
||||
-- constant : integer := 76; --
|
||||
-- constant : integer := 7; --
|
||||
-- constant : integer := 7; --
|
||||
-- constant : integer := 7; --
|
||||
|
||||
constant lastOpcBit : integer := 77;
|
||||
|
||||
component TG68K_ALU
|
||||
generic(
|
||||
MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
||||
DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
Reset : in std_logic;
|
||||
clkena_lw : in std_logic:='1';
|
||||
execOPC : in bit;
|
||||
exe_condition : in std_logic;
|
||||
exec_tas : in std_logic;
|
||||
long_start : in bit;
|
||||
movem_presub : in bit;
|
||||
set_stop : in bit;
|
||||
Z_error : in bit;
|
||||
rot_bits : in std_logic_vector(1 downto 0);
|
||||
exec : in bit_vector(lastOpcBit downto 0);
|
||||
OP1out : in std_logic_vector(31 downto 0);
|
||||
OP2out : in std_logic_vector(31 downto 0);
|
||||
reg_QA : in std_logic_vector(31 downto 0);
|
||||
reg_QB : in std_logic_vector(31 downto 0);
|
||||
opcode : in std_logic_vector(15 downto 0);
|
||||
datatype : in std_logic_vector(1 downto 0);
|
||||
exe_opcode : in std_logic_vector(15 downto 0);
|
||||
exe_datatype : in std_logic_vector(1 downto 0);
|
||||
sndOPC : in std_logic_vector(15 downto 0);
|
||||
last_data_read : in std_logic_vector(15 downto 0);
|
||||
data_read : in std_logic_vector(15 downto 0);
|
||||
FlagsSR : in std_logic_vector(7 downto 0);
|
||||
micro_state : in micro_states;
|
||||
bf_ext_in : in std_logic_vector(7 downto 0);
|
||||
bf_ext_out : out std_logic_vector(7 downto 0);
|
||||
bf_shift : in std_logic_vector(5 downto 0);
|
||||
bf_width : in std_logic_vector(5 downto 0);
|
||||
bf_loffset : in std_logic_vector(4 downto 0);
|
||||
|
||||
set_V_Flag : buffer bit;
|
||||
Flags : buffer std_logic_vector(7 downto 0);
|
||||
c_out : buffer std_logic_vector(2 downto 0);
|
||||
addsub_q : buffer std_logic_vector(31 downto 0);
|
||||
ALUout : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
3231
cores/ql/TG68KdotC_Kernel.vhd
Normal file
3231
cores/ql/TG68KdotC_Kernel.vhd
Normal file
File diff suppressed because it is too large
Load Diff
120
cores/ql/data_io.v
Normal file
120
cores/ql/data_io.v
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// data_io.v
|
||||
//
|
||||
// io controller writable ram for the MiST board
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module data_io (
|
||||
// io controller spi interface
|
||||
input sck,
|
||||
input ss,
|
||||
input sdi,
|
||||
|
||||
output downloading, // signal indicating an active download
|
||||
output reg [4:0] index, // menu index used to upload the file
|
||||
|
||||
// external ram interface
|
||||
input clk,
|
||||
output reg wr,
|
||||
output reg [24:0] addr,
|
||||
output reg [15:0] data
|
||||
);
|
||||
|
||||
// *********************************************************************************
|
||||
// spi client
|
||||
// *********************************************************************************
|
||||
|
||||
// this core supports only the display related OSD commands
|
||||
// of the minimig
|
||||
reg [14:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [4:0] cnt;
|
||||
reg rclk;
|
||||
|
||||
reg [24:0] laddr;
|
||||
reg [15:0] ldata;
|
||||
|
||||
localparam UIO_FILE_TX = 8'h53;
|
||||
localparam UIO_FILE_TX_DAT = 8'h54;
|
||||
localparam UIO_FILE_INDEX = 8'h55;
|
||||
|
||||
assign downloading = downloading_reg;
|
||||
reg downloading_reg = 1'b0;
|
||||
|
||||
// data_io has its own SPI interface to the io controller
|
||||
always@(posedge sck, posedge ss) begin
|
||||
if(ss == 1'b1)
|
||||
cnt <= 5'd0;
|
||||
else begin
|
||||
rclk <= 1'b0;
|
||||
|
||||
// don't shift in last bit. It is evaluated directly
|
||||
// when writing to ram
|
||||
if(cnt != 23)
|
||||
sbuf <= { sbuf[13:0], sdi};
|
||||
|
||||
// count 0-7 8-15 16-23 8-15 16-23 ...
|
||||
if(cnt < 23) cnt <= cnt + 4'd1;
|
||||
else cnt <= 4'd8;
|
||||
|
||||
// finished command byte
|
||||
if(cnt == 7)
|
||||
cmd <= {sbuf[6:0], sdi};
|
||||
|
||||
// prepare/end transmission
|
||||
if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
|
||||
// prepare
|
||||
if(sdi) begin
|
||||
// download rom to address 0, microdrive image to 16MB+
|
||||
if(index == 0) laddr <= 25'h0 - 25'd1;
|
||||
else laddr <= 25'h800000 - 25'd1;
|
||||
|
||||
downloading_reg <= 1'b1;
|
||||
end else
|
||||
downloading_reg <= 1'b0;
|
||||
end
|
||||
|
||||
// command 0x54: UIO_FILE_TX
|
||||
if((cmd == UIO_FILE_TX_DAT) && (cnt == 23)) begin
|
||||
ldata <= {sbuf, sdi};
|
||||
laddr <= laddr + 1;
|
||||
rclk <= 1'b1;
|
||||
end
|
||||
|
||||
// expose file (menu) index
|
||||
if((cmd == UIO_FILE_INDEX) && (cnt == 15))
|
||||
index <= {sbuf[3:0], sdi};
|
||||
end
|
||||
end
|
||||
|
||||
reg rclkD, rclkD2;
|
||||
always@(posedge clk) begin
|
||||
// bring all signals from spi clock domain into local clock domain
|
||||
rclkD <= rclk;
|
||||
rclkD2 <= rclkD;
|
||||
wr <= 1'b0;
|
||||
|
||||
if(rclkD && !rclkD2) begin
|
||||
addr <= laddr;
|
||||
data <= ldata;
|
||||
wr <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
131
cores/ql/ipc.v
Normal file
131
cores/ql/ipc.v
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// ipc.v
|
||||
//
|
||||
// Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module ipc (
|
||||
input reset,
|
||||
input clk_bus,
|
||||
|
||||
input ipc_bit_strobe,
|
||||
input ipc_bit,
|
||||
output reg ipc_reply_bit,
|
||||
output ipc_busy,
|
||||
|
||||
input ps2_kbd_clk,
|
||||
input ps2_kbd_data
|
||||
);
|
||||
|
||||
assign ipc_busy = 1'b0;
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- KBD --------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
reg key_strobe;
|
||||
wire [8:0] key;
|
||||
wire key_available, key_pressed;
|
||||
|
||||
keyboard keyboard (
|
||||
.reset ( reset ),
|
||||
.clk ( clk_bus ),
|
||||
|
||||
.ps2_clk ( ps2_kbd_clk ),
|
||||
.ps2_data ( ps2_kbd_data ),
|
||||
|
||||
.keycode_available ( key_available ),
|
||||
.keycode ( key ),
|
||||
.strobe ( key_strobe ),
|
||||
.pressed ( key_pressed )
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// ----------------------------------- simple IPC ----------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
reg [15:0] ipc_reply;
|
||||
reg [3:0] ipc_unexpected /* synthesis noprune */;
|
||||
reg [7:0] ipc_reply_len;
|
||||
reg [3:0] ipc_cmd;
|
||||
reg [31:0] ipc_len /* synthesis noprune */;
|
||||
|
||||
always @(posedge ipc_bit_strobe or posedge reset) begin
|
||||
if(reset) begin
|
||||
ipc_len <= 32'd0;
|
||||
ipc_reply_len <= 8'h00;
|
||||
ipc_reply <= 8'h00;
|
||||
ipc_reply_bit <= 1'b0;
|
||||
ipc_unexpected <= 4'h0;
|
||||
key_strobe <= 1'b0;
|
||||
end else begin
|
||||
key_strobe <= 1'b0;
|
||||
|
||||
if(ipc_reply_len == 0) begin
|
||||
ipc_cmd <= { ipc_cmd[2:0], ipc_bit};
|
||||
ipc_len <= ipc_len + 32'd1;
|
||||
|
||||
// last bit of a 4 bit command being written?
|
||||
if(ipc_len[1:0] == 2'b11) begin
|
||||
case({ ipc_cmd[2:0], ipc_bit })
|
||||
// request status
|
||||
1: begin
|
||||
// send 8 bit ipc status reply, bit 0 -> 1=kbd data available
|
||||
ipc_reply_len <= 8'd8;
|
||||
ipc_reply_bit <= 1'b0;
|
||||
ipc_reply <= { 7'b0000000, key_available, 8'h00 };
|
||||
end
|
||||
|
||||
// keyboard
|
||||
// nibble: PNNN N = chars in buffer, P = last key still pressed
|
||||
// N*(
|
||||
// nibble: ctrl/alt/shift
|
||||
// byte: keycode
|
||||
// )
|
||||
8: begin
|
||||
if(key_available) begin
|
||||
// currently we can only report one key at once ...
|
||||
ipc_reply_len <= 8'd16;
|
||||
ipc_reply_bit <= 1'b0;
|
||||
ipc_reply <= { 1'b0, 3'd1, 1'b0, key[8:6], 2'b00, key[5:0]};
|
||||
key_strobe <= 1'b1;
|
||||
end else begin
|
||||
// no key to report
|
||||
ipc_reply_len <= 8'd4;
|
||||
ipc_reply_bit <= 1'b0;
|
||||
ipc_reply <= { 1'b0, 3'd0, 12'h000};
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
if(ipc_unexpected == 0)
|
||||
ipc_unexpected <= { ipc_cmd[2:0], ipc_bit };
|
||||
end
|
||||
endcase;
|
||||
end
|
||||
end else begin
|
||||
// sending reply: shift it out through the ipc_reply_bit register
|
||||
ipc_reply_len <= ipc_reply_len - 8'd1;
|
||||
ipc_reply_bit <= ipc_reply[15];
|
||||
ipc_reply <= { ipc_reply[14:0], 1'b0 };
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
231
cores/ql/keyboard.v
Normal file
231
cores/ql/keyboard.v
Normal file
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// keyboard.v
|
||||
//
|
||||
// Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module keyboard (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
// ps2 interface
|
||||
input ps2_clk,
|
||||
input ps2_data,
|
||||
|
||||
output keycode_available,
|
||||
output [8:0] keycode,
|
||||
input strobe,
|
||||
output reg pressed
|
||||
);
|
||||
|
||||
// F1 ESC 1 2 3 4 5 6 7 8 9 0 - = £ \
|
||||
// F2 TAB Q W E R T Y U I O P [ ]
|
||||
// F3 CAPS A S D F G H J K L ; ' ENTER
|
||||
// F4 SHIFT Z X C V B N M , . / SHIFT
|
||||
// F5 CTRL LEFT RIGHT SPACE UP DOWN ALT
|
||||
|
||||
// buffer to hold up to 8 keys
|
||||
reg [2:0] modifier;
|
||||
reg [2:0] key_rptr, key_wptr;
|
||||
reg [8:0] key_fifo [7:0];
|
||||
|
||||
// read from fifo
|
||||
assign keycode_available = key_rptr != key_wptr;
|
||||
assign keycode = key_fifo[key_rptr];
|
||||
always @(posedge strobe or posedge reset) begin
|
||||
if(reset) key_rptr <= 3'd0;
|
||||
else key_rptr <= key_rptr + 3'd1;
|
||||
end
|
||||
|
||||
// the top most bit is set when the new value is written and cleared
|
||||
// shortly after when the value itself is stable
|
||||
always @(negedge ql_key[9] or posedge reset) begin
|
||||
if(reset)
|
||||
key_wptr <= 3'd0;
|
||||
else begin
|
||||
if(ql_key[8:6] == 3'b000)
|
||||
key_fifo[key_wptr] <= { modifier, ql_key[5:0] };
|
||||
else
|
||||
key_fifo[key_wptr] <= ql_key[8:0];
|
||||
|
||||
key_wptr <= key_wptr + 3'd1;
|
||||
end
|
||||
end
|
||||
|
||||
wire released = reset || key_released;
|
||||
always @(negedge ql_key[9] or posedge released) begin
|
||||
if(released) pressed <= 1'b0;
|
||||
else pressed <= 1'b1;
|
||||
end
|
||||
|
||||
wire [7:0] byte;
|
||||
wire valid;
|
||||
wire error;
|
||||
|
||||
reg key_released;
|
||||
reg key_extended;
|
||||
|
||||
reg [9:0] ql_key;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
ql_key <= 10'b0;
|
||||
key_released <= 1'b0;
|
||||
key_extended <= 1'b0;
|
||||
modifier <= 3'b000;
|
||||
end else begin
|
||||
ql_key[9] <= 1'b0;
|
||||
|
||||
// ps2 decoder has received a valid byte
|
||||
if(valid) begin
|
||||
if(byte == 8'he0)
|
||||
// extended key code
|
||||
key_extended <= 1'b1;
|
||||
else if(byte == 8'hf0)
|
||||
// release code
|
||||
key_released <= 1'b1;
|
||||
else begin
|
||||
key_extended <= 1'b0;
|
||||
key_released <= 1'b0;
|
||||
|
||||
// SHIFT
|
||||
if((byte == 8'h12) || (byte == 8'h59))
|
||||
modifier[2] <= !key_released;
|
||||
|
||||
// CTRL
|
||||
if(byte == 8'h14)
|
||||
modifier[1] <= !key_released;
|
||||
|
||||
// ALT
|
||||
if(byte == 8'h11)
|
||||
modifier[0] <= !key_released;
|
||||
|
||||
// only key down events are enqueued
|
||||
if(!key_released) begin
|
||||
case(byte)
|
||||
// function keys
|
||||
8'h05: ql_key <= {1'b1, 3'b000, 6'd57}; // F1
|
||||
8'h06: ql_key <= {1'b1, 3'b000, 6'd59}; // F2
|
||||
8'h04: ql_key <= {1'b1, 3'b000, 6'd60}; // F3
|
||||
8'h0c: ql_key <= {1'b1, 3'b000, 6'd56}; // F4
|
||||
8'h03: ql_key <= {1'b1, 3'b000, 6'd61}; // F5
|
||||
|
||||
// cursor keys
|
||||
8'h75: ql_key <= {1'b1, 3'b000, 6'd50}; // Up
|
||||
8'h72: ql_key <= {1'b1, 3'b000, 6'd55}; // Down
|
||||
8'h6b: ql_key <= {1'b1, 3'b000, 6'd49}; // Left
|
||||
8'h74: ql_key <= {1'b1, 3'b000, 6'd52}; // Right
|
||||
|
||||
8'h1c: ql_key <= {1'b1, 3'b000, 6'd28}; // a
|
||||
8'h32: ql_key <= {1'b1, 3'b000, 6'd44}; // b
|
||||
8'h21: ql_key <= {1'b1, 3'b000, 6'd43}; // c
|
||||
8'h23: ql_key <= {1'b1, 3'b000, 6'd30}; // d
|
||||
8'h24: ql_key <= {1'b1, 3'b000, 6'd12}; // e
|
||||
8'h2b: ql_key <= {1'b1, 3'b000, 6'd36}; // f
|
||||
8'h34: ql_key <= {1'b1, 3'b000, 6'd38}; // g
|
||||
8'h33: ql_key <= {1'b1, 3'b000, 6'd26}; // h
|
||||
8'h43: ql_key <= {1'b1, 3'b000, 6'd18}; // i
|
||||
8'h3b: ql_key <= {1'b1, 3'b000, 6'd31}; // j
|
||||
8'h42: ql_key <= {1'b1, 3'b000, 6'd34}; // k
|
||||
8'h4b: ql_key <= {1'b1, 3'b000, 6'd24}; // l
|
||||
8'h3a: ql_key <= {1'b1, 3'b000, 6'd46}; // m
|
||||
8'h31: ql_key <= {1'b1, 3'b000, 6'd06}; // n
|
||||
8'h44: ql_key <= {1'b1, 3'b000, 6'd23}; // o
|
||||
8'h4d: ql_key <= {1'b1, 3'b000, 6'd29}; // p
|
||||
8'h15: ql_key <= {1'b1, 3'b000, 6'd11}; // q
|
||||
8'h2d: ql_key <= {1'b1, 3'b000, 6'd20}; // r
|
||||
8'h1b: ql_key <= {1'b1, 3'b000, 6'd35}; // s
|
||||
8'h2c: ql_key <= {1'b1, 3'b000, 6'd14}; // t
|
||||
8'h3c: ql_key <= {1'b1, 3'b000, 6'd15}; // u
|
||||
8'h2a: ql_key <= {1'b1, 3'b000, 6'd04}; // v
|
||||
8'h1d: ql_key <= {1'b1, 3'b000, 6'd17}; // w
|
||||
8'h22: ql_key <= {1'b1, 3'b000, 6'd03}; // x
|
||||
8'h35: ql_key <= {1'b1, 3'b000, 6'd22}; // y
|
||||
8'h1a: ql_key <= {1'b1, 3'b000, 6'd41}; // z
|
||||
|
||||
8'h45: ql_key <= {1'b1, 3'b000, 6'd13}; // 0
|
||||
8'h16: ql_key <= {1'b1, 3'b000, 6'd27}; // 1
|
||||
8'h1e: ql_key <= {1'b1, 3'b000, 6'd09}; // 2
|
||||
8'h26: ql_key <= {1'b1, 3'b000, 6'd25}; // 3
|
||||
8'h25: ql_key <= {1'b1, 3'b000, 6'd62}; // 4
|
||||
8'h2e: ql_key <= {1'b1, 3'b000, 6'd58}; // 5
|
||||
8'h36: ql_key <= {1'b1, 3'b000, 6'd10}; // 6
|
||||
8'h3d: ql_key <= {1'b1, 3'b000, 6'd63}; // 7
|
||||
8'h3e: ql_key <= {1'b1, 3'b000, 6'd08}; // 8
|
||||
8'h46: ql_key <= {1'b1, 3'b000, 6'd16}; // 9
|
||||
|
||||
8'h5a: ql_key <= {1'b1, 3'b000, 6'd48}; // RET
|
||||
8'h29: ql_key <= {1'b1, 3'b000, 6'd54}; // SPACE
|
||||
8'h0d: ql_key <= {1'b1, 3'b000, 6'd19}; // TAB
|
||||
8'h76: ql_key <= {1'b1, 3'b000, 6'd51}; // ESC
|
||||
8'h58: ql_key <= {1'b1, 3'b000, 6'd33}; // CAPS
|
||||
|
||||
8'h4e: ql_key <= {1'b1, 3'b000, 6'd21}; // -
|
||||
8'h55: ql_key <= {1'b1, 3'b000, 6'd37}; // =
|
||||
8'h61: ql_key <= {1'b1, 3'b000, 6'd45}; // Pound
|
||||
8'h5d: ql_key <= {1'b1, 3'b000, 6'd53}; // \
|
||||
|
||||
8'h54: ql_key <= {1'b1, 3'b000, 6'd32}; // [
|
||||
8'h5b: ql_key <= {1'b1, 3'b000, 6'd40}; // ]
|
||||
|
||||
8'h4c: ql_key <= {1'b1, 3'b000, 6'd39}; // ;
|
||||
8'h52: ql_key <= {1'b1, 3'b000, 6'd47}; // '
|
||||
|
||||
8'h41: ql_key <= {1'b1, 3'b000, 6'd07}; // ,
|
||||
8'h49: ql_key <= {1'b1, 3'b000, 6'd42}; // .
|
||||
8'h4a: ql_key <= {1'b1, 3'b000, 6'd05}; // /
|
||||
|
||||
// special keys that include modifier
|
||||
8'h66: ql_key <= {1'b1, 3'b010, 6'd49}; // Backspace -> CTRL+LEFT
|
||||
8'h71: ql_key <= {1'b1, 3'b010, 6'd52}; // Delete -> CTRL+RIGHT
|
||||
8'h7d: ql_key <= {1'b1, 3'b100, 6'd50}; // PageUp -> SHIFT+UP
|
||||
8'h7a: ql_key <= {1'b1, 3'b100, 6'd55}; // PageDown -> SHIFT+DOWN
|
||||
8'h6c: ql_key <= {1'b1, 3'b001, 6'd49}; // Home -> ALT+LEFT
|
||||
8'h69: ql_key <= {1'b1, 3'b001, 6'd52}; // End -> ALT+RIGHT
|
||||
8'h0b: ql_key <= {1'b1, 3'b100, 6'd57}; // F6 -> SHIFT+F1
|
||||
8'h83: ql_key <= {1'b1, 3'b100, 6'd59}; // F7 -> SHIFT+F2
|
||||
8'h0a: ql_key <= {1'b1, 3'b100, 6'd60}; // F8 -> SHIFT+F3
|
||||
8'h01: ql_key <= {1'b1, 3'b100, 6'd56}; // F9 -> SHIFT+F4
|
||||
8'h09: ql_key <= {1'b1, 3'b100, 6'd61}; // F10 -> SHIFT+F5
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// the ps2 decoder has been taken from the zx spectrum core
|
||||
ps2_intf ps2_keyboard (
|
||||
.CLK ( clk ),
|
||||
.nRESET ( !reset ),
|
||||
|
||||
// PS/2 interface
|
||||
.PS2_CLK ( ps2_clk ),
|
||||
.PS2_DATA ( ps2_data ),
|
||||
|
||||
// Byte-wide data interface - only valid for one clock
|
||||
// so must be latched externally if required
|
||||
.DATA ( byte ),
|
||||
.VALID ( valid ),
|
||||
.ERROR ( error )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
195
cores/ql/mdv.v
Normal file
195
cores/ql/mdv.v
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// mdv.v - Microdrive
|
||||
//
|
||||
// Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module mdv (
|
||||
input clk, // 21mhz clock
|
||||
input reset,
|
||||
|
||||
input sel,
|
||||
|
||||
// control bits
|
||||
output gap,
|
||||
output tx_empty,
|
||||
output rx_ready,
|
||||
output [7:0] dout,
|
||||
|
||||
// ram interface to read image
|
||||
input download,
|
||||
input [24:0] dl_addr,
|
||||
|
||||
input mem_ena,
|
||||
input mem_cycle,
|
||||
input mem_clk,
|
||||
output reg mem_read,
|
||||
output reg [24:0] mem_addr,
|
||||
input [15:0] mem_din
|
||||
);
|
||||
|
||||
localparam BASE_ADDR = 25'h800000;
|
||||
|
||||
// a gap is permanently present if no mdv is inserted or if
|
||||
// there's a gap on the inserted one. This is the signal that triggers
|
||||
// the irq and can be seen by the cpu
|
||||
assign gap = (!mdv_present) || mdv_gap /* synthesis keep */;
|
||||
|
||||
// the mdv_rx_ready flag must be quite short as the CPU never waist for it to end
|
||||
wire mdv_valid = (mdv_bit_cnt[2:0] == 2);
|
||||
assign rx_ready = mdv_present && mdv_data_valid && mdv_valid /* synthesis keep */;
|
||||
assign tx_empty = 1'b0;
|
||||
|
||||
// microdrive implementation works with images which are uploaded by the user into
|
||||
// the part of ram which is unavailable to the 68k CPU (>16MB). It is then continously
|
||||
// replayed from there at 200kbit/s
|
||||
|
||||
reg [7:0] mdv_sector /* synthesis noprune */;
|
||||
|
||||
reg [24:0] mdv_end /* synthesis noprune */;
|
||||
|
||||
// determine mdv image size after download
|
||||
always @(negedge download or posedge reset) begin
|
||||
if(reset) mdv_end <= BASE_ADDR;
|
||||
else mdv_end <= dl_addr;
|
||||
end
|
||||
|
||||
// the microdrive at 200kbit/s reads a bit every 8.3us and needs a new word
|
||||
// every 80us. video hsync comes every 64us. A new word can thus be read in
|
||||
// the hsync phase while video isn't accessing ram and the next word will not
|
||||
// be needed before the next hsync
|
||||
|
||||
// gaps are 2800/3400 us which is 35 words at 200kbit/s
|
||||
|
||||
assign dout = mdv_bit_cnt[3]?mdv_data[7:0]:mdv_data[15:8];
|
||||
|
||||
// data is valid at the end of the video cycle while mem_read is active
|
||||
reg [15:0] mdv_din /* synthesis noprune */;
|
||||
always @(negedge mem_cycle)
|
||||
if(mem_read) mdv_din <= mem_din;
|
||||
|
||||
// activate memory read for the next full video cycle after mdv_required
|
||||
always @(negedge mem_clk) begin
|
||||
// mdv memory enable signal from zx8301 to give mdv emulation ram access
|
||||
if(!mem_cycle)
|
||||
mem_read <= mdv_rd_wait && mem_ena;
|
||||
end
|
||||
|
||||
// wait for next hsync to service request
|
||||
reg mdv_rd_wait /* synthesis noprune */;
|
||||
wire mdv_rd_ack = mem_read;
|
||||
always @(posedge mdv_next_word or posedge mdv_rd_ack) begin
|
||||
if(mdv_rd_ack) mdv_rd_wait <= 1'b0;
|
||||
else mdv_rd_wait <= 1'b1;
|
||||
end
|
||||
|
||||
// a microdrive image is present if at least one word is in the buffer
|
||||
wire mdv_present = sel && (mdv_end != BASE_ADDR);
|
||||
reg mdv_next_word /* synthesis noprune */;
|
||||
reg [3:0] mdv_bit_cnt /* synthesis noprune */;
|
||||
|
||||
// also generate gap timing
|
||||
reg [9:0] mdv_gap_cnt /* synthesis noprune */;
|
||||
reg mdv_gap_state /* synthesis noprune */;
|
||||
reg mdv_gap_active /* synthesis noprune */;
|
||||
reg [15:0] mdv_data;
|
||||
reg mdv_data_valid;
|
||||
reg mdv_gap;
|
||||
|
||||
always @(posedge mdv_clk) begin
|
||||
mdv_next_word <= 1'b0;
|
||||
|
||||
mdv_bit_cnt <= mdv_bit_cnt + 4'd1;
|
||||
if(mdv_bit_cnt == 15) begin
|
||||
mdv_data <= mdv_din;
|
||||
mdv_data_valid <= !mdv_gap_active &&
|
||||
// don't generate data_valid for first 12 bytes (preamble)
|
||||
(mdv_gap_cnt > 5) &&
|
||||
// and also not for the sector internal preamble
|
||||
!(mdv_gap_state && (mdv_gap_cnt > 7) && (mdv_gap_cnt < 12));
|
||||
|
||||
mdv_next_word <= 1'b1;
|
||||
|
||||
// reset counters when address is out of range
|
||||
if((mem_addr > mdv_end)||(mem_addr < 25'h800000)) begin
|
||||
mem_addr <= BASE_ADDR;
|
||||
|
||||
// assume we start at the end of a post-sector/pre-header gap
|
||||
mdv_gap_cnt <= 10'd0; // count bytes until gap
|
||||
mdv_gap_state <= 1'b1; // toggle header + data gap
|
||||
mdv_gap_active <= 1'b1; // gap atm
|
||||
mdv_sector <= 8'd0;
|
||||
mdv_gap <= 1'b1;
|
||||
end else begin
|
||||
mdv_gap_cnt <= mdv_gap_cnt + 10'd1;
|
||||
|
||||
if(mdv_gap_active) begin
|
||||
|
||||
// stop sending gap after 35 words = 70 bytes = 2800us
|
||||
if(mdv_gap_cnt == 34) begin
|
||||
mdv_gap_cnt <= 10'd0; // restart counter until next gap
|
||||
mdv_gap_active <= 1'b0; // no gap anymore
|
||||
mdv_gap_state <= !mdv_gap_state; // toggle gap/data
|
||||
mdv_gap <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
mem_addr <= mem_addr + 25'd1;
|
||||
|
||||
if((!mdv_gap_state) && (mdv_gap_cnt == 13)) begin
|
||||
// done reading 14 words header data
|
||||
mdv_gap_cnt <= 10'd0; // restart counter for gap
|
||||
mdv_gap_active <= 1'b1; // now comes a gap
|
||||
mdv_gap <= 1'b1;
|
||||
end else if(mdv_gap_state && (mdv_gap_cnt == 328)) begin
|
||||
// done reading 330 words sector data
|
||||
mdv_gap_cnt <= 10'd0; // restart counter for gap
|
||||
mdv_gap_active <= 1'b1; // now comes a gap
|
||||
mdv_gap <= 1'b1;
|
||||
|
||||
// The sectors on cartridges are written in descending order
|
||||
// The images seem to contain them in ascending order. So we
|
||||
// have to replay them backwards for better performance
|
||||
|
||||
if(mem_addr == BASE_ADDR + 343 - 1)
|
||||
mem_addr <= mdv_end - 343 + 1;
|
||||
else
|
||||
mem_addr <= mem_addr - 2*343 + 1;
|
||||
|
||||
mdv_sector <= mdv_sector + 8'd1;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// microdrive clock runs at 200khz
|
||||
// -> new word required every 80us
|
||||
localparam mdv_clk_scaler = 21000000/(2*200000)-1;
|
||||
reg mdv_clk;
|
||||
reg [7:0] mdv_clk_cnt;
|
||||
always @(posedge clk) begin
|
||||
if(mdv_clk_cnt == mdv_clk_scaler) begin
|
||||
mdv_clk_cnt <= 8'd0;
|
||||
mdv_clk <= !mdv_clk;
|
||||
end else
|
||||
mdv_clk_cnt <= mdv_clk_cnt + 8'd1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
204
cores/ql/osd.v
Normal file
204
cores/ql/osd.v
Normal file
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// osd.v
|
||||
//
|
||||
// A simple OSD implementation. Can be hooked up between a cores
|
||||
// VGA output and the physical VGA pins
|
||||
//
|
||||
// Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module osd (
|
||||
// OSDs pixel clock, should be synchronous to cores pixel clock to
|
||||
// avoid jitter.
|
||||
input pclk,
|
||||
|
||||
// SPI interface
|
||||
input sck,
|
||||
input ss,
|
||||
input sdi,
|
||||
|
||||
// VGA signals coming from core
|
||||
input [5:0] red_in,
|
||||
input [5:0] green_in,
|
||||
input [5:0] blue_in,
|
||||
input hs_in,
|
||||
input vs_in,
|
||||
|
||||
// VGA signals going to video connector
|
||||
output [5:0] red_out,
|
||||
output [5:0] green_out,
|
||||
output [5:0] blue_out,
|
||||
output hs_out,
|
||||
output vs_out
|
||||
);
|
||||
|
||||
parameter OSD_X_OFFSET = 10'd0;
|
||||
parameter OSD_Y_OFFSET = 10'd0;
|
||||
parameter OSD_COLOR = 3'd0;
|
||||
|
||||
localparam OSD_WIDTH = 10'd256;
|
||||
localparam OSD_HEIGHT = 10'd128;
|
||||
|
||||
// *********************************************************************************
|
||||
// spi client
|
||||
// *********************************************************************************
|
||||
|
||||
// this core supports only the display related OSD commands
|
||||
// of the minimig
|
||||
reg [7:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [4:0] cnt;
|
||||
reg [10:0] bcnt;
|
||||
reg osd_enable;
|
||||
|
||||
reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself
|
||||
|
||||
// the OSD has its own SPI interface to the io controller
|
||||
always@(posedge sck, posedge ss) begin
|
||||
if(ss == 1'b1) begin
|
||||
cnt <= 5'd0;
|
||||
bcnt <= 11'd0;
|
||||
end else begin
|
||||
sbuf <= { sbuf[6:0], sdi};
|
||||
|
||||
// 0:7 is command, rest payload
|
||||
if(cnt < 15)
|
||||
cnt <= cnt + 4'd1;
|
||||
else
|
||||
cnt <= 4'd8;
|
||||
|
||||
if(cnt == 7) begin
|
||||
cmd <= {sbuf[6:0], sdi};
|
||||
|
||||
// lower three command bits are line address
|
||||
bcnt <= { sbuf[1:0], sdi, 8'h00};
|
||||
|
||||
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
|
||||
if(sbuf[6:3] == 4'b0100)
|
||||
osd_enable <= sdi;
|
||||
end
|
||||
|
||||
// command 0x20: OSDCMDWRITE
|
||||
if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
|
||||
osd_buffer[bcnt] <= {sbuf[6:0], sdi};
|
||||
bcnt <= bcnt + 11'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// *********************************************************************************
|
||||
// video timing and sync polarity anaylsis
|
||||
// *********************************************************************************
|
||||
|
||||
// horizontal counter
|
||||
reg [9:0] h_cnt;
|
||||
reg hsD, hsD2;
|
||||
reg [9:0] hs_low, hs_high;
|
||||
wire hs_pol = hs_high < hs_low;
|
||||
wire [9:0] h_dsp_width = hs_pol?hs_low:hs_high;
|
||||
wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] };
|
||||
|
||||
always @(posedge pclk) begin
|
||||
// bring hsync into local clock domain
|
||||
hsD <= hs_in;
|
||||
hsD2 <= hsD;
|
||||
|
||||
// falling edge of hs_in
|
||||
if(!hsD && hsD2) begin
|
||||
h_cnt <= 10'd0;
|
||||
hs_high <= h_cnt;
|
||||
end
|
||||
|
||||
// rising edge of hs_in
|
||||
else if(hsD && !hsD2) begin
|
||||
h_cnt <= 10'd0;
|
||||
hs_low <= h_cnt;
|
||||
end
|
||||
|
||||
else
|
||||
h_cnt <= h_cnt + 10'd1;
|
||||
end
|
||||
|
||||
// vertical counter
|
||||
reg [9:0] v_cnt;
|
||||
reg vsD, vsD2;
|
||||
reg [9:0] vs_low, vs_high;
|
||||
wire vs_pol = vs_high < vs_low;
|
||||
wire [9:0] v_dsp_width = vs_pol?vs_low:vs_high;
|
||||
wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_width[9:1] };
|
||||
|
||||
always @(posedge hs_in) begin
|
||||
// bring vsync into local clock domain
|
||||
vsD <= vs_in;
|
||||
vsD2 <= vsD;
|
||||
|
||||
// falling edge of vs_in
|
||||
if(!vsD && vsD2) begin
|
||||
v_cnt <= 10'd0;
|
||||
vs_high <= v_cnt;
|
||||
end
|
||||
|
||||
// rising edge of vs_in
|
||||
else if(vsD && !vsD2) begin
|
||||
v_cnt <= 10'd0;
|
||||
vs_low <= v_cnt;
|
||||
end
|
||||
|
||||
else
|
||||
v_cnt <= v_cnt + 10'd1;
|
||||
end
|
||||
|
||||
// area in which OSD is being displayed
|
||||
wire [9:0] h_osd_start = h_dsp_ctr + OSD_X_OFFSET - (OSD_WIDTH >> 1);
|
||||
wire [9:0] h_osd_end = h_dsp_ctr + OSD_X_OFFSET + (OSD_WIDTH >> 1) - 1;
|
||||
wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (OSD_HEIGHT >> 1);
|
||||
wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (OSD_HEIGHT >> 1) - 1;
|
||||
|
||||
reg h_osd_active, v_osd_active;
|
||||
always @(posedge pclk) begin
|
||||
if(hs_in != hs_pol) begin
|
||||
if(h_cnt == h_osd_start) h_osd_active <= 1'b1;
|
||||
if(h_cnt == h_osd_end) h_osd_active <= 1'b0;
|
||||
end
|
||||
if(vs_in != vs_pol) begin
|
||||
if(v_cnt == v_osd_start) v_osd_active <= 1'b1;
|
||||
if(v_cnt == v_osd_end) v_osd_active <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
wire osd_de = osd_enable && h_osd_active && v_osd_active;
|
||||
|
||||
wire [7:0] osd_hcnt = h_cnt - h_osd_start + 7'd1; // one pixel offset for osd_byte register
|
||||
wire [6:0] osd_vcnt = v_cnt - v_osd_start;
|
||||
|
||||
wire osd_pixel = osd_byte[osd_vcnt[3:1]];
|
||||
|
||||
reg [7:0] osd_byte;
|
||||
always @(posedge pclk)
|
||||
osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}];
|
||||
|
||||
wire [2:0] osd_color = OSD_COLOR;
|
||||
assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] };
|
||||
assign green_out = !osd_de?green_in:{osd_pixel, osd_pixel, osd_color[1], green_in[5:3]};
|
||||
assign blue_out = !osd_de?blue_in: {osd_pixel, osd_pixel, osd_color[0], blue_in[5:3] };
|
||||
|
||||
assign hs_out = hs_in;
|
||||
assign vs_out = vs_in;
|
||||
|
||||
endmodule
|
||||
4
cores/ql/pll.qip
Normal file
4
cores/ql/pll.qip
Normal file
@@ -0,0 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
|
||||
337
cores/ql/pll.v
Normal file
337
cores/ql/pll.v
Normal file
@@ -0,0 +1,337 @@
|
||||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.4 Build 182 03/12/2014 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2014 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll (
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
locked);
|
||||
|
||||
input inclk0;
|
||||
output c0;
|
||||
output c1;
|
||||
output locked;
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire2;
|
||||
wire [0:0] sub_wire6 = 1'h0;
|
||||
wire [0:0] sub_wire3 = sub_wire0[0:0];
|
||||
wire [1:1] sub_wire1 = sub_wire0[1:1];
|
||||
wire c1 = sub_wire1;
|
||||
wire locked = sub_wire2;
|
||||
wire c0 = sub_wire3;
|
||||
wire sub_wire4 = inclk0;
|
||||
wire [1:0] sub_wire5 = {sub_wire6, sub_wire4};
|
||||
|
||||
altpll altpll_component (
|
||||
.inclk (sub_wire5),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire2),
|
||||
.activeclock (),
|
||||
.areset (1'b0),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "AUTO",
|
||||
altpll_component.clk0_divide_by = 9,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 7,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 9,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 7,
|
||||
altpll_component.clk1_phase_shift = "-5000",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 37037,
|
||||
altpll_component.intended_device_family = "Cyclone III",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "9"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "21.000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "21.000000"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "7"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "7"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "21.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "21.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "-5000.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "7"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "7"
|
||||
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "-5000"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
||||
4
cores/ql/pll_rtc.qip
Normal file
4
cores/ql/pll_rtc.qip
Normal file
@@ -0,0 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_rtc.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_rtc.ppf"]
|
||||
301
cores/ql/pll_rtc.v
Normal file
301
cores/ql/pll_rtc.v
Normal file
@@ -0,0 +1,301 @@
|
||||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll_rtc.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.4 Build 182 03/12/2014 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2014 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll_rtc (
|
||||
inclk0,
|
||||
c0);
|
||||
|
||||
input inclk0;
|
||||
output c0;
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire [0:0] sub_wire4 = 1'h0;
|
||||
wire [0:0] sub_wire1 = sub_wire0[0:0];
|
||||
wire c0 = sub_wire1;
|
||||
wire sub_wire2 = inclk0;
|
||||
wire [1:0] sub_wire3 = {sub_wire4, sub_wire2};
|
||||
|
||||
altpll altpll_component (
|
||||
.inclk (sub_wire3),
|
||||
.clk (sub_wire0),
|
||||
.activeclock (),
|
||||
.areset (1'b0),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.locked (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "AUTO",
|
||||
altpll_component.clk0_divide_by = 328125,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 1024,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 47619,
|
||||
altpll_component.intended_device_family = "Cyclone III",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_rtc",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_UNUSED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_UNUSED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "0.065536"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "21.000"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "0.06553600"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_rtc.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "328125"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1024"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "47619"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_rtc_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
||||
158
cores/ql/ps2_intf.vhd
Executable file
158
cores/ql/ps2_intf.vhd
Executable file
@@ -0,0 +1,158 @@
|
||||
-- ZX Spectrum for Altera DE1
|
||||
--
|
||||
-- Copyright (c) 2009-2011 Mike Stirling
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- * Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- * Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- * Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written agreement from the author.
|
||||
--
|
||||
-- * License is granted for non-commercial use only. A fee may not be charged
|
||||
-- for redistributions as source code or in synthesized/hardware form without
|
||||
-- specific prior written agreement from the author.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
|
||||
-- PS/2 interface (input only)
|
||||
-- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
-- This is input-only for the time being
|
||||
entity ps2_intf is
|
||||
generic (filter_length : positive := 8);
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
nRESET : in std_logic;
|
||||
|
||||
-- PS/2 interface (could be bi-dir)
|
||||
PS2_CLK : in std_logic;
|
||||
PS2_DATA : in std_logic;
|
||||
|
||||
-- Byte-wide data interface - only valid for one clock
|
||||
-- so must be latched externally if required
|
||||
DATA : out std_logic_vector(7 downto 0);
|
||||
VALID : out std_logic;
|
||||
ERROR : out std_logic
|
||||
);
|
||||
end ps2_intf;
|
||||
|
||||
architecture ps2_intf_arch of ps2_intf is
|
||||
subtype filter_t is std_logic_vector(filter_length-1 downto 0);
|
||||
signal clk_filter : filter_t;
|
||||
|
||||
signal ps2_clk_in : std_logic;
|
||||
signal ps2_dat_in : std_logic;
|
||||
-- Goes high when a clock falling edge is detected
|
||||
signal clk_edge : std_logic;
|
||||
signal bit_count : unsigned (3 downto 0);
|
||||
signal shiftreg : std_logic_vector(8 downto 0);
|
||||
signal parity : std_logic;
|
||||
begin
|
||||
-- Register input signals
|
||||
process(nRESET,CLK)
|
||||
begin
|
||||
if nRESET = '0' then
|
||||
ps2_clk_in <= '1';
|
||||
ps2_dat_in <= '1';
|
||||
clk_filter <= (others => '1');
|
||||
clk_edge <= '0';
|
||||
elsif rising_edge(CLK) then
|
||||
-- Register inputs (and filter clock)
|
||||
ps2_dat_in <= PS2_DATA;
|
||||
clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1);
|
||||
clk_edge <= '0';
|
||||
|
||||
if clk_filter = filter_t'(others => '1') then
|
||||
-- Filtered clock is high
|
||||
ps2_clk_in <= '1';
|
||||
elsif clk_filter = filter_t'(others => '0') then
|
||||
-- Filter clock is low, check for edge
|
||||
if ps2_clk_in = '1' then
|
||||
clk_edge <= '1';
|
||||
end if;
|
||||
ps2_clk_in <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Shift in keyboard data
|
||||
process(nRESET,CLK)
|
||||
begin
|
||||
if nRESET = '0' then
|
||||
bit_count <= (others => '0');
|
||||
shiftreg <= (others => '0');
|
||||
parity <= '0';
|
||||
DATA <= (others => '0');
|
||||
VALID <= '0';
|
||||
ERROR <= '0';
|
||||
elsif rising_edge(CLK) then
|
||||
-- Clear flags
|
||||
VALID <= '0';
|
||||
ERROR <= '0';
|
||||
|
||||
if clk_edge = '1' then
|
||||
-- We have a new bit from the keyboard for processing
|
||||
if bit_count = 0 then
|
||||
-- Idle state, check for start bit (0) only and don't
|
||||
-- start counting bits until we get it
|
||||
|
||||
parity <= '0';
|
||||
|
||||
if ps2_dat_in = '0' then
|
||||
-- This is a start bit
|
||||
bit_count <= bit_count + 1;
|
||||
end if;
|
||||
else
|
||||
-- Running. 8-bit data comes in LSb first followed by
|
||||
-- a single stop bit (1)
|
||||
if bit_count < 10 then
|
||||
-- Shift in data and parity (9 bits)
|
||||
bit_count <= bit_count + 1;
|
||||
shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
|
||||
parity <= parity xor ps2_dat_in; -- Calculate parity
|
||||
elsif ps2_dat_in = '1' then
|
||||
-- Valid stop bit received
|
||||
bit_count <= (others => '0'); -- back to idle
|
||||
if parity = '1' then
|
||||
-- Parity correct, submit data to host
|
||||
DATA <= shiftreg(7 downto 0);
|
||||
VALID <= '1';
|
||||
else
|
||||
-- Error
|
||||
ERROR <= '1';
|
||||
end if;
|
||||
else
|
||||
-- Invalid stop bit
|
||||
bit_count <= (others => '0'); -- back to idle
|
||||
ERROR <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end ps2_intf_arch;
|
||||
30
cores/ql/ql.qpf
Normal file
30
cores/ql/ql.qpf
Normal file
@@ -0,0 +1,30 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2010 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II
|
||||
# Version 10.1 Build 153 11/29/2010 SJ Full Version
|
||||
# Date created = 11:11:11 June 13, 2011
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "10.1"
|
||||
DATE = "11:11:11 June 13, 2011"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "ql"
|
||||
395
cores/ql/ql.qsf
Normal file
395
cores/ql/ql.qsf
Normal file
@@ -0,0 +1,395 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2011 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II
|
||||
# Version 11.0 Build 157 04/27/2011 SJ Full Version
|
||||
# Date created = 17:14:01 April 10, 2012
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# led_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY "Cyclone III"
|
||||
set_global_assignment -name DEVICE EP3C25E144C8
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY ql
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 11.0
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:14:01 APRIL 10, 2012"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"
|
||||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED"
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
|
||||
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
|
||||
|
||||
set_location_assignment PIN_7 -to LED
|
||||
set_location_assignment PIN_22 -to CLOCK_50[0]
|
||||
set_location_assignment PIN_23 -to CLOCK_50[1]
|
||||
set_location_assignment PIN_128 -to CLOCK_32[0]
|
||||
set_location_assignment PIN_129 -to CLOCK_32[1]
|
||||
set_location_assignment PIN_54 -to CLOCK_27[0]
|
||||
set_location_assignment PIN_55 -to CLOCK_27[1]
|
||||
set_location_assignment PIN_144 -to VGA_R[5]
|
||||
set_location_assignment PIN_143 -to VGA_R[4]
|
||||
set_location_assignment PIN_142 -to VGA_R[3]
|
||||
set_location_assignment PIN_141 -to VGA_R[2]
|
||||
set_location_assignment PIN_137 -to VGA_R[1]
|
||||
set_location_assignment PIN_135 -to VGA_R[0]
|
||||
set_location_assignment PIN_133 -to VGA_B[5]
|
||||
set_location_assignment PIN_132 -to VGA_B[4]
|
||||
set_location_assignment PIN_125 -to VGA_B[3]
|
||||
set_location_assignment PIN_121 -to VGA_B[2]
|
||||
set_location_assignment PIN_120 -to VGA_B[1]
|
||||
set_location_assignment PIN_115 -to VGA_B[0]
|
||||
set_location_assignment PIN_114 -to VGA_G[5]
|
||||
set_location_assignment PIN_113 -to VGA_G[4]
|
||||
set_location_assignment PIN_112 -to VGA_G[3]
|
||||
set_location_assignment PIN_111 -to VGA_G[2]
|
||||
set_location_assignment PIN_110 -to VGA_G[1]
|
||||
set_location_assignment PIN_106 -to VGA_G[0]
|
||||
set_location_assignment PIN_136 -to VGA_VS
|
||||
set_location_assignment PIN_119 -to VGA_HS
|
||||
set_location_assignment PIN_65 -to AUDIO_L
|
||||
set_location_assignment PIN_80 -to AUDIO_R
|
||||
set_location_assignment PIN_46 -to UART_TX
|
||||
set_location_assignment PIN_31 -to UART_RX
|
||||
set_location_assignment PIN_105 -to SPI_DO
|
||||
set_location_assignment PIN_88 -to SPI_DI
|
||||
set_location_assignment PIN_126 -to SPI_SCK
|
||||
set_location_assignment PIN_127 -to SPI_SS2
|
||||
set_location_assignment PIN_91 -to SPI_SS3
|
||||
set_location_assignment PIN_90 -to SPI_SS4
|
||||
set_location_assignment PIN_13 -to CONF_DATA0
|
||||
|
||||
set_location_assignment PIN_49 -to SDRAM_A[0]
|
||||
set_location_assignment PIN_44 -to SDRAM_A[1]
|
||||
set_location_assignment PIN_42 -to SDRAM_A[2]
|
||||
set_location_assignment PIN_39 -to SDRAM_A[3]
|
||||
set_location_assignment PIN_4 -to SDRAM_A[4]
|
||||
set_location_assignment PIN_6 -to SDRAM_A[5]
|
||||
set_location_assignment PIN_8 -to SDRAM_A[6]
|
||||
set_location_assignment PIN_10 -to SDRAM_A[7]
|
||||
set_location_assignment PIN_11 -to SDRAM_A[8]
|
||||
set_location_assignment PIN_28 -to SDRAM_A[9]
|
||||
set_location_assignment PIN_50 -to SDRAM_A[10]
|
||||
set_location_assignment PIN_30 -to SDRAM_A[11]
|
||||
set_location_assignment PIN_32 -to SDRAM_A[12]
|
||||
set_location_assignment PIN_83 -to SDRAM_DQ[0]
|
||||
set_location_assignment PIN_79 -to SDRAM_DQ[1]
|
||||
set_location_assignment PIN_77 -to SDRAM_DQ[2]
|
||||
set_location_assignment PIN_76 -to SDRAM_DQ[3]
|
||||
set_location_assignment PIN_72 -to SDRAM_DQ[4]
|
||||
set_location_assignment PIN_71 -to SDRAM_DQ[5]
|
||||
set_location_assignment PIN_69 -to SDRAM_DQ[6]
|
||||
set_location_assignment PIN_68 -to SDRAM_DQ[7]
|
||||
set_location_assignment PIN_86 -to SDRAM_DQ[8]
|
||||
set_location_assignment PIN_87 -to SDRAM_DQ[9]
|
||||
set_location_assignment PIN_98 -to SDRAM_DQ[10]
|
||||
set_location_assignment PIN_99 -to SDRAM_DQ[11]
|
||||
set_location_assignment PIN_100 -to SDRAM_DQ[12]
|
||||
set_location_assignment PIN_101 -to SDRAM_DQ[13]
|
||||
set_location_assignment PIN_103 -to SDRAM_DQ[14]
|
||||
set_location_assignment PIN_104 -to SDRAM_DQ[15]
|
||||
set_location_assignment PIN_58 -to SDRAM_BA[0]
|
||||
set_location_assignment PIN_51 -to SDRAM_BA[1]
|
||||
set_location_assignment PIN_85 -to SDRAM_DQMH
|
||||
set_location_assignment PIN_67 -to SDRAM_DQML
|
||||
set_location_assignment PIN_60 -to SDRAM_nRAS
|
||||
set_location_assignment PIN_64 -to SDRAM_nCAS
|
||||
set_location_assignment PIN_66 -to SDRAM_nWE
|
||||
set_location_assignment PIN_59 -to SDRAM_nCS
|
||||
set_location_assignment PIN_33 -to SDRAM_CKE
|
||||
set_location_assignment PIN_43 -to SDRAM_CLK
|
||||
|
||||
|
||||
set_global_assignment -name ENABLE_SIGNALTAP ON
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON
|
||||
set_global_assignment -name FITTER_EFFORT "FAST FIT"
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
|
||||
set_global_assignment -name SLD_NODE_CREATOR_ID 110 -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_ENTITY_NAME sld_signaltap -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=AUTO" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_INFO=805334528" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_POWER_UP_TRIGGER=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ATTRIBUTE_MEM_MODE=OFF" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_FLOW_USE_GENERATED=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_BITS=11" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_BUFFER_FULL_STOP=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_CURRENT_RESOURCE_WIDTH=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_IN_ENABLED=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ADVANCED_TRIGGER_ENTITY=basic,1," -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL_PIPELINE=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ENABLE_ADVANCED_TRIGGER=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SEGMENT_SIZE=256" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SAMPLE_DEPTH=256" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[0] -to "TG68KdotC_Kernel:tg68k|IPL[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[1] -to "TG68KdotC_Kernel:tg68k|IPL[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[2] -to "TG68KdotC_Kernel:tg68k|IPL[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[3] -to "TG68KdotC_Kernel:tg68k|Reset" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[4] -to "TG68KdotC_Kernel:tg68k|addr[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[5] -to "TG68KdotC_Kernel:tg68k|addr[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[6] -to "TG68KdotC_Kernel:tg68k|addr[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[7] -to "TG68KdotC_Kernel:tg68k|addr[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[8] -to "TG68KdotC_Kernel:tg68k|addr[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[9] -to "TG68KdotC_Kernel:tg68k|addr[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[10] -to "TG68KdotC_Kernel:tg68k|addr[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[11] -to "TG68KdotC_Kernel:tg68k|addr[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[12] -to "TG68KdotC_Kernel:tg68k|addr[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[13] -to "TG68KdotC_Kernel:tg68k|addr[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[14] -to "TG68KdotC_Kernel:tg68k|addr[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[15] -to "TG68KdotC_Kernel:tg68k|addr[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[16] -to "TG68KdotC_Kernel:tg68k|addr[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[17] -to "TG68KdotC_Kernel:tg68k|addr[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[18] -to "TG68KdotC_Kernel:tg68k|addr[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[19] -to "TG68KdotC_Kernel:tg68k|addr[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[20] -to "TG68KdotC_Kernel:tg68k|addr[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[21] -to "TG68KdotC_Kernel:tg68k|addr[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[22] -to "TG68KdotC_Kernel:tg68k|addr[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[23] -to "TG68KdotC_Kernel:tg68k|addr[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[24] -to "TG68KdotC_Kernel:tg68k|addr[28]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[25] -to "TG68KdotC_Kernel:tg68k|addr[29]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[26] -to "TG68KdotC_Kernel:tg68k|addr[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[27] -to "TG68KdotC_Kernel:tg68k|addr[30]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[28] -to "TG68KdotC_Kernel:tg68k|addr[31]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[29] -to "TG68KdotC_Kernel:tg68k|addr[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[30] -to "TG68KdotC_Kernel:tg68k|addr[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[31] -to "TG68KdotC_Kernel:tg68k|addr[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[32] -to "TG68KdotC_Kernel:tg68k|addr[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[33] -to "TG68KdotC_Kernel:tg68k|addr[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[34] -to "TG68KdotC_Kernel:tg68k|addr[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[35] -to "TG68KdotC_Kernel:tg68k|addr[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[36] -to "TG68KdotC_Kernel:tg68k|busstate[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[37] -to "TG68KdotC_Kernel:tg68k|busstate[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[38] -to "TG68KdotC_Kernel:tg68k|clk" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[39] -to "TG68KdotC_Kernel:tg68k|clkena_in" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[40] -to "TG68KdotC_Kernel:tg68k|data_in[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[41] -to "TG68KdotC_Kernel:tg68k|data_in[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[42] -to "TG68KdotC_Kernel:tg68k|data_in[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[43] -to "TG68KdotC_Kernel:tg68k|data_in[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[44] -to "TG68KdotC_Kernel:tg68k|data_in[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[45] -to "TG68KdotC_Kernel:tg68k|data_in[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[46] -to "TG68KdotC_Kernel:tg68k|data_in[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[47] -to "TG68KdotC_Kernel:tg68k|data_in[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[48] -to "TG68KdotC_Kernel:tg68k|data_in[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[49] -to "TG68KdotC_Kernel:tg68k|data_in[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[50] -to "TG68KdotC_Kernel:tg68k|data_in[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[51] -to "TG68KdotC_Kernel:tg68k|data_in[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[52] -to "TG68KdotC_Kernel:tg68k|data_in[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[53] -to "TG68KdotC_Kernel:tg68k|data_in[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[54] -to "TG68KdotC_Kernel:tg68k|data_in[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[55] -to "TG68KdotC_Kernel:tg68k|data_in[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[56] -to "TG68KdotC_Kernel:tg68k|data_write[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[57] -to "TG68KdotC_Kernel:tg68k|data_write[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[58] -to "TG68KdotC_Kernel:tg68k|data_write[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[59] -to "TG68KdotC_Kernel:tg68k|data_write[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[60] -to "TG68KdotC_Kernel:tg68k|data_write[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[61] -to "TG68KdotC_Kernel:tg68k|data_write[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[62] -to "TG68KdotC_Kernel:tg68k|data_write[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[63] -to "TG68KdotC_Kernel:tg68k|data_write[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[64] -to "TG68KdotC_Kernel:tg68k|data_write[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[65] -to "TG68KdotC_Kernel:tg68k|data_write[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[66] -to "TG68KdotC_Kernel:tg68k|data_write[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[67] -to "TG68KdotC_Kernel:tg68k|data_write[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[68] -to "TG68KdotC_Kernel:tg68k|data_write[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[69] -to "TG68KdotC_Kernel:tg68k|data_write[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[70] -to "TG68KdotC_Kernel:tg68k|data_write[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[71] -to "TG68KdotC_Kernel:tg68k|data_write[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[72] -to "TG68KdotC_Kernel:tg68k|exe_opcode[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[73] -to "TG68KdotC_Kernel:tg68k|exe_opcode[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[74] -to "TG68KdotC_Kernel:tg68k|exe_opcode[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[75] -to "TG68KdotC_Kernel:tg68k|exe_opcode[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[76] -to "TG68KdotC_Kernel:tg68k|exe_opcode[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[77] -to "TG68KdotC_Kernel:tg68k|exe_opcode[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[78] -to "TG68KdotC_Kernel:tg68k|exe_opcode[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[79] -to "TG68KdotC_Kernel:tg68k|exe_opcode[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[80] -to "TG68KdotC_Kernel:tg68k|exe_opcode[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[81] -to "TG68KdotC_Kernel:tg68k|exe_opcode[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[82] -to "TG68KdotC_Kernel:tg68k|exe_opcode[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[83] -to "TG68KdotC_Kernel:tg68k|exe_opcode[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[84] -to "TG68KdotC_Kernel:tg68k|exe_opcode[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[85] -to "TG68KdotC_Kernel:tg68k|exe_opcode[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[86] -to "TG68KdotC_Kernel:tg68k|exe_opcode[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[87] -to "TG68KdotC_Kernel:tg68k|exe_opcode[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[88] -to "TG68KdotC_Kernel:tg68k|nLDS" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[89] -to "TG68KdotC_Kernel:tg68k|nReset" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[90] -to "TG68KdotC_Kernel:tg68k|nUDS" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[91] -to "TG68KdotC_Kernel:tg68k|nWr" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[0] -to "TG68KdotC_Kernel:tg68k|IPL[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[1] -to "TG68KdotC_Kernel:tg68k|IPL[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[2] -to "TG68KdotC_Kernel:tg68k|IPL[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[3] -to "TG68KdotC_Kernel:tg68k|Reset" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[4] -to "TG68KdotC_Kernel:tg68k|addr[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[5] -to "TG68KdotC_Kernel:tg68k|addr[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[6] -to "TG68KdotC_Kernel:tg68k|addr[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[7] -to "TG68KdotC_Kernel:tg68k|addr[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[8] -to "TG68KdotC_Kernel:tg68k|addr[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[9] -to "TG68KdotC_Kernel:tg68k|addr[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[10] -to "TG68KdotC_Kernel:tg68k|addr[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[11] -to "TG68KdotC_Kernel:tg68k|addr[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[12] -to "TG68KdotC_Kernel:tg68k|addr[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[13] -to "TG68KdotC_Kernel:tg68k|addr[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[14] -to "TG68KdotC_Kernel:tg68k|addr[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[15] -to "TG68KdotC_Kernel:tg68k|addr[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[16] -to "TG68KdotC_Kernel:tg68k|addr[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[17] -to "TG68KdotC_Kernel:tg68k|addr[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[18] -to "TG68KdotC_Kernel:tg68k|addr[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[19] -to "TG68KdotC_Kernel:tg68k|addr[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[20] -to "TG68KdotC_Kernel:tg68k|addr[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[21] -to "TG68KdotC_Kernel:tg68k|addr[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[22] -to "TG68KdotC_Kernel:tg68k|addr[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[23] -to "TG68KdotC_Kernel:tg68k|addr[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[24] -to "TG68KdotC_Kernel:tg68k|addr[28]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[25] -to "TG68KdotC_Kernel:tg68k|addr[29]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[26] -to "TG68KdotC_Kernel:tg68k|addr[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[27] -to "TG68KdotC_Kernel:tg68k|addr[30]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[28] -to "TG68KdotC_Kernel:tg68k|addr[31]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[29] -to "TG68KdotC_Kernel:tg68k|addr[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[30] -to "TG68KdotC_Kernel:tg68k|addr[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[31] -to "TG68KdotC_Kernel:tg68k|addr[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[32] -to "TG68KdotC_Kernel:tg68k|addr[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[33] -to "TG68KdotC_Kernel:tg68k|addr[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[34] -to "TG68KdotC_Kernel:tg68k|addr[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[35] -to "TG68KdotC_Kernel:tg68k|addr[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[36] -to "TG68KdotC_Kernel:tg68k|busstate[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[37] -to "TG68KdotC_Kernel:tg68k|busstate[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[38] -to "TG68KdotC_Kernel:tg68k|clk" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[39] -to "TG68KdotC_Kernel:tg68k|clkena_in" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[40] -to "TG68KdotC_Kernel:tg68k|data_in[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[41] -to "TG68KdotC_Kernel:tg68k|data_in[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[42] -to "TG68KdotC_Kernel:tg68k|data_in[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[43] -to "TG68KdotC_Kernel:tg68k|data_in[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[44] -to "TG68KdotC_Kernel:tg68k|data_in[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[45] -to "TG68KdotC_Kernel:tg68k|data_in[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[46] -to "TG68KdotC_Kernel:tg68k|data_in[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[47] -to "TG68KdotC_Kernel:tg68k|data_in[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[48] -to "TG68KdotC_Kernel:tg68k|data_in[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[49] -to "TG68KdotC_Kernel:tg68k|data_in[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[50] -to "TG68KdotC_Kernel:tg68k|data_in[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[51] -to "TG68KdotC_Kernel:tg68k|data_in[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[52] -to "TG68KdotC_Kernel:tg68k|data_in[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[53] -to "TG68KdotC_Kernel:tg68k|data_in[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[54] -to "TG68KdotC_Kernel:tg68k|data_in[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[55] -to "TG68KdotC_Kernel:tg68k|data_in[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[56] -to "TG68KdotC_Kernel:tg68k|data_write[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[57] -to "TG68KdotC_Kernel:tg68k|data_write[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[58] -to "TG68KdotC_Kernel:tg68k|data_write[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[59] -to "TG68KdotC_Kernel:tg68k|data_write[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[60] -to "TG68KdotC_Kernel:tg68k|data_write[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[61] -to "TG68KdotC_Kernel:tg68k|data_write[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[62] -to "TG68KdotC_Kernel:tg68k|data_write[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[63] -to "TG68KdotC_Kernel:tg68k|data_write[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[64] -to "TG68KdotC_Kernel:tg68k|data_write[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[65] -to "TG68KdotC_Kernel:tg68k|data_write[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[66] -to "TG68KdotC_Kernel:tg68k|data_write[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[67] -to "TG68KdotC_Kernel:tg68k|data_write[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[68] -to "TG68KdotC_Kernel:tg68k|data_write[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[69] -to "TG68KdotC_Kernel:tg68k|data_write[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[70] -to "TG68KdotC_Kernel:tg68k|data_write[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[71] -to "TG68KdotC_Kernel:tg68k|data_write[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[72] -to "TG68KdotC_Kernel:tg68k|exe_opcode[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[73] -to "TG68KdotC_Kernel:tg68k|exe_opcode[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[74] -to "TG68KdotC_Kernel:tg68k|exe_opcode[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[75] -to "TG68KdotC_Kernel:tg68k|exe_opcode[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[76] -to "TG68KdotC_Kernel:tg68k|exe_opcode[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[77] -to "TG68KdotC_Kernel:tg68k|exe_opcode[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[78] -to "TG68KdotC_Kernel:tg68k|exe_opcode[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[79] -to "TG68KdotC_Kernel:tg68k|exe_opcode[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[80] -to "TG68KdotC_Kernel:tg68k|exe_opcode[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[81] -to "TG68KdotC_Kernel:tg68k|exe_opcode[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[82] -to "TG68KdotC_Kernel:tg68k|exe_opcode[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[83] -to "TG68KdotC_Kernel:tg68k|exe_opcode[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[84] -to "TG68KdotC_Kernel:tg68k|exe_opcode[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[85] -to "TG68KdotC_Kernel:tg68k|exe_opcode[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[86] -to "TG68KdotC_Kernel:tg68k|exe_opcode[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[87] -to "TG68KdotC_Kernel:tg68k|exe_opcode[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[88] -to "TG68KdotC_Kernel:tg68k|nLDS" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[89] -to "TG68KdotC_Kernel:tg68k|nReset" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[90] -to "TG68KdotC_Kernel:tg68k|nUDS" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[91] -to "TG68KdotC_Kernel:tg68k|nWr" -section_id auto_signaltap_0
|
||||
set_global_assignment -name VERILOG_FILE zx8301.v
|
||||
set_global_assignment -name VHDL_FILE ps2_intf.vhd
|
||||
set_global_assignment -name VERILOG_FILE keyboard.v
|
||||
set_global_assignment -name VHDL_FILE TG68KdotC_Kernel.vhd
|
||||
set_global_assignment -name VHDL_FILE TG68K_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE TG68K_ALU.vhd
|
||||
set_global_assignment -name VERILOG_FILE data_io.v
|
||||
set_global_assignment -name VERILOG_FILE sdram.v
|
||||
set_global_assignment -name VERILOG_FILE osd.v
|
||||
set_global_assignment -name VERILOG_FILE user_io.v
|
||||
set_global_assignment -name QIP_FILE pll.qip
|
||||
set_global_assignment -name VERILOG_FILE ql.v
|
||||
set_global_assignment -name SIGNALTAP_FILE stp1.stp
|
||||
set_global_assignment -name QIP_FILE pll_rtc.qip
|
||||
set_global_assignment -name VERILOG_FILE mdv.v
|
||||
set_global_assignment -name VERILOG_FILE zx8302.v
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[92] -to cpu_enable -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[93] -to cpu_mem -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[94] -to cpu_rd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[95] -to cpu_wr -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[96] -to video_cycle_rd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[92] -to cpu_enable -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[93] -to cpu_mem -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[94] -to cpu_rd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[95] -to cpu_wr -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[96] -to video_cycle_rd -section_id auto_signaltap_0
|
||||
set_global_assignment -name VERILOG_FILE ipc.v
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT acq_clk -to clk5 -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_DATA_BITS=97" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_BITS=97" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK=0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LENGTH=313" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_LOWORD=20891" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_HIWORD=32699" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_FILE db/stp1_auto_stripped.stp
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
413
cores/ql/ql.v
Normal file
413
cores/ql/ql.v
Normal file
@@ -0,0 +1,413 @@
|
||||
//
|
||||
// ql.v - Sinclair QL for the MiST
|
||||
//
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module ql (
|
||||
input [1:0] CLOCK_27,
|
||||
|
||||
// LED outputs
|
||||
output LED, // LED Yellow
|
||||
|
||||
// SDRAM interface
|
||||
inout [15:0] SDRAM_DQ, // SDRAM Data bus 16 Bits
|
||||
output [12:0] SDRAM_A, // SDRAM Address bus 13 Bits
|
||||
output SDRAM_DQML, // SDRAM Low-byte Data Mask
|
||||
output SDRAM_DQMH, // SDRAM High-byte Data Mask
|
||||
output SDRAM_nWE, // SDRAM Write Enable
|
||||
output SDRAM_nCAS, // SDRAM Column Address Strobe
|
||||
output SDRAM_nRAS, // SDRAM Row Address Strobe
|
||||
output SDRAM_nCS, // SDRAM Chip Select
|
||||
output [1:0] SDRAM_BA, // SDRAM Bank Address
|
||||
output SDRAM_CLK, // SDRAM Clock
|
||||
output SDRAM_CKE, // SDRAM Clock Enable
|
||||
|
||||
// SPI interface to arm io controller
|
||||
output SPI_DO,
|
||||
input SPI_DI,
|
||||
input SPI_SCK,
|
||||
input SPI_SS2,
|
||||
input SPI_SS3,
|
||||
input SPI_SS4,
|
||||
input CONF_DATA0,
|
||||
|
||||
output AUDIO_L, // sigma-delta DAC output left
|
||||
output AUDIO_R, // sigma-delta DAC output right
|
||||
|
||||
output VGA_HS,
|
||||
output VGA_VS,
|
||||
output [5:0] VGA_R,
|
||||
output [5:0] VGA_G,
|
||||
output [5:0] VGA_B
|
||||
);
|
||||
|
||||
// the configuration string is returned to the io controller to allow
|
||||
// it to control the menu on the OSD
|
||||
parameter CONF_STR = {
|
||||
"QL;;",
|
||||
"F1,MDV;",
|
||||
"O2,RAM,128k,640k;",
|
||||
"O3,Video mode,PAL,NTSC;",
|
||||
"O4,Scanlines,Off,On;",
|
||||
"T5,Reset"
|
||||
};
|
||||
|
||||
parameter CONF_STR_LEN = 4+7+17+23+20+8;
|
||||
|
||||
// the status register is controlled by the on screen display (OSD)
|
||||
wire [7:0] status;
|
||||
wire tv15khz;
|
||||
wire [1:0] buttons;
|
||||
|
||||
wire ps2_kbd_clk, ps2_kbd_data;
|
||||
|
||||
// generate ps2_clock
|
||||
wire ps2_clock = ps2_clk_div[6]; // ~20khz
|
||||
reg [6:0] ps2_clk_div;
|
||||
always @(posedge clk2)
|
||||
ps2_clk_div <= ps2_clk_div + 7'd1;
|
||||
|
||||
// include user_io module for arm controller communication
|
||||
user_io #(.STRLEN(CONF_STR_LEN)) user_io (
|
||||
.conf_str ( CONF_STR ),
|
||||
|
||||
.SPI_CLK ( SPI_SCK ),
|
||||
.SPI_SS_IO ( CONF_DATA0 ),
|
||||
.SPI_MISO ( SPI_DO ),
|
||||
.SPI_MOSI ( SPI_DI ),
|
||||
|
||||
.scandoubler_disable ( tv15khz ),
|
||||
.buttons ( buttons ),
|
||||
|
||||
// ps2 interface
|
||||
.ps2_clk ( ps2_clock ),
|
||||
.ps2_kbd_clk ( ps2_kbd_clk ),
|
||||
.ps2_kbd_data ( ps2_kbd_data ),
|
||||
|
||||
.status ( status )
|
||||
);
|
||||
|
||||
// csync for tv15khz
|
||||
// QLs vsync is positive, QLs hsync is negative
|
||||
wire vga_csync = !(!vga_hsync ^ vga_vsync);
|
||||
wire vga_hsync, vga_vsync;
|
||||
|
||||
// TV SCART has csync on hsync pin and "high" on vsync pin
|
||||
assign VGA_VS = tv15khz?1'b1:vga_vsync;
|
||||
assign VGA_HS = tv15khz?vga_csync:vga_hsync;
|
||||
|
||||
// tv15hkz has half the pixel rate
|
||||
wire osd_clk = tv15khz?clk10:clk21;
|
||||
|
||||
// include the on screen display
|
||||
osd #(12,0,5) osd (
|
||||
.pclk ( osd_clk ),
|
||||
|
||||
// spi for OSD
|
||||
.sdi ( SPI_DI ),
|
||||
.sck ( SPI_SCK ),
|
||||
.ss ( SPI_SS3 ),
|
||||
|
||||
.red_in ( video_r ),
|
||||
.green_in ( video_g ),
|
||||
.blue_in ( video_b ),
|
||||
.hs_in ( video_hs ),
|
||||
.vs_in ( video_vs ),
|
||||
|
||||
.red_out ( VGA_R ),
|
||||
.green_out ( VGA_G ),
|
||||
.blue_out ( VGA_B ),
|
||||
.hs_out ( vga_hsync ),
|
||||
.vs_out ( vga_vsync )
|
||||
);
|
||||
|
||||
// SDRAM control signals
|
||||
assign SDRAM_CKE = 1'b1;
|
||||
|
||||
|
||||
// CPU and data_io share the same bus cycle. Thus the CPU cannot run while
|
||||
// (ROM) data is being downloaded which wouldn't make any sense, anyway
|
||||
// during ROM download data_io writes the ram. Otherwise the CPU
|
||||
wire [24:0] sys_addr = dio_download?dio_addr[24:0]:{ 6'b000000, cpu_addr[19:1]};
|
||||
wire [1:0] sys_ds = dio_download?2'b11:~cpu_ds;
|
||||
wire [15:0] sys_dout = dio_download?dio_data:cpu_dout;
|
||||
wire sys_wr = dio_download?dio_write:(cpu_wr && cpu_ram);
|
||||
wire sys_oe = dio_download?1'b0:(cpu_rd && cpu_mem);
|
||||
|
||||
// microdrive emulation and video share the video cycle time slot
|
||||
wire [24:0] video_cycle_addr = mdv_read?mdv_addr:{6'd0, video_addr};
|
||||
wire video_cycle_rd = mdv_read?1'b1:video_rd;
|
||||
|
||||
// video and CPU/data_io time share the sdram bus
|
||||
wire [24:0] sdram_addr = video_cycle?video_cycle_addr:sys_addr;
|
||||
wire sdram_wr = video_cycle?1'b0:sys_wr;
|
||||
wire sdram_oe = video_cycle?video_cycle_rd:sys_oe;
|
||||
wire [1:0] sdram_ds = video_cycle?2'b11:sys_ds;
|
||||
wire [15:0] sdram_dout;
|
||||
wire [15:0] sdram_din = sys_dout;
|
||||
|
||||
sdram sdram (
|
||||
// interface to the MT48LC16M16 chip
|
||||
.sd_data ( SDRAM_DQ ),
|
||||
.sd_addr ( SDRAM_A ),
|
||||
.sd_dqm ( {SDRAM_DQMH, SDRAM_DQML} ),
|
||||
.sd_cs ( SDRAM_nCS ),
|
||||
.sd_ba ( SDRAM_BA ),
|
||||
.sd_we ( SDRAM_nWE ),
|
||||
.sd_ras ( SDRAM_nRAS ),
|
||||
.sd_cas ( SDRAM_nCAS ),
|
||||
|
||||
// system interface
|
||||
.clk ( clk21 ),
|
||||
.clkref ( clk2 ),
|
||||
.init ( !pll_locked ),
|
||||
|
||||
// cpu interface
|
||||
.din ( sdram_din ),
|
||||
.addr ( sdram_addr ),
|
||||
.we ( sdram_wr ),
|
||||
.oe ( sdram_oe ),
|
||||
.ds ( sdram_ds ),
|
||||
.dout ( sdram_dout )
|
||||
);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// ------------------------------------- data io -----------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire dio_download;
|
||||
wire [4:0] dio_index;
|
||||
wire [24:0] dio_addr;
|
||||
wire [15:0] dio_data;
|
||||
wire dio_write;
|
||||
|
||||
// include ROM download helper
|
||||
// this receives a byte stream from the arm io controller via spi and
|
||||
// writes it into sdram
|
||||
data_io data_io (
|
||||
// io controller spi interface
|
||||
.sck ( SPI_SCK ),
|
||||
.ss ( SPI_SS2 ),
|
||||
.sdi ( SPI_DI ),
|
||||
|
||||
.downloading ( dio_download ), // signal indicating an active rom download
|
||||
.index ( dio_index ),
|
||||
|
||||
// external ram interface
|
||||
.clk ( cpu_cycle ),
|
||||
.wr ( dio_write ),
|
||||
.addr ( dio_addr ),
|
||||
.data ( dio_data )
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- video ------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire [5:0] video_r, video_g, video_b;
|
||||
wire video_hs, video_vs;
|
||||
|
||||
wire [18:0] video_addr;
|
||||
wire video_rd;
|
||||
|
||||
// the zx8301 has only one write-only register at $18063
|
||||
wire zx8301_cs = cpu_cycle && cpu_io &&
|
||||
({cpu_addr[6:5], cpu_addr[1]} == 3'b111)&& cpu_wr && !cpu_ds[0];
|
||||
|
||||
zx8301 zx8301 (
|
||||
.reset ( reset ),
|
||||
.clk_vga ( clk21 ),
|
||||
.clk_video ( clk10 ),
|
||||
.video_cycle ( video_cycle ),
|
||||
|
||||
.ntsc ( status[3] ),
|
||||
.scandoubler ( !tv15khz ),
|
||||
.scanlines ( status[4] ),
|
||||
|
||||
.clk_bus ( clk2 ),
|
||||
.cpu_cs ( zx8301_cs ),
|
||||
.cpu_data ( cpu_dout[7:0] ),
|
||||
|
||||
.mdv_men ( mdv_men ),
|
||||
|
||||
.addr ( video_addr ),
|
||||
.din ( sdram_dout ),
|
||||
.rd ( video_rd ),
|
||||
|
||||
.hs ( video_hs ),
|
||||
.vs ( video_vs ),
|
||||
.r ( video_r ),
|
||||
.g ( video_g ),
|
||||
.b ( video_b )
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- reset ------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire rom_download = dio_download && (dio_index == 0);
|
||||
reg [11:0] reset_cnt;
|
||||
wire reset = (reset_cnt != 0);
|
||||
always @(posedge clk2) begin
|
||||
if(buttons[1] || status[0] || status[5] || !pll_locked || rom_download)
|
||||
reset_cnt <= 12'hfff;
|
||||
else if(reset_cnt != 0)
|
||||
reset_cnt <= reset_cnt - 1;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// --------------------------------------- IO --------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire zx8302_sel = cpu_cycle && cpu_io && !cpu_addr[6];
|
||||
wire [1:0] zx8302_addr = {cpu_addr[5], cpu_addr[1]};
|
||||
wire [15:0] zx8302_dout;
|
||||
|
||||
wire mdv_download = (dio_index == 1) && dio_download;
|
||||
wire mdv_men;
|
||||
wire mdv_read;
|
||||
wire [24:0] mdv_addr;
|
||||
|
||||
zx8302 zx8302 (
|
||||
.reset ( reset ),
|
||||
.init ( !pll_locked ),
|
||||
.clk ( clk21 ),
|
||||
|
||||
.ipl ( cpu_ipl ),
|
||||
.led ( LED ),
|
||||
|
||||
// CPU connection
|
||||
.clk_bus ( clk2 ),
|
||||
.cpu_sel ( zx8302_sel ),
|
||||
.cpu_wr ( cpu_wr ),
|
||||
.cpu_addr ( zx8302_addr ),
|
||||
.cpu_ds ( cpu_ds ),
|
||||
.cpu_din ( cpu_dout ),
|
||||
.cpu_dout ( zx8302_dout ),
|
||||
|
||||
.ps2_kbd_clk ( ps2_kbd_clk ),
|
||||
.ps2_kbd_data ( ps2_kbd_data ),
|
||||
|
||||
.vs ( video_vs ),
|
||||
|
||||
// microdrive sdram interface
|
||||
.mdv_addr ( mdv_addr ),
|
||||
.mdv_din ( sdram_dout ),
|
||||
.mdv_read ( mdv_read ),
|
||||
.mdv_men ( mdv_men ),
|
||||
.video_cycle ( video_cycle ),
|
||||
|
||||
.mdv_download ( mdv_download ),
|
||||
.mdv_dl_addr ( dio_addr )
|
||||
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- CPU --------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
// address decoding
|
||||
wire cpu_io = ({cpu_addr[19:14], 2'b00} == 8'h18); // internal IO $18000-$1bffff
|
||||
wire cpu_bram = (cpu_addr[19:17] == 3'b001); // 128k RAM at $20000
|
||||
wire cpu_xram = status[2] && ((cpu_addr[19:18] == 2'b01) ||
|
||||
(cpu_addr[19:18] == 2'b10)); // 512k RAM at $40000 if enabled
|
||||
wire cpu_ram = cpu_bram || cpu_xram; // any RAM
|
||||
wire cpu_rom = (cpu_addr[19:16] == 4'h0); // 64k ROM at $0
|
||||
wire cpu_mem = cpu_ram || cpu_rom; // any memory mapped to sdram
|
||||
|
||||
wire [15:0] io_dout = cpu_addr[6]?16'h0000:zx8302_dout;
|
||||
|
||||
// demultiplex the various data sources
|
||||
wire [15:0] cpu_din =
|
||||
cpu_mem?sdram_dout:
|
||||
cpu_io?io_dout:
|
||||
16'hffff;
|
||||
|
||||
wire [31:0] cpu_addr;
|
||||
wire [1:0] cpu_ds;
|
||||
wire [15:0] cpu_dout;
|
||||
wire [2:0] cpu_ipl;
|
||||
wire cpu_rw;
|
||||
wire [1:0] cpu_busstate;
|
||||
wire cpu_rd = (cpu_busstate == 2'b00) || (cpu_busstate == 2'b10);
|
||||
wire cpu_wr = (cpu_busstate == 2'b11) && !cpu_rw;
|
||||
wire cpu_idle = (cpu_busstate == 2'b01);
|
||||
|
||||
reg cpu_enable;
|
||||
always @(negedge clk2)
|
||||
cpu_enable <= (cpu_cycle && !dio_download) || cpu_idle;
|
||||
|
||||
TG68KdotC_Kernel #(0,0,0,0,0,0) tg68k (
|
||||
.clk ( clk2 ),
|
||||
.nReset ( ~reset ),
|
||||
.clkena_in ( cpu_enable ),
|
||||
.data_in ( cpu_din ),
|
||||
.IPL ( cpu_ipl ),
|
||||
.IPL_autovector ( 1'b1 ),
|
||||
.berr ( 1'b0 ),
|
||||
.clr_berr ( 1'b0 ),
|
||||
.CPU ( 2'b00 ), // 00=68000
|
||||
.addr ( cpu_addr ),
|
||||
.data_write ( cpu_dout ),
|
||||
.nUDS ( cpu_ds[1] ),
|
||||
.nLDS ( cpu_ds[0] ),
|
||||
.nWr ( cpu_rw ),
|
||||
.busstate ( cpu_busstate ), // 00-> fetch code 10->read data 11->write data 01->no memaccess
|
||||
.nResetOut ( ),
|
||||
.FC ( )
|
||||
);
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// -------------------------- clock generation -----------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
reg clk10; // 10.5 MHz QL pixel clock
|
||||
wire clk21;
|
||||
always @(posedge clk21)
|
||||
clk10 <= !clk10;
|
||||
|
||||
reg clk5; // 5.25 MHz CPU clock
|
||||
always @(posedge clk10)
|
||||
clk5 <= !clk5;
|
||||
|
||||
reg clk2; // 2.625 MHz bus clock
|
||||
always @(posedge clk5)
|
||||
clk2 <= !clk2;
|
||||
|
||||
// CPU and Video share the bus
|
||||
reg video_cycle;
|
||||
wire cpu_cycle = !video_cycle;
|
||||
always @(posedge clk2)
|
||||
video_cycle <= !video_cycle;
|
||||
|
||||
wire pll_locked;
|
||||
|
||||
// A PLL to derive the system clock from the MiSTs 27MHz
|
||||
pll pll (
|
||||
.inclk0( CLOCK_27[0] ),
|
||||
.c0( clk21 ), // 21.000 MHz
|
||||
.c1( SDRAM_CLK ), // 21.000 MHz phase shifted
|
||||
.locked( pll_locked )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
6
cores/ql/readme.md
Normal file
6
cores/ql/readme.md
Normal file
@@ -0,0 +1,6 @@
|
||||
QL for MIST
|
||||
===========
|
||||
|
||||
This is an implementation of the Sinclair QL for the MIST board.
|
||||
|
||||
It's based on the TG68K CPU core.
|
||||
150
cores/ql/sdram.v
Normal file
150
cores/ql/sdram.v
Normal file
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// sdram.v
|
||||
//
|
||||
// sdram controller implementation for the MiST board
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module sdram (
|
||||
|
||||
// interface to the MT48LC16M16 chip
|
||||
inout [15:0] sd_data, // 16 bit bidirectional data bus
|
||||
output reg [12:0] sd_addr, // 13 bit multiplexed address bus
|
||||
output reg [1:0] sd_dqm, // two byte masks
|
||||
output reg[1:0] sd_ba, // two banks
|
||||
output sd_cs, // a single chip select
|
||||
output sd_we, // write enable
|
||||
output sd_ras, // row address select
|
||||
output sd_cas, // columns address select
|
||||
|
||||
// cpu/chipset interface
|
||||
input init, // init signal after FPGA config to initialize RAM
|
||||
input clk, // sdram is accessed at up to 128MHz
|
||||
input clkref, // reference clock to sync to
|
||||
|
||||
input [15:0] din, // data input from chipset/cpu
|
||||
output [15:0] dout, // data output to chipset/cpu
|
||||
input [24:0] addr, // 25 bit word address
|
||||
input [1:0] ds, // data strobe for hi/low byte
|
||||
input oe, // cpu/chipset requests read
|
||||
input we // cpu/chipset requests write
|
||||
);
|
||||
|
||||
// no burst configured
|
||||
localparam RASCAS_DELAY = 3'd3; // tRCD>=20ns -> 2 cycles@64MHz
|
||||
localparam BURST_LENGTH = 3'b000; // 000=none, 001=2, 010=4, 011=8
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd3; // 2/3 allowed
|
||||
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
|
||||
localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
|
||||
|
||||
localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------------ cycle state machine ------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
localparam STATE_IDLE = 3'd0; // first state in cycle
|
||||
localparam STATE_CMD_START = 3'd1; // state in which a new command can be started
|
||||
localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY - 3'd1; // 4 command can be continued
|
||||
localparam STATE_LAST = 3'd7; // last state in cycle
|
||||
|
||||
reg [2:0] q /* synthesis noprune */;
|
||||
always @(posedge clk) begin
|
||||
// 32Mhz counter synchronous to 4 Mhz clock
|
||||
// force counter to pass state 5->6 exactly after the rising edge of clkref
|
||||
// since clkref is two clocks early
|
||||
if(((q == 7) && ( clkref == 0)) ||
|
||||
((q == 0) && ( clkref == 1)) ||
|
||||
((q != 7) && (q != 0)))
|
||||
q <= q + 3'd1;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// --------------------------- startup/reset ---------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// wait 1ms (32 clkref cycles) after FPGA config is done before going
|
||||
// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
|
||||
reg [4:0] reset;
|
||||
always @(posedge clk) begin
|
||||
if(init) reset <= 5'h1f;
|
||||
else if((q == STATE_LAST) && (reset != 0))
|
||||
reset <= reset - 5'd1;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------ generate ram control signals ---------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// all possible commands
|
||||
localparam CMD_INHIBIT = 4'b1111;
|
||||
localparam CMD_NOP = 4'b0111;
|
||||
localparam CMD_ACTIVE = 4'b0011;
|
||||
localparam CMD_READ = 4'b0101;
|
||||
localparam CMD_WRITE = 4'b0100;
|
||||
localparam CMD_BURST_TERMINATE = 4'b0110;
|
||||
localparam CMD_PRECHARGE = 4'b0010;
|
||||
localparam CMD_AUTO_REFRESH = 4'b0001;
|
||||
localparam CMD_LOAD_MODE = 4'b0000;
|
||||
|
||||
reg [3:0] sd_cmd; // current command sent to sd ram
|
||||
|
||||
// drive control signals according to current command
|
||||
assign sd_cs = sd_cmd[3];
|
||||
assign sd_ras = sd_cmd[2];
|
||||
assign sd_cas = sd_cmd[1];
|
||||
assign sd_we = sd_cmd[0];
|
||||
|
||||
assign sd_data = we?din:16'bZZZZZZZZZZZZZZZZ;
|
||||
|
||||
assign dout = sd_data;
|
||||
|
||||
always @(posedge clk) begin
|
||||
sd_cmd <= CMD_INHIBIT;
|
||||
|
||||
if(reset != 0) begin
|
||||
sd_ba <= 2'b00;
|
||||
sd_dqm <= 2'b00;
|
||||
|
||||
if(reset == 13) sd_addr <= 13'b0010000000000;
|
||||
else sd_addr <= MODE;
|
||||
|
||||
if(q == STATE_IDLE) begin
|
||||
if(reset == 13) sd_cmd <= CMD_PRECHARGE;
|
||||
if(reset == 2) sd_cmd <= CMD_LOAD_MODE;
|
||||
end
|
||||
end else begin
|
||||
if(q <= STATE_CMD_START) begin
|
||||
sd_addr <= addr[20:8];
|
||||
sd_ba <= addr[22:21];
|
||||
sd_dqm <= { !ds[1], !ds[0] };
|
||||
end else
|
||||
sd_addr <= { 4'b0010, addr[23], addr[7:0]};
|
||||
|
||||
if(q == STATE_IDLE) begin
|
||||
if(we || oe) sd_cmd <= CMD_ACTIVE;
|
||||
else sd_cmd <= CMD_AUTO_REFRESH;
|
||||
end else if(q == STATE_CMD_CONT) begin
|
||||
if(we) sd_cmd <= CMD_WRITE;
|
||||
else if(oe) sd_cmd <= CMD_READ;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
418
cores/ql/user_io.v
Normal file
418
cores/ql/user_io.v
Normal file
@@ -0,0 +1,418 @@
|
||||
//
|
||||
// user_io.v - interface to MIST arm io controller
|
||||
//
|
||||
// Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// parameter STRLEN and the actual length of conf_str have to match
|
||||
|
||||
module user_io #(parameter STRLEN=0) (
|
||||
input [(8*STRLEN)-1:0] conf_str,
|
||||
|
||||
input SPI_CLK,
|
||||
input SPI_SS_IO,
|
||||
output reg SPI_MISO,
|
||||
input SPI_MOSI,
|
||||
|
||||
output reg [7:0] joystick_0,
|
||||
output reg [7:0] joystick_1,
|
||||
output reg [15:0] joystick_analog_0,
|
||||
output reg [15:0] joystick_analog_1,
|
||||
output [1:0] buttons,
|
||||
output [1:0] switches,
|
||||
output scandoubler_disable,
|
||||
|
||||
output reg [7:0] status,
|
||||
|
||||
// connection to sd card emulation
|
||||
input [31:0] sd_lba,
|
||||
input sd_rd,
|
||||
input sd_wr,
|
||||
output reg sd_ack,
|
||||
input sd_conf,
|
||||
input sd_sdhc,
|
||||
output [7:0] sd_dout, // valid on rising edge of sd_dout_strobe
|
||||
output reg sd_dout_strobe,
|
||||
input [7:0] sd_din,
|
||||
output reg sd_din_strobe,
|
||||
output reg sd_change,
|
||||
|
||||
// ps2 keyboard emulation
|
||||
input ps2_clk, // 12-16khz provided by core
|
||||
output ps2_kbd_clk,
|
||||
output reg ps2_kbd_data,
|
||||
output ps2_mouse_clk,
|
||||
output reg ps2_mouse_data,
|
||||
|
||||
// serial com port
|
||||
input [7:0] serial_data,
|
||||
input serial_strobe
|
||||
);
|
||||
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [7:0] byte_cnt; // counts bytes
|
||||
reg [5:0] joystick0;
|
||||
reg [5:0] joystick1;
|
||||
reg [7:0] but_sw;
|
||||
reg [2:0] stick_idx;
|
||||
|
||||
assign buttons = but_sw[1:0];
|
||||
assign switches = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
assign sd_dout = { sbuf, SPI_MOSI};
|
||||
|
||||
// this variant of user_io is for 8 bit cores (type == a4) only
|
||||
wire [7:0] core_type = 8'ha4;
|
||||
|
||||
// command byte read by the io controller
|
||||
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
|
||||
|
||||
// filter spi clock. the 8 bit gate delay is ~2.5ns in total
|
||||
wire [7:0] spi_sck_D = { spi_sck_D[6:0], SPI_CLK } /* synthesis keep */;
|
||||
wire spi_sck = (spi_sck && spi_sck_D != 8'h00) || (!spi_sck && spi_sck_D == 8'hff);
|
||||
|
||||
// drive MISO only when transmitting core id
|
||||
always@(negedge spi_sck or posedge SPI_SS_IO) begin
|
||||
if(SPI_SS_IO == 1) begin
|
||||
SPI_MISO <= 1'bZ;
|
||||
end else begin
|
||||
|
||||
// first byte returned is always core type, further bytes are
|
||||
// command dependent
|
||||
if(byte_cnt == 0) begin
|
||||
SPI_MISO <= core_type[~bit_cnt];
|
||||
|
||||
end else begin
|
||||
// reading serial fifo
|
||||
if(cmd == 8'h1b) begin
|
||||
// send alternating flag byte and data
|
||||
if(byte_cnt[0]) SPI_MISO <= serial_out_status[~bit_cnt];
|
||||
else SPI_MISO <= serial_out_byte[~bit_cnt];
|
||||
end
|
||||
|
||||
// reading config string
|
||||
else if(cmd == 8'h14) begin
|
||||
// returning a byte from string
|
||||
if(byte_cnt < STRLEN + 1)
|
||||
SPI_MISO <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
|
||||
else
|
||||
SPI_MISO <= 1'b0;
|
||||
end
|
||||
|
||||
// reading sd card status
|
||||
else if(cmd == 8'h16) begin
|
||||
if(byte_cnt == 1)
|
||||
SPI_MISO <= sd_cmd[~bit_cnt];
|
||||
else if((byte_cnt >= 2) && (byte_cnt < 6))
|
||||
SPI_MISO <= sd_lba[{5-byte_cnt, ~bit_cnt}];
|
||||
else
|
||||
SPI_MISO <= 1'b0;
|
||||
end
|
||||
|
||||
// reading sd card write data
|
||||
else if(cmd == 8'h18)
|
||||
SPI_MISO <= sd_din[~bit_cnt];
|
||||
|
||||
else
|
||||
SPI_MISO <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------- PS2 ---------------------
|
||||
|
||||
// 8 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 3;
|
||||
|
||||
// keyboard
|
||||
reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_kbd_tx_state;
|
||||
reg [7:0] ps2_kbd_tx_byte;
|
||||
reg ps2_kbd_parity;
|
||||
|
||||
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 ps2_clk) begin
|
||||
ps2_kbd_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_kbd_r_inc)
|
||||
ps2_kbd_rptr <= ps2_kbd_rptr + 1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_kbd_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
|
||||
ps2_kbd_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_kbd_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_kbd_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_kbd_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
|
||||
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
|
||||
ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
|
||||
if(ps2_kbd_tx_byte[0])
|
||||
ps2_kbd_parity <= !ps2_kbd_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_kbd_tx_state == 9)
|
||||
ps2_kbd_data <= ps2_kbd_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_kbd_tx_state == 10)
|
||||
ps2_kbd_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_kbd_tx_state < 11)
|
||||
ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1;
|
||||
else
|
||||
ps2_kbd_tx_state <= 4'd0;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// mouse
|
||||
reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_mouse_tx_state;
|
||||
reg [7:0] ps2_mouse_tx_byte;
|
||||
reg ps2_mouse_parity;
|
||||
|
||||
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 ps2_clk) begin
|
||||
ps2_mouse_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_mouse_r_inc)
|
||||
ps2_mouse_rptr <= ps2_mouse_rptr + 1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_mouse_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
|
||||
ps2_mouse_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_mouse_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_mouse_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_mouse_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin
|
||||
ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits
|
||||
ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down
|
||||
if(ps2_mouse_tx_byte[0])
|
||||
ps2_mouse_parity <= !ps2_mouse_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_mouse_tx_state == 9)
|
||||
ps2_mouse_data <= ps2_mouse_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_mouse_tx_state == 10)
|
||||
ps2_mouse_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_mouse_tx_state < 11)
|
||||
ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1;
|
||||
else
|
||||
ps2_mouse_tx_state <= 4'd0;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// fifo to receive serial data from core to be forwarded to io controller
|
||||
|
||||
// 16 byte fifo to store serial bytes
|
||||
localparam SERIAL_OUT_FIFO_BITS = 6;
|
||||
reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0];
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr;
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr;
|
||||
|
||||
wire serial_out_data_available = serial_out_wptr != serial_out_rptr;
|
||||
wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */;
|
||||
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
|
||||
if(status[0] == 1) begin
|
||||
serial_out_wptr <= 0;
|
||||
end else begin
|
||||
serial_out_fifo[serial_out_wptr] <= serial_data;
|
||||
serial_out_wptr <= serial_out_wptr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always@(negedge spi_sck or posedge status[0]) begin
|
||||
if(status[0] == 1) begin
|
||||
serial_out_rptr <= 0;
|
||||
end else begin
|
||||
if((byte_cnt != 0) && (cmd == 8'h1b)) begin
|
||||
// read last bit -> advance read pointer
|
||||
if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available)
|
||||
serial_out_rptr <= serial_out_rptr + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SPI receiver
|
||||
always@(posedge spi_sck or posedge SPI_SS_IO) begin
|
||||
|
||||
if(SPI_SS_IO == 1) begin
|
||||
bit_cnt <= 3'd0;
|
||||
byte_cnt <= 8'd0;
|
||||
sd_ack <= 1'b0;
|
||||
sd_dout_strobe <= 1'b0;
|
||||
sd_din_strobe <= 1'b0;
|
||||
sd_change <= 1'b0;
|
||||
end else begin
|
||||
sd_dout_strobe <= 1'b0;
|
||||
sd_din_strobe <= 1'b0;
|
||||
|
||||
if(bit_cnt != 7)
|
||||
sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
|
||||
|
||||
bit_cnt <= bit_cnt + 3'd1;
|
||||
if((bit_cnt == 7)&&(byte_cnt != 8'd255))
|
||||
byte_cnt <= byte_cnt + 8'd1;
|
||||
|
||||
// finished reading command byte
|
||||
if(bit_cnt == 7) begin
|
||||
if(byte_cnt == 0) begin
|
||||
cmd <= { sbuf, SPI_MOSI};
|
||||
|
||||
// fetch first byte when sectore FPGA->IO command has been seen
|
||||
if({ sbuf, SPI_MOSI} == 8'h18)
|
||||
sd_din_strobe <= 1'b1;
|
||||
|
||||
if(({ sbuf, SPI_MOSI} == 8'h17) || ({ sbuf, SPI_MOSI} == 8'h18))
|
||||
sd_ack <= 1'b1;
|
||||
|
||||
end else begin
|
||||
|
||||
// buttons and switches
|
||||
if(cmd == 8'h01)
|
||||
but_sw <= { sbuf, SPI_MOSI };
|
||||
|
||||
if(cmd == 8'h02)
|
||||
joystick_0 <= { sbuf, SPI_MOSI };
|
||||
|
||||
if(cmd == 8'h03)
|
||||
joystick_1 <= { sbuf, SPI_MOSI };
|
||||
|
||||
if(cmd == 8'h04) begin
|
||||
// store incoming ps2 mouse bytes
|
||||
ps2_mouse_fifo[ps2_mouse_wptr] <= { sbuf, SPI_MOSI };
|
||||
ps2_mouse_wptr <= ps2_mouse_wptr + 1;
|
||||
end
|
||||
|
||||
if(cmd == 8'h05) begin
|
||||
// store incoming ps2 keyboard bytes
|
||||
ps2_kbd_fifo[ps2_kbd_wptr] <= { sbuf, SPI_MOSI };
|
||||
ps2_kbd_wptr <= ps2_kbd_wptr + 1;
|
||||
end
|
||||
|
||||
if(cmd == 8'h15)
|
||||
status <= { sbuf[6:0], SPI_MOSI };
|
||||
|
||||
// send sector IO -> FPGA
|
||||
if(cmd == 8'h17) begin
|
||||
// flag that download begins
|
||||
sd_dout_strobe <= 1'b1;
|
||||
end
|
||||
|
||||
// send sector FPGA -> IO
|
||||
if(cmd == 8'h18)
|
||||
sd_din_strobe <= 1'b1;
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
if(cmd == 8'h19) begin
|
||||
// flag that download begins
|
||||
// sd card knows data is config if sd_dout_strobe is asserted
|
||||
// with sd_ack still being inactive (low)
|
||||
sd_dout_strobe <= 1'b1;
|
||||
end
|
||||
|
||||
// joystick analog
|
||||
if(cmd == 8'h1a) begin
|
||||
// first byte is joystick indes
|
||||
if(byte_cnt == 1)
|
||||
stick_idx <= { sbuf[1:0], SPI_MOSI };
|
||||
else if(byte_cnt == 2) begin
|
||||
// second byte is x axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[15:8] <= { sbuf, SPI_MOSI };
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[15:8] <= { sbuf, SPI_MOSI };
|
||||
end else if(byte_cnt == 3) begin
|
||||
// third byte is y axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[7:0] <= { sbuf, SPI_MOSI };
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[7:0] <= { sbuf, SPI_MOSI };
|
||||
end
|
||||
end
|
||||
|
||||
// set sd card status. The fact that this register is being
|
||||
// set by the arm controller indicates a possible disk change
|
||||
if(cmd == 8'h1c)
|
||||
sd_change <= 1'b1;
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
345
cores/ql/zx8301.v
Normal file
345
cores/ql/zx8301.v
Normal file
@@ -0,0 +1,345 @@
|
||||
//
|
||||
// zx8301.v
|
||||
//
|
||||
// ZX8301 ULA for Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module zx8301 (
|
||||
input reset,
|
||||
|
||||
// clock
|
||||
input clk_vga, // 21 Mhz VGA pixel clock
|
||||
input clk_video, // 10.5 MHz QL pixel clock
|
||||
input video_cycle,
|
||||
|
||||
// config options
|
||||
input ntsc,
|
||||
input scandoubler,
|
||||
input scanlines,
|
||||
|
||||
// CPU interface to access $18063
|
||||
input clk_bus,
|
||||
input cpu_cs,
|
||||
input [7:0] cpu_data,
|
||||
|
||||
// sdram interface
|
||||
output reg [18:0] addr,
|
||||
output rd,
|
||||
input [15:0] din,
|
||||
|
||||
// signal telling mdv emulation that it may use the video
|
||||
output reg mdv_men,
|
||||
|
||||
// VIDEO output
|
||||
output hs,
|
||||
output reg vs,
|
||||
output [5:0] r,
|
||||
output [5:0] g,
|
||||
output [5:0] b
|
||||
);
|
||||
|
||||
assign rd = me;
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* -------------------------- CPU register ------------------------- */
|
||||
/* ----------------------------------------------------------------- */
|
||||
// [6] -> NTSC?
|
||||
|
||||
wire membase = mc_stat[7]; // 0 = $20000, 1 = $28000
|
||||
wire mode = mc_stat[3]; // 0 = 512*256*2bpp, 1=256*256*4bpp
|
||||
wire blank = mc_stat[1]; // 0 = normal video, 1 = blanked video
|
||||
|
||||
reg [7:0] mc_stat;
|
||||
|
||||
always @(negedge clk_bus) begin
|
||||
if(reset)
|
||||
mc_stat <= 8'h00;
|
||||
else if(cpu_cs)
|
||||
mc_stat <= cpu_data;
|
||||
end
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* ---------------------- video timing values ---------------------- */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
// PAL video parameters
|
||||
parameter H = 512; // width of visible area
|
||||
//parameter PAL_HFP = 112; // unused time before hsync
|
||||
//parameter PAL_HSW = 96; // width of hsync
|
||||
//parameter PAL_HBP = 176; // unused time after hsync
|
||||
//// PAL total: 896
|
||||
//parameter NTSC_HFP = 112; // unused time before hsync
|
||||
//parameter NTSC_HSW = 88; // width of hsync
|
||||
//parameter NTSC_HBP = 176; // unused time after hsync
|
||||
//// NTSC total: 888
|
||||
parameter PAL_HFP = 34; // unused time before hsync
|
||||
parameter PAL_HSW = 72; // width of hsync
|
||||
parameter PAL_HBP = 54; // unused time after hsync
|
||||
// PAL total: 672
|
||||
parameter NTSC_HFP = 34; // unused time before hsync
|
||||
parameter NTSC_HSW = 64; // width of hsync
|
||||
parameter NTSC_HBP = 54; // unused time after hsync
|
||||
// NTSC total: 664
|
||||
|
||||
parameter V = 256; // height of visible area
|
||||
parameter PAL_VFP = 15; // unused time before vsync
|
||||
parameter PAL_VSW = 6; // width of vsync
|
||||
parameter PAL_VBP = 35; // unused time after vsync
|
||||
// PAL total: 312
|
||||
parameter NTSC_VFP = 2; // unused time before vsync
|
||||
parameter NTSC_VSW = 2; // width of vsync
|
||||
parameter NTSC_VBP = 2; // unused time after vsync
|
||||
// NTSC total: 262
|
||||
|
||||
// both counters count from the begin of the visibla area
|
||||
reg [9:0] h_cnt; // horizontal pixel counter
|
||||
reg [9:0] sd_h_cnt; // scandoubler horizontal pixel counter
|
||||
reg [9:0] v_cnt; // vertical pixel counter
|
||||
|
||||
// swtich between ntsc and pal values
|
||||
wire [9:0] hfp = ntsc?NTSC_HFP:PAL_HFP;
|
||||
wire [9:0] hsw = ntsc?NTSC_HSW:PAL_HSW;
|
||||
wire [9:0] hbp = ntsc?NTSC_HBP:PAL_HBP;
|
||||
wire [9:0] vfp = ntsc?NTSC_VFP:PAL_VFP;
|
||||
wire [9:0] vsw = ntsc?NTSC_VSW:PAL_VSW;
|
||||
wire [9:0] vbp = ntsc?NTSC_VBP:PAL_VBP;
|
||||
|
||||
// QL colors
|
||||
localparam BLACK = 3'b000;
|
||||
localparam BLUE = 3'b001;
|
||||
localparam GREEN = 3'b010;
|
||||
localparam CYAN = 3'b011;
|
||||
localparam RED = 3'b100;
|
||||
localparam MAGENTA = 3'b101;
|
||||
localparam YELLOW = 3'b110;
|
||||
localparam WHITE = 3'b111;
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* ------------------------ VGA scandoubler ------------------------ */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
// scan doubler buffer can hold two lines
|
||||
reg [2:0] sd_buffer [1023:0];
|
||||
reg sd_scanline;
|
||||
reg sd_toggle;
|
||||
|
||||
// the scandoubler alternates between two buffers
|
||||
// one is being written while the other one is being output
|
||||
always @(posedge clk_video)
|
||||
if(h_cnt == H+hfp+hsw+hbp-1)
|
||||
sd_toggle = !sd_toggle;
|
||||
|
||||
// scandoubler horizontal pixel counter
|
||||
always@(posedge clk_vga) begin
|
||||
// synchronize to
|
||||
if((!clk_video && (h_cnt==H+hfp+hsw+hbp-1)) ||
|
||||
(sd_h_cnt==H+hfp+hsw+hbp-1)) sd_h_cnt <= 0;
|
||||
else sd_h_cnt <= sd_h_cnt + 1;
|
||||
|
||||
// generate negative hsync signal
|
||||
if(sd_h_cnt == H+hfp) sd_hs <= 1'b0;
|
||||
if(sd_h_cnt == H+hfp+hsw) begin
|
||||
sd_hs <= 1'b1;
|
||||
sd_scanline <= !sd_scanline;
|
||||
end
|
||||
|
||||
if(v_cnt == V+vfp+vsw+vbp-1)
|
||||
sd_scanline <= 1'b0;
|
||||
end
|
||||
|
||||
// write to scandoubler buffer at QL pixel clock
|
||||
always @(posedge clk_video) begin
|
||||
if(h_cnt < H) begin
|
||||
if(v_cnt < V)
|
||||
sd_buffer[{sd_toggle, h_cnt[8:0]}] <= mode?pixel_color_4bpp:pixel_color_2bpp;
|
||||
else
|
||||
sd_buffer[{sd_toggle, h_cnt[8:0]}] <= 3'b000;
|
||||
end
|
||||
end
|
||||
|
||||
// read from scandoubler buffer at twice QL pixel clock
|
||||
reg [2:0] sd_pixel;
|
||||
reg [2:0] sd_buffer_out;
|
||||
always @(posedge clk_vga) begin
|
||||
sd_buffer_out <= sd_buffer[{~sd_toggle, sd_h_cnt[8:0]}];
|
||||
if((sd_h_cnt > 1) && (sd_h_cnt <= H)) sd_pixel <= sd_buffer_out;
|
||||
else sd_pixel <= 3'b000;
|
||||
end
|
||||
// sd_pixel <= (sd_h_cnt < H)?sd_buffer[{~sd_toggle, sd_h_cnt[8:0]}]:3'b000;
|
||||
// sd_buffer_out <= sd_buffer[{~sd_toggle, sd_h_cnt[8:0]}];
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* -------------------- video timing generation -------------------- */
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
// toggle between scandoubler hsync and ql hsync
|
||||
reg sd_hs, ql_hs;
|
||||
assign hs = scandoubler?sd_hs:ql_hs;
|
||||
|
||||
reg video_cycleD;
|
||||
reg [2:0] video_cycle_cnt;
|
||||
|
||||
// mode 8 supports hardware flashing
|
||||
reg flash_state;
|
||||
reg [5:0] flash_cnt;
|
||||
always @(posedge vs) begin
|
||||
if(flash_cnt == 25) begin
|
||||
flash_cnt <= 6'd0;
|
||||
flash_state <= !flash_state;
|
||||
end else
|
||||
flash_cnt <= flash_cnt + 6'd1;
|
||||
end
|
||||
|
||||
// horizontal pixel counter
|
||||
always@(posedge clk_video) begin
|
||||
// video cycle counter runs at pixel clock and
|
||||
// synchronous to video_cycle
|
||||
video_cycleD <= video_cycle;
|
||||
if(video_cycle && !video_cycleD)
|
||||
video_cycle_cnt <= 3'd0;
|
||||
else
|
||||
video_cycle_cnt <= video_cycle_cnt + 3'd1;
|
||||
|
||||
// make sure h counter runs synchronous to bus_cycle
|
||||
if(h_cnt==H+hfp+hsw+hbp-1) begin
|
||||
if(video_cycle_cnt == 6)
|
||||
h_cnt <= 0;
|
||||
end else
|
||||
h_cnt <= h_cnt + 1;
|
||||
|
||||
// generate negative hsync signal
|
||||
if(h_cnt == H+hfp) ql_hs <= 1'b0;
|
||||
if(h_cnt == H+hfp+hsw) ql_hs <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
// veritical pixel counter
|
||||
always@(posedge clk_video) begin
|
||||
// the vertical counter is processed at the begin of each hsync
|
||||
if(h_cnt == H+hfp) begin
|
||||
if(v_cnt==V+vfp+vsw+vbp-1) v_cnt <= 0;
|
||||
else v_cnt <= v_cnt + 1;
|
||||
|
||||
// generate positive vsync signal
|
||||
if(v_cnt == V+vfp) vs <= 1'b1;
|
||||
if(v_cnt == V+vfp+vsw) vs <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
reg [15:0] video_din;
|
||||
reg [15:0] video_word;
|
||||
reg [2:0] ql_pixel;
|
||||
|
||||
always @(negedge video_cycle)
|
||||
video_din <= din;
|
||||
|
||||
// memory enable is 16 pixels ahead of display
|
||||
reg meV, me;
|
||||
always@(posedge clk_video) begin
|
||||
// the verical "memory enable" changes
|
||||
if(h_cnt == H+hfp+hsw+hbp-1-9) begin
|
||||
if(v_cnt == 0) meV <= 1'b1;
|
||||
if(v_cnt == V) meV <= 1'b0;
|
||||
end
|
||||
|
||||
if(meV) begin
|
||||
if(h_cnt == H+hfp+hsw+hbp-1-8) me <= 1'b1;
|
||||
if(h_cnt == H-1-8) me <= 1'b0;
|
||||
end
|
||||
|
||||
// mdv emulation may use the video bus cycle to read
|
||||
// data whenever video is not using the bus
|
||||
if(h_cnt == H-1) mdv_men <= 1'b1;
|
||||
if(h_cnt == H+31) mdv_men <= 1'b0;
|
||||
end
|
||||
|
||||
// 2BPP: G0,G1,G2,G3,G4,G5,G6,G7 R0,R1,R2,R3,R4,R5,R6,R7
|
||||
wire [1:0] pixel_code_2bpp = {video_word[15], video_word[7]};
|
||||
wire [2:0] pixel_color_2bpp =
|
||||
(pixel_code_2bpp == 0)?BLACK: // 0=black
|
||||
(pixel_code_2bpp == 1)?RED: // 1=red
|
||||
(pixel_code_2bpp == 2)?GREEN: // 2=green
|
||||
WHITE; // 3=white
|
||||
|
||||
// 4BPP: G0,F0,G1,F1,G2,F2,G3,F3 R0,B0,R1,B1,R2,B2,R3,B3
|
||||
wire [2:0] pixel_code_4bpp = {video_word[15], video_word[7:6]};
|
||||
wire pixel_flash_toggle = video_word[14];
|
||||
|
||||
wire [2:0] pixel_color_4bpp =
|
||||
(flash_reg && flash_state)?flash_col: // flash to saved color
|
||||
(pixel_code_4bpp == 0)?BLACK: // 0=black
|
||||
(pixel_code_4bpp == 1)?BLUE: // 1=blue
|
||||
(pixel_code_4bpp == 2)?RED: // 2=red
|
||||
(pixel_code_4bpp == 3)?MAGENTA: // 3=magenta
|
||||
(pixel_code_4bpp == 4)?GREEN: // 4=green
|
||||
(pixel_code_4bpp == 5)?CYAN: // 5=cyan
|
||||
(pixel_code_4bpp == 6)?YELLOW: // 6=yellow
|
||||
WHITE; // 7=white
|
||||
|
||||
reg flash_reg;
|
||||
reg [2:0] flash_col;
|
||||
always@(posedge clk_video) begin
|
||||
if(h_cnt == H+1)
|
||||
flash_reg <= 1'b0; // reset flash state at the begin of each line
|
||||
|
||||
if((v_cnt == V+1) && (h_cnt == H+1))
|
||||
addr <= membase?19'h14000:19'h10000; // word! address
|
||||
|
||||
if((me)&&(h_cnt[2:0] == 3'b111)) begin
|
||||
addr <= addr + 19'd1;
|
||||
video_word <= video_din;
|
||||
end else begin
|
||||
if(mode) begin
|
||||
// 4bpp: shift rgbf every second pixel clock
|
||||
if(h_cnt[0])
|
||||
video_word <= { video_word[13:8], 2'b00, video_word[5:0], 2'b00 };
|
||||
end else
|
||||
// 2bpp, shift green byte and red byte up one pixel
|
||||
video_word <= { video_word[14:8], 1'b0, video_word[6:0], 1'b0 };
|
||||
end
|
||||
|
||||
// visible area?
|
||||
if((v_cnt < V) && (h_cnt < H)) begin
|
||||
if(mode) begin
|
||||
ql_pixel <= pixel_color_4bpp;
|
||||
|
||||
// change state of flash_reg if flasg bit in current pixel is set
|
||||
// do this in the second half of the pixel so it's valid afterwards for the
|
||||
// next pixels. the current pixel directly honours pixel_flash_toggle
|
||||
if(h_cnt[0] && pixel_flash_toggle) begin
|
||||
flash_reg <= !flash_reg;
|
||||
flash_col <= pixel_color_4bpp;
|
||||
end
|
||||
end else
|
||||
ql_pixel <= pixel_color_2bpp;
|
||||
end else
|
||||
// black pixel outside active area
|
||||
ql_pixel <= 4'h0;
|
||||
end
|
||||
|
||||
wire [2:0] pixel = blank?3'b000:scandoubler?sd_pixel:ql_pixel;
|
||||
|
||||
// the current line is a scanline if the scandoubler is being used, if
|
||||
// scanlines are emnabled and if it's a scanline
|
||||
wire is_scanline = scandoubler && scanlines && sd_scanline;
|
||||
assign r = {(is_scanline?1'b0:pixel[2]), {5{pixel[2]}}};
|
||||
assign g = {(is_scanline?1'b0:pixel[1]), {5{pixel[1]}}};
|
||||
assign b = {(is_scanline?1'b0:pixel[0]), {5{pixel[0]}}};
|
||||
|
||||
endmodule
|
||||
244
cores/ql/zx8302.v
Normal file
244
cores/ql/zx8302.v
Normal file
@@ -0,0 +1,244 @@
|
||||
//
|
||||
// zx8302.v
|
||||
//
|
||||
// ZX8302 for Sinclair QL for the MiST
|
||||
// https://github.com/mist-devel
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
module zx8302 (
|
||||
input clk, // 21 mhz
|
||||
input reset,
|
||||
input init,
|
||||
|
||||
// interrupts
|
||||
output [2:0] ipl,
|
||||
|
||||
// sdram interface for microdrive emulation
|
||||
output [24:0] mdv_addr,
|
||||
input [15:0] mdv_din,
|
||||
output mdv_read,
|
||||
input mdv_men,
|
||||
input video_cycle,
|
||||
|
||||
// interface to watch MDV cartridge upload
|
||||
input [24:0] mdv_dl_addr,
|
||||
input mdv_download,
|
||||
|
||||
output led,
|
||||
|
||||
// vertical synv
|
||||
input vs,
|
||||
|
||||
input ps2_kbd_clk,
|
||||
input ps2_kbd_data,
|
||||
|
||||
// bus interface
|
||||
input clk_bus,
|
||||
input cpu_sel,
|
||||
input cpu_wr,
|
||||
input [1:0] cpu_addr, // a[5,1]
|
||||
input [1:0] cpu_ds,
|
||||
input [15:0] cpu_din,
|
||||
output [15:0] cpu_dout
|
||||
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// ----------------------------- CPU register write --------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
reg [7:0] mctrl;
|
||||
reg ipc_bit_strobe;
|
||||
wire ipc_reply_bit;
|
||||
|
||||
// cpu is writing io registers
|
||||
always @(negedge clk_bus) begin
|
||||
irq_ack <= 5'd0;
|
||||
ipc_bit_strobe <= 1'b0;
|
||||
|
||||
// cpu writes to 0x18XXX area
|
||||
if(cpu_sel && cpu_wr) begin
|
||||
// even addresses have lds=0 and use the lower 8 data bus bits
|
||||
if(!cpu_ds[1]) begin
|
||||
// cpu writes microdrive control register
|
||||
if(cpu_addr == 2'b10)
|
||||
mctrl <= cpu_din[15:8];
|
||||
end
|
||||
|
||||
// odd addresses have lds=0 and use the lower 8 data bus bits
|
||||
if(!cpu_ds[0]) begin
|
||||
// 18003 - IPCWR
|
||||
// (host sends a single bit to ipc)
|
||||
if(cpu_addr == 2'b01) begin
|
||||
// data is ----XEDS
|
||||
// S = start bit (should be 0)
|
||||
// D = data bit (0/1)
|
||||
// E = stop bit (should be 1)
|
||||
// X = extra stopbit (should be 1)
|
||||
|
||||
// QL will always write 11D0 here with one exception: At startup it sends
|
||||
// one single bit through the start bit by writing 0001. Thus we ignore
|
||||
// anything which doesn't match the 11D0 pattern
|
||||
if((cpu_din[3:2]== 2'b11)&&(cpu_din[0]==1'b0))
|
||||
ipc_bit_strobe <= 1'b1;
|
||||
end
|
||||
|
||||
// cpu writes interrupt register
|
||||
if(cpu_addr == 2'b10) begin
|
||||
irq_mask <= cpu_din[7:5];
|
||||
irq_ack <= cpu_din[4:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// ----------------------------- CPU register read ---------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
// status register read
|
||||
// bit 0 Network port
|
||||
// bit 1 Transmit buffer full
|
||||
// bit 2 Receive buffer full
|
||||
// bit 3 Microdrive GAP
|
||||
// bit 4 SER1 DTR
|
||||
// bit 5 SER2 CTS
|
||||
// bit 6 IPC busy
|
||||
// bit 7 COMDATA
|
||||
|
||||
wire [7:0] io_status = { ipc_reply_bit, ipc_busy, 2'b00,
|
||||
mdv_gap, mdv_rx_ready, mdv_tx_empty, 1'b0 };
|
||||
|
||||
assign cpu_dout =
|
||||
// 18000/18001 and 18002/18003
|
||||
(cpu_addr == 2'b00)?rtc[46:31]:
|
||||
(cpu_addr == 2'b01)?rtc[30:15]:
|
||||
|
||||
// 18020/18021 and 18022/18023
|
||||
(cpu_addr == 2'b10)?{io_status, irq_pending}:
|
||||
(cpu_addr == 2'b11)?{mdv_byte, mdv_byte}:
|
||||
|
||||
16'h0000;
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- IPC --------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
ipc ipc (
|
||||
.reset ( reset ),
|
||||
.clk_bus ( clk_bus ),
|
||||
|
||||
.ipc_bit_strobe ( ipc_bit_strobe ),
|
||||
.ipc_bit ( cpu_din[1] ),
|
||||
.ipc_reply_bit ( ipc_reply_bit ),
|
||||
.ipc_busy ( ipc_busy ),
|
||||
|
||||
.ps2_kbd_clk ( ps2_kbd_clk ),
|
||||
.ps2_kbd_data ( ps2_kbd_data )
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- IRQs -------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire [7:0] irq_pending = {1'b0, (mdv_sel == 0), clk64k,
|
||||
1'b0, vsync_irq, 1'b0, 1'b0, gap_irq };
|
||||
reg [2:0] irq_mask;
|
||||
reg [4:0] irq_ack;
|
||||
|
||||
|
||||
// any pending irq raises ipl to 2
|
||||
assign ipl = (irq_pending[4:0] == 0)?3'b111:3'b101;
|
||||
|
||||
// vsync irq is set whenever vsync rises
|
||||
reg vsync_irq;
|
||||
wire vsync_irq_reset = reset || irq_ack[3];
|
||||
always @(posedge vs or posedge vsync_irq_reset) begin
|
||||
if(vsync_irq_reset) vsync_irq <= 1'b0;
|
||||
else vsync_irq <= 1'b1;
|
||||
end
|
||||
|
||||
// toggling the mask will also trigger irqs ...
|
||||
wire gap_irq_in = mdv_gap && irq_mask[0];
|
||||
reg gap_irq;
|
||||
wire gap_irq_reset = reset || irq_ack[0];
|
||||
always @(posedge gap_irq_in or posedge gap_irq_reset) begin
|
||||
if(gap_irq_reset) gap_irq <= 1'b0;
|
||||
else gap_irq <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// ----------------------------------- microdrive ----------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
wire mdv_gap;
|
||||
wire mdv_tx_empty;
|
||||
wire mdv_rx_ready;
|
||||
wire [7:0] mdv_byte;
|
||||
|
||||
assign led = !mdv_sel[0];
|
||||
|
||||
mdv mdv (
|
||||
.clk ( clk ),
|
||||
.reset ( init ),
|
||||
|
||||
.sel ( mdv_sel[0] ),
|
||||
|
||||
// control bits
|
||||
.gap ( mdv_gap ),
|
||||
.tx_empty ( mdv_tx_empty ),
|
||||
.rx_ready ( mdv_rx_ready ),
|
||||
.dout ( mdv_byte ),
|
||||
|
||||
.download ( mdv_download ),
|
||||
.dl_addr ( mdv_dl_addr ),
|
||||
|
||||
// ram interface to read image
|
||||
.mem_ena ( mdv_men ),
|
||||
.mem_cycle( video_cycle ),
|
||||
.mem_clk ( clk_bus ),
|
||||
.mem_addr ( mdv_addr ),
|
||||
.mem_read ( mdv_read ),
|
||||
.mem_din ( mdv_din )
|
||||
);
|
||||
|
||||
// the microdrive control register mctrl generates the drive selection
|
||||
reg [7:0] mdv_sel;
|
||||
|
||||
always @(negedge mctrl[1])
|
||||
mdv_sel <= { mdv_sel[6:0], mctrl[0] };
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// -------------------------------------- RTC --------------------------------------
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
// PLL for the real time clock (rtc)
|
||||
reg [46:0] rtc;
|
||||
always @(posedge clk64k)
|
||||
rtc <= rtc + 47'd1;
|
||||
|
||||
wire clk64k;
|
||||
pll_rtc pll_rtc (
|
||||
.inclk0(clk),
|
||||
.c0(clk64k) // 65536Hz
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user