最後の投稿が半年前とは時が経つのは早いもので、(ry
とりあえず、作業ログとしていろいろ書いてきたい。ということで、こんなの作った!
|
これを |
|
こうして |
|
こうじゃ! |
単純に興味本位で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)