----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
---- ----
|
---- ----
|
---- File : cordic_iterative_tb.vhd ----
|
---- File : cordic_iterative_tb.vhd ----
|
---- Project : YAC (Yet Another CORDIC Core) ----
|
---- Project : YAC (Yet Another CORDIC Core) ----
|
---- Creation : Feb. 2014 ----
|
---- Creation : Feb. 2014 ----
|
---- Limitations : ----
|
---- Limitations : ----
|
---- Synthesizer : ----
|
---- Synthesizer : ----
|
---- Target : ----
|
---- Target : ----
|
---- ----
|
---- ----
|
---- Author(s): : Christian Haettich ----
|
---- Author(s): : Christian Haettich ----
|
---- Email : feddischson@opencores.org ----
|
---- Email : feddischson@opencores.org ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
----- -----
|
----- -----
|
---- ----
|
---- ----
|
---- Description ----
|
---- Description ----
|
---- VHDL Testbench ----
|
---- VHDL Testbench ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
----- -----
|
----- -----
|
---- ----
|
---- ----
|
---- TODO ----
|
---- TODO ----
|
---- Some documentation ----
|
---- Some documentation ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
---- ----
|
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
---- ----
|
---- ----
|
---- Copyright Notice ----
|
---- Copyright Notice ----
|
---- ----
|
---- ----
|
---- This file is part of YAC - Yet Another CORDIC Core ----
|
---- This file is part of YAC - Yet Another CORDIC Core ----
|
---- Copyright (c) 2014, Author(s), All rights reserved. ----
|
---- Copyright (c) 2014, Author(s), All rights reserved. ----
|
---- ----
|
---- ----
|
---- YAC is free software; you can redistribute it and/or ----
|
---- YAC is free software; you can redistribute it and/or ----
|
---- modify it under the terms of the GNU Lesser General Public ----
|
---- modify it under the terms of the GNU Lesser General Public ----
|
---- License as published by the Free Software Foundation; either ----
|
---- License as published by the Free Software Foundation; either ----
|
---- version 3.0 of the License, or (at your option) any later version. ----
|
---- version 3.0 of the License, or (at your option) any later version. ----
|
---- ----
|
---- ----
|
---- YAC is distributed in the hope that it will be useful, ----
|
---- YAC is distributed in the hope that it will be useful, ----
|
---- but WITHOUT ANY WARRANTY; without even the implied warranty of ----
|
---- but WITHOUT ANY WARRANTY; without even the implied warranty of ----
|
---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ----
|
---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ----
|
---- Lesser General Public License for more details. ----
|
---- Lesser General Public License for more details. ----
|
---- ----
|
---- ----
|
---- You should have received a copy of the GNU Lesser General Public ----
|
---- You should have received a copy of the GNU Lesser General Public ----
|
---- License along with this library. If not, download it from ----
|
---- License along with this library. If not, download it from ----
|
---- http://www.gnu.org/licenses/lgpl ----
|
---- http://www.gnu.org/licenses/lgpl ----
|
---- ----
|
---- ----
|
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
|
|
|
|
|
|
LIBRARY ieee;
|
LIBRARY ieee;
|
USE ieee.std_logic_1164.ALL;
|
USE ieee.std_logic_1164.ALL;
|
use ieee.numeric_std.ALL;
|
use ieee.numeric_std.ALL;
|
|
|
library std;
|
library std;
|
use std.textio.all; -- for reading/writing from/to files
|
use std.textio.all; -- for reading/writing from/to files
|
use std.env.all; -- for finish()
|
use std.env.all; -- for finish()
|
|
|
library work;
|
library work;
|
|
|
|
|
entity cordic_iterative_tb is
|
entity cordic_iterative_tb is
|
|
|
end entity cordic_iterative_tb;
|
end entity cordic_iterative_tb;
|
|
|
|
|
architecture IMP of cordic_iterative_tb is
|
architecture IMP of cordic_iterative_tb is
|
|
|
|
|
constant FRQ_MULT_VALUE : integer :=18;
|
constant FRQ_MULT_VALUE : integer :=18;
|
|
|
constant stim_file : string := "../../c_octave/tb_data.txt";
|
constant stim_file : string := "../../c_octave/tb_data.txt";
|
constant err_file : string := "./error_out.txt";
|
constant err_file : string := "./error_out.txt";
|
|
|
constant clk_T : time := 5 ns;
|
constant clk_T : time := 5 ns;
|
signal clk : std_logic;
|
signal clk : std_logic;
|
signal rst : std_logic;
|
signal rst : std_logic;
|
signal nrst : std_logic;
|
signal nrst : std_logic;
|
|
|
constant XY_WIDTH : natural := 8;
|
constant XY_WIDTH : natural := 8;
|
constant A_WIDTH : natural := 8;
|
constant A_WIDTH : natural := 8;
|
constant GUARD_BITS : natural := 2;
|
constant GUARD_BITS : natural := 2;
|
constant RM_GAIN : natural := 3;
|
constant RM_GAIN : natural := 3;
|
component cordic_iterative_int is
|
component cordic_iterative_int is
|
generic(
|
generic(
|
XY_WIDTH : natural := 12;
|
XY_WIDTH : natural := 12;
|
A_WIDTH : natural := 12;
|
A_WIDTH : natural := 12;
|
GUARD_BITS : natural := 2;
|
GUARD_BITS : natural := 2;
|
RM_GAIN : natural := 4
|
RM_GAIN : natural := 4
|
);
|
);
|
port(
|
port(
|
clk, rst : in std_logic;
|
clk, rst : in std_logic;
|
en : in std_logic;
|
en : in std_logic;
|
start : in std_logic;
|
start : in std_logic;
|
done : out std_logic;
|
done : out std_logic;
|
mode_i : in std_logic_vector( 4-1 downto 0 );
|
mode_i : in std_logic_vector( 4-1 downto 0 );
|
x_i : in std_logic_vector( XY_WIDTH-1 downto 0 );
|
x_i : in std_logic_vector( XY_WIDTH-1 downto 0 );
|
y_i : in std_logic_vector( XY_WIDTH-1 downto 0 );
|
y_i : in std_logic_vector( XY_WIDTH-1 downto 0 );
|
a_i : in std_logic_vector( A_WIDTH+2-1 downto 0 );
|
a_i : in std_logic_vector( A_WIDTH+2-1 downto 0 );
|
x_o : out std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
x_o : out std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
y_o : out std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
y_o : out std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
a_o : out std_logic_vector( A_WIDTH+2-1 downto 0 )
|
a_o : out std_logic_vector( A_WIDTH+2-1 downto 0 )
|
);
|
);
|
end component cordic_iterative_int;
|
end component cordic_iterative_int;
|
signal en : std_logic;
|
signal en : std_logic;
|
signal start : std_logic;
|
signal start : std_logic;
|
signal done : std_logic;
|
signal done : std_logic;
|
signal mode_i : std_logic_vector( 4-1 downto 0 );
|
signal mode_i : std_logic_vector( 4-1 downto 0 );
|
signal x_i : std_logic_vector( XY_WIDTH-1 downto 0 );
|
signal x_i : std_logic_vector( XY_WIDTH-1 downto 0 );
|
signal y_i : std_logic_vector( XY_WIDTH-1 downto 0 );
|
signal y_i : std_logic_vector( XY_WIDTH-1 downto 0 );
|
signal a_i : std_logic_vector( A_WIDTH+2-1 downto 0 );
|
signal a_i : std_logic_vector( A_WIDTH+2-1 downto 0 );
|
signal x_o : std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
signal x_o : std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
signal y_o : std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
signal y_o : std_logic_vector( XY_WIDTH+GUARD_BITS-1 downto 0 );
|
signal a_o : std_logic_vector( A_WIDTH+2-1 downto 0 );
|
signal a_o : std_logic_vector( A_WIDTH+2-1 downto 0 );
|
|
|
|
|
begin
|
begin
|
|
|
|
|
-- --
|
-- --
|
-- clock and reset
|
-- clock and reset
|
--
|
--
|
nrst <= not rst;
|
nrst <= not rst;
|
clk_gen : process
|
clk_gen : process
|
begin
|
begin
|
clk <= '1';
|
clk <= '1';
|
wait for clk_T/2;
|
wait for clk_T/2;
|
clk <= '0';
|
clk <= '0';
|
wait for clk_T/2;
|
wait for clk_T/2;
|
end process;
|
end process;
|
rst_gen : process
|
rst_gen : process
|
begin
|
begin
|
rst <= '1';
|
rst <= '1';
|
wait for clk_T * 10;
|
wait for clk_T * 10;
|
rst <= '0';
|
rst <= '0';
|
wait;
|
wait;
|
end process;
|
end process;
|
|
|
|
|
|
|
|
|
dut : cordic_iterative_int
|
dut : cordic_iterative_int
|
generic map (
|
generic map (
|
XY_WIDTH => XY_WIDTH ,
|
XY_WIDTH => XY_WIDTH ,
|
A_WIDTH => A_WIDTH ,
|
A_WIDTH => A_WIDTH ,
|
GUARD_BITS => GUARD_BITS,
|
GUARD_BITS => GUARD_BITS,
|
RM_GAIN => RM_GAIN
|
RM_GAIN => RM_GAIN
|
)
|
)
|
port map(
|
port map(
|
clk => clk ,
|
clk => clk ,
|
rst => rst ,
|
rst => rst ,
|
en => en ,
|
en => en ,
|
start => start ,
|
start => start ,
|
done => done ,
|
done => done ,
|
mode_i => mode_i ,
|
mode_i => mode_i ,
|
x_i => x_i ,
|
x_i => x_i ,
|
y_i => y_i ,
|
y_i => y_i ,
|
a_i => a_i ,
|
a_i => a_i ,
|
x_o => x_o ,
|
x_o => x_o ,
|
y_o => y_o ,
|
y_o => y_o ,
|
a_o => a_o
|
a_o => a_o
|
);
|
);
|
|
|
|
|
|
|
--
|
--
|
--
|
--
|
--
|
--
|
stims_p : process
|
stims_p : process
|
|
|
file test_pattern_file : text;
|
file test_pattern_file : text;
|
file error_pattern_file : text;
|
file error_pattern_file : text;
|
variable file_status : file_open_status;
|
variable file_status : file_open_status;
|
variable input_line : line;
|
variable input_line : line;
|
variable input_line_bak : line;
|
variable input_line_bak : line;
|
variable good : boolean;
|
variable good : boolean;
|
|
|
type values_t is array ( 0 to 7 ) of integer;
|
type values_t is array ( 0 to 7 ) of integer;
|
variable tmp_value : values_t;
|
variable tmp_value : values_t;
|
|
|
variable x_ex : std_logic_vector( x_o'range );
|
variable x_ex : std_logic_vector( x_o'range );
|
variable y_ex : std_logic_vector( y_o'range );
|
variable y_ex : std_logic_vector( y_o'range );
|
variable a_ex : std_logic_vector( a_o'range );
|
variable a_ex : std_logic_vector( a_o'range );
|
variable err_cnt : integer := 0;
|
variable err_cnt : integer := 0;
|
variable stim_cnt : integer := 0;
|
variable stim_cnt : integer := 0;
|
begin
|
begin
|
|
|
err_cnt := 0;
|
err_cnt := 0;
|
|
|
--
|
--
|
-- open file
|
-- open file
|
--
|
--
|
file_open( file_status, test_pattern_file, stim_file, READ_MODE );
|
file_open( file_status, test_pattern_file, stim_file, READ_MODE );
|
if file_status /= open_ok then
|
if file_status /= open_ok then
|
report "unable to open input stimulation file, please use cordic_iterative_test.m to create stimulation file" severity error;
|
report "unable to open input stimulation file, please use cordic_iterative_test.m to create stimulation file" severity error;
|
stop( -1 );
|
stop( -1 );
|
end if;
|
end if;
|
file_open( file_status, error_pattern_file, err_file, WRITE_MODE );
|
file_open( file_status, error_pattern_file, err_file, WRITE_MODE );
|
if file_status /= open_ok then
|
if file_status /= open_ok then
|
report "unable to open output error file" severity error;
|
report "unable to open output error file" severity error;
|
stop( -1 );
|
stop( -1 );
|
end if;
|
end if;
|
|
|
-- wait some cycles
|
-- wait some cycles
|
x_i <= ( others => '0' );
|
x_i <= ( others => '0' );
|
y_i <= ( others => '0' );
|
y_i <= ( others => '0' );
|
a_i <= ( others => '0' );
|
a_i <= ( others => '0' );
|
mode_i <= ( others => '0' );
|
mode_i <= ( others => '0' );
|
start <= '0';
|
start <= '0';
|
wait for clk_T * 20;
|
wait for clk_T * 20;
|
|
|
wait until clk'event and clk='1';
|
wait until clk'event and clk='1';
|
|
|
while ( not endfile( test_pattern_file ) )loop
|
while ( not endfile( test_pattern_file ) )loop
|
|
|
wait until en='1';
|
wait until en='1';
|
wait for clk_T;
|
wait for clk_T;
|
|
|
|
|
-- read line and extract values
|
-- read line and extract values
|
readline( test_pattern_file, input_line );
|
readline( test_pattern_file, input_line );
|
input_line_bak := new string'( input_line.ALL );
|
input_line_bak := new string'( input_line.ALL );
|
for i in 0 to 6 loop
|
for i in 0 to 6 loop
|
read( input_line, tmp_value(i), good );
|
read( input_line, tmp_value(i), good );
|
--report "rd: "& integer'image( i ) & " : " & integer'image( tmp_value( i ) );
|
--report "rd: "& integer'image( i ) & " : " & integer'image( tmp_value( i ) );
|
end loop;
|
end loop;
|
|
|
-- assign values to DUT
|
-- assign values to DUT
|
x_i <= std_logic_vector( to_signed ( tmp_value(0), x_i'length ) );
|
x_i <= std_logic_vector( to_signed ( tmp_value(0), x_i'length ) );
|
y_i <= std_logic_vector( to_signed ( tmp_value(1), y_i'length ) );
|
y_i <= std_logic_vector( to_signed ( tmp_value(1), y_i'length ) );
|
a_i <= std_logic_vector( to_signed ( tmp_value(2), a_i'length ) );
|
a_i <= std_logic_vector( to_signed ( tmp_value(2), a_i'length ) );
|
x_ex := std_logic_vector( to_signed ( tmp_value(3), x_ex'length ) );
|
x_ex := std_logic_vector( to_signed ( tmp_value(3), x_ex'length ) );
|
y_ex := std_logic_vector( to_signed ( tmp_value(4), y_ex'length ) );
|
y_ex := std_logic_vector( to_signed ( tmp_value(4), y_ex'length ) );
|
a_ex := std_logic_vector( to_signed ( tmp_value(5), a_ex'length ) );
|
a_ex := std_logic_vector( to_signed ( tmp_value(5), a_ex'length ) );
|
mode_i <= std_logic_vector( to_unsigned( tmp_value(6), mode_i'length ) );
|
mode_i <= std_logic_vector( to_unsigned( tmp_value(6), mode_i'length ) );
|
-- start the DUT and wait, until the DUT is done
|
-- start the DUT and wait, until the DUT is done
|
start <= '1';
|
start <= '1';
|
wait for clk_T;
|
wait for clk_T;
|
start <= '0';
|
start <= '0';
|
|
|
wait until done = '1';
|
wait until done = '1';
|
wait until clk'event and clk='1';
|
wait until clk'event and clk='1';
|
stim_cnt := stim_cnt+1;
|
stim_cnt := stim_cnt+1;
|
|
|
if x_ex /= x_o or
|
if x_ex /= x_o or
|
y_ex /= y_o or
|
y_ex /= y_o or
|
a_ex /= a_o then
|
a_ex /= a_o then
|
assert x_ex = x_o report
|
assert x_ex = x_o report
|
<<<<<<< HEAD
|
|
<<<<<<< HEAD
|
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected x result:"
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected x result:"
|
& integer'image( tmp_value(3) ) & ", but got:"
|
& integer'image( tmp_value(3) ) & ", but got:"
|
& integer'image( to_integer( signed( x_o ) ) );
|
& integer'image( to_integer( signed( x_o ) ) );
|
assert y_ex = y_o report
|
assert y_ex = y_o report
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected y result:"
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected y result:"
|
& integer'image( tmp_value(4) ) & ", but got:"
|
& integer'image( tmp_value(4) ) & ", but got:"
|
& integer'image( to_integer( signed( y_o ) ) );
|
& integer'image( to_integer( signed( y_o ) ) );
|
assert a_ex = a_o report
|
assert a_ex = a_o report
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected a result:"
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected a result:"
|
<<<<<<< HEAD
|
|
=======
|
|
" Serial Cordic Failed: expected x result:"
|
|
=======
|
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected x result:"
|
|
>>>>>>> Updated C and RTL model as well as the documentation
|
|
& integer'image( tmp_value(5) ) & ", but got:"
|
|
& integer'image( to_integer( signed( x_ex ) ) );
|
|
assert y_ex = y_o report
|
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected y result:"
|
|
& integer'image( tmp_value(6) ) & ", but got:"
|
|
& integer'image( to_integer( signed( y_ex ) ) );
|
|
assert a_ex = a_o report
|
|
<<<<<<< HEAD
|
|
" Serial Cordic Failed: expected a result:"
|
|
>>>>>>> initial commit
|
|
=======
|
|
integer'image( stim_cnt ) & ": Serial Cordic Failed: expected a result:"
|
|
>>>>>>> Updated C and RTL model as well as the documentation
|
|
& integer'image( tmp_value(7) ) & ", but got:"
|
|
& integer'image( to_integer( signed( a_ex ) ) );
|
|
=======
|
|
& integer'image( tmp_value(5) ) & ", but got:"
|
& integer'image( tmp_value(5) ) & ", but got:"
|
& integer'image( to_integer( signed( a_o ) ) );
|
& integer'image( to_integer( signed( a_o ) ) );
|
>>>>>>> Removed some bugs regarding pre-rotation and negative numbers in the wb wrapper
|
|
err_cnt := err_cnt + 1;
|
err_cnt := err_cnt + 1;
|
writeline( error_pattern_file, input_line_bak );
|
writeline( error_pattern_file, input_line_bak );
|
|
|
end if;
|
end if;
|
|
|
wait for CLK_T * 5;
|
wait for CLK_T * 5;
|
|
|
end loop;
|
end loop;
|
report "====>>>> Serial Cordic Verification Result:" & integer'image( err_cnt ) & " of " & integer'image( stim_cnt ) & " tests failed";
|
report "====>>>> Serial Cordic Verification Result:" & integer'image( err_cnt ) & " of " & integer'image( stim_cnt ) & " tests failed";
|
stop( 0 );
|
stop( 0 );
|
end process stims_p;
|
end process stims_p;
|
|
|
|
|
|
|
|
|
en_test : process
|
en_test : process
|
begin
|
begin
|
en <= '0';
|
en <= '0';
|
wait for clk_T * 10;
|
wait for clk_T * 10;
|
en <= '1';
|
en <= '1';
|
wait for clk_T * 1000;
|
wait for clk_T * 1000;
|
|
|
end process;
|
end process;
|
|
|
|
|
end architecture IMP;
|
end architecture IMP;
|
|
|
|
|
|
|
|
|
|
|