diff --git a/projects/cordic/Makefile b/projects/cordic/Makefile new file mode 100644 index 0000000..02b059c --- /dev/null +++ b/projects/cordic/Makefile @@ -0,0 +1,61 @@ +# ------------------------------------------------- +# Global options +# ------------------------------------------------- +LANG_STD := 93c +IEEE_STD := standard +WORK_PATH := work +SOURCE_PATH := src +LIB_PATH := ../lib + +# ------------------------------------------------- +# Target options +# ------------------------------------------------- +TARGET := tb_cordic_top + +SOURCES := src/cordic_pkg.vhd \ + src/cordic_rom.vhd \ + src/cordic_stage_pre.vhd \ + src/cordic_stage.vhd \ + src/cordic_stage_post.vhd \ + src/cordic_top.vhd \ + src/tb_cordic_top.vhd + + +# ------------------------------------------------- +GHDL_OPT := --workdir=$(WORK_PATH) --std=$(LANG_STD) --ieee=$(IEEE_STD) + +# ------------------------------------------------- +all: elaborate + +.PHONY: syntax +syntax: + ghdl -s $(GHDL_OPT) $(SOURCES) + +import: + ghdl -i $(GHDL_OPT) $(LIB_PATH)/*.vhd $(SOURCES) + +analyze: + ghdl -a $(GHDL_OPT) $(LIB_PATH)/*.vhd $(SOURCES) + +anaborate: + ghdl -c $(GHDL_OPT) $(LIB_PATH)/*.vhd $(SOURCES) -e $(TARGET) + +makeunit: analyze + ghdl -m $(GHDL_OPT) $(TARGET) + +elaborate: analyze + ghdl -e $(GHDL_OPT) $(TARGET) + +run: elaborate + ghdl -r $(GHDL_OPT) $(TARGET) --vcd=$(TARGET).vcd --assert-level=error + +show: $(TARGET).vcd + gtkwave $(TARGET).vcd $(TARGET).sav + +# ------------------------------------------------- +.PHONY: clean +clean: + rm -rf $(TARGET) + cd $(WORK_PATH); rm -rf *.o *.cf + +# ------------------------------------------------- diff --git a/projects/cordic/eval_cordic.m b/projects/cordic/eval_cordic.m new file mode 100644 index 0000000..b64a87a --- /dev/null +++ b/projects/cordic/eval_cordic.m @@ -0,0 +1,10 @@ +% function eval_cordic(x0,y0,z0, mode) +function eval_cordic(x0,y0,z0, mode) + +if (mode == 'rot') + Xn = x0*cos(z0) - y0*sin(z0) + Yn = y0*cos(z0) + x0*sin(z0) +else + Xn = sqrt(x0^2 + y0^2) + Yn = z0 + atan(y0/x0) +end; \ No newline at end of file diff --git a/projects/cordic/src/cordic_pkg.vhd b/projects/cordic/src/cordic_pkg.vhd new file mode 100644 index 0000000..cf28dd5 --- /dev/null +++ b/projects/cordic/src/cordic_pkg.vhd @@ -0,0 +1,194 @@ + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; +use work.fixed_ja.all; + +package cordic_pkg is + + constant tpd : time := 0 ns; + + type cordic_mode_t is (none, cordic_mode_rotate, cordic_mode_vector); + type reg_mode_t is (none, reg_mode_in, reg_mode_out, reg_mode_inout); + + -- Global set arithmetic rounding mode + constant cordic_round_mode : round_mode_t := round_nearest; + + -- Global set arithmetic saturating mode + constant cordic_saturate_mode : saturate_mode_t := saturate; + + constant max_iteration : integer := 80; + constant pi : real := 3.141592653589793e+000; + constant sqrt2 : real := 1.414213562373095e+000; + constant sqrt2_inv : real := 7.071067811865475e-001; + + type real_tbl_t is array (natural range <>) of real; + constant arctan_tbl : real_tbl_t (0 to max_iteration-1) := + ( + 7.853981633974483e-001, + 4.636476090008061e-001, + 2.449786631268641e-001, + 1.243549945467614e-001, + 6.241880999595735e-002, + 3.123983343026828e-002, + 1.562372862047683e-002, + 7.812341060101111e-003, + 3.906230131966972e-003, + 1.953122516478819e-003, + 9.765621895593195e-004, + 4.882812111948983e-004, + 2.441406201493618e-004, + 1.220703118936702e-004, + 6.103515617420877e-005, + 3.051757811552610e-005, + 1.525878906131576e-005, + 7.629394531101970e-006, + 3.814697265606496e-006, + 1.907348632810187e-006, + 9.536743164059608e-007, + 4.768371582030888e-007, + 2.384185791015580e-007, + 1.192092895507807e-007, + 5.960464477539055e-008, + 2.980232238769530e-008, + 1.490116119384766e-008, + 7.450580596923828e-009, + 3.725290298461914e-009, + 1.862645149230957e-009, + 9.313225746154785e-010, + 4.656612873077393e-010, + 2.328306436538696e-010, + 1.164153218269348e-010, + 5.820766091346741e-011, + 2.910383045673370e-011, + 1.455191522836685e-011, + 7.275957614183426e-012, + 3.637978807091713e-012, + 1.818989403545857e-012, + 9.094947017729282e-013, + 4.547473508864641e-013, + 2.273736754432321e-013, + 1.136868377216160e-013, + 5.684341886080802e-014, + 2.842170943040401e-014, + 1.421085471520200e-014, + 7.105427357601002e-015, + 3.552713678800501e-015, + 1.776356839400251e-015, + 8.881784197001252e-016, + 4.440892098500626e-016, + 2.220446049250313e-016, + 1.110223024625157e-016, + 5.551115123125783e-017, + 2.775557561562891e-017, + 1.387778780781446e-017, + 6.938893903907228e-018, + 3.469446951953614e-018, + 1.734723475976807e-018, + 8.673617379884036e-019, + 4.336808689942018e-019, + 2.168404344971009e-019, + 1.084202172485504e-019, + 5.421010862427522e-020, + 2.710505431213761e-020, + 1.355252715606881e-020, + 6.776263578034403e-021, + 3.388131789017201e-021, + 1.694065894508601e-021, + 8.470329472543003e-022, + 4.235164736271502e-022, + 2.117582368135751e-022, + 1.058791184067875e-022, + 5.293955920339377e-023, + 2.646977960169689e-023, + 1.323488980084844e-023, + 6.617444900424221e-024, + 3.308722450212111e-024, + 1.654361225106055e-024 + ); + + constant gain_tbl : real_tbl_t (0 to max_iteration-1) := + ( + 7.071067811865475e-001, + 6.324555320336759e-001, + 6.135719910778963e-001, + 6.088339125177524e-001, + 6.076482562561681e-001, + 6.073517701412959e-001, + 6.072776440935260e-001, + 6.072591122988928e-001, + 6.072544793325624e-001, + 6.072533210898752e-001, + 6.072530315291344e-001, + 6.072529591389448e-001, + 6.072529410413973e-001, + 6.072529365170103e-001, + 6.072529353859135e-001, + 6.072529351031394e-001, + 6.072529350324457e-001, + 6.072529350147724e-001, + 6.072529350103540e-001, + 6.072529350092495e-001, + 6.072529350089733e-001, + 6.072529350089043e-001, + 6.072529350088870e-001, + 6.072529350088827e-001, + 6.072529350088816e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001, + 6.072529350088813e-001 + ); + +end; -- package cordig_pkg; diff --git a/projects/cordic/src/cordic_rom.vhd b/projects/cordic/src/cordic_rom.vhd new file mode 100644 index 0000000..9d93ee2 --- /dev/null +++ b/projects/cordic/src/cordic_rom.vhd @@ -0,0 +1,80 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:37:26 10/02/05 +-- Design Name: +-- Module Name: coeff_rom - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +library work; +use work.fixed_ja.all; +use work.cordic_pkg.all; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity rom_arctan is + Generic + ( + nbits : integer := 8; + nbits_int : integer := 0 + ); + Port + ( + addr : in unsigned(6 downto 0); + dout : out sfixed_t + ); +end rom_arctan; + +architecture Behavioral of rom_arctan is + +subtype word_t is sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); +type rom_t is array (natural range <>) of word_t; + +------------------------------------------------------------------------------- +function rom_gen(nstages : integer; round_mode : round_mode_t) return rom_t is +variable rom : rom_t (0 to nstages-1); +variable word : word_t; +begin + + for i in 0 to nstages-1 loop + word := to_sfixed(arctan_tbl(i), word, round_mode); + rom(i) := word; + end loop; + + return rom; +end rom_gen; + +------------------------------------------------------------------------------- +-- Create ROM +constant arctan_rom : rom_t (0 to max_iteration-1) := rom_gen(max_iteration, cordic_round_mode); + +------------------------------------------------------------------------------- + +begin + +-- ROM implementation +rom_arctan: process(addr) +begin + dout <= arctan_rom(to_integer(addr)); +end process; + +------------------------------------------------------------------------------- +end Behavioral; diff --git a/projects/cordic/src/cordic_stage.vhd b/projects/cordic/src/cordic_stage.vhd new file mode 100644 index 0000000..f287b59 --- /dev/null +++ b/projects/cordic/src/cordic_stage.vhd @@ -0,0 +1,285 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:16:14 10/02/05 +-- Design Name: +-- Module Name: cordic_stage - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; +use work.fixed_ja.all; +use work.cordic_pkg.all; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity cordic_stage is +Generic +( + nbits : integer := 8; + nbits_int : integer := 2; + nbits_out : integer := 8; + nbits_int_out : integer := 2; + reg_mode : reg_mode_t := reg_mode_in +); +Port +( + clk : in std_logic; + rst : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + coeff : in sfixed_t; + dir_cw : in std_logic; + stage_count : in integer; + cordic_mode : in cordic_mode_t; + ready : out std_logic; + valid : out std_logic +); +end cordic_stage; + +architecture Behavioral of cordic_stage is + +type xyz_in_t is record + x : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + y : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + z : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); +end record; + +type xyz_out_t is record + x : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + y : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + z : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); +end record; + +constant zero_in_sfix : sfixed_t := to_sfixed(0.0, nbits, nbits_int); +constant zero_out_sfix : sfixed_t := to_sfixed(0.0, nbits_out, nbits_int_out); + +signal xyz_in : xyz_in_t; +signal xyz_out : xyz_out_t; +signal valid_r, ready_r : std_logic; + +begin +------------------------------------------------------------ +gen_direct: if reg_mode = none generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; +------------------------------------------------------------ + +gen_reg_in: if (reg_mode = reg_mode_in) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_out: if (reg_mode = reg_mode_out) generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_inout: if (reg_mode = reg_mode_inout) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + +end generate; + +------------------------------------------------------------ +cordic_proc_stage: process(rst, clk, ce, stage_count, coeff, dir_cw, xyz_in) +variable dir_cw_r : std_logic; +variable stage_count_r : integer range 0 to nbits-1; +variable x2, y2 : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + +begin + + if (rst = '1') then + dir_cw_r := dir_cw; + stage_count_r := 0; + x2 := zero_in_sfix; + y2 := zero_in_sfix; + xyz_out.x <= zero_out_sfix; + xyz_out.y <= zero_out_sfix; + xyz_out.z <= zero_out_sfix; + else + if (clk'event and clk = '1') then + dir_cw_r := dir_cw; + stage_count_r := stage_count; + end if; + + x2 := xyz_in.x sra stage_count_r; + y2 := xyz_in.y sra stage_count_r; + + if (dir_cw_r = '1') then + xyz_out.x <= to_sfixed(xyz_in.x + y2, nbits_out, nbits_int_out) after tpd; + xyz_out.y <= to_sfixed(xyz_in.y - x2, nbits_out, nbits_int_out) after tpd; + xyz_out.z <= to_sfixed(xyz_in.z + coeff, nbits_out, nbits_int_out) after tpd; + else + xyz_out.x <= to_sfixed(xyz_in.x - y2, nbits_out, nbits_int_out) after tpd; + xyz_out.y <= to_sfixed(xyz_in.y + x2, nbits_out, nbits_int_out) after tpd; + xyz_out.z <= to_sfixed(xyz_in.z - coeff, nbits_out, nbits_int_out) after tpd; + end if; + end if; +end process; + +------------------------------------------------------------ +end Behavioral; diff --git a/projects/cordic/src/cordic_stage_post.vhd b/projects/cordic/src/cordic_stage_post.vhd new file mode 100644 index 0000000..49ecf16 --- /dev/null +++ b/projects/cordic/src/cordic_stage_post.vhd @@ -0,0 +1,273 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:16:14 10/02/05 +-- Design Name: +-- Module Name: cordic_stage_post - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; +use work.fixed_ja.all; +use work.cordic_pkg.all; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity cordic_stage_post is +Generic +( + nbits : integer := 8; + nbits_int : integer := 2; + nbits_out : integer := 8; + nbits_int_out : integer := 2; + reg_mode : reg_mode_t := reg_mode_in +); +Port +( + clk : in std_logic; + rst : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + cordic_mode : in cordic_mode_t; + ready : out std_logic; + valid : out std_logic +); +end cordic_stage_post; + +architecture Behavioral of cordic_stage_post is + +type xyz_in_t is record + x : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + y : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + z : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); +end record; + +type xyz_out_t is record + x : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + y : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + z : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); +end record; + +constant zero_in_sfix : sfixed_t := to_sfixed(0.0, nbits, nbits_int); +constant zero_out_sfix : sfixed_t := to_sfixed(0.0, nbits_out, nbits_int_out); + +signal xyz_in : xyz_in_t; +signal xyz_out : xyz_out_t; +signal valid_r, ready_r : std_logic; + +------------------------------------------------------------ +begin + +gen_direct: if reg_mode = none generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; +------------------------------------------------------------ + +gen_reg_in: if (reg_mode = reg_mode_in) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_out: if (reg_mode = reg_mode_out) generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_inout: if (reg_mode = reg_mode_inout) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + + end generate; + +------------------------------------------------------------ +cordic_post_stage: process(xyz_in, cordic_mode) +begin + + xyz_out.x <= to_sfixed(xyz_in.x, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(xyz_in.y, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z, nbits_out, nbits_int_out); + + case cordic_mode is + + when cordic_mode_rotate => + + xyz_out.x <= to_sfixed(xyz_in.x * to_sfixed(gain_tbl(nbits_out-1), xyz_in.x), nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + xyz_out.y <= to_sfixed(xyz_in.y * to_sfixed(gain_tbl(nbits_out-1), xyz_in.y), nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + xyz_out.z <= to_sfixed(xyz_in.z, nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + + when cordic_mode_vector => + + xyz_out.x <= to_sfixed(xyz_in.x * to_sfixed(gain_tbl(nbits_out-1), xyz_in.x), nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + xyz_out.y <= to_sfixed(xyz_in.y, nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + xyz_out.z <= to_sfixed(xyz_in.z, nbits_out, nbits_int_out, cordic_round_mode, cordic_saturate_mode); + + when others => null; + + end case; +end process; + +------------------------------------------------------------ +end Behavioral; diff --git a/projects/cordic/src/cordic_stage_pre.vhd b/projects/cordic/src/cordic_stage_pre.vhd new file mode 100644 index 0000000..008908f --- /dev/null +++ b/projects/cordic/src/cordic_stage_pre.vhd @@ -0,0 +1,314 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:16:14 10/02/05 +-- Design Name: +-- Module Name: cordic_stage_pre - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; +use work.fixed_ja.all; +use work.cordic_pkg.all; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity cordic_stage_pre is +Generic +( + nbits : integer := 8; + nbits_int : integer := 2; + nbits_out : integer := 8; + nbits_int_out : integer := 2; + reg_mode : reg_mode_t := reg_mode_in +); +Port +( + clk : in std_logic; + rst : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + cordic_mode : in cordic_mode_t; + ready : out std_logic; + valid : out std_logic +); +end cordic_stage_pre; + +architecture Behavioral of cordic_stage_pre is + +type xyz_in_t is record + x : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + y : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + z : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); +end record; + +type xyz_out_t is record + x : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + y : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); + z : sfixed_t(sproto(nbits_out, nbits_int_out)'high downto sproto(nbits_out, nbits_int_out)'low); +end record; + +constant zero_in_sfix : sfixed_t := to_sfixed(0.0, nbits, nbits_int); +constant zero_out_sfix : sfixed_t := to_sfixed(0.0, nbits_out, nbits_int_out); +constant pi_out_sfix : sfixed_t := to_sfixed(pi, nbits_out, nbits_int_out); +constant pi2_out_sfix : sfixed_t := to_sfixed(pi/2.0, nbits_out, nbits_int_out); +constant pi2_in_sfix : sfixed_t := to_sfixed(pi/2.0, nbits, nbits_int); + +signal xyz_in : xyz_in_t; +signal xyz_out : xyz_out_t; +signal valid_r, ready_r : std_logic; + +------------------------------------------------------------ +begin + +gen_direct: if reg_mode = none generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; +------------------------------------------------------------ + +gen_reg_in: if (reg_mode = reg_mode_in) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + else + ready <= ready_r; + valid <= valid_r; + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_out: if (reg_mode = reg_mode_out) generate + + reg_in : process (rst, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + else + ready_r <= '1'; + valid_r <= ce; + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + +end generate; + +------------------------------------------------------------ +gen_reg_inout: if (reg_mode = reg_mode_inout) generate + + reg_in : process (rst, clk, ce, xin, yin, zin) + begin + if (rst = '1') then + ready_r <= '0'; + valid_r <= '0'; + xyz_in.x <= zero_in_sfix; + xyz_in.y <= zero_in_sfix; + xyz_in.z <= zero_in_sfix; + elsif rising_edge(clk) then + ready_r <= '1'; + valid_r <= ce; + if (ce = '1') then + xyz_in.x <= to_sfixed(xin, nbits, nbits_int); + xyz_in.y <= to_sfixed(yin, nbits, nbits_int); + xyz_in.z <= to_sfixed(zin, nbits, nbits_int); + end if; + end if; + end process; + + reg_out : process (rst, clk, ce, ready_r, valid_r, xyz_out) + begin + if (rst = '1') then + ready <= '0'; + valid <= '0'; + xout <= zero_out_sfix; + yout <= zero_out_sfix; + zout <= zero_out_sfix; + elsif rising_edge(clk) then + ready <= ready_r; + valid <= valid_r; + if (ce = '1') then + xout <= xyz_out.x; + yout <= xyz_out.y; + zout <= xyz_out.z; + end if; + end if; + end process; + + end generate; + +------------------------------------------------------------ +cordic_proc_pre_stage: process(xyz_in, cordic_mode) +begin + + xyz_out.x <= to_sfixed(xyz_in.x, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(xyz_in.y, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z, nbits_out, nbits_int_out); + + case cordic_mode is + + when cordic_mode_rotate => + + if (xyz_in.z < -pi2_in_sfix) then + xyz_out.x <= to_sfixed(-xyz_in.x, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(-xyz_in.y, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z + pi_out_sfix, nbits_out, nbits_int_out); + elsif (xyz_in.z > pi2_in_sfix) then + xyz_out.x <= to_sfixed(-xyz_in.x, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(-xyz_in.y, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z - pi_out_sfix, nbits_out, nbits_int_out); + end if; + + + when cordic_mode_vector => + +-- if (xyz_in.x < zero_in_sfix) then +-- xyz_out.x <= to_sfixed(-xyz_in.x, nbits_out, nbits_int_out); +-- xyz_out.y <= to_sfixed(-xyz_in.y, nbits_out, nbits_int_out); +-- xyz_out.z <= to_sfixed(xyz_in.z - pi_out_sfix, nbits_out, nbits_int_out); +-- end if; + if (xyz_in.y < zero_in_sfix) then + xyz_out.x <= to_sfixed(-xyz_in.y, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(xyz_in.x, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z + pi2_out_sfix, nbits_out, nbits_int_out); + else + xyz_out.x <= to_sfixed(xyz_in.y, nbits_out, nbits_int_out); + xyz_out.y <= to_sfixed(-xyz_in.x, nbits_out, nbits_int_out); + xyz_out.z <= to_sfixed(xyz_in.z - pi2_out_sfix, nbits_out, nbits_int_out); + end if; + + when others => null; + + end case; +end process; + +------------------------------------------------------------ +end Behavioral; + +-- if (y < 0) then +-- x' = -y +-- y' = x +-- z' = z + pi/2; +-- else +-- x' = y +-- y' = -x +-- z' = z - pi/2; +-- end if; +-- +-- if (x < 0) then +-- x' = -x; +-- y' = -y; +-- z' = z - pi +-- else +-- x' = x; +-- y' = y; +-- z' = z +-- end if; diff --git a/projects/cordic/src/cordic_top.vhd b/projects/cordic/src/cordic_top.vhd new file mode 100644 index 0000000..4e852c2 --- /dev/null +++ b/projects/cordic/src/cordic_top.vhd @@ -0,0 +1,460 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 11:52:30 10/02/05 +-- Design Name: +-- Module Name: cordic_top - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.MATH_REAL.ALL; +USE ieee.numeric_std.ALL; +use work.fixed_ja.all; +use work.cordic_pkg.all; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; +entity cordic_top is +Generic +( + nbits : integer := 8; + nbits_int : integer := 2; + nbits_out : integer := 8; + nbits_out_int : integer := 2 +); +Port ( + rst : in std_logic; + clk : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + ready : out std_logic; + valid : out std_logic; + cordic_mode : in cordic_mode_t +); +end cordic_top; + +architecture Behavioral of cordic_top is + +----------------------------------------------------------------------- +COMPONENT cordic_stage_pre is +GENERIC +( + nbits : integer; + nbits_int : integer; + nbits_out : integer; + nbits_int_out : integer; + reg_mode : reg_mode_t +); +PORT +( + rst : in std_logic; + clk : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + cordic_mode : in cordic_mode_t; + ready : OUT std_logic; + valid : out std_logic +); +END COMPONENT; + +COMPONENT cordic_stage +GENERIC +( + nbits : integer; + nbits_int : integer; + nbits_out : integer; + nbits_int_out : integer; + reg_mode : reg_mode_t +); +PORT( + rst : IN std_logic; + clk : IN std_logic; + ce : IN std_logic; + xin : IN sfixed_t; + yin : IN sfixed_t; + zin : IN sfixed_t; + xout : OUT sfixed_t; + yout : OUT sfixed_t; + zout : OUT sfixed_t; + coeff : in sfixed_t; + dir_cw : in std_logic; + stage_count : IN integer; + cordic_mode : in cordic_mode_t; + ready : OUT std_logic; + valid : out std_logic +); +END COMPONENT; + +COMPONENT cordic_stage_post is +GENERIC +( + nbits : integer; + nbits_int : integer; + nbits_out : integer; + nbits_int_out : integer; + reg_mode : reg_mode_t +); +PORT +( + rst : in std_logic; + clk : in std_logic; + ce : in std_logic; + xin : in sfixed_t; + yin : in sfixed_t; + zin : in sfixed_t; + xout : out sfixed_t; + yout : out sfixed_t; + zout : out sfixed_t; + cordic_mode : in cordic_mode_t; + ready : OUT std_logic; + valid : out std_logic +); +END COMPONENT; + +COMPONENT rom_arctan is +GENERIC +( + nbits : integer := 8; + nbits_int : integer := 0 +); +PORT +( + addr : in unsigned(6 downto 0); + dout : out sfixed_t +); +END COMPONENT; + +----------------------------------------------------------------------- +type state_type is (st_input, st_ready, st_pre_stage_in, st_pre_stage_out, st_proc_stage_in, st_proc_stage_out, st_post_stage_in, st_post_stage_out); + +constant zero_sfix : sfixed_t := to_sfixed(0.0, nbits_out, nbits_out_int); + +-- Define number of LSB guard bits +constant guard_nbits : integer := integer(log2(real(nbits))+0.5); + +-- Define number of internal stage bits +constant stage_nbits : integer := nbits + guard_nbits; -- add more internal precision +constant stage_nbits_int : integer := nbits_int; + +-- Set number of coefficient bits +constant coeff_nbits : integer := stage_nbits - stage_nbits_int; +constant coeff_nbits_int : integer := 0; -- coeffs have no integer part + +-- Set number of iteration with respect to bit size +constant max_stage_count : integer := stage_nbits; + +-- INPUT +-- Input pre stage +signal pre_stage_en : std_logic; +signal xin_pre, yin_pre, zin_pre : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + +-- Output pre stage +signal pre_stage_ready, pre_stage_valid : std_logic; +signal xout_pre, yout_pre, zout_pre : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low); + +-- Input processing stage +signal proc_stage_en: std_logic; +signal xin_stage, yin_stage, zin_stage : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low); + +-- Output processing stage +signal proc_stage_ready, proc_stage_valid : std_logic; +signal xout_stage, yout_stage, zout_stage : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low); + +-- Input post stage +signal post_stage_en : std_logic; +signal xin_post, yin_post, zin_post : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low); + +-- Output post stage +signal post_stage_ready, post_stage_valid : std_logic; +signal xout_post, yout_post, zout_post : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low); + +-- ROM +signal rom_addr : unsigned (6 downto 0); +signal rom_data : sfixed_t(sproto(coeff_nbits, coeff_nbits_int)'high downto sproto(coeff_nbits, coeff_nbits_int)'low); + +-- Misc. +signal state, next_state : state_type; +signal count : integer range 0 to max_stage_count-1 := 0; +signal count_en, dir_cw, valid_s : std_logic; + + +begin + +----------------------------------------------------------------------- +cordic_proc_mode : process(rst, zin_stage, yin_stage, cordic_mode) + +begin + + if (rst = '1') then + dir_cw <= '0'; + else + dir_cw <= '0'; + case cordic_mode is + + when cordic_mode_rotate => + if (zin_stage(zin_stage'high) = '1') then + dir_cw <= '1'; + end if; + + when cordic_mode_vector => + if (yin_stage(yin_stage'high) = '1') then + dir_cw <= '0'; + else + dir_cw <= '1'; + end if; + + when others => null; + + end case; + end if; +end process; + +----------------------------------------------------------------------- +counter: process (clk, rst, count, count_en) +begin + if (rst = '1') then + count <= 0; + rom_addr <= (others => '0'); + else + if (clk'event and clk = '1') then + rom_addr <= to_unsigned(count, rom_addr'length); + if (count_en = '1' and count < max_stage_count-1) then + count <= count + 1 after tpd; + else + count <= 0; + end if; + end if; + end if; +end process; + +----------------------------------------------------------------------- +OUTPUT_PROC: process (clk, rst, state, xout_stage, yout_stage, zout_stage) +begin + if (rst='1') then + valid <= '0'; + xout <= zero_sfix after tpd; + yout <= zero_sfix after tpd; + zout <= zero_sfix after tpd; + + -- assign other outputs to reset value + elsif (clk'event and clk = '1') then + valid <= '0'; + if(post_stage_valid = '1') then + xout <= xout_post; + yout <= yout_post; + zout <= zout_post; + valid <= '1'; + end if; + end if; +end process; + +----------------------------------------------------------------------- +--Insert the following in the architecture after the begin keyword + FSM_PROC: process (clk, rst, xout_stage, yout_stage, zout_stage) + begin + if (rst='1') then + state <= st_ready; + -- assign other outputs to reset value + elsif (clk'event and clk = '1') then + state <= next_state after tpd; + -- assign other outputs to internal signals + end if; + end process; + + --MOORE State Machine - Outputs based on state only +Control_proc: process (state, xin, yin, zin, xout_pre, yout_pre, zout_pre, xout_stage, yout_stage, zout_stage) +begin + --insert statements to decode internal output signals + --below is simple example + ready <= '0'; + valid_s <= '0'; + count_en <= '0'; + pre_stage_en <= '0'; + proc_stage_en <= '0'; + post_stage_en <= '0'; + + xin_pre <= xin; + yin_pre <= yin; + zin_pre <= zin; + xin_stage <= xout_stage; + yin_stage <= yout_stage; + zin_stage <= zout_stage; + xin_post <= xout_stage; + yin_post <= yout_stage; + zin_post <= zout_stage; + + case (state) is + when st_ready => + ready <= '1'; + when st_pre_stage_in => + pre_stage_en <= '1'; + when st_pre_stage_out => + count_en <= '1'; + proc_stage_en <= '1'; + xin_stage <= xout_pre; + yin_stage <= yout_pre; + zin_stage <= zout_pre; + when st_proc_stage_in => + count_en <= '1'; + proc_stage_en <= '1'; + when st_post_stage_in => + post_stage_en <= '1'; + + when others => + end case; +end process; + +NEXT_STATE_DECODE: process (state, ce, count) +begin + --declare default state for next_state to avoid latches + next_state <= state; --default is to stay in current state + --insert statements to decode next_state + --below is a simple example + case (state) is + when st_ready => + if ce = '1' then + next_state <= st_input; + end if; + + when st_input => + if ce = '0' then + next_state <= st_pre_stage_in; + end if; + + when st_pre_stage_in => + next_state <= st_pre_stage_out; + + when st_pre_stage_out => + next_state <= st_proc_stage_in; + + when st_proc_stage_in => + if (count = max_stage_count-2) then + next_state <= st_post_stage_in; + end if; + + when st_post_stage_in => + next_state <= st_ready; + + when others => + next_state <= st_ready; + + end case; +end process; + +----------------------------------------------------------------------- +Inst_cordic_stage_pre: cordic_stage_pre +GENERIC MAP +( + nbits => nbits, + nbits_int => nbits_int, + nbits_out => stage_nbits, + nbits_int_out => stage_nbits_int, + reg_mode => reg_mode_in +) +PORT MAP +( + rst => rst, + clk => clk, + ce => pre_stage_en, + xin => xin_pre, + yin => yin_pre, + zin => zin_pre, + xout => xout_pre, + yout => yout_pre, + zout => zout_pre, + ready => pre_stage_ready, + valid => pre_stage_valid, + cordic_mode => cordic_mode +); + +Inst_cordic_stage: cordic_stage +GENERIC MAP +( + nbits => stage_nbits, + nbits_int => stage_nbits_int, + nbits_out => stage_nbits, + nbits_int_out => stage_nbits_int, + reg_mode => reg_mode_in +) +PORT MAP +( + rst => rst, + clk => clk, + ce => proc_stage_en, + xin => xin_stage, + yin => yin_stage, + zin => zin_stage, + xout => xout_stage, + yout => yout_stage, + zout => zout_stage, + coeff => rom_data, + dir_cw => dir_cw, + stage_count => count, + ready => proc_stage_ready, + valid => proc_stage_valid, + cordic_mode => cordic_mode +); + +Inst_cordic_stage_post: cordic_stage_post +GENERIC MAP +( + nbits => stage_nbits, + nbits_int => stage_nbits_int, + nbits_out => nbits_out, + nbits_int_out => nbits_out_int, + reg_mode => reg_mode_in +) +PORT MAP +( + rst => rst, + clk => clk, + ce => post_stage_en, + xin => xin_post, + yin => yin_post, + zin => zin_post, + xout => xout_post, + yout => yout_post, + zout => zout_post, + ready => post_stage_ready, + valid => post_stage_valid, + cordic_mode => cordic_mode +); + +Inst_rom_arctan: rom_arctan +GENERIC MAP +( + nbits => coeff_nbits, + nbits_int => coeff_nbits_int +) +PORT MAP +( + addr => rom_addr, + dout => rom_data +); + +-------------------------------------------------------------------- +end Behavioral; diff --git a/projects/cordic/src/tb_cordic_top.vhd b/projects/cordic/src/tb_cordic_top.vhd new file mode 100644 index 0000000..545e111 --- /dev/null +++ b/projects/cordic/src/tb_cordic_top.vhd @@ -0,0 +1,645 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:16:42 10/02/2005 +-- Design Name: cordic_top +-- Module Name: tb_cordic_top.vhd +-- Project Name: cordic +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: cordic_top +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +-- Results:In 16i2 and Out 16i0 +------------------------------ +-- xmean = -3.051757808671257e-7 +-- ymean = 1.525878906192144e-6 +-- zmean = 0.0 +-- xvar = 7.723598281502283e-10 +-- yvar = 8.539443970667266e-10 +-- zvar = 0.0 +-- xstd = 2.779136247380161e-5 +-- ystd = 2.922232703031582e-5 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 16i2 and Out 16i1 +------------------------------ +-- xmean = 6.103515628828741e-7 +-- ymean = -1.220703125057855e-6 +-- zmean = 0.0 +-- xvar = 9.76293486677989e-10 +-- yvar = 7.934037490259732e-10 +-- zvar = 0.0 +-- xstd = 3.124569549038697e-5 +-- ystd = 2.816742354256017e-5 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 16i2 and Out 16i2 +------------------------------ +-- xmean = 2.441406250382875e-6 +-- ymean = -1.220703125057855e-6 +-- zmean = 0.0 +-- xvar = 2.126680036682826e-9 +-- yvar = 2.117107754473399e-9 +-- zvar = 0.0 +-- xstd = 4.611594124251206e-5 +-- ystd = 4.601203923402438e-5 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 32i2 and Out 32i0 +------------------------------ +-- xmean = -9.312842871812748e-12 +-- ymean = -5.78558739545293e-17 +-- zmean = 0.0 +-- xvar = 1.671709854744817e-19 +-- yvar = 1.790442305004033e-19 +-- zvar = 0.0 +-- xstd = 4.088654857951228e-10 +-- ystd = 4.231361843430591e-10 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 32i2 and Out 32i1 +------------------------------ +-- xmean = 9.313608620496825e-12 +-- ymean = 9.31316789028083e-12 +-- zmean = 0.0 +-- xvar = 1.876480788588237e-19 +-- yvar = 2.238344116260579e-19 +-- zvar = 0.0 +-- xstd = 4.331836548841885e-10 +-- ystd = 4.731114156581492e-10 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 32i2 and Out 32i2 +------------------------------ +-- xmean = -3.72525201102771e-11 +-- ymean = -5.78558739545293e-17 +-- zmean = 0.0 +-- xvar = 5.458335981037092e-19 +-- yvar = 5.704280631341228e-19 +-- zvar = 0.0 +-- xstd = 7.388055211648797e-10 +-- ystd = 7.552668820583376e-10 +-- zstd = 0.0 +-- +------------------------------ +-- Results:In 64i2 and Out 64i0 +------------------------------ +-- xmean = 3.45418680637588e-17 +-- ymean = 3.859475130978118e-17 +-- zmean = 2.205267218835516e-16 +-- xvar = 5.54111959258452e-28 +-- yvar = 5.549496221074054e-28 +-- zvar = 7.916891206490056e-29 +-- xstd = 2.353958281827551e-14 +-- ystd = 2.355736874329146e-14 +-- zstd = 8.897691389619023e-15 +-- +------------------------------ +-- Results:In 64i2 and Out 64i1 +------------------------------ +-- xmean = 3.45418680637588e-17 +-- ymean = 3.859475130978118e-17 +-- zmean = 2.205267218835516e-16 +-- xvar = 5.541120861185077e-28 +-- yvar = 5.549497432144743e-28 +-- zvar = 7.916856202525234e-29 +-- xstd = 2.353958551288674e-14 +-- ystd = 2.355737131376237e-14 +-- zstd = 8.897671719346156e-15 +-- +------------------------------ +-- Results:In 64i2 and Out 64i2 +------------------------------ +-- xmean = 3.343164503913365e-17 +-- ymean = 3.859475130978118e-17 +-- zmean = 2.205223850748616e-16 +-- xvar = 5.540559656182732e-28 +-- yvar = 5.549495010008071e-28 +-- zvar = 7.916821581863743e-29 +-- xstd = 2.353839343749427e-14 +-- ystd = 2.355736617283025e-14 +-- zstd = 8.897652264425568e-15 +-- +-------------------------------------------------------------------------------- +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.MATH_REAL.ALL; +USE ieee.numeric_std.ALL; +use std.textio.all; -- Imports the standard textio package. + +library work; +use work.fixed_ja.all; +use work.cordic_pkg.all; +use work.PCK_FIO.all; + +ENTITY tb_cordic_top IS + Generic ( + nbits : integer := 32; + nbits_int : integer := 2; + nbits_out : integer := 32; + nbits_out_int : integer := 1 + ); +END tb_cordic_top; + +ARCHITECTURE behavior OF tb_cordic_top IS + + -- Component Declaration for the Unit Under Test (UUT) + COMPONENT cordic_top + GENERIC ( + nbits : integer; + nbits_int : integer; + nbits_out : integer; + nbits_out_int : integer + ); + PORT( + rst : IN std_logic; + clk : IN std_logic; + ce : in std_logic; + xin : IN sfixed_t; + yin : IN sfixed_t; + zin : IN sfixed_t; + xout : OUT sfixed_t; + yout : OUT sfixed_t; + zout : OUT sfixed_t; + ready : OUT std_logic; + valid : out std_logic; + cordic_mode : in cordic_mode_t + ); + END COMPONENT; + + --Constants + constant num_cycles : integer := 5; + constant num_steps_per_cycle : integer := 100; + constant PERIOD : time := 10 ns; + + constant one_sfix : sfixed_t := to_sfixed(1.0, nbits, nbits_int); + constant zero_sfix : sfixed_t := to_sfixed(0.0, nbits, nbits_int); + + --Inputs + SIGNAL clk : std_logic := '0'; + SIGNAL rst : std_logic := '1'; + SIGNAL ce : std_logic := '0'; + SIGNAL xin, yin, zin : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low) := zero_sfix; + + --Outputs + SIGNAL xout, yout, zout : sfixed_t(sproto(nbits_out, nbits_out_int)'high downto sproto(nbits_out, nbits_out_int)'low); + SIGNAL valid, ready : std_logic; + SIGNAL cordic_mode : cordic_mode_t := cordic_mode_vector; + + + -------------------------------------------------------------------- + --Functions + -------------------------------------------------------------------- + type real_vector_t is array (natural range <>) of real; + function mean(x : real_vector_t; len : integer) return real is + variable xm : real := 0.0; + begin + for i in 0 to len-1 loop + xm := xm + x(i); + end loop; + + return xm / real(len); + end mean; + + -------------------------------------------------------------------- + function var(x : real_vector_t; len : integer) return real is + variable xv, xm, xp : real := 0.0; + begin + xm := mean(x, len); + + for i in 0 to len-1 loop + xp := x(i) - xm; + xv := xv + xp*xp; + end loop; + + return xv / real(len); + end var; + + -------------------------------------------------------------------- + function stddev(x : real_vector_t; len : integer) return real is + variable xv, xs : real := 0.0; + begin + xv := var(x, len); + if xv > 0.0 then + xs := sqrt(xv); + end if; + + return xs; + end stddev; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: cordic_top + GENERIC MAP ( + nbits => nbits, + nbits_int => nbits_int, + nbits_out => nbits_out, + nbits_out_int => nbits_out_int + ) + PORT MAP( + rst => rst, + clk => clk, + ce => ce, + xin => xin, + yin => yin, + zin => zin, + xout => xout, + yout => yout, + zout => zout, + ready => ready, + valid => valid, + cordic_mode => cordic_mode + ); + + tb_clk : PROCESS + BEGIN + clk <= not clk; + wait for PERIOD/2; + END PROCESS; + + tb : PROCESS + variable xerr, yerr, zerr : real_vector_t (0 to num_steps_per_cycle*num_cycles-1); + variable xvar, xstd, xmean, yvar, ystd, ymean, zvar, zstd, zmean : real; + variable argx, argy, argz : real := 0.0; + variable phi, dphi : real := 0.0; + file RESULT: text open write_mode is "STD_OUTPUT"; + file RESULT_X: text open write_mode is "x.txt"; + file RESULT_Y: text open write_mode is "y.txt"; + file RESULT_Z: text open write_mode is "z.txt"; + variable L: line; + variable j : integer := 0; + BEGIN + + -- Wait 100 ns for global reset to finish + wait for 4*PERIOD; + rst <= '0'; + + wait for 2*PERIOD; + + for i in 0 to arctan_tbl'length-1 loop + fprint(RESULT, L,"coeff arctan (%d) = %s\n", fo(i), REAL'image(arctan_tbl(i))); + end loop; + for i in 0 to gain_tbl'length-1 loop + fprint(RESULT, L,"coeff gain (%d) = %s\n", fo(i), REAL'image(gain_tbl(i))); + end loop; + fprint(RESULT, L,"Pi = %s\n", REAL'image(MATH_PI)); + fprint(RESULT, L,"sqrt(2) = %s\n", REAL'image(SQRT(2.0))); + fprint(RESULT, L,"1/sqrt(2) = %s\n", REAL'image(1.0/SQRT(2.0))); + + ------------------------------------------- + -- 1 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_rotate; + argx := 1.0; + argy := 0.0; + argz := -pi/4.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*[X0*cos(Z0) - Y0*sin(Z0)]\n"); + fprint(RESULT, L,"Yn = An*[Y0*cos(Z0) + X0*sin(Z0)]\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 2 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_rotate; + argx := 1.0; + argy := 0.0; + argz := pi/2.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*[X0*cos(Z0) - Y0*sin(Z0)]\n"); + fprint(RESULT, L,"Yn = An*[Y0*cos(Z0) + X0*sin(Z0)]\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 3 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_rotate; + argx := sqrt2_inv; + argy := -sqrt2_inv; + argz := pi/2.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*[X0*cos(Z0) - Y0*sin(Z0)]\n"); + fprint(RESULT, L,"Yn = An*[Y0*cos(Z0) + X0*sin(Z0)]\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 4 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_rotate; + argx := sqrt2_inv; + argy := -sqrt2_inv; + argz := -pi/4.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*[X0*cos(Z0) - Y0*sin(Z0)]\n"); + fprint(RESULT, L,"Yn = An*[Y0*cos(Z0) + X0*sin(Z0)]\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 5 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_vector; + argx := 1.0; + argy := 1.0; + argz := 0.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*sqrt(X0^2 + Y0^2)\n"); + fprint(RESULT, L,"Zn = Z0 + arctan(Y0/X0)\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 6 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_vector; + argx := sqrt2_inv; + argy := -sqrt2_inv; + argz := 0.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*sqrt(X0^2 + Y0^2)\n"); + fprint(RESULT, L,"Zn = Z0 + arctan(Y0/X0)\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 7 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_vector; + argx := -sqrt2_inv; + argy := sqrt2_inv; + argz := 0.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*sqrt(X0^2 + Y0^2)\n"); + fprint(RESULT, L,"Zn = Z0 + arctan(Y0/X0)\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- 8 + wait until rising_edge(clk) and ready = '1'; + + cordic_mode <= cordic_mode_vector; + argx := -sqrt2_inv; + argy := -sqrt2_inv; + argz := 0.0; + + xin <= to_sfixed(argx, xin); + yin <= to_sfixed(argy, yin); + zin <= to_sfixed(argz, zin); + + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT, L,"--------------------------------\n"); + fprint(RESULT, L,"%s\n", cordic_mode_t'image(cordic_mode)); + fprint(RESULT, L,"Xn = An*sqrt(X0^2 + Y0^2)\n"); + fprint(RESULT, L,"Zn = Z0 + arctan(Y0/X0)\n"); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"X0 = %s\n", REAL'image(to_real(xin))); + fprint(RESULT, L,"Y0 = %s\n", REAL'image(to_real(yin))); + fprint(RESULT, L,"Z0 = %s\n", REAL'image(to_real(zin))); + fprint(RESULT, L,"\n"); + fprint(RESULT, L,"Xn = %s\n", REAL'image(to_real(xout))); + fprint(RESULT, L,"Yn = %s\n", REAL'image(to_real(yout))); + fprint(RESULT, L,"Zn = %s\n", REAL'image(to_real(zout))); + fprint(RESULT, L,"\n"); + + ------------------------------------------- + -- Place stimulus here + wait for 10*PERIOD; + j := 0; + cordic_mode <= cordic_mode_rotate; + dphi := 2.0*pi/real(num_steps_per_cycle); + for k in 0 to num_cycles-1 loop + phi := -pi; + for i in 0 to num_steps_per_cycle-1 loop + xin <= one_sfix; + yin <= zero_sfix; + zin <= to_sfixed(phi, zin, round_nearest); + + wait until rising_edge(clk) and ready = '1'; + ce <= '1'; + wait until rising_edge(clk); + ce <= '0'; + + wait until rising_edge(clk) and ready = '0'; + wait until rising_edge(clk) and valid = '1'; + + fprint(RESULT_X, L,"%s\n", REAL'image(to_real(xout))); + fprint(RESULT_Y, L,"%s\n", REAL'image(to_real(yout))); + fprint(RESULT_Z, L,"%s\n", REAL'image(to_real(zout))); + +-- fprint(RESULT_X, L,"%s\n", REAL'image(cos(phi))); +-- fprint(RESULT_Y, L,"%s\n", REAL'image(sin(phi))); +-- fprint(RESULT_Z, L,"%s\n", REAL'image(0.0)); + + xerr(j) := to_real(xout) - cos(phi); + yerr(j) := to_real(yout) - sin(phi); + zerr(j) := to_real(zout); + j := j + 1; + phi := (phi + dphi); + end loop; + end loop; + xmean := mean(xerr, j); + ymean := mean(yerr, j); + zmean := mean(zerr, j); + xvar := var(xerr, j); + yvar := var(yerr, j); + zvar := var(zerr, j); + xstd := stddev(xerr, j); + ystd := stddev(yerr, j); + zstd := stddev(zerr, j); + fprint(RESULT, L,"------------------------------------------\n"); + fprint(RESULT, L,"Results: \n"); + fprint(RESULT, L,"xmean = %s\n", REAL'image(xmean)); + fprint(RESULT, L,"ymean = %s\n", REAL'image(ymean)); + fprint(RESULT, L,"zmean = %s\n", REAL'image(zmean)); + fprint(RESULT, L,"xvar = %s\n", REAL'image(xvar)); + fprint(RESULT, L,"yvar = %s\n", REAL'image(yvar)); + fprint(RESULT, L,"zvar = %s\n", REAL'image(zvar)); + fprint(RESULT, L,"xstd = %s\n", REAL'image(xstd)); + fprint(RESULT, L,"ystd = %s\n", REAL'image(ystd)); + fprint(RESULT, L,"zstd = %s\n", REAL'image(zstd)); + fprint(RESULT, L,"------------------------------------------\n"); + + assert false report "Test finished" severity error; + wait; + END PROCESS; + +END; diff --git a/projects/cordic/tb_cordic_top.fdo b/projects/cordic/tb_cordic_top.fdo new file mode 100644 index 0000000..e8b0aee --- /dev/null +++ b/projects/cordic/tb_cordic_top.fdo @@ -0,0 +1,18 @@ +vlib work +vcom -explicit -93 "../../lib/src/fixed_ja/fixed_ja.vhd" +vcom -explicit -93 "../../lib/src/fixed_ja/fixed_ja_body.vhd" +vcom -explicit -93 "../../lib/src/PCK_FIO-2002.7/PCK_FIO_1993.vhd" +vcom -explicit -93 "../../lib/src/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd" +vcom -explicit -93 "src/cordic_pkg.vhd" +vcom -explicit -93 "src/cordic_rom.vhd" +vcom -explicit -93 "src/cordic_stage.vhd" +vcom -explicit -93 "src/cordic_stage_pre.vhd" +vcom -explicit -93 "src/cordic_stage_post.vhd" +vcom -explicit -93 "src/cordic_top.vhd" +vcom -explicit -93 "src/tb_cordic_top.vhd" +vsim -t 1ps -lib work tb_cordic_top +do {tb_cordic_top.wdo} +view wave +view structure +view signals +run 2000us diff --git a/projects/cordic/tb_cordic_top.wdo b/projects/cordic/tb_cordic_top.wdo new file mode 100644 index 0000000..e0ace94 --- /dev/null +++ b/projects/cordic/tb_cordic_top.wdo @@ -0,0 +1,64 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider Top +add wave -noupdate -format Literal /tb_cordic_top/uut/cordic_mode +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/xin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/yin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/zin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/xout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/yout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/zout +add wave -noupdate -format Logic /tb_cordic_top/ce +add wave -noupdate -format Logic /tb_cordic_top/valid +add wave -noupdate -divider {Pre stage} +add wave -noupdate -format Literal /tb_cordic_top/uut/inst_cordic_stage_pre/cordic_mode +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/xin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/yin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/zin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/xout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/yout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_pre/zout +add wave -noupdate -divider {Process stage} +add wave -noupdate -format Literal /tb_cordic_top/uut/count +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/coeff +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/xin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/yin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/zin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/xout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/yout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage/zout +add wave -noupdate -divider {Post stage} +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/xin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/yin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/zin +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/xout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/yout +add wave -noupdate -format Literal -radix hexadecimal /tb_cordic_top/uut/inst_cordic_stage_post/zout +add wave -noupdate -divider Signals +add wave -noupdate -format Logic /tb_cordic_top/uut/ce +add wave -noupdate -format Logic /tb_cordic_top/uut/pre_stage_ready +add wave -noupdate -format Logic /tb_cordic_top/uut/pre_stage_en +add wave -noupdate -format Logic /tb_cordic_top/uut/pre_stage_valid +add wave -noupdate -format Logic /tb_cordic_top/uut/proc_stage_ready +add wave -noupdate -format Logic /tb_cordic_top/uut/proc_stage_en +add wave -noupdate -format Logic /tb_cordic_top/uut/proc_stage_valid +add wave -noupdate -format Logic /tb_cordic_top/uut/post_stage_ready +add wave -noupdate -format Logic /tb_cordic_top/uut/post_stage_en +add wave -noupdate -format Logic /tb_cordic_top/uut/post_stage_valid +add wave -noupdate -format Literal /tb_cordic_top/uut/state +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {1463518 ps} 0} +configure wave -namecolwidth 184 +configure wave -valuecolwidth 124 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {655140 ps} {1967644 ps} diff --git a/projects/cordic/tb_results.m b/projects/cordic/tb_results.m new file mode 100644 index 0000000..6c0ee52 --- /dev/null +++ b/projects/cordic/tb_results.m @@ -0,0 +1,34 @@ +% Read data +X = TEXTREAD('x.txt'); +Y = TEXTREAD('y.txt'); +Z = TEXTREAD('z.txt'); + +% Output +close all; +plot(0:length(X)-1, X, 0:length(Y)-1, Y, 0:length(Z)-1, Z); +title ('Output'); +legend('X','Y','Z'); +grid; + +W= 2*pi/100; +phi = 0; + +xd = -cos(phi+W*(0:length(X)-1))'; +yd = -sin(phi+W*(0:length(Y)-1))'; + +VarErrorX = var(X-xd) +VarErrorY = var(Y-yd) +MeanErrorX = mean(X-xd) +MeanErrorY = mean(Y-yd) + +figure; +plot(0:length(X)-1, X-xd, 0:length(Y)-1, Y-yd, 0:length(Z)-1, Z); +title ('Error'); +legend('X - X_D','Y - Y_D', 'Z'); +grid; + +figure; +plot(0:length(X)-1, X, 0:length(Y)-1, Y, 0:length(Z)-1, xd, 0:length(yd)-1, yd); +title ('Output'); +legend('X','Y','X_D','Y_D'); +grid; diff --git a/projects/cordic/x.txt b/projects/cordic/x.txt new file mode 100644 index 0000000..b1382e8 --- /dev/null +++ b/projects/cordic/x.txt @@ -0,0 +1,254 @@ +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +-9.313226e-010 +6.279052e-002 +1.253332e-001 +1.873813e-001 +2.486899e-001 +3.090170e-001 +3.681246e-001 +4.257793e-001 +4.817537e-001 +5.358268e-001 +5.877853e-001 +6.374240e-001 +6.845471e-001 +7.289686e-001 +7.705132e-001 +8.090170e-001 +8.443279e-001 +8.763067e-001 +9.048271e-001 +9.297765e-001 +9.510565e-001 +9.685832e-001 +9.822873e-001 +9.921147e-001 +9.980267e-001 +1.000000e+000 +9.980267e-001 +9.921147e-001 +9.822873e-001 +9.685832e-001 +9.510565e-001 +9.297765e-001 +9.048271e-001 +8.763067e-001 +8.443279e-001 +8.090170e-001 +7.705132e-001 +7.289686e-001 +6.845471e-001 +6.374240e-001 +5.877853e-001 +5.358268e-001 +4.817537e-001 +4.257793e-001 +3.681246e-001 +3.090170e-001 +2.486899e-001 +1.873813e-001 +1.253332e-001 +6.279052e-002 +-9.313226e-010 +-6.279052e-002 +-1.253332e-001 +-1.873813e-001 +-2.486899e-001 +-3.090170e-001 +-3.681246e-001 +-4.257793e-001 +-4.817537e-001 +-5.358268e-001 +-5.877853e-001 +-6.374240e-001 +-6.845471e-001 +-7.289686e-001 +-7.705132e-001 +-8.090170e-001 +-8.443279e-001 +-8.763067e-001 +-9.048271e-001 +-9.297765e-001 +-9.510565e-001 +-9.685832e-001 +-9.822873e-001 +-9.921147e-001 +-9.980267e-001 +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +-9.313226e-010 +6.279052e-002 +1.253332e-001 +1.873813e-001 +2.486899e-001 +3.090170e-001 +3.681246e-001 +4.257793e-001 +4.817537e-001 +5.358268e-001 +5.877853e-001 +6.374240e-001 +6.845471e-001 +7.289686e-001 +7.705132e-001 +8.090170e-001 +8.443279e-001 +8.763067e-001 +9.048271e-001 +9.297765e-001 +9.510565e-001 +9.685832e-001 +9.822873e-001 +9.921147e-001 +9.980267e-001 +1.000000e+000 +9.980267e-001 +9.921147e-001 +9.822873e-001 +9.685832e-001 +9.510565e-001 +9.297765e-001 +9.048271e-001 +8.763067e-001 +8.443279e-001 +8.090170e-001 +7.705132e-001 +7.289686e-001 +6.845471e-001 +6.374240e-001 +5.877853e-001 +5.358268e-001 +4.817537e-001 +4.257793e-001 +3.681246e-001 +3.090170e-001 +2.486899e-001 +1.873813e-001 +1.253332e-001 +6.279052e-002 +-9.313226e-010 +-6.279052e-002 +-1.253332e-001 +-1.873813e-001 +-2.486899e-001 +-3.090170e-001 +-3.681246e-001 +-4.257793e-001 +-4.817537e-001 +-5.358268e-001 +-5.877853e-001 +-6.374240e-001 +-6.845471e-001 +-7.289686e-001 +-7.705132e-001 +-8.090170e-001 +-8.443279e-001 +-8.763067e-001 +-9.048271e-001 +-9.297765e-001 +-9.510565e-001 +-9.685832e-001 +-9.822873e-001 +-9.921147e-001 +-9.980267e-001 +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +-9.313226e-010 +6.279052e-002 +1.253332e-001 +1.873813e-001 +2.486899e-001 +3.090170e-001 +3.681246e-001 +4.257793e-001 +4.817537e-001 +5.358268e-001 +5.877853e-001 +6.374240e-001 +6.845471e-001 +7.289686e-001 +7.705132e-001 +8.090170e-001 +8.443279e-001 +8.763067e-001 +9.048271e-001 +9.297765e-001 +9.510565e-001 +9.685832e-001 +9.822873e-001 +9.921147e-001 +9.980267e-001 +1.000000e+000 +9.980267e-001 +9.921147e-001 +9.822873e-001 diff --git a/projects/cordic/y.txt b/projects/cordic/y.txt new file mode 100644 index 0000000..954db4b --- /dev/null +++ b/projects/cordic/y.txt @@ -0,0 +1,254 @@ +0.000000e+000 +-6.279052e-002 +-1.253332e-001 +-1.873813e-001 +-2.486899e-001 +-3.090170e-001 +-3.681246e-001 +-4.257793e-001 +-4.817537e-001 +-5.358268e-001 +-5.877853e-001 +-6.374240e-001 +-6.845471e-001 +-7.289686e-001 +-7.705132e-001 +-8.090170e-001 +-8.443279e-001 +-8.763067e-001 +-9.048271e-001 +-9.297765e-001 +-9.510565e-001 +-9.685832e-001 +-9.822873e-001 +-9.921147e-001 +-9.980267e-001 +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +0.000000e+000 +6.279052e-002 +1.253332e-001 +1.873813e-001 +2.486899e-001 +3.090170e-001 +3.681246e-001 +4.257793e-001 +4.817537e-001 +5.358268e-001 +5.877853e-001 +6.374240e-001 +6.845471e-001 +7.289686e-001 +7.705132e-001 +8.090170e-001 +8.443279e-001 +8.763067e-001 +9.048271e-001 +9.297765e-001 +9.510565e-001 +9.685832e-001 +9.822873e-001 +9.921147e-001 +9.980267e-001 +1.000000e+000 +9.980267e-001 +9.921147e-001 +9.822873e-001 +9.685832e-001 +9.510565e-001 +9.297765e-001 +9.048271e-001 +8.763067e-001 +8.443279e-001 +8.090170e-001 +7.705132e-001 +7.289686e-001 +6.845471e-001 +6.374240e-001 +5.877853e-001 +5.358268e-001 +4.817537e-001 +4.257793e-001 +3.681246e-001 +3.090170e-001 +2.486899e-001 +1.873813e-001 +1.253332e-001 +6.279052e-002 +0.000000e+000 +-6.279052e-002 +-1.253332e-001 +-1.873813e-001 +-2.486899e-001 +-3.090170e-001 +-3.681246e-001 +-4.257793e-001 +-4.817537e-001 +-5.358268e-001 +-5.877853e-001 +-6.374240e-001 +-6.845471e-001 +-7.289686e-001 +-7.705132e-001 +-8.090170e-001 +-8.443279e-001 +-8.763067e-001 +-9.048271e-001 +-9.297765e-001 +-9.510565e-001 +-9.685832e-001 +-9.822873e-001 +-9.921147e-001 +-9.980267e-001 +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +0.000000e+000 +6.279052e-002 +1.253332e-001 +1.873813e-001 +2.486899e-001 +3.090170e-001 +3.681246e-001 +4.257793e-001 +4.817537e-001 +5.358268e-001 +5.877853e-001 +6.374240e-001 +6.845471e-001 +7.289686e-001 +7.705132e-001 +8.090170e-001 +8.443279e-001 +8.763067e-001 +9.048271e-001 +9.297765e-001 +9.510565e-001 +9.685832e-001 +9.822873e-001 +9.921147e-001 +9.980267e-001 +1.000000e+000 +9.980267e-001 +9.921147e-001 +9.822873e-001 +9.685832e-001 +9.510565e-001 +9.297765e-001 +9.048271e-001 +8.763067e-001 +8.443279e-001 +8.090170e-001 +7.705132e-001 +7.289686e-001 +6.845471e-001 +6.374240e-001 +5.877853e-001 +5.358268e-001 +4.817537e-001 +4.257793e-001 +3.681246e-001 +3.090170e-001 +2.486899e-001 +1.873813e-001 +1.253332e-001 +6.279052e-002 +0.000000e+000 +-6.279052e-002 +-1.253332e-001 +-1.873813e-001 +-2.486899e-001 +-3.090170e-001 +-3.681246e-001 +-4.257793e-001 +-4.817537e-001 +-5.358268e-001 +-5.877853e-001 +-6.374240e-001 +-6.845471e-001 +-7.289686e-001 +-7.705132e-001 +-8.090170e-001 +-8.443279e-001 +-8.763067e-001 +-9.048271e-001 +-9.297765e-001 +-9.510565e-001 +-9.685832e-001 +-9.822873e-001 +-9.921147e-001 +-9.980267e-001 +-1.000000e+000 +-9.980267e-001 +-9.921147e-001 +-9.822873e-001 +-9.685832e-001 +-9.510565e-001 +-9.297765e-001 +-9.048271e-001 +-8.763067e-001 +-8.443279e-001 +-8.090170e-001 +-7.705132e-001 +-7.289686e-001 +-6.845471e-001 +-6.374240e-001 +-5.877853e-001 +-5.358268e-001 +-4.817537e-001 +-4.257793e-001 +-3.681246e-001 +-3.090170e-001 +-2.486899e-001 +-1.873813e-001 +-1.253332e-001 +-6.279052e-002 +0.000000e+000 +6.279052e-002 +1.253332e-001 +1.873813e-001 diff --git a/projects/cordic/z.txt b/projects/cordic/z.txt new file mode 100644 index 0000000..d8f8675 --- /dev/null +++ b/projects/cordic/z.txt @@ -0,0 +1,254 @@ +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000 +0.000000e+000