Skip to content
Snippets Groups Projects
Commit d445ea94 authored by Daniel van der Schuur's avatar Daniel van der Schuur
Browse files

-Added permutator + test bench.

parent f364c923
No related branches found
No related tags found
No related merge requests found
...@@ -7,8 +7,8 @@ build_dir_sim = $HDL_BUILD_DIR ...@@ -7,8 +7,8 @@ build_dir_sim = $HDL_BUILD_DIR
build_dir_synth = $HDL_BUILD_DIR build_dir_synth = $HDL_BUILD_DIR
synth_files = synth_files =
$SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/src/vhdl/carousel.vhd $SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/src/vhdl/permutator.vhd
test_bench_files = test_bench_files =
$SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/tb/vhdl/tb_carousel.vhd $SVN/RadioHDL/trunk/libraries/dsp/carousel_correlator/tb/vhdl/tb_permutator.vhd
--------------------------------------------------------------------------------
--
-- 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
-- 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 permutator 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_2arr : OUT t_dp_sosi_2arr_2(g_nof_outputs-1 DOWNTO 0) -- Array of pairs
);
END permutator;
ARCHITECTURE rtl OF permutator IS
CONSTANT c_nof_permutations : NATURAL := g_nof_inputs*(g_nof_inputs+1)/2;
CONSTANT c_nof_cycles : NATURAL := ceil_div(c_nof_permutations,g_nof_outputs);
TYPE t_permu_in_2arr IS ARRAY(g_nof_inputs-1 DOWNTO 0) OF t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL permu_in_2arr : t_permu_in_2arr;
SIGNAL permu_out_2arr : t_dp_sosi_2arr_2(g_nof_outputs-1 DOWNTO 0);
BEGIN
-----------------------------------------------------------------------------
-- Input wiring: copy the inputs g_nof_inputs times
-----------------------------------------------------------------------------
gen_input: FOR i IN 0 TO g_nof_inputs-1 GENERATE
gen_input: FOR j IN 0 TO g_nof_inputs-1 GENERATE
permu_in_2arr(i)(j) <= snk_in_arr(i);
END GENERATE;
END GENERATE;
-----------------------------------------------------------------------------
-- Permutation wiring, 4-input example:
--
-- 0 1 2 3 4 5 6 7 8 9 <-- permu_out_2arr[g_nof_outputs][2]
-- _ | | | | | | | | | |
-- |0|0-->[0] | | | | | | | | |
-- | |1------->[0] | | | | | | | |
-- | |2---------|-->[0] | | | | | | |
-- |_|3---------|----|-->[0] | | | | | |
-- |1|0------->[1] | | | | | | | |
-- | |1--------------|----|-->[1] | | | | |
-- | |2--------------|----|------->[1] | | | |
-- |_|3--------------|----|---------|-->[1] | | |
-- |2|0------------>[2] | | | | | |
-- | |1-------------------|------->[2] | | | |
-- | |2-------------------|--------------|-->[2] | |
-- |_|3-------------------|--------------|------->[2] |
-- |3|0----------------->[3] | | |
-- | |1-------------------------------->[3] | |
-- | |2------------------------------------------>[3] |
-- |_|3----------------------------------------------->[3]
-- ^
-- |
-- permu_in_2arr[g_nof_inputs][g_nof_inputs]
--
-- Observe the following:
-- . Inverse indexing: E.g. permutation[5], pair index 1 gets assigned
-- indices opposite to those of pair index 0:
-- . permu_out_2arr(5)(0) <= permu_in_arr(1)(2);
-- permu_out_2arr(5)(1) <= permu_in_arr(2)(1);
-- . The number of inputs that carry duplicates increments by one
-- for each input increment (only pair index 0 shown):
-- . permu_out_2arr(0)(0) <= permu_in_arr(0)(0); --permu_in_arr(0): 0 duplicates
-- permu_out_2arr(1)(0) <= permu_in_arr(0)(1);
-- permu_out_2arr(2)(0) <= permu_in_arr(0)(2);
-- permu_out_2arr(3)(0) <= permu_in_arr(0)(3);
-- -- Duplicate permu_in_arr(1)(0); --permu_in_arr(1): 1 duplicate
-- permu_out_2arr(4)(0) <= permu_in_arr(1)(1);
-- permu_out_2arr(5)(0) <= permu_in_arr(1)(2);
-- permu_out_2arr(6)(0) <= permu_in_arr(1)(3);
-- -- Duplicate permu_in_arr(2)(0); --permu_in_arr(2): 2 duplicates
-- -- Duplicate permu_in_arr(2)(1);
-- permu_out_2arr(7)(0) <= permu_in_arr(2)(2);
-- permu_out_2arr(8)(0) <= permu_in_arr(2)(3);
-- -- Duplicate permu_in_arr(3)(0); --permu_in_arr(3): 3 duplicates
-- -- Duplicate permu_in_arr(3)(1);
-- -- Duplicate permu_in_arr(3)(2);
-- permu_out_2arr(9)(0) <= permu_in_arr(3)(3);
-----------------------------------------------------------------------------
p_permu_wires: PROCESS(permu_in_2arr)
VARIABLE v_out_index : NATURAL;
VARIABLE v_duplicates : NATURAL;
BEGIN
v_out_index := 0;
v_duplicates := 0;
FOR i IN 0 TO g_nof_inputs-1 LOOP
v_duplicates := i;
FOR j IN 0 TO g_nof_inputs-1 LOOP
permu_out_2arr(v_out_index)(0) <= permu_in_2arr(i)(j);
permu_out_2arr(v_out_index)(1) <= permu_in_2arr(j)(i);
IF v_duplicates = 0 THEN
-- We assigned a unique pair. Keep incrementing the index.
v_out_index := v_out_index+1;
ELSE
-- We just assigned a duplicate. Don't increment v_out_index so
-- that output will get re-assigned in the next loop iteration.
v_duplicates := v_duplicates-1;
END IF;
END LOOP;
END LOOP;
END PROCESS;
-----------------------------------------------------------------------------
-- Output wiring
-----------------------------------------------------------------------------
src_out_2arr <= permu_out_2arr;
END rtl;
--------------------------------------------------------------------------------
--
-- 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_permutator IS
GENERIC (
g_nof_inputs : NATURAL := 4;
g_nof_outputs : NATURAL := 10
);
END tb_permutator;
ARCHITECTURE tb OF tb_permutator 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 permutator_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL permutator_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_permutator : ENTITY work.permutator
GENERIC MAP (
g_nof_inputs => g_nof_inputs,
g_nof_outputs => g_nof_outputs
)
PORT MAP (
rst => rst,
clk => clk,
snk_in_arr => permutator_snk_in_arr,
src_out_2arr => permutator_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 permutator. Use the stream index as data word
permutator_snk_in_arr(j).data(c_data_w-1 DOWNTO 0) <= TO_UVEC(j, c_data_w);
permutator_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 permutator do its thing
permutator_snk_in_arr(j).data <= (OTHERS=>'0');
permutator_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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment