📄 tb_xfft16_fio.vhd
字号:
--
-- Filename: tb_xfft16_fio.vhd
--
--
-- NOTE: This test bench must be compiled as VHDL-93
--
-- ************************************************************************************************
-- ==========
-- Test Bench
-- ==========
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all; --
use ieee.std_logic_unsigned.all; -- for conv_integer()
use std.textio.all; -- For File I/O
Entity tb_xfft16_fio is
End tb_xfft16_fio;
Architecture Test_Bench of tb_xfft16_fio is
Signal RS : std_logic;
Signal DR : std_logic_vector(15 downto 0 );
Signal DI : std_logic_vector(15 downto 0 );
Signal START : std_logic;
Signal CE : std_logic;
Signal CLK : std_logic;
Signal FRAME : std_logic;
Signal XK_R : std_logic_vector(15 downto 0 );
Signal XK_I : std_logic_vector(15 downto 0 );
Signal ce_i : std_logic; -- unbuffered CE
Signal init : std_logic; -- initialization complete signal
--
-- Test Bench Signals
--
Signal ckper : time := 40 ns; -- temporary tester clock period
Signal fin : real; -- Input Data to be sampled
Signal fs : real; -- Input Sample Frequency
Signal rd : real; -- real data (real)
Signal id : real; -- imaginary data (real)
Signal i : integer; -- sample number
Signal j : integer; -- data index var
Signal frame_count : integer; -- number of frames elapsed
Shared Variable result_frame : integer; -- result frame to capture
Signal output_capture_count : integer; -- count # of words captured in selected frame
Signal output_capture_flag : boolean; -- capture words 2 - 16 flag
type output_storage is array (1 to 16) of std_logic_vector(15 downto 0);
type input_storage is array (1 to 16) of std_logic_vector(15 downto 0);
signal fft_real_result : output_storage;
signal fft_imag_result : output_storage;
signal fft_real_in : input_storage;
signal fft_imag_in : input_storage;
--
-- Dr. Dicks' FFT16 Design
--
Component xfft16
Port (
RS : in std_logic ; -- master reset
DR : in std_logic_vector(15 downto 0 ); -- real data in
DI : in std_logic_vector(15 downto 0 ); -- imaginary data in
START : in std_logic ; -- fft start control
CE : in std_logic ; -- clock enable
CLK : in std_logic ; -- clock input
FRAME : out std_logic ; -- transform complet strobe
XK_R : out std_logic_vector(15 downto 0 ); -- real data out
XK_I : out std_logic_vector(15 downto 0 ) -- imaginary data out
); -- (end of port)
End component; -- xfft16
procedure l2str (l : inout line ;
result : out string ) is
variable j : integer := 0;
variable ch : character;
begin
for i in 1 to l'right loop
read(l, ch);
result(i) := ch;
j := i;
end loop;
result(j+1) := NUL; -- terminate the string
end;
procedure calculate_magnitude_phase
(r : in std_logic_vector(15 downto 0) ; -- real data, 2's complement form
i : in std_logic_vector(15 downto 0) ; -- imaginary data, 2's complement form
magnitude : out integer ;
phase : out integer) is
variable ri, ii : integer;
variable rr, ir : real;
begin
ri := conv_integer(r); -- real data, integer type
ii := conv_integer(i); -- imaginary data, integer type
if (ri > 32767) then -- 2's comp to integer
ri := ri + (-65536);
end if;
if (ii > 32767) then -- 2's comp to integer
ii := ii + (-65536);
end if;
magnitude := ri;
phase := ii;
end;
-- Syntax below is : Entity pin name => Actual schematic signal name.
Begin
U2 : xfft16
Port Map (
RS => RS,
DR => DR,
DI => DI,
START => START,
CE => CE,
CLK => CLK,
FRAME => FRAME,
XK_R => XK_R,
XK_I => XK_I
); -- end port map
TB : Block
Begin
ce <= ce_i; -- old bufgs
--
-- This process will create the main clock
--
p_clock : process -- make tester clock
begin
clk <='1';
wait for ckper /2 ;
clk <='0';
wait for ckper / 2;
end process p_clock;
--
-- This process will apply the real and imaginary input data on the negative edge of the clock
--
apply_input_data : process (clk, rs)
variable ird, iid : integer;
variable std_logic_xnr: std_logic_vector(15 downto 0);
variable std_logic_xni: std_logic_vector(15 downto 0);
begin
if (rs = '1') then
DR <= "0000000000000000" ;
DI <= "0000000000000000" ;
i <= 0;
j <= 1;
elsif (clk'event and clk = '0') then -- negative edge of clock
if (init = '1') then
if (j < 16) then
j <= j+1;
end if;
std_logic_xnr := fft_real_in(j);
std_logic_xni := fft_imag_in(j);
DR <= std_logic_xnr; --conv_std_logic_vector(ird,16); -- integer to std_logic_vector;
DI <= std_logic_xni; --conv_std_logic_vector(iid,16); -- integer to std_logic_vector;
--DR <= fft_real_in(i);
--DI <= fft_imag_in(i);
i <= i + 1;
else
DR <= "0000000000000000" ;
DI <= "0000000000000000" ;
end if;
end if;
end process;
--
-- This process will capture the 16 pair (real and imaginary) of output data from the
-- fft engine for (frame number = frame_count) and store it in a temporary array
--
capture_output_data : process (clk, rs)
File outfile_dsp : text; -- Output File file variable
file fft_xk_file : text;
Variable result_mag : integer;
Variable result_phase : integer;
Variable bin_frequency : real;
Variable bin_number : integer;
Variable oline : line; -- output line
variable ixkr,ixki : integer;
begin
if (rs = '1') then
frame_count <= 1; -- number of frames elapsed
output_capture_count <= 1; -- count # of words captured in selected frame
output_capture_flag <= false; -- capture words 2 - 16 flag
elsif (clk'event and clk = '1') then -- positive edge of clock
if ( (frame_count = result_frame) and frame = '1') then
fft_real_result(1) <= xk_r;
fft_imag_result(1) <= xk_i;
output_capture_count <= output_capture_count + 1;
output_capture_flag <= true;
elsif (output_capture_flag = true) then
fft_real_result(output_capture_count) <= xk_r;
fft_imag_result(output_capture_count) <= xk_i;
output_capture_count <= output_capture_count + 1;
if (output_capture_count = 16) then
frame_count <= frame_count + 1;
output_capture_flag <= false;
end if;
elsif (output_capture_flag = false) and (output_capture_count = 17) then
--
-- requested frame data has been captured and is written to the output file "fft16xk.dat"
--
file_open(fft_xk_file, "fft16xk.dat", write_mode);
-- write input samples
for index in 1 to 16 loop
calculate_magnitude_phase(fft_real_result(index), fft_imag_result(index),
result_mag, result_phase);
write(oline,result_mag);
writeline(fft_xk_file, oline);
write(oline,result_phase);
writeline(fft_xk_file, oline);
assert false report (LF &
" x(k): " & integer'image(index) & " " & integer'image(result_mag) &
" " & integer'image(result_phase)
) severity Note;
end loop;
file_close(fft_xk_file);
output_capture_count <= output_capture_count + 1; -- increment so not execute this elsif section again
elsif (frame = '1') then
frame_count <= frame_count + 1;
end if;
end if;
end process;
--
-- Main Test Bench Process
--
p_main : process -- Main test bench process
Variable l1 : line; -- pointer to a string
Variable rfs, rfin : real;
Variable str_fs, str_fin : string(1 to 10);
Variable str_xnr, str_xni : string(1 to 4);
Variable str_frame, ckper_time : string(1 to 10);
Variable ckper_time1 : string(1 to 13);
Variable ckper_timer : real;
Variable line_descriptor : string(1 to 2);
Variable len1 : integer;
Variable sch : string(1 to 1); -- required for fscan
Variable ls : string(1 to 132);
File s_file : text; -- Input parameter File file variable
File fft_in_file : text;
type integer_file is file of integer;
file fft_in_file_txt : text; -- FFT input data file (integer vals)
variable open_status : file_open_status;
variable rxnr,rxni : real;
variable ixnr,ixni : integer;
begin
ckper <= 25.000 ns;
result_frame := 1;
-- read FFT input vector
file_open(open_status, fft_in_file, "xin.dat", read_mode);
for index in 1 to 16 loop
readline(fft_in_file, l1);
read(l1,ixnr);
fft_real_in(index) <= conv_std_logic_vector(ixnr,16);
readline(fft_in_file, l1);
read(l1,ixni);
fft_imag_in(index) <= conv_std_logic_vector(ixni,16);
assert false report (LF &
" x(n): " & integer'image(index) & " " & integer'image(ixnr) &
" " & integer'image(ixni)
) severity Note;
end loop;
file_close(fft_in_file);
-- Initialize all signals
RS <= '1' ;
START <= '0' ;
CE_i <= '0' ;
init <= '0';
wait for (ckper * 2);
--- now start stimulus ---
CE_i <= '1'; -- enable core
wait for ckper;
rs <= '0'; -- release reset
wait for ckper;
start <= '1'; -- start fft processing
wait for ckper / 2;
init <= '1';
wait for ckper / 2;
start <= '0'; -- set start inactive
wait for ckper;
wait;
end process p_main;
End Block TB;
End Test_Bench;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -