----------------------------------------------------------------------------------
-- 
-- Copyright (C) 2010  Christoph Raab

-- This program 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 program 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/>. 

-- Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, 
-- wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß 
-- Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
-- Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber 
-- OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR 
-- EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
-- Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. 
-- Falls nicht, siehe <http://www.gnu.org/licenses/>. 

-- Create Date:    14:15:23 04/05/2010 
-- Design Name: 
-- Module Name:    bridgette - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.15 - ChipRegister & Latch für XC9500XL
-- Additional Comments: 
-- 
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
--
entity bridgette is
    Port ( PDL : inout  STD_LOGIC_VECTOR (15 downto 0);
           PDH : inout  STD_LOGIC_VECTOR (15 downto 0);
           CDL : inout  STD_LOGIC_VECTOR (15 downto 0);
           CDH : inout  STD_LOGIC_VECTOR (15 downto 0);
           XD : inout  STD_LOGIC_VECTOR (15 downto 0);
           XOEL : in  STD_LOGIC;
           XOEH : in  STD_LOGIC;
           XSTORED : in  STD_LOGIC;
           XCLK : in  STD_LOGIC;
           XDIR : in  STD_LOGIC;
           CBR : in  STD_LOGIC;
           CBR_DIR : in  STD_LOGIC;
           CDIR : in  STD_LOGIC;
           CLATCH : in  STD_LOGIC;
           COE : in  STD_LOGIC);
end bridgette;

architecture Behavioral of bridgette is

shared variable PDL_MUX,CDL_MUX,CDH_MUX,XD_MUX: STD_LOGIC_VECTOR (1 downto 0); -- Variablen für die Multiplexer 
shared variable PDH_MUX:  STD_LOGIC_VECTOR (2 downto 0); -- Variablen für die Multiplexer 

--shared variable coolrunner: STD_LOGIC := '0'; -- Auswahl zwischen Coolrunner und XC9500XL

--signal CDSTOREH, CDSTOREL, XSTORE: STD_LOGIC_VECTOR (15 downto 0);  -- Latches für Chipdata und Zorro-Data
signal CDSTOREH, CDSTOREL : STD_LOGIC_VECTOR (15 downto 0);  -- Latches für Chipdata und Zorro-Data
signal CBR_LATCH,CBR_DIR_LATCH: STD_LOGIC; -- Latches für CBR und CBR_DIR Signal

begin

process(CLATCH) -- prozess für Latch Chipdata
--process
begin
		if CLATCH='1' then --and CDIR='1' and COE='0' then -- Inhalt des Latches wir aktualisiert, wenn CLATCH = 0
			CDSTOREH <= CDH;
			CDSTOREL <= CDL;
			CBR_LATCH <= CBR;
			CBR_DIR_LATCH <= CBR_DIR;
		end if;
--	wait for 1 ns;
end process;

--process(XCLK) -- prozess für Latch Zorro-Data
--begin
--	if rising_edge(XCLK) then -- Inhalt des Latches wird bei steigender XCLK Flanke aktualisiert
--		XSTORE <= XD;
--	end if;
--end process;

process(XD,XOEL,XOEH,XDIR,CBR,CBR_DIR,CDIR,CLATCH,COE,PDL,PDH,CDL,CDH,XD)
--process
begin

	-- Behandlung für CDL

	if COE='0' and CDIR='0' then
		if CBR='1' or (CBR='0' and CBR_DIR='0') then
		  CDL_MUX:="00"; -- wenn Ausgang an und Richtung P->C und (Bridge aus oder Bridge an und Richtung L->H), dann CDL<=PDL
		else
		  CDL_MUX:="01"; -- wenn Ausgang an und Richtung P->C und Bridge an und Richtung H->L), dann CDL<=PDH
		end if;
	else
		if (COE='1' and CBR='0' and CBR_DIR='1') or (COE='0' and CDIR='1' and CBR='0' and CBR_DIR='1') then
			CDL_MUX:="10"; -- wenn Ausgang aus und Bridge an und Bridge an und Richtung H->L, dann CDL<=CDH
		else
			CDL_MUX:="11"; -- alle anderen Fälle, dann CDL<=Z
		end if;
	end if;
	case CDL_MUX is
		when "00" => CDL <= PDL;
		when "01" => CDL <= PDH;
		when "10" => CDL <= CDH;
		when others => CDL <= (others => 'Z');
	end case;
	
	-- Behandlung für CDH
	--if XOEH='0' and XDIR='0' then
	--  CDH_MUX:="11"; -- alle anderen Fälle, dann CDL<=Z
	--else
		if COE='0' and CDIR='0' then
			if CBR='1' or (CBR='0' and CBR_DIR='1') then
			CDH_MUX:="00"; -- wenn Ausgang an und Richtung P->C und (Bridge aus oder Bridge an und Richtung L->H), dann CDH<=PDH
			else
			CDH_MUX:="01"; -- wenn Ausgang an und Richtung P->C und Bridge an und Richtung H->L), dann CDH<=PDL
			end if;
		else
			if (COE='1' and CBR='0' and CBR_DIR='0') or (COE='0' and CDIR='1' and CBR='0' and CBR_DIR='0') then
				CDH_MUX:="10"; -- wenn Ausgang aus und Bridge an und Bridge an und Richtung H->L, dann CDH<=CDL
			else
				CDH_MUX:="11"; -- alle anderen Fälle, dann CDL<=Z
			end if;
		end if;
	--end if;
	case CDH_MUX is
		when "00" => CDH <= PDH;
		when "01" => CDH <= PDL;
		when "10" => CDH <= CDL;
		when others => CDH <= (others => 'Z');
	end case;
	
	-- Behandlung für XD
	
	--if XOEL='0' and XDIR='1' then
	--	XD_MUX:="00"; -- wenn AusgangL an und Richtung P-> X, dann XD<=PDL;
	--else
	--	if XOEH='0' and XOEL='1' and XDIR='1' then
	--		XD_MUX:="01"; -- wenn AusgangH an und Richtung P-> X, dann XD<=PDL;
	--	else
	--		XD_MUX:="11"; -- alle anderen Fälle, dann XD<=Z
	--	end if;
	--end if;
	if XDIR='0' then
		XD_MUX:="11";	-- XDIR='0' -> Richtung XD -> PD, XD Eingänge
	else
		if XOEH='0' then
			XD_MUX:="11"; -- XDIR='1' und XOEH='0' -> PDH -> XD aber über Treiber, deshalb 'z'
		else
			if XOEL='0' and XDIR='1' then
				XD_MUX:="00"; -- XDIR='1' und XOEL='0' -> PDL -> XD
			else
				XD_MUX:="11"; -- sonst 'Z' -> XD;
			end if;
		end if;
	end if;
	case XD_MUX is
		when "00" => XD <= PDL;
		--when "01" => XD <= PDH;
		when others => XD <= (others => 'Z');
	end case;
	
	-- Behandlung für PDL
	
	if COE='0' and CDIR='1' then
			if CBR_LATCH='1' or CBR_DIR_LATCH='1' then
				PDL_MUX:="00"; -- wenn AusgangC an und Richtung C->P und CLatch=0, Bridge aus oder Bridge Richtung L->H dann PDL<=CDSTOREL;
			else
				PDL_MUX:="01"; -- wenn AusgangC an und Richtung C->P und CLatch=0, Bridge an und Bridge Richtung H->L dann PDL<=CDSTOREH;
			end if;
	else
		if XOEL='0' and XDIR='0' then
			PDL_MUX:="10"; -- wenn AusgangXL an und Richtung X->P, dann PDL<=XD;
		else
			PDL_MUX:="11"; -- sonst, PDL<=Z
		end if;	
	end if;
	case PDL_MUX is
		when "00" => PDL<=CDSTOREL;
		when "01" => PDL<=CDSTOREH;
		when "10" => PDL<=XD;
		when others => PDL<= (others => 'Z');
	end case;
	
	-- Behandlung für PDH
	if COE='0' and CDIR='1' then
			if CBR_LATCH='1' or CBR_DIR_LATCH='0' then
				PDH_MUX:="000"; -- wenn AusgangC an und Richtung C->P und CLatch=0, Bridge aus oder Bridge Richtung H->L dann PDH<=CDSTOREH;
			else
				PDH_MUX:="001"; -- wenn AusgangC an und Richtung C->P und CLatch=0, Bridge an und Bridge Richtung L->H dann PDH<=CDSTOREL;
			end if;
	else
--		if XOEH='0' and XDIR='0' then
--			if XSTORED='0' then
--				PDH_MUX:="010"; -- wenn AusgangXH an und Richtung X->P und Stored aus, dann PDH<=XD;
--			else
--				PDH_MUX:="011"; -- wenn AusgangXH an und Richtung X->P und Stored an, dann PDH<=XDstored;
--			end if;
--		else
			PDH_MUX:="111";
--		end if;
	end if;
	case PDH_MUX is
		when "000" => PDH<=CDSTOREH;
		when "001" => PDH<=CDSTOREL;
		--when "010" => PDH<=XD;
		--when "011" => PDH<=XSTORE;
		when others => PDH<=(others => 'Z');
	end case;
	
--	wait for 5 ns; -- für Simulation
	
end process;
end Behavioral;

