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