---------------------------------------------------------------------------------------------------
-- TOP_FPGA.VHD
-- (C) 2025 JAPAN LOGIC DESIGN 日本ロジック設計
-- No unauthorized reproduction or AI training allowed.
-- Unauthorized reproduction prohibited.
---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
-- Ver : Date		: Description
-- 0.1 : 2026.01.01	: 1st Version
-- 0.2 : 2026.01.12	: FPGA-CLOCK:50MHz, シリアル通信:460800 BPS
---------------------------------------------------------------------------------------------------
-- 概要：	FPGA全体のTOPロジック
-- 
---------------------------------------------------------------------------------------------------

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

-- エンティティ宣言 -------------------------------------------------------------------------------

entity TOP_FPGA is
port (
	-- システム
	nRESET				: in	std_logic;						-- nRESET
	CLK_IN				: in	std_logic;						-- CLOCK 12MHz
	SWITCH_RES_IN		: in	std_logic;						-- RESET用スイッチ(正論理)
	-- UART
	UART_RX				: in	std_logic;
	UART_TX				: out	std_logic;
	-- ロジアナ入力
	LOGIC_ANALYZER_IN	: in	std_logic_vector(14 downto 0);
	-- LED
	LED_ONOFF_OUT		: out std_logic							-- ロジック動作中LED
);
end TOP_FPGA;

architecture RTL of TOP_FPGA is ------------------------------------------------------

-- 固定値定義 -------------------------------------------------------------------------------------
-- LED 1秒点滅分周比
--	50MHz/2-1 = 24999999d = 17D783Fh
	constant	LED_BLINK_DIV	: std_logic_vector(31 downto 0)	:= X"017D783F";
-- RESET-SW用チャタリング除去分周比
--	ノイズ除去時間:100mS, 50MHz/10Hz-1 = 4999999d = 4C4B3Fh
	constant	REDUCTION_TIME	: std_logic_vector(23 downto 0)	:= X"4C4B3F";

-- 信号定義 ---------------------------------------------------------------------------------------
-- 一般信号 -------------------------------------
signal CLK_MMCM			: std_logic;
signal PLL_LOCKED		: std_logic;
signal pRESET			: std_logic;
signal nRESET_2			: std_logic;
signal RESET_C			: std_logic_vector(7 downto 0);
signal SWITCH_RES_OUT	: std_logic;
signal SIG_IN_DATA		: std_logic_vector(15 downto 0);
signal LED_ONOFF_OUT_f	: std_logic;

signal DUMMY_WAVE_C		: std_logic_vector(4 downto 0);
signal DUMMY_WAVE_F		: std_logic;

-- 使用モジュール宣言 -----------------------------------------------------------------------------

-- MMCM(PLL) ------------------------------------
component clk_wiz_0
port (
	clk_out1			: out	std_logic;
	reset				: in	std_logic;
	locked				: out	std_logic;
	clk_in1				: in	std_logic
);
end component ;

-- ロジックアナライザー -------------------------
component TOP_A7_LOGIC_ANALYZER
port(
	-- システム
	nRESET				: in	std_logic;						-- nRESET
	CLK_IN				: in	std_logic;						-- CLOCK 12MHz
	-- 波形入力
	SIG_IN_DATA			: in	std_logic_vector(15 downto 0);	-- 波形入力
	-- UART
	UART_RX				: in	std_logic;
	UART_TX				: out	std_logic
);
end component ;

-- LED点滅ロジック ------------------------------
component LED_BLINK
port(
	-- システム
	nRESET			: in	std_logic;						-- Reset
	CLK_IN			: in	std_logic;						-- Clock
	-- データ
	LED_BLINK_DIV	: in	std_logic_vector(31 downto 0);	-- 点滅周期指定
	LED_ONOFF_OUT	: out	std_logic						-- LED ON/OFF OUT
);
end component ;

-- ノイズ除去ロジック ---------------------------
component NOISE_REDUCTION
port(
	-- システム
	nRESET				: in std_logic;
	CLK_IN				: in std_logic;						-- CLOCK
	-- 時間指定
	REDUCTION_TIME		: in std_logic_vector(23 downto 0);	-- ノイズ除去時間
	-- 初期値指定
	NOISE_DEFAULT		: in std_logic;						-- 初期値指定 正論理='0'、負論理='1' 推奨
	-- 入出力
	NOISE_REDUC_IN		: in std_logic;						-- 元信号入力
	NOISE_REDUC_OUT		: out std_logic						-- ノイズ除去後の信号出力
);
end component ;

begin ---------------------------------------------------------------------------------------------

-- モジュール読み出し -----------------------------------------------------------------------------

-- MMCM(PLL)モジュール --------------------------
m_clk_wiz_0 : clk_wiz_0
port map(
	clk_out1			=> CLK_MMCM,
	reset				=> pRESET,			-- 正規RESET(正論理)
	locked				=> PLL_LOCKED,
	clk_in1				=> CLK_IN
);
-- RESET 正論理
	pRESET	<= not nRESET;	-- 正規RESET

-- ロジックアナライザー -------------------------
m_TOP_A7_LOGIC_ANALYZER : TOP_A7_LOGIC_ANALYZER
port map(
	-- システム
	nRESET				=> nRESET_2,		-- nRESET-2
	CLK_IN				=> CLK_MMCM,
	-- 波形入力
	SIG_IN_DATA			=> SIG_IN_DATA,
	-- UART
	UART_RX				=> UART_RX,
	UART_TX				=> UART_TX
);

-- LED点滅ロジック ------------------------------
m_LED_BLINK : LED_BLINK
port map(
	-- システム
	nRESET				=> nRESET_2,		-- nRESET-2
	CLK_IN				=> CLK_MMCM,
	-- データ
	LED_BLINK_DIV		=> LED_BLINK_DIV,
	LED_ONOFF_OUT		=> LED_ONOFF_OUT_f
);

-- ノイズ除去ロジック ---------------------------
m_NOISE_REDUCTION : NOISE_REDUCTION
port map(
	-- システム
	nRESET				=> nRESET,			-- 正規RESET
	CLK_IN				=> CLK_MMCM,
	-- 時間指定
	REDUCTION_TIME		=> REDUCTION_TIME,
	-- 初期値指定
	NOISE_DEFAULT		=> '0',
	-- 入出力
	NOISE_REDUC_IN		=> SWITCH_RES_IN,	-- スイッチ入力(正論理)
	NOISE_REDUC_OUT		=> SWITCH_RES_OUT	-- チャタリング除去後の信号
);

-- ロジック本体 -----------------------------------------------------------------------------------

	---------------------------------------------
	-- ロジアナ入力接続
	---------------------------------------------
	-- CH00 : ダミー波形
	SIG_IN_DATA(0)				<= DUMMY_WAVE_F;
	-- CH01-15 : 外部入力端子
	SIG_IN_DATA( 15 downto 1 )	<= LOGIC_ANALYZER_IN( 14 downto 0 );

	---------------------------------------------
	-- ダミー波形生成 (1MHz)
	---------------------------------------------
	process ( CLK_MMCM ) begin
		if ( CLK_MMCM'event and CLK_MMCM = '1' ) then	-- '
			if ( nRESET_2 = '0' ) then
				DUMMY_WAVE_C(4 downto 0)	<= (others => '0');
				DUMMY_WAVE_F				<= '0';
			-- MAX
			elsif ( DUMMY_WAVE_C = "11000" ) then				-- 50MHz/25=2MHzで反転=1MHz
				DUMMY_WAVE_C(4 downto 0)	<= (others => '0');
				DUMMY_WAVE_F				<= not DUMMY_WAVE_F;
			-- +1
			else
				DUMMY_WAVE_C(4 downto 0)	<= DUMMY_WAVE_C(4 downto 0) +1;
				DUMMY_WAVE_F				<= DUMMY_WAVE_F;
			end if;
		end if;
	end process;

	---------------------------------------------
	-- RESET
	---------------------------------------------
	-- nRESET が本来のRESET入力。ただし基板にRESET-ICがついていないため、内蔵PULL-UPで '1' 固定。
	-- SWITCH_RES_OUT は、基板上のスイッチのチャタリングを取り除いた信号。
	-- この２つを合成してメインロジックのRESETとする。
	process ( CLK_MMCM ) begin
		if ( CLK_MMCM'event and CLK_MMCM = '1' ) then	-- '
			-- RESET
			if ( nRESET = '0' ) then						-- 負論理
				RESET_C(7 downto 0)	<= (others => '0');
				nRESET_2			<= '0';
			elsif ( SWITCH_RES_OUT = '1' )  then			-- 正論理
				RESET_C(7 downto 0)	<= (others => '0');
				nRESET_2			<= '0';
			-- END
			elsif ( RESET_C(7 downto 0) = X"CC" )  then
				RESET_C(7 downto 0)	<= RESET_C(7 downto 0);
				nRESET_2			<= '1';
			-- +1
			else
				RESET_C(7 downto 0)	<= RESET_C(7 downto 0) + 1 ;
				nRESET_2			<= '0';
			end if;
		end if;
	end process;

-- 出力 -------------------------------------------------------------------------------------------
	LED_ONOFF_OUT	<= LED_ONOFF_OUT_f;		-- 点滅LED

-- END --------------------------------------------------------------------------------------------
-- (C) 2025 JAPAN LOGIC DESIGN 日本ロジック設計
-- No unauthorized reproduction or AI training allowed.
-- Unauthorized reproduction prohibited.
end RTL;

