1 -- title: S/PDIF
2 -- author: ACK.space
3 -- last change: 25.10.13
4
5
6 library IEEE;
7 use IEEE.std_logic_1164.all;
8 use IEEE.numeric_std.all;
9 use IEEE.math_real.all;
10
11 entity spdif is
12 generic
13 (
14 prescaler : natural := 8
15 );
16
17 port
18 (
19 clk : in std_logic;
20 ch0 : in std_logic_vector(23 downto 0);
21 ch1 : in std_logic_vector(23 downto 0);
22 sdo : out std_logic
23 );
24 end entity;
25
26 architecture behavioral of spdif is
27 constant log2pre : integer := integer(ceil(log2(real(prescaler))));
28 signal pre : unsigned(log2pre-1 downto 0) := (others => '0');
29 signal data_in_buffer : std_logic_vector(23 downto 0);
30 signal bit_counter : unsigned(5 downto 0) := (others => '0');
31 signal frame_counter : unsigned(8 downto 0) := (others => '0');
32 signal data_biphase : std_logic := '0';
33 signal data_out_buffer : std_logic_vector(7 downto 0);
34 signal parity : std_logic;
35 signal channel_status_shift : std_logic_vector(23 downto 0);
36 signal channel_status : std_logic_vector(23 downto 0) := "001000000000000001000000";
37 signal ch_sel : std_logic := '0';
38 signal clk_en : std_logic := '0';
39 begin
40
41 clock : process begin
42 wait until rising_edge(clk);
43 pre <= pre + 1;
44 if pre = 0 then
45 clk_en <= '1';
46 else
47 clk_en <= '0';
48 end if;
49 end process clock;
50
51 bit_clock_counter : process begin
52 wait until rising_edge(clk);
53 if clk_en = '1' then
54 bit_counter <= bit_counter + 1;
55 end if;
56 end process bit_clock_counter;
57
58 data_latch : process begin
59 wait until rising_edge(clk);
60 if clk_en = '1' then
61 parity <= data_in_buffer(23) xor data_in_buffer(22) xor data_in_buffer(21) xor data_in_buffer(20) xor data_in_buffer(19)
62 xor data_in_buffer(18) xor data_in_buffer(17) xor data_in_buffer(16) xor data_in_buffer(15)
63 xor data_in_buffer(14) xor data_in_buffer(13) xor data_in_buffer(12) xor data_in_buffer(11)
64 xor data_in_buffer(10) xor data_in_buffer(9) xor data_in_buffer(8) xor data_in_buffer(7)
65 xor data_in_buffer(6) xor data_in_buffer(5) xor data_in_buffer(4) xor data_in_buffer(3)
66 xor data_in_buffer(2) xor data_in_buffer(1) xor data_in_buffer(0) xor channel_status_shift(23);
67 if bit_counter = "000011" then
68 if ch_sel = '0' then
69 data_in_buffer <= ch0;
70 else
71 data_in_buffer <= ch1;
72 end if;
73 end if;
74 if bit_counter = "111111" then
75 if frame_counter = "101111111" then
76 frame_counter <= (others => '0');
77 else
78 frame_counter <= frame_counter + 1;
79 end if;
80 end if;
81 end if;
82 end process data_latch;
83
84 data_output : process begin
85 wait until rising_edge(clk);
86 if clk_en = '1' then
87 if bit_counter = "111111" then
88 if frame_counter = "101111111" then
89 -- next frame is 0, load preamble B
90 ch_sel <= '0';
91 channel_status_shift <= channel_status;
92 data_out_buffer <= "10011100";
93 else
94 if frame_counter(0) = '1' then
95 -- next frame is even, load preamble M
96 ch_sel <= '0';
97 channel_status_shift <= channel_status_shift(22 downto 0) & '0';
98 data_out_buffer <= "10010011";
99 else
100 -- next frame is odd, load preable W
101 ch_sel <= '1';
102 data_out_buffer <= "10010110";
103 end if;
104 end if;
105 else
106 if bit_counter(2 downto 0) = "111" then
107 -- load new part of data into buffer
108 case bit_counter(5 downto 3) is
109 when "000" =>
110 data_out_buffer <= '1' & data_in_buffer(0) & '1' & data_in_buffer(1) & '1' & data_in_buffer(2) & '1' & data_in_buffer(3);
111 when "001" =>
112 data_out_buffer <= '1' & data_in_buffer(4) & '1' & data_in_buffer(5) & '1' & data_in_buffer(6) & '1' & data_in_buffer(7);
113 when "010" =>
114 data_out_buffer <= '1' & data_in_buffer(8) & '1' & data_in_buffer(9) & '1' & data_in_buffer(10) & '1' & data_in_buffer(11);
115 when "011" =>
116 data_out_buffer <= '1' & data_in_buffer(12) & '1' & data_in_buffer(13) & '1' & data_in_buffer(14) & '1' & data_in_buffer(15);
117 when "100" =>
118 data_out_buffer <= '1' & data_in_buffer(16) & '1' & data_in_buffer(17) & '1' & data_in_buffer(18) & '1' & data_in_buffer(19);
119 when "101" =>
120 data_out_buffer <= '1' & data_in_buffer(20) & '1' & data_in_buffer(21) & '1' & data_in_buffer(22) & '1' & data_in_buffer(23);
121 when "110" =>
122 data_out_buffer <= "10101" & channel_status_shift(23) & "1" & parity;
123 when others =>
124 end case;
125 else
126 data_out_buffer <= data_out_buffer(6 downto 0) & '0';
127 end if;
128 end if;
129 end if;
130 end process data_output;
131
132 biphaser : process
133 begin
134 wait until rising_edge(clk);
135 if clk_en = '1' then
136 if data_out_buffer(data_out_buffer'left) = '1' then
137 data_biphase <= not data_biphase;
138 end if;
139 end if;
140 end process biphaser;
141
142 sdo <= data_biphase;
143
144 end behavioral;
145
This page was generated using GHDL 0.29 (20100109) [Sokcho edition], a program written by Tristan Gingold