----------------------------------------------------------------------------------
-- マルツ電子株式会社
--
-- 　　　　【MFPGA-BASE】　　FPGAトレーニング用学習ベースボード 
-- 
-- 　　　　　　機能検証用　サンプルコード
--
-- 設計言語	: VHDL言語
-- FPGA名	: 米国ザイリンクス社　XC3S250E-VQ100
-- 設計日	: 2009年2月14日
-- 提供日	: 2009年4月10日
-- バージョン	: 1.0.0
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Module_TOP is

	port (
	--**** System signals **** --
		SysCLK_in			: in	std_logic ;				-- 10.000MHz oscillator
		nSysRST_in			: in	std_logic ;
		
	--**** I/O function ****--
	--**** 7segment LED **** --
		SEG7_Digit1_out		: out	std_logic_vector(8 downto 1) ;
		SEG7_Digit2_out		: out	std_logic_vector(8 downto 1) ;
		SEG7_Digit3_out		: out	std_logic_vector(8 downto 1) ;
		SEG7_Digit4_out		: out	std_logic_vector(8 downto 1) ;
		
	--**** SWITCH **** --
		PUSHSW_in			: in	std_logic_vector(4 downto 1) ;
		DIPSW_in			: in	std_logic_vector(4 downto 1) ;
		
	--**** I/O PORT **** --
--		PORT_in				: in	std_logic_vector(7 downto 0) ;
		PORT_in				: in	std_logic_vector(7 downto 4) ;
--		PORT_out			: out	std_logic_vector(7 downto 0) ;
		PORT_out			: out	std_logic_vector(7 downto 2) ;
		nDAC_ENB			: out	std_logic ;							-- D/A convertor output enable
		
	--**** RS232 UART ****--
--		RxD_in				: in	std_logic ;
		TxD_out				: out	std_logic ;
		nTxD_Ready			: out	std_logic
	) ;

end Module_TOP;

architecture Behavioral of Module_TOP is

	constant	FPGA_is_XILINX	: integer := 1 ;			-- Board specification.

--*****************************************************************************************--
--**** General signals ****--
	constant	Always_H		: std_logic := '1' ;
	constant	Always_L		: std_logic := '0' ;
	signal		SysRST_in		: std_logic ;

--*****************************************************************************************--
--**** Timing generator ****--
constant	Seg7_Inclement_rate	: std_logic_vector(23 downto 0) := x"100000" ;
constant	DAC_Inclement_rate	: std_logic_vector(23 downto 0) := x"000010" ;

component Module_Freq_div is
	port (
	--**** System signals **** --
		SysCLK_in			: in	std_logic ;				-- 10.000MHz oscillator
		SysRST_in			: in	std_logic ;
		
		DIV_rate			: in	std_logic_vector(23 downto 0) ;
		
		SysOSC_out			: out	std_logic
	) ;
end component ;

	signal	Seg7_CntEnb_Timing	: std_logic ;
	signal	DAC_IncEnb_Timing	: std_logic ;

--*****************************************************************************************--
--**** 7segment LED **** --
	constant	SEG7_porarity	: std_logic := '0' ;	-- 0 : Active-L Light

component module_7seg_x4 is
	port (
	--**** Hexa-decimal data input ****--
		HEX_Data1_in	: in	std_logic_vector(3 downto 0) ;
		HEX_Data2_in	: in	std_logic_vector(3 downto 0) ;
		HEX_Data3_in	: in	std_logic_vector(3 downto 0) ;
		HEX_Data4_in	: in	std_logic_vector(3 downto 0) ;

		SEG7_porarity	: in	std_logic ;				-- 1 : H-Light, 0 : L-Light
		
	--**** 7segment array output ****--
		Seg_Data1_out	: out	std_logic_vector(7 downto 0) ;
		Seg_Data2_out	: out	std_logic_vector(7 downto 0) ;
		Seg_Data3_out	: out	std_logic_vector(7 downto 0) ;
		Seg_Data4_out	: out	std_logic_vector(7 downto 0)
	) ;
end component ;

	signal	int_PORT_in			: std_logic_vector(7 downto 0) ;

	signal	Seg7_Digit1_Value	: std_logic_vector(3 downto 0) ;
	signal	Seg7_Digit2_Value	: std_logic_vector(3 downto 0) ;
	signal	Seg7_Digit3_Value	: std_logic_vector(3 downto 0) ;
	signal	Seg7_Digit4_Value	: std_logic_vector(3 downto 0) ;
	
	signal	Seg7_Counter		: std_logic_vector(15 downto 0) ;
	
--*****************************************************************************************--
-- SWITCHs
	constant	PUSHSW_porarity	: std_logic := '1' ;	-- 1 : Active-H.

component Module_PUSHsw_sync4 is
	port (
		SysCLK_in		: in	std_logic ;
		SysRST_in		: in	std_logic ;
		
		PUSHSW_in		: in	std_logic_vector(4 downto 1) ;
		PUSHSW_porarity	: in	std_logic ;							-- 1 : Active-H, 0 : Active-L
		
	--********--
		PUSHSW_out		: out	std_logic_vector(4 downto 1) ;
		PUSHSW_H_edge	: out	std_logic_vector(4 downto 1) ;
		PUSHSW_L_edge	: out	std_logic_vector(4 downto 1)
	) ;
end component ;

	signal	PUSHSW_4to1_H_edge : std_logic_vector(4 downto 1) ;

--*****************************************************************************************--
-- R-2R radder D/A test
component Module_WaveGenerator is
	port (
		SysCLK_in		: in	std_logic ;
		SysRST_in		: in	std_logic ;
		
		STEP_in			: in	std_logic_vector(7 downto 0) ;	-- Adder step
		STEP_IncEnb_in	: in	std_logic ;						-- Inclement Enable
		
		WaveType_in		: in	std_logic_vector(1 downto 0) ;	-- %00 : SIN wave
																-- %10 : Triangle wave
																-- %10 : Sawtooth wave ( Inclement )
																-- %11 : Sawtooth wave ( Declement )
																
		WaveOut			: out	std_logic_vector(7 downto 0)
	) ;
end component;

	signal	DAC_STEP_in		: std_logic_vector(7 downto 0) ;
	signal	DAC_WaveOut		: std_logic_vector(7 downto 0) ;
	
--*****************************************************************************************--
--**** RS-232C transmitter function ****--
component Module_TxBlock is
	port(
		SysCLK_in		: in	std_logic ;							-- System clock
		SysRST_in		: in	std_logic ;							-- System reset
		
		TxDataWen_i		: in	std_logic ;							-- Transmit data write strobe
		TxData_i		: in	std_logic_vector(7 downto 0) ;		-- Transmit 8bits data

		TxD_o			: out	std_logic ;							-- TxD port
		TxRdy_o			: out	std_logic							-- Transmitter ready flag
	);
end component ;

	signal	TxData_Wen_i	: std_logic ;
	signal	TxRdy_out		: std_logic ;
	
begin

--*****************************************************************************************--
--**** General signals ****--
	SysRST_in	<= not nSysRST_in ;

--*****************************************************************************************--
--**** Timing generator ****--
u_FreqDiv_Seg7 : Module_Freq_div
	port map (
	--**** System signals **** --
		SysCLK_in		=> SysCLK_in ,
		SysRST_in		=> SysRST_in ,
			
		DIV_rate		=> Seg7_Inclement_rate(23 downto 0) ,
		
		SysOSC_out		=> Seg7_CntEnb_Timing
	) ;

u_FreqDiv_WaveGen : Module_Freq_div
	port map (
	--**** System signals **** --
		SysCLK_in		=> SysCLK_in ,
		SysRST_in		=> SysRST_in ,
			
		DIV_rate		=> DAC_Inclement_rate(23 downto 0) ,
		
		SysOSC_out		=> DAC_IncEnb_Timing
	) ;

--*****************************************************************************************--
--**** 7segment LED **** --
	int_PORT_in(7 downto 4) <= PORT_in(7 downto 4) ;			-- XILINX mode.
	int_PORT_in(3 downto 0) <= PORT_in(7 downto 4) ;			-- XILINX mode.

--	int_PORT_in(7 downto 4) <= PORT_in(7 downto 4) ;			-- ALTERA / LATTICE mode.
--	int_PORT_in(3 downto 0) <= PORT_in(3 downto 0) ;			-- ALTERA / LATTICE mode.

	Seg7_Digit4_Value	<= Seg7_Counter(15 downto 12)	when ( DIPSW_in(1) = '1' ) else
						   int_PORT_in(7 downto 4) ;

	Seg7_Digit3_Value	<= Seg7_Counter(11 downto 8)	when ( DIPSW_in(1) = '1' ) else
						   int_PORT_in(3 downto 0) ;

	Seg7_Digit2_Value	<= Seg7_Counter(7 downto 4) ;

	Seg7_Digit1_Value	<= Seg7_Counter(3 downto 0) ;

Seg7_DispOut_counter : process ( SysCLK_in )
begin
	if ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( SysRST_in = '1' ) then
			Seg7_Counter <= ( others => '0' ) ;
		else
			if ( DIPSW_in(1) = '1' ) then
				if ( PUSHSW_4to1_H_edge(1) = '1' ) then
					Seg7_Counter( 3 downto  0) <= Seg7_Counter( 3 downto  0) + 1 ;
				end if ;
				if ( PUSHSW_4to1_H_edge(2) = '1' ) then
					Seg7_Counter( 7 downto  4) <= Seg7_Counter( 7 downto  4) + 1 ;
				end if ;
				if ( PUSHSW_4to1_H_edge(3) = '1' ) then
					Seg7_Counter(11 downto  8) <= Seg7_Counter(11 downto  8) + 1 ;
				end if ;
				if ( PUSHSW_4to1_H_edge(4) = '1' ) then
					Seg7_Counter(15 downto 12) <= Seg7_Counter(15 downto 12) + 1 ;
				end if ;
			else
				if ( Seg7_CntEnb_Timing = '1' ) then
					Seg7_Counter( 7 downto 0) <= Seg7_Counter( 7 downto 0) + 1 ;			-- Auto inclement.
					Seg7_Counter(15 downto 8) <= ( others => '0' ) ;						-- Refresh
				end if ;
			end if ;
		end if ;
	end if ;
end process ;

u_7Seg_digit_1 : module_7seg_x4
	port map (
	--**** Hexa-decimal data input ****--
		HEX_Data1_in	=> Seg7_Digit1_Value ,
		HEX_Data2_in	=> Seg7_Digit2_Value ,
		HEX_Data3_in	=> Seg7_Digit3_Value ,
		HEX_Data4_in	=> Seg7_Digit4_Value ,
		
		SEG7_porarity	=> SEG7_porarity ,		-- 1 : H-Light, 0 : L-Light
		
	--**** 7segment array output ****--
		Seg_Data1_out	=> SEG7_Digit1_out ,
		Seg_Data2_out	=> SEG7_Digit2_out ,
		Seg_Data3_out	=> SEG7_Digit3_out ,
		Seg_Data4_out	=> SEG7_Digit4_out
	) ;

--*****************************************************************************************--
--**** SWITCHs --
u_PUSHSW_sync : Module_PUSHsw_sync4
	port map (
		SysCLK_in		=> SysCLK_in ,
		SysRST_in		=> SysRST_in ,
		
		PUSHSW_in		=> PUSHSW_in(4 downto 1) ,
		PUSHSW_porarity	=> PUSHSW_porarity ,							-- 1 : Active-H, 0 : Active-L
		
	--********--
		PUSHSW_out		=> open ,
		PUSHSW_H_edge	=> PUSHSW_4to1_H_edge ,
		PUSHSW_L_edge	=> open
	) ;

--*****************************************************************************************--
--**** I/O PORT **** --
-- R-2R radder D/A test
	u_mdl_WaveGen : Module_WaveGenerator
		port map (
			SysCLK_in		=> SysCLK_in ,
			SysRST_in		=> SysRST_in ,
			
			STEP_in			=> DAC_STEP_in(7 downto 0) ,			-- Adder step
			STEP_IncEnb_in	=> DAC_IncEnb_Timing ,					-- Inclement Enable
			
			WaveType_in		=> DIPSW_in(4 downto 3) ,				-- %00 : SIN wave
																				-- %01 : Triangle wave
																				-- %10 : Sawtooth wave ( Inclement )
																				-- %11 : Sawtooth wave ( Declement )
																	
			WaveOut			=> DAC_WaveOut(7 downto 0)
		) ;

	DAC_STEP_in	<= Seg7_Counter(7 downto 0) ; --  when ( DIPSW_in(1) = '1' ) else
--				   "00010000" ;

	PORT_out	<= DAC_WaveOut(7 downto 2)			when ( DIPSW_in(2) = '1' ) else		-- WaveGenerator signal out
				   Seg7_Digit4_Value(3 downto 0) & Seg7_Digit3_Value(3 downto 2) ;		-- 7Segment signal out

	nDAC_ENB	<= Always_L ;			-- Always asserted.

--*****************************************************************************************--
--**** RS232 UART ****--
u_TxBlock : Module_TxBlock
	port map (
		SysCLK_in		=> SysCLK_in ,								-- System clock
		SysRST_in		=> SysRST_in ,								-- System reset
		
		TxDataWen_i		=> TxData_Wen_i ,							-- Transmit data write strobe
		TxData_i		=> Seg7_Counter(15 downto 8) ,				-- Transmit 8bits data

		TxD_o			=> TxD_out ,								-- TxD port
		TxRdy_o			=> TxRdy_out								-- Transmitter ready flag
	);

TxOUT_Trigger : process ( SysCLK_in, SysRST_in )
begin
	if ( SysRST_in = '1' ) then
		TxData_Wen_i	<= '0' ;
	elsif ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( PUSHSW_4to1_H_edge(4 downto 3) /= "00" ) then			-- 1clock delay
			TxData_Wen_i	<= '1' ;
		else
			TxData_Wen_i	<= '0' ;
		end if ;
	end if ;
end process ;

	nTxD_Ready		<= not TxRdy_out ;
	
end Behavioral;

