diff --git a/libraries/dsp/carousel_correlator/hdllib.cfg b/libraries/dsp/carousel_correlator/hdllib.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9d78e2cb3494e6c9de57b6166ef39d8b8cbc8acc --- /dev/null +++ b/libraries/dsp/carousel_correlator/hdllib.cfg @@ -0,0 +1,14 @@ +hdl_lib_name = carousel_correlator +hdl_library_clause_name = carousel_correlator_lib +hdl_lib_uses = common dp +hdl_lib_technology = + +build_dir_sim = $HDL_BUILD_DIR +build_dir_synth = $HDL_BUILD_DIR + +synth_files = + $SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/src/vhdl/carousel.vhd + +test_bench_files = + $SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/tb/vhdl/tb_carousel.vhd + diff --git a/libraries/dsp/carousel_correlator/src/vhdl/carousel.vhd b/libraries/dsp/carousel_correlator/src/vhdl/carousel.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5699eca8b31bf278f96357efb6ed574873006a6b --- /dev/null +++ b/libraries/dsp/carousel_correlator/src/vhdl/carousel.vhd @@ -0,0 +1,119 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +-- Purpose: +-- . Outputs all unique pair permutations of the words at the inputs. +-- Description: +-- . Example permutations of [0,1,2]: [[0,0],[0,1],[0,2],[1,2],[1,1],[2,2]] +-- . c_nof_permutations = g_nof_inputs*(g_nof_inputs+1)/2 +-- . Each permutation can be used to calculate one unique visibility. +-- . snk_in_arr(0).valid is used to indicate validity of all inputs. +-- Usage: +-- . Determine g_nof_inputs; e.g. 3 +-- . Calculate c_nof_permutations: e.g. 6 +-- . Note your output options, e.g. +-- . 6 cycles * 1 output +-- . 3 cycles * 2 outputs +-- . 2 cycles * 3 outputs +-- . 1 cycle * 6 outputs +-- . Set your g_nof_outputs accordingly. + + +ENTITY carousel IS + GENERIC ( + g_nof_inputs : NATURAL := 8; + g_nof_outputs : NATURAL := 9 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + + snk_in_arr : IN t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + snk_out_arr : OUT t_dp_siso_arr(g_nof_inputs-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + + src_out_arr : OUT t_dp_sosi_2arr_2(g_nof_outputs-1 DOWNTO 0) -- Array of pairs + ); +END carousel; + +ARCHITECTURE rtl OF carousel IS + + CONSTANT c_nof_permutations : NATURAL := g_nof_inputs*(g_nof_inputs+1)/2; + + SIGNAL nxt_reg_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); + SIGNAL reg_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); + +BEGIN + + ----------------------------------------------------------------------------- + -- Carousel register shifting + -- . 3-input example, carousel rotation is counter-clockwise: + -- ___ + -- | | + -- snk_in_arr[2]--->nxt_reg_out_2arr_2[2][1]->[1]--|---> reg_out_2arr_2[2][1] + -- \-->nxt_reg_out_2arr_2[2][0]---|->[0]--> reg_out_2arr_2[2][0] + -- snk_in_arr[1]--->nxt_reg_out_2arr_2[1][1]--[1] | --> reg_out_2arr_2[1][1] + -- \-->nxt_reg_out_2arr_2[1][0]---|->[0]--> reg_out_2arr_2[1][0] + -- snk_in_arr[0]--->nxt_reg_out_2arr_2[0][1]->[1] | --> reg_out_2arr_2[0][1] + -- \-->nxt_reg_out_2arr_2[0][0]---|->[0]--> reg_out_2arr_2[0][0] + -- |___| + ----------------------------------------------------------------------------- + p_carousel: PROCESS(snk_in_arr, reg_out_2arr_2) + BEGIN + IF snk_in_arr(0).valid = '1' THEN -- Take fresh set of input data + FOR i IN 0 TO g_nof_inputs-1 LOOP + nxt_reg_out_2arr_2(i)(0) <= snk_in_arr(i); + nxt_reg_out_2arr_2(i)(1) <= snk_in_arr(i); + END LOOP; + ELSE -- Shift around the current data; keep producing new permutations + -- Top of carousel, shift left + nxt_reg_out_2arr_2(g_nof_inputs-1)(1) <= reg_out_2arr_2(g_nof_inputs-1)(0); + -- Left column of carousel, shift down + FOR i IN 0 TO g_nof_inputs-2 LOOP + nxt_reg_out_2arr_2(i)(1) <= reg_out_2arr_2(i+1)(1); + END LOOP; + -- Right column of carousel, shift up + FOR i IN 1 TO g_nof_inputs-1 LOOP + nxt_reg_out_2arr_2(i)(0) <= reg_out_2arr_2(i-1)(0); + END LOOP; + -- Bottom of carousel, shift right + nxt_reg_out_2arr_2(0)(0) <= reg_out_2arr_2(0)(1); + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- Registers + ----------------------------------------------------------------------------- + p_clk: PROCESS(clk, rst) + BEGIN + IF rst='1' THEN + reg_out_2arr_2 <= (OTHERS=>(OTHERS=>c_dp_sosi_rst)); + ELSIF rising_edge(clk) THEN + reg_out_2arr_2 <= nxt_reg_out_2arr_2; + END IF; + END PROCESS; + +END rtl; diff --git a/libraries/dsp/carousel_correlator/tb/vhdl/tb_carousel.vhd b/libraries/dsp/carousel_correlator/tb/vhdl/tb_carousel.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5a31005e2be523182a04b46ba92a0b154f0b43ae --- /dev/null +++ b/libraries/dsp/carousel_correlator/tb/vhdl/tb_carousel.vhd @@ -0,0 +1,88 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +--USE dp_lib.tb_dp_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; + +ENTITY tb_carousel IS + GENERIC ( + g_nof_inputs : NATURAL := 8; + g_nof_outputs : NATURAL := 9 + ); +END tb_carousel; + +ARCHITECTURE tb OF tb_carousel IS + + CONSTANT c_clk_period : TIME := 10 ns; + CONSTANT c_data_w : NATURAL := 32; + CONSTANT c_nof_permutations : NATURAL := (g_nof_inputs*(g_nof_inputs+1))/2; + CONSTANT c_nof_clk_cycles_per_input_val : NATURAL := c_nof_permutations/g_nof_outputs; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC; + + SIGNAL carousel_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + SIGNAL carousel_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_outputs-1 DOWNTO 0); + +BEGIN + + clk <= NOT clk OR tb_end AFTER c_clk_period/2; + rst <= '1', '0' AFTER c_clk_period*7; + + u_carousel : ENTITY work.carousel + GENERIC MAP ( + g_nof_inputs => g_nof_inputs, + g_nof_outputs => g_nof_outputs + ) + PORT MAP ( + rst => rst, + clk => clk, + snk_in_arr => carousel_snk_in_arr, + src_out_arr => carousel_src_out_2arr_2 + ); + + p_stimuli: PROCESS + BEGIN + WAIT UNTIL rst = '0'; + WAIT FOR 100 ns; + FOR i IN 0 TO 10-1 LOOP + FOR j IN 0 TO g_nof_inputs-1 LOOP + -- Feed the carousel. Use the stream index as data word + carousel_snk_in_arr(j).data(c_data_w-1 DOWNTO 0) <= TO_UVEC(j, c_data_w); + carousel_snk_in_arr(j).valid <= '1'; + END LOOP; + WAIT FOR c_clk_period; + FOR j IN 0 TO g_nof_inputs-1 LOOP + -- Let the carousel do its thing + carousel_snk_in_arr(j).data <= (OTHERS=>'0'); + carousel_snk_in_arr(j).valid <= '0'; + END LOOP; + WAIT FOR (c_nof_clk_cycles_per_input_val-1)*c_clk_period; + END LOOP; + END PROCESS; + +END tb;