----------------------------------------------------------------------------------
-- マルツ電子株式会社
--
-- 　　　　【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_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
																-- %01 : Triangle wave
																-- %10 : Sawtooth wave ( Inclement )
																-- %11 : Sawtooth wave ( Declement )
																
		WaveOut			: out	std_logic_vector(7 downto 0)
	) ;
end Module_WaveGenerator;

architecture Behavioral of Module_WaveGenerator is

component module_sintable is
	port (
		SysCLK_in	: in	std_logic ;		-- Operation clock
		SysRST_in	: in	std_logic ;		-- System reset
		adrs		: in	std_logic_vector(13 downto 0) ;		-- Table address
		
		dout1		: out	std_logic_vector(15 downto 0) ;
								-- Sin(x) value. + range : 0x0000 - 0x7FFF, - range : 0x8000 - 0xFFFF. Signed.
		dout2		: out	std_logic_vector(15 downto 0)
								-- Sin(x) value. - range : 0x0000 - 0x7FFF, + range : 0x8000 - 0xFFFF. Unsigned.
	) ;
end component ;

	signal	AddressStep_adder		: std_logic_vector(15 downto 0) ;	-- 65536 step
	
	signal	mdl_sintabel_adrs		: std_logic_vector(13 downto 0) ;
	signal	mdl_sintabel_dout		: std_logic_vector(15 downto 0) ;
	
	signal	wave_triangle_value		: std_logic_vector(15 downto 0) ;
	signal	wave_sawtooth_value		: std_logic_vector(15 downto 0) ;
	
begin

--**************************************--
-- SINTABLE declare
	u_mdl_sintable : module_sintable
	port map (
		SysCLK_in		=> SysCLK_in ,
		SysRST_in		=> SysRST_in ,
		adrs			=> mdl_sintabel_adrs(13 downto 0) ,
		dout1			=> open ,
		dout2			=> mdl_sintabel_dout(15 downto 0)
	) ;

	mdl_sintabel_adrs	<= AddressStep_adder(15 downto 2) ;


--**************************************--
AdrsStep_equ : process ( SysCLK_in )
begin
	if ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( SysRST_in = '1' ) then
			AddressStep_adder	<= ( others => '0' ) ;
		else
			if ( STEP_IncEnb_in = '1' ) then
				AddressStep_adder	<= AddressStep_adder + ( "000000" & STEP_in & "00" ) ;	-- Address inclement
			else
				AddressStep_adder	<= AddressStep_adder ;			-- Hold
			end if ;
		end if ;
	end if ;
end process ;

--**************************************--
WAVE_triangle_equ : process ( SysCLK_in )
	variable	hld_AdrsStp15	: std_logic ;
begin
	if ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( SysRST_in = '1' ) then
			hld_AdrsStp15	:= '0' ;
			wave_triangle_value	<= ( others => '0' ) ;
		else
			hld_AdrsStp15	:= AddressStep_adder(15) ;
--			if ( STEP_IncEnb_in = '1' ) then
				if ( AddressStep_adder(15) = '0' ) then
					wave_triangle_value <=     AddressStep_adder(14 downto 0) & '0' ;
				else
					wave_triangle_value <= not AddressStep_adder(14 downto 0) & '0' ;
				end if ;
--			else												-- 090320 : Comment out
--				wave_triangle_value	<= ( others => '0' ) ;		-- 090320 : Comment out
--			end if ;
		end if ;
	end if ;
end process ;

--**************************************--
WAVE_sawtooth_equ : process ( SysCLK_in )
	variable	hld_AdrsStp15	: std_logic ;
begin
	if ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( SysRST_in = '1' ) then
			hld_AdrsStp15	:= '0' ;
			wave_sawtooth_value	<= ( others => '0' ) ;
		else
			hld_AdrsStp15	:= AddressStep_adder(15) ;
--			if ( STEP_IncEnb_in = '1' ) then
--				if ( hld_AdrsStp15 = '0' and AddressStep_adder(15) = '1' ) then
--					wave_sawtooth_value	<= ( others => '0' ) ;
--				else
--					wave_sawtooth_value <= wave_sawtooth_value + 1 ;
--				end if ;
--			else												-- 090320 : Comment out
--				wave_sawtooth_value	<= ( others => '0' ) ;		-- 090320 : Comment out
--			end if ;
			wave_sawtooth_value	<= AddressStep_adder(15 downto 0) ;
		end if ;
	end if ;
end process ;




--**************************************--
-- Wave_output
WAVEout_equ : process ( SysCLK_in )
begin
	if ( SysCLK_in'event and SysCLK_in = '1' ) then
		if ( SysRST_in = '1' ) then
			WaveOut	<= ( others => '0' ) ;
		else
			case WaveType_in is
				when "00" =>	WaveOut	<=		mdl_sintabel_dout(15 downto 8) ;
				when "01" =>	WaveOut	<=		wave_triangle_value(15 downto 8) ;
				when "10" =>	WaveOut	<=		wave_sawtooth_value(15 downto 8) ;
				when "11" =>	WaveOut	<= not	wave_sawtooth_value(15 downto 8) ;
				when others => null ;
			end case ;
		end if ;
	end if ;
end process ;

end Behavioral;

