blob: 0cfd8586447ed3c83b09598bd830283c551d7068 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity codec_dac is
generic (
system_frequency : real := 50.0E6; -- 50 MHz
sample_rate : real := 48.0E3; -- 48 kHz
data_width : positive := 16; -- 16 bits
channel_num : positive := 2 -- dual channel
);
port (
clk : in std_logic; --
resetn : in std_logic; --
go : in std_logic;
data_in : in std_logic_vector(data_width-1 downto 0);
-- codec
tempo_dac : out std_logic;
end_dac : out std_logic;
codec_dac_bclk : out std_logic; -- B4
codec_dac_data : out std_logic; -- A4
codec_dac_lrck : out std_logic -- C6
);
end entity;
architecture rtl of codec_dac is
constant mod_bclk : positive := integer(system_frequency/(2.0*sample_rate*real(data_width)*real(channel_num)));
constant mod_lrck : positive := data_width*channel_num/2;
type state is (wait_for_go, tx);
signal current_state : state;
signal next_state : state;
signal ctr_bclk : natural range 0 to mod_bclk-1;
signal ctr_lrck : natural range 0 to mod_lrck-1;
signal reg_data : std_logic_vector(data_in'range);
signal cmd_data : std_logic_vector(1 downto 0);
signal bclk : std_logic;
signal lrck : std_logic;
signal end_bit : std_logic;
begin
codec_dac_bclk <= bclk;
codec_dac_lrck <= lrck;
codec_dac_data <= reg_data(reg_data'low);
tempo_dac <= end_bit;
end_bit <= '0' when (ctr_bclk< mod_bclk-1) or bclk='0'
else '1';
-- registers and counters
process(clk, resetn) is
begin
if resetn ='0' then
bclk <= '0';
lrck <= '0';
reg_data <= (others => '0');
ctr_bclk <= 0;
ctr_lrck <= 0;
current_state <= wait_for_go;
elsif rising_edge(clk) then
current_state <= next_state;
if ctr_bclk< mod_bclk-1 then
ctr_bclk <= ctr_bclk+1;
else
ctr_bclk <= 0;
bclk <=not bclk;
end if;
-- data register
case cmd_data is
when "10" => reg_data <= data_in;
when "11" => reg_data <= '0'®_data(reg_data'high downto 1);
when others => null;
end case;
if end_bit = '1' then
if ctr_lrck < mod_lrck-1 then
ctr_lrck <= ctr_lrck +1;
else
ctr_lrck <= 0;
lrck <= not lrck;
end if;
end if;
end if;
end process;
process(current_state,go,end_bit, ctr_lrck) is
begin
next_state <= current_state;
cmd_data <= "00";
end_dac <= '1';
case current_state is
when wait_for_go => if go = '1' then
next_state <= tx;
cmd_data <= "10";
end if;
when tx => if end_bit='1' then
if ctr_lrck >= mod_lrck-1 then
if go ='0' then
next_state <= wait_for_go;
else
cmd_data <= "10";
end if;
else
cmd_data <= "11";
end if;
end if;
end_dac <= '0';
end case;
end process;
end architecture;
|