とりあえず、作業ログとしていろいろ書いてきたい。ということで、こんなの作った!
![]() |
これを |
![]() |
こうして |
![]() |
こうじゃ! |
単純に興味本位でCPLD(Altera MAX II)で光デジタル出力をしてみました。
一応出力出来たけど、なぜか波形が汚め。たぶん光デジタルのDACが500円くらいの安物だからかな?
VHDL初心者が勢いで作って3日くらいで出来たから、そんなに難しい事でもないんだろうな。
とりあえず完成したときは131ロジックエレメント(LE)で、その後ガリガリ削ったら88LEまで減らせた。ここらへんで満足。
さて、次はなに作ろうか
ソースコード
(あとから見たら恥ずかしくなるんだろうなぁ…)spdif_top.vhd
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity SPDIF_TOP is port ( CLK : in std_logic; SPDIF : out std_logic); end entity; architecture RTL of SPDIF_TOP is component SPDIF_ENC is port ( CLK : in std_logic; SPDIF : out std_logic; DATA : in std_logic_vector(15 downto 0)); end component; subtype DELAY is std_logic_vector(4 downto 0); type DELAY_TABLE is array (0 to 191) of DELAY; constant delay_tbl : DELAY_TABLE := ( "01111","10000","01111","01111","10000","01111","01111","01111","10000","01111", "01111","10000","01111","01111","01111","10000","01111","01111","01111","10000", "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000", "01111","01111","01111","10000","01111","01111","01111","10000","01111","01111", "10000","01111","01111","01111","10000","01111","01111","01111","10000","01111", "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111", "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000", "01111","01111","01111","10000","01111","01111","01111","10000","01111","01111", "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111", "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111", "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000", "01111","01111","01111","10000","01111","01111","10000","01111","01111","01111", "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111", "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111", "01111","01111","10000","01111","01111","10000","01111","01111","01111","10000", "01111","01111","01111","10000","01111","01111","10000","01111","01111","01111", "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111", "01111","10000","01111","01111","10000","01111","01111","01111","10000","01111", "01111","01111","10000","01111","01111","10000","01111","01111","01111","10000", "01111","01111"); signal delay_phase : std_logic_vector(7 downto 0); signal delay_cnt : std_logic_vector(4 downto 0); signal spdif_clk : std_logic; signal spdif_data : std_logic_vector(15 downto 0); signal cnt : std_logic_vector(12 downto 0); begin encoder : SPDIF_ENC port map (spdif_clk, SPDIF, spdif_data); process (CLK) begin if (CLK'event and CLK = '1') then if (delay_cnt < delay_tbl(conv_integer(delay_phase))) then delay_cnt <= delay_cnt + 1; spdif_clk <= '0'; else delay_cnt <= (others => '0'); if (delay_phase < 192 - 1) then delay_phase <= delay_phase + 1; else delay_phase <= (others => '0'); end if; spdif_clk <= '1'; cnt <= cnt + 1; spdif_data <= (15 downto 13 => (cnt(11) xor cnt(6)), 12 => '1' , others => '0'); end if; end if; end process; end architecture;
spdif_enc.vhd
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity SPDIF_ENC is port ( CLK : in std_logic; SPDIF : out std_logic; DATA : in std_logic_vector(15 downto 0)); end entity; architecture RTL of SPDIF_ENC is signal reset : std_logic := '0'; signal frame : std_logic_vector(7 downto 0) := (others => '0'); signal channel : std_logic := '0'; signal cnt : std_logic_vector(5 downto 0) := (others => '0'); signal preamble : std_logic_vector(7 downto 0); signal parity : std_logic := '0'; signal cell : std_logic := '0'; constant preamble_b : std_logic_vector(7 downto 0) := "11101000"; constant preamble_m : std_logic_vector(7 downto 0) := "11100010"; constant preamble_w : std_logic_vector(7 downto 0) := "11100100"; begin process (CLK) variable v_logic : std_logic; variable v_cell : std_logic; begin if (CLK'event and CLK = '1') then if (reset = '0') then preamble <= preamble_b; reset <= '1'; else cnt <= cnt + 1; if (cnt(5 downto 3) = 0) then -- Preamble parity <= '0'; SPDIF <= preamble(7 - conv_integer(cnt(2 downto 0))) xor cell; else if (cnt(0) = '1') then if (cnt(5 downto 1) >= 12 and cnt(5 downto 1) <= 27) then -- Sample v_logic := DATA(conv_integer(cnt(5 downto 1)) - 12); elsif (cnt(5 downto 1) = 31) then -- Parity v_logic := parity; else -- AUX,Validity,Subcode,Channel info v_logic := '0'; end if; parity <= parity xor v_logic; v_cell := cell xor v_logic; if (cnt(5 downto 1) = 31) then if (frame < 191) then frame <= frame + 1; else frame <= (others => '0'); end if; channel <= not channel; if (channel = '0') then preamble <= preamble_w; else if (frame /= 191) then preamble <= preamble_m; else preamble <= preamble_b; end if; end if; end if; else v_cell := not cell; end if; cell <= v_cell; SPDIF <= v_cell; end if; end if; end if; end process; end architecture;
参考サイト
ePanorama.net (http://www.epanorama.net/documents/audio/spdif.html)
minidisc.org (http://www.minidisc.org/spdif_c_channel.html)
ボクにもわかる地上デジタル (http://www.geocities.jp/bokunimowakaru/std-spdif.html)
0 件のコメント:
コメントを投稿