-
Notifications
You must be signed in to change notification settings - Fork 0
/
i2s_tb.vhd
150 lines (131 loc) · 3.93 KB
/
i2s_tb.vhd
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
library ieee;
use ieee.std_logic_1164.all;
entity i2s_tb is
generic ( DATA_WIDTH : integer := 24;
BITPERFRAME : integer := 64);
end i2s_tb;
architecture behavioral of i2s_tb is
signal clk_50 : std_logic;
signal dac_d : std_logic;
signal adc_d : std_logic;
signal bclk : std_logic;
signal lrclk : std_logic;
signal dstim : std_logic_vector(63 downto 0) := x"aaaaeeeebbbb5555";
signal sample : std_logic_vector(DATA_WIDTH - 1 downto 0) := x"fafafa";
constant period : time := 20 ns;
constant bclk_period : time := 32552 ns / BITPERFRAME;
signal zbclk, zzbclk, zzzbclk : std_logic;
signal neg_edge, pos_edge : std_logic;
signal wdth : integer := DATA_WIDTH;
signal cnt : integer := 0;
signal toggle : std_logic := '1';
signal new_sample : std_logic := '0';
signal sample_out : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal valid : std_logic;
signal ready : std_logic := '1';
signal rst : std_logic := '0';
component i2s_interface is
generic ( DATA_WIDTH : integer range 16 to 32;
BITPERFRAME: integer );
port (
clk : in std_logic;
reset : in std_logic;
bclk : in std_logic;
lrclk : in std_logic;
sample_out : out std_logic_vector(DATA_WIDTH - 1 downto 0);
sample_in : in std_logic_vector(DATA_WIDTH - 1 downto 0);
dac_data : out std_logic;
adc_data : in std_logic;
valid : out std_logic;
ready : out std_logic
);
end component;
begin
-- Instantiate
DUT : i2s_interface
generic map ( DATA_WIDTH => DATA_WIDTH,
BITPERFRAME => BITPERFRAME )
port map (
clk => clk_50,
reset => rst,
bclk => bclk,
lrclk => lrclk,
sample_out => sample_out,
sample_in => sample,
dac_data => dac_d,
adc_data => adc_d,
valid => valid,
ready => ready
);
clk_proc : process
begin
clk_50 <= '0';
wait for period/2;
clk_50 <= '1';
wait for period/2;
end process;
-- lrclk <= lrstim(lrstim'high);
i2s_bclk : process
begin
bclk <= '0';
-- lrstim <= lrstim(lrstim'high - 1 downto 0) & lrstim(lrstim'high);
wait for bclk_period/2;
-- lrstim <= lrstim(lrstim'high - 1 downto 0) & lrstim(lrstim'high);
bclk <= '1';
wait for bclk_period/2;
end process;
detect : process(clk_50)
begin
if rising_edge(clk_50) then
zbclk <= bclk;
zzbclk <= zbclk;
zzzbclk <= zzbclk;
if zzbclk = '1' and zzzbclk = '0' then
neg_edge <= '1';
elsif zzbclk = '0' and zzzbclk = '1' then
pos_edge <= '1';
else
neg_edge <= '0';
pos_edge <= '0';
end if;
end if;
end process;
lrclk <= toggle;
i2s_lrclk : process(bclk)
begin
if rising_edge(bclk) then
if cnt < BITPERFRAME/2 - 1 then
cnt <= cnt + 1;
elsif cnt = BITPERFRAME/2 - 1 then
cnt <= 0;
end if;
end if;
if falling_edge(bclk) then
if cnt >= BITPERFRAME/2 - 1 then
toggle <= not toggle;
else
if cnt = 0 then
new_sample <= '1';
elsif cnt >= wdth then
new_sample <= '0';
end if;
end if;
end if;
end process;
adc_d <= dstim(dstim'high);
i2s_data : process(bclk)
begin
if falling_edge(bclk) then
if new_sample = '1' then
dstim <= dstim(dstim'high - 1 downto 0) & dstim(dstim'high);
end if;
end if;
if rising_edge(clk_50) then
if ready = '1' then
sample <= dstim(dstim'high downto dstim'high - DATA_WIDTH + 1);
else
sample <= (others => '0');
end if;
end if;
end process;
end behavioral;