library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity vcont is Port ( --デバグ用ピン clk_test : out std_logic; dump : out std_logic_vector(4 downto 0); --単なるNOT not_in :in std_logic; not_out : out std_logic; --コントロール信号(マイコン) sig_end : out std_logic; --取り込み終了 Go : in std_logic; --取り込み開始指示(読み込み終了までHiにしておくこと) --クロック入力 Clk : in std_logic; Vsync : in std_logic; Hsync : in std_logic; --RAM接続 R_we : out std_logic; --A/Dコンバータへのクロック信号を兼ねる R_re : out std_logic; R_add: inout std_logic_vector(15 downto 0); R_data: inout std_logic_vector(7 downto 0); --A/Dコンバータ AD_data: in std_logic_vector(7 downto 0); --データ取り出し(マイコン) M_data: out std_logic_vector(7 downto 0); M_rclk: in std_logic); end vcont; architecture Behavioral of vcont is type t_state is (st_ready,st_ready1,st_gowait,st_gowait1,st_gowait2,st_pre_rec,st_rec,st_rec_end,st_read,st_pre_hblank); signal cur_state : t_state; signal clk_count : std_logic_vector(1 downto 0); signal wait_count : std_logic_vector(7 downto 0); signal read_add : std_logic_vector(15 downto 0); signal add_clk :std_logic; signal write_clk:std_logic; signal zero_addr: std_logic; signal tHsync: std_logic; signal tVsync: std_logic; signal of_addr: std_logic; begin --ステート表示 --頭1桁が読み込み可能状態2桁目が録画中それ以降は適当 dump <= "00001" when cur_state=st_ready or cur_state=st_ready1 else "00010" when cur_state=st_gowait else "00011" when cur_state=st_gowait1 else "00100" when cur_state=st_gowait2 else "01000" when cur_state=st_pre_rec else "01001" when cur_state=st_rec else "01010" when cur_state=st_pre_hblank else "01011" when cur_state=st_rec_end else "10000" when cur_state=st_read else "00000"; clk_test <= M_rclk;--rclkがちゃんと届いていることを示すack(バッファ回路の遅延が大きいとき) not_out <= not not_in; --7404の代わり(キャプチャ回路で使用) M_data <= R_data; --データは常にスルーパス(電圧変換のため物理的に直結にしない) R_add <= read_add;--メモリに指定するアドレス --録画モードならばA/Dのデータを流し込む --ただし、A/Dコンバータから0xffが入力されたときは0xfeに置換 --(FFは1ライン取り込み完了のデリミタ) R_data <= "11111111" when cur_state=st_pre_hblank else "ZZZZZZZZ" when cur_state=st_read else "11111110" when cur_state=st_rec and AD_data = "11111111" else AD_data; --アドレス用クロック選択 --st_read(マイコンからの読み込み)の時外部クロック端子、それ以外の時は内部生成。 add_clk <= M_rclk when cur_state=st_read else write_clk; --アドレスカウンタzero_addr=1でリセット process (add_clk,zero_addr) begin if(zero_addr='1')then read_add <= X"0000"; of_addr <='0'; elsif(add_clk'event and add_clk = '1')then --アドレスインクリメント if(read_add = X"FFFF")then of_addr <='1'; else read_add <= read_add + '1'; end if; else end if; end process; process (clk,go) begin if(go ='0') then --リセット cur_state <= st_ready; elsif(clk'event and clk='1') then tHsync <= Hsync; tVsync <= Vsync; case cur_state is when st_ready => R_we <= '1'; R_re <= '0'; sig_end <= '0'; write_clk <='0'; cur_state <= st_ready1; when st_ready1 => --リセット状態 if(tVsync='0') then cur_state <= st_gowait; wait_count <= X"00"; zero_addr<='1'; end if; when st_gowait => --Vsync終了待ち if(tVsync='1') then cur_state <= st_gowait1; R_re <= '1'; R_we <= '0'; zero_addr<='0'; end if; when st_gowait1 => --頭15ラインを無視するために追加 if(tHsync='0' and wait_count >= 15)then --YMM:頭何ライン消すかを指定 clk_count<="00"; cur_state <=st_pre_hblank; wait_count <= X"00"; elsif(tHsync='0') then cur_state <= st_gowait2; end if; when st_gowait2 => if(tHsync='1') then wait_count <=wait_count + '1'; cur_state <= st_gowait1; end if; when st_pre_rec => --あたま18ドット+水平同期期間を無視するために追加 wait_count <= wait_count +'1'; if(wait_count >= 200) then --頭何ドット消すかを指定 wait_count <= X"00"; clk_count<="00"; cur_state <= st_rec; end if; when st_rec => --録画フェーズ case clk_count is when "00" => R_we <='0'; write_clk <='0'; clk_count <= "01"; if(tHsync='0') then wait_count <= wait_count + '1'; end if; when "01" => clk_count <= "10"; if(tHsync='0') then wait_count <= wait_count + '1'; end if; when "10" => if(tVsync ='0' or of_addr='1') then --終了 R_we <='1'; R_re <='0'; cur_state <= st_rec_end; zero_addr<='1'; else clk_count <= "11"; R_we <= '1'; end if; if(tHsync='0') then wait_count <= wait_count + '1'; end if; when "11" => clk_count <= "00"; write_clk <= '1'; if(tHsync='0') then cur_state <= st_pre_hblank; end if; when others => end case; when st_pre_hblank => --Hsyncに入ったのでデリミタを書き込む case clk_count is when "00" => clk_count <= "01"; write_clk <='0'; R_we <='0'; when "01" => clk_count <= "10"; when "10" => clk_count <= "11"; R_we <= '1'; when "11" => clk_count <="00"; write_clk <= '1'; cur_state <= st_pre_rec; when others => end case; when st_rec_end => --取り込み終了(アドレス初期化を1クロックまつ) cur_state <= st_read; zero_addr<='0'; sig_end <='1'; when st_read => --リセットかかるまでまつ when others => cur_state <=st_ready; end case; end if; end process; end Behavioral;