1+ -------------------------------------------------------------------------------
2+ -- Title : gc_iq_modulator.vhd testbench
3+ -- Project :
4+ -------------------------------------------------------------------------------
5+ -- File : gc_iq_mod_tb.vhd
6+ -- Author : David Daminelli <david.daminelli@lnls.br>
7+ -- Company : Brazilian Synchrotron Light Laboratory, LNLS/CNPEM
8+ -- Created : 2025-06-18
9+ -- Last update: 2025-06-18
10+ -- Platform :
11+ -- Standard : VHDL'08
12+ -------------------------------------------------------------------------------
13+ -- Description:
14+ -------------------------------------------------------------------------------
15+ -- Copyright (c) 2025 Brazilian Synchrotron Light Laboratory, LNLS/CNPEM
16+ --
17+ -------------------------------------------------------------------------------
18+ -- Revisions :
19+ -- Date Version Author Description
20+ -- 2025-06-18 1.0 david.daminelli Created
21+ -------------------------------------------------------------------------------
22+
23+ library ieee;
24+ use ieee.std_logic_1164.all ;
25+ use ieee.numeric_std.all ;
26+ use ieee.math_real.all ;
27+
28+ library std;
29+
30+ library work;
31+
32+ entity gc_iq_mod_tb is
33+ end entity gc_iq_mod_tb;
34+
35+ architecture tb of gc_iq_mod_tb is
36+ -----------------------Procedure Declaration----------------------------------
37+ -- Clock Generation
38+ procedure f_gen_clk(constant freq : in natural ;
39+ signal clk : inout std_logic ) is
40+ begin
41+ loop
42+ wait for (0.5 / real (freq)) * 1 sec ;
43+ clk <= not clk;
44+ end loop ;
45+ end procedure f_gen_clk;
46+
47+ -- Wait procedure
48+ procedure f_wait_cycles(signal clk : in std_logic ;
49+ constant cycles : natural ) is
50+ begin
51+ for i in 1 to cycles loop
52+ wait until rising_edge (clk);
53+ end loop ;
54+ end procedure f_wait_cycles;
55+ --------------------------- Constants Declaration ---------------------------
56+ constant c_clk_freq : natural := 100e3 ; -- Clk Freq
57+ constant c_in_freq : real := real (c_clk_freq)/ 4.1 ;
58+ constant c_N : positive := 16 ; -- data size
59+ ----------------------------- Signal Declaration -----------------------------
60+ signal clk : std_logic := '0' ;
61+ signal rst : std_logic := '0' ;
62+ signal s_data_in : std_logic_vector (c_N- 1 downto 0 ) := (others => '0' );
63+ signal s_data_in_d0 : std_logic_vector (c_N- 1 downto 0 ) := (others => '0' );
64+ signal s_data_in_d1 : std_logic_vector (c_N- 1 downto 0 ) := (others => '0' );
65+ signal s_data_in_d2 : std_logic_vector (c_N- 1 downto 0 ) := (others => '0' );
66+ signal s_i_o, s_q_o : std_logic_vector (c_N- 1 downto 0 ) := (others => '0' );
67+ signal s_i_i, s_q_i : std_logic_vector (c_N downto 0 ) := (others => '0' );
68+ signal s_sync, s_sync_d0 : std_logic := '0' ;
69+ signal s_timestamp : integer := 0 ;
70+ signal s_sine_amp : real := 0.0 ;
71+ signal s_sine_phs : real := math_pi / 4.0 ;
72+ signal s_sine : real := 0.0 ;
73+ begin
74+ -------- Clock generation --------
75+ f_gen_clk(c_clk_freq, clk);
76+
77+ -------- Test Processes --------
78+ s_data_in <= std_logic_vector (to_signed (integer (s_sine), s_data_in'length ));
79+
80+ -- Time stamp
81+ p_timestamp: process (clk)
82+ begin
83+ if rising_edge (clk) then
84+ if rst = '1' then
85+ s_timestamp <= 0 ;
86+ else
87+ s_timestamp <= s_timestamp + 1 ;
88+ end if ;
89+ end if ;
90+ end process ;
91+
92+ -- delay the input in 3 cycles for comparting it with the outputs
93+ p_dly: process (clk)
94+ begin
95+ if rising_edge (clk) then
96+ s_data_in_d0 <= s_data_in;
97+ s_data_in_d1 <= s_data_in_d0;
98+ s_data_in_d2 <= s_data_in_d1;
99+ s_sync_d0 <= s_sync;
100+ end if ;
101+ end process ;
102+
103+ -- Sine generation
104+ p_sine: process (clk)
105+ begin
106+ if rising_edge (clk) then
107+ if rst = '1' then
108+ s_sine <= 0.0 ;
109+ else
110+ s_sine <= s_sine_amp *
111+ cos (2.0 * math_pi * c_in_freq *
112+ real (s_timestamp)/ real (c_clk_freq)
113+ + s_sine_phs);
114+ end if ;
115+ end if ;
116+ end process ;
117+
118+ p_loop: process
119+ begin
120+ rst <= '1' ;
121+ f_wait_cycles(clk, 5 );
122+ rst <= '0' ;
123+ f_wait_cycles(clk, 1 );
124+ for i in 0 to c_N- 1 loop -- Loop through c_N amplitudes
125+ s_sync <= '1' ;
126+ f_wait_cycles(clk, 1 );
127+ s_sync <= '0' ;
128+ f_wait_cycles(clk, 1 );
129+ s_sine_amp <= 2.0 ** real (i) - 1.0 ;
130+ for j in 0 to 19 loop -- Loop through 20 phases
131+ s_sine_phs <= real (j) * 2.0 * math_pi / 20.0 ;
132+ f_wait_cycles(clk, 50 ); -- wait 50 cycles in each value
133+ end loop ;
134+ end loop ;
135+ report " Finished!" ;
136+ std.env.finish ;
137+ end process ;
138+
139+ p_assert: process (clk)
140+ variable v_error : signed (s_i_o'range ) := (others => '0' );
141+ begin
142+ if rising_edge (clk) then
143+ v_error := signed (s_i_o) - signed (s_data_in_d2);
144+ assert to_integer (v_error) = 0
145+ report " Error in output value"
146+ severity warning ;
147+ end if ;
148+ end process ;
149+
150+ ------ Entity declaration ------
151+ UUT: entity work.gc_iq_modulator
152+ generic map (
153+ g_N => c_N
154+ )
155+ port map (
156+ clk_i => clk,
157+ en_i => '1' ,
158+ rst_i => rst,
159+ sync_p1_i => s_sync_d0,
160+ i_i => s_i_i(c_N- 1 downto 0 ),
161+ q_i => s_q_i(c_N- 1 downto 0 ),
162+ i_o => s_i_o,
163+ q_o => s_q_o
164+ );
165+
166+ ------ Entity declaration ------
167+ UUT2: entity work.gc_iq_demodulator
168+ generic map (
169+ g_N => c_N
170+ )
171+ port map (
172+ clk_i => clk,
173+ rst_i => rst,
174+ sync_p1_i => s_sync,
175+ adc_data_i => s_data_in,
176+ i_o => s_i_i,
177+ q_o => s_q_i
178+ );
179+
180+ end architecture tb;
0 commit comments