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

-Added 7 libraries to be uploaded to OpenCores:

 . common_pkg
 . common_components
 . dp_pkg
 . dp_components
 . dp_pipeline
 . dp_repack_data
 . dp_counter
-Added scripts to copy+edit the base files from $RADIOHDL/libraries
-Added readme.txt
parent bbba8dcb
Branches
No related tags found
No related merge requests found
Showing
with 6213 additions and 0 deletions
-------------------------------------------------------------------------------
--
-- Copyright (C) 2009
-- 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/>.
--
-------------------------------------------------------------------------------
-- Purpose : Switch output high or low
-- Description:
-- . The output goes high when switch_high='1' and low when switch_low='1'.
-- . If g_or_high is true then the output follows the switch_high immediately,
-- else it goes high in the next clk cycle.
-- . If g_and_low is true then the output follows the switch_low immediately,
-- else it goes low in the next clk cycle.
-- The g_priority_lo defines which input has priority when switch_high and
-- switch_low are active simultaneously.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY common_switch IS
GENERIC (
g_rst_level : STD_LOGIC := '0'; -- Defines the output level at reset.
g_priority_lo : BOOLEAN := TRUE; -- When TRUE then input switch_low has priority, else switch_high. Don't care when switch_high and switch_low are pulses that do not occur simultaneously.
g_or_high : BOOLEAN := FALSE; -- When TRUE and priority hi then the registered switch_level is OR-ed with the input switch_high to get out_level, else out_level is the registered switch_level
g_and_low : BOOLEAN := FALSE -- When TRUE and priority lo then the registered switch_level is AND-ed with the input switch_low to get out_level, else out_level is the registered switch_level
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
clken : IN STD_LOGIC := '1';
switch_high : IN STD_LOGIC; -- A pulse on switch_high makes the out_level go high
switch_low : IN STD_LOGIC; -- A pulse on switch_low makes the out_level go low
out_level : OUT STD_LOGIC
);
END;
ARCHITECTURE rtl OF common_switch IS
SIGNAL switch_level : STD_LOGIC := g_rst_level;
SIGNAL nxt_switch_level : STD_LOGIC;
BEGIN
gen_wire : IF g_or_high=FALSE AND g_and_low=FALSE GENERATE
out_level <= switch_level;
END GENERATE;
gen_or : IF g_or_high=TRUE AND g_and_low=FALSE GENERATE
out_level <= switch_level OR switch_high;
END GENERATE;
gen_and : IF g_or_high=FALSE AND g_and_low=TRUE GENERATE
out_level <= switch_level AND (NOT switch_low);
END GENERATE;
gen_or_and : IF g_or_high=TRUE AND g_and_low=TRUE GENERATE
out_level <= (switch_level OR switch_high) AND (NOT switch_low);
END GENERATE;
p_reg : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
switch_level <= g_rst_level;
ELSIF rising_edge(clk) THEN
IF clken='1' THEN
switch_level <= nxt_switch_level;
END IF;
END IF;
END PROCESS;
p_switch_level : PROCESS(switch_level, switch_low, switch_high)
BEGIN
nxt_switch_level <= switch_level;
IF g_priority_lo=TRUE THEN
IF switch_low='1' THEN
nxt_switch_level <= '0';
ELSIF switch_high='1' THEN
nxt_switch_level <= '1';
END IF;
ELSE
IF switch_high='1' THEN
nxt_switch_level <= '1';
ELSIF switch_low='1' THEN
nxt_switch_level <= '0';
END IF;
END IF;
END PROCESS;
END rtl;
hdl_lib_name = common_components
hdl_library_clause_name = common_components_lib
hdl_lib_uses_synth =
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
common_switch.vhd
test_bench_files =
regression_test_vhdl =
[modelsim_project_file]
modelsim_copy_files =
[quartus_project_file]
--------------------------------------------------------------------------------
--
-- Copyright (C) 2009
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE work.common_pkg.ALL;
PACKAGE common_lfsr_sequences_pkg IS
CONSTANT c_common_lfsr_max_nof_feedbacks : NATURAL := 6;
CONSTANT c_common_lfsr_first : NATURAL := 1; -- also support n = 1 and 2 in addition to n >= 3
TYPE t_FEEDBACKS IS ARRAY (c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0) OF NATURAL;
TYPE t_SEQUENCES IS ARRAY (NATURAL RANGE <>) OF t_FEEDBACKS;
-- XNOR feedbacks for n = 1:
-- (0,0,0,0,0, 0) yields repeat <1>
-- (0,0,0,0,0, 1) yields repeat <0, 1>
-- XNOR feedbacks for n = 2:
-- (0,0,0,0, 0, 1) yields repeat <1, 2>
-- (0,0,0,0, 0, 2) yields repeat <0, 1, 3, 2>
-- (0,0,0,0, 2, 1) yields repeat <0, 1, 2>
-- XNOR feedbacks from outputs for n = 3 .. 72 from Xilinx xapp052.pdf (that lists feedbacks for in total 168 sequences)
CONSTANT c_common_lfsr_sequences : t_SEQUENCES := ((0,0,0,0,0, 1), -- 1 : <0, 1>
(0,0,0,0, 0, 2), -- 2 : <0, 1, 3, 2>
(0,0,0,0, 3, 2), -- 3
(0,0,0,0, 4, 3), -- 4
(0,0,0,0, 5, 3), -- 5
(0,0,0,0, 6, 5), -- 6
(0,0,0,0, 7, 6), -- 7
(0,0, 8, 6, 5, 4), -- 8
(0,0,0,0, 9, 5), -- 9
(0,0,0,0, 10, 7), -- 10
(0,0,0,0, 11, 9), -- 11
(0,0, 12, 6, 4, 1), -- 12
(0,0, 13, 4, 3, 1), -- 13
(0,0, 14, 5, 3, 1), -- 14
(0,0,0,0, 15,14 ), -- 15
(0,0, 16,15,13, 4), -- 16
(0,0,0,0, 17,14 ), -- 17
(0,0,0,0, 18,11 ), -- 18
(0,0, 19, 6, 2, 1), -- 19
(0,0,0,0, 20,17 ), -- 20
(0,0,0,0, 21,19 ), -- 21
(0,0,0,0, 22,21 ), -- 22
(0,0,0,0, 23,18 ), -- 23
(0,0, 24,23,22,17), -- 24
(0,0,0,0, 25,22 ), -- 25
(0,0, 26, 6, 2, 1), -- 26
(0,0, 27, 5, 2, 1), -- 27
(0,0,0,0, 28,25 ), -- 28
(0,0,0,0, 29,27 ), -- 29
(0,0, 30, 6, 4, 1), -- 30
(0,0,0,0, 31,28 ), -- 31
(0,0, 32,22, 2, 1), -- 32
(0,0,0,0, 33,20 ), -- 33
(0,0, 34,27, 2, 1), -- 34
(0,0,0,0, 35,33 ), -- 35
(0,0,0,0, 36,25 ), -- 36
( 37, 5, 4, 3, 2, 1), -- 37
(0,0, 38, 6, 5, 1), -- 38
(0,0,0,0, 39,35 ), -- 39
(0,0, 40,38,21,19), -- 40
(0,0,0,0, 41,38 ), -- 41
(0,0, 42,41,20,19), -- 42
(0,0, 43,42,38,37), -- 43
(0,0, 44,43,18,17), -- 44
(0,0, 45,44,42,41), -- 45
(0,0, 46,45,26,25), -- 46
(0,0,0,0, 47,42 ), -- 47
(0,0, 48,47,21,20), -- 48
(0,0,0,0, 49,40 ), -- 49
(0,0, 50,49,24,23), -- 50
(0,0, 51,50,36,35), -- 51
(0,0,0,0, 52,49 ), -- 52
(0,0, 53,52,38,37), -- 53
(0,0, 54,53,18,17), -- 54
(0,0,0,0, 55,31 ), -- 55
(0,0, 56,55,35,34), -- 56
(0,0,0,0, 57,50 ), -- 57
(0,0,0,0, 58,39 ), -- 58
(0,0, 59,58,38,37), -- 59
(0,0,0,0, 60,59 ), -- 60
(0,0, 61,60,46,45), -- 61
(0,0, 62,61, 6, 5), -- 62
(0,0,0,0, 63,62 ), -- 63
(0,0, 64,63,61,60), -- 64
(0,0,0,0, 65,47 ), -- 65
(0,0, 66,65,57,56), -- 66
(0,0, 67,66,58,57), -- 67
(0,0,0,0, 68,59 ), -- 68
(0,0, 69,67,42,40), -- 69
(0,0, 70,69,55,54), -- 70
(0,0,0,0, 71,65 ), -- 71
(0,0, 72,66,25,19)); -- 72
-- Procedure for calculating the next PSRG and COUNTER sequence value
PROCEDURE common_lfsr_nxt_seq(CONSTANT c_lfsr_nr : IN NATURAL;
CONSTANT g_incr : IN INTEGER;
in_en : IN STD_LOGIC;
in_req : IN STD_LOGIC;
in_dat : IN STD_LOGIC_VECTOR;
prsg : IN STD_LOGIC_VECTOR;
cntr : IN STD_LOGIC_VECTOR;
SIGNAL nxt_prsg : OUT STD_LOGIC_VECTOR;
SIGNAL nxt_cntr : OUT STD_LOGIC_VECTOR);
-- Use lfsr part of common_lfsr_nxt_seq to make a random bit generator function
-- . width of lfsr selects the LFSR sequence
-- . initialized lfsr with (OTHERS=>'0')
-- . use lfsr(lfsr'HIGH) as random bit
FUNCTION func_common_random(lfsr : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
END common_lfsr_sequences_pkg;
PACKAGE BODY common_lfsr_sequences_pkg IS
PROCEDURE common_lfsr_nxt_seq(CONSTANT c_lfsr_nr : IN NATURAL;
CONSTANT g_incr : IN INTEGER;
in_en : IN STD_LOGIC;
in_req : IN STD_LOGIC;
in_dat : IN STD_LOGIC_VECTOR;
prsg : IN STD_LOGIC_VECTOR;
cntr : IN STD_LOGIC_VECTOR;
SIGNAL nxt_prsg : OUT STD_LOGIC_VECTOR;
SIGNAL nxt_cntr : OUT STD_LOGIC_VECTOR) IS
VARIABLE v_feedback : STD_LOGIC;
BEGIN
nxt_prsg <= prsg;
nxt_cntr <= cntr;
IF in_en='0' THEN -- init reference value
nxt_prsg <= in_dat;
nxt_cntr <= in_dat;
ELSIF in_req='1' THEN -- next reference value
-- PRSG shift
nxt_prsg <= prsg(prsg'HIGH-1 DOWNTO 0) & '0';
-- PRSG feedback
v_feedback := '0';
FOR I IN c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0 LOOP
IF c_common_lfsr_sequences(c_lfsr_nr)(I) /= 0 THEN
v_feedback := v_feedback XOR prsg(c_common_lfsr_sequences(c_lfsr_nr)(I)-1);
END IF;
END LOOP;
nxt_prsg(0) <= NOT v_feedback;
-- COUNTER
nxt_cntr <= INCR_UVEC(cntr, g_incr);
END IF;
END common_lfsr_nxt_seq;
FUNCTION func_common_random(lfsr : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
CONSTANT c_lfsr_nr : NATURAL := lfsr'LENGTH - c_common_lfsr_first;
VARIABLE v_nxt_lfsr : STD_LOGIC_VECTOR(lfsr'RANGE);
VARIABLE v_feedback : STD_LOGIC;
BEGIN
-- shift
v_nxt_lfsr := lfsr(lfsr'HIGH-1 DOWNTO 0) & '0';
-- feedback
v_feedback := '0';
FOR I IN c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0 LOOP
IF c_common_lfsr_sequences(c_lfsr_nr)(I) /= 0 THEN
v_feedback := v_feedback XOR lfsr(c_common_lfsr_sequences(c_lfsr_nr)(I)-1);
END IF;
END LOOP;
v_nxt_lfsr(0) := NOT v_feedback;
RETURN v_nxt_lfsr;
END func_common_random;
END common_lfsr_sequences_pkg;
This diff is collapsed.
-------------------------------------------------------------------------------
--
-- Copyright (C) 2012
-- 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;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE STD.TEXTIO.ALL;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE work.common_pkg.ALL;
PACKAGE common_str_pkg IS
TYPE t_str_4_arr IS ARRAY (INTEGER RANGE <>) OF STRING(1 TO 4);
FUNCTION nof_digits(number: NATURAL) RETURN NATURAL;
FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL;
FUNCTION time_to_str(in_time : TIME) RETURN STRING;
FUNCTION str_to_time(in_str : STRING) RETURN TIME;
FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING;
FUNCTION str_to_hex(str : STRING) RETURN STRING;
FUNCTION slv_to_hex(slv : STD_LOGIC_VECTOR) RETURN STRING;
FUNCTION hex_to_slv(str : STRING) RETURN STD_LOGIC_VECTOR;
Function hex_nibble_to_slv(c: character) return std_logic_vector;
FUNCTION int_to_str(int: INTEGER) RETURN STRING;
FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING;
PROCEDURE print_str(str : STRING);
FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr;
FUNCTION str_to_ascii_slv_8_arr( s: STRING) RETURN t_slv_8_arr;
FUNCTION str_to_ascii_slv_32_arr( s: STRING) RETURN t_slv_32_arr;
FUNCTION str_to_ascii_slv_32_arr( s: STRING; arr_size : NATURAL) RETURN t_slv_32_arr;
END common_str_pkg;
PACKAGE BODY common_str_pkg IS
FUNCTION nof_digits(number: NATURAL) RETURN NATURAL IS
-- Returns number of digits in a natural number. Only used in string processing, so defined here.
-- log10(0) is not allowed so:
-- . nof_digits(0) = 1
-- We're adding 1 so:
-- . nof_digits(1) = 1
-- . nof_digits(9) = 1
-- . nof_digits(10) = 2
BEGIN
IF number>0 THEN
RETURN floor_log10(number)+1;
ELSE
RETURN 1;
END IF;
END;
FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL IS
-- Returns number of digits in a natural number. Only used in string processing, so defined here.
-- log10(0) is not allowed so:
-- . nof_digits(0) = 1
-- We're adding 1 so:
-- . nof_digits(1) = 1
-- . nof_digits(9) = 1
-- . nof_digits(10) = 2
-- . nof_digits(1) = 2
BEGIN
IF number=0 THEN
RETURN 1;
ELSE
IF number > 0 THEN
RETURN floor_log10(number)+1;
ELSE
RETURN floor_log10(-1*number)+2;
END IF;
END IF;
END;
FUNCTION time_to_str(in_time : TIME) RETURN STRING IS
CONSTANT c_max_len_time : NATURAL := 20;
VARIABLE v_line : LINE;
VARIABLE v_str : STRING(1 TO c_max_len_time):= (OTHERS => ' ');
BEGIN
write(v_line, in_time);
v_str(v_line.ALL'RANGE) := v_line.ALL;
deallocate(v_line);
RETURN v_str;
END;
FUNCTION str_to_time(in_str : STRING) RETURN TIME IS
BEGIN
RETURN TIME'VALUE(in_str);
END;
FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING IS
VARIABLE v_line : LINE;
VARIABLE v_str : STRING(1 TO slv'LENGTH) := (OTHERS => ' ');
BEGIN
write(v_line, slv);
v_str(v_line.ALL'RANGE) := v_line.ALL;
deallocate(v_line);
RETURN v_str;
END;
FUNCTION str_to_hex(str : STRING) RETURN STRING IS
CONSTANT c_nof_nibbles : NATURAL := ceil_div(str'LENGTH, c_nibble_w);
VARIABLE v_nibble_arr : t_str_4_arr(0 TO c_nof_nibbles-1) := (OTHERS=>(OTHERS=>'0'));
VARIABLE v_hex : STRING(1 TO c_nof_nibbles) := (OTHERS => '0');
BEGIN
FOR i IN 0 TO v_hex'RIGHT-1 LOOP
v_nibble_arr(i) := slice_up(str, c_nibble_w, i, '0');
CASE v_nibble_arr(i) IS
WHEN "0000" => v_hex(i+1) := '0';
WHEN "0001" => v_hex(i+1) := '1';
WHEN "0010" => v_hex(i+1) := '2';
WHEN "0011" => v_hex(i+1) := '3';
WHEN "0100" => v_hex(i+1) := '4';
WHEN "0101" => v_hex(i+1) := '5';
WHEN "0110" => v_hex(i+1) := '6';
WHEN "0111" => v_hex(i+1) := '7';
WHEN "1000" => v_hex(i+1) := '8';
WHEN "1001" => v_hex(i+1) := '9';
WHEN "1010" => v_hex(i+1) := 'A';
WHEN "1011" => v_hex(i+1) := 'B';
WHEN "1100" => v_hex(i+1) := 'C';
WHEN "1101" => v_hex(i+1) := 'D';
WHEN "1110" => v_hex(i+1) := 'E';
WHEN "1111" => v_hex(i+1) := 'F';
WHEN OTHERS => v_hex(i+1) := 'X';
END CASE;
END LOOP;
RETURN v_hex;
END;
FUNCTION slv_to_hex(slv :STD_LOGIC_VECTOR) RETURN STRING IS
BEGIN
RETURN str_to_hex(slv_to_str(slv));
END;
FUNCTION hex_to_slv(str: STRING) RETURN STD_LOGIC_VECTOR IS
CONSTANT c_length : NATURAL := str'LENGTH;
VARIABLE v_str : STRING(1 TO str'LENGTH) := str; -- Keep local copy of str to prevent range mismatch
VARIABLE v_result : STD_LOGIC_VECTOR(c_length * 4 - 1 DOWNTO 0);
BEGIN
FOR i IN c_length DOWNTO 1 LOOP
v_result(3 +(c_length - i)*4 DOWNTO (c_length-i)*4) := hex_nibble_to_slv(v_str(i));
END LOOP;
RETURN v_result;
END;
FUNCTION hex_nibble_to_slv(c: CHARACTER) RETURN STD_LOGIC_VECTOR IS
VARIABLE v_result : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
CASE c IS
WHEN '0' => v_result := "0000";
WHEN '1' => v_result := "0001";
WHEN '2' => v_result := "0010";
WHEN '3' => v_result := "0011";
WHEN '4' => v_result := "0100";
WHEN '5' => v_result := "0101";
WHEN '6' => v_result := "0110";
WHEN '7' => v_result := "0111";
WHEN '8' => v_result := "1000";
WHEN '9' => v_result := "1001";
WHEN 'A' => v_result := "1010";
WHEN 'B' => v_result := "1011";
WHEN 'C' => v_result := "1100";
WHEN 'D' => v_result := "1101";
WHEN 'E' => v_result := "1110";
WHEN 'F' => v_result := "1111";
WHEN 'a' => v_result := "1010";
WHEN 'b' => v_result := "1011";
WHEN 'c' => v_result := "1100";
WHEN 'd' => v_result := "1101";
WHEN 'e' => v_result := "1110";
WHEN 'f' => v_result := "1111";
WHEN 'x' => v_result := "XXXX";
WHEN 'X' => v_result := "XXXX";
WHEN 'z' => v_result := "ZZZZ";
WHEN 'Z' => v_result := "ZZZZ";
WHEN OTHERS => v_result := "0000";
END CASE;
RETURN v_result;
END hex_nibble_to_slv;
FUNCTION int_to_str(int: INTEGER) RETURN STRING IS
-- CONSTANT c_max_len_int : NATURAL := 20;
VARIABLE v_line: LINE;
VARIABLE v_str: STRING(1 TO nof_digits_int(int)):= (OTHERS => ' ');
BEGIN
STD.TEXTIO.WRITE(v_line, int);
v_str(v_line.ALL'RANGE) := v_line.ALL;
deallocate(v_line);
RETURN v_str;
END;
FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING IS
VARIABLE v_line: LINE;
VARIABLE v_str: STRING(1 TO width):= (OTHERS => ' ');
BEGIN
STD.TEXTIO.WRITE(v_line, re, right, width, digits);
v_str(v_line.ALL'RANGE) := v_line.ALL;
deallocate(v_line);
RETURN v_str;
END;
PROCEDURE print_str(str: STRING) IS
VARIABLE v_line: LINE;
BEGIN
write(v_line, str);
writeline(output, v_line);
deallocate(v_line);
END;
FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr IS
VARIABLE r: t_integer_arr(0 TO s'RIGHT-1);
BEGIN
FOR i IN s'RANGE LOOP
r(i-1) := CHARACTER'POS(s(i));
END LOOP;
RETURN r;
END;
FUNCTION str_to_ascii_slv_8_arr(s: STRING) RETURN t_slv_8_arr IS
VARIABLE r: t_slv_8_arr(0 TO s'RIGHT-1);
BEGIN
FOR i IN s'RANGE LOOP
r(i-1) := TO_UVEC(str_to_ascii_integer_arr(s)(i-1), 8);
END LOOP;
RETURN r;
END;
-- Returns minimum array size required to fit the string
FUNCTION str_to_ascii_slv_32_arr(s: STRING) RETURN t_slv_32_arr IS
CONSTANT c_slv_8: t_slv_8_arr(0 TO s'RIGHT-1) := str_to_ascii_slv_8_arr(s);
CONSTANT c_bytes_per_word : NATURAL := 4;
-- Initialize all elements to (OTHERS=>'0') so any unused bytes become a NULL character
VARIABLE r: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := (OTHERS=>(OTHERS=>'0'));
BEGIN
FOR word IN r'RANGE LOOP --0, 1
FOR byte IN 0 TO c_bytes_per_word-1 LOOP -- 0,1,2,3
IF byte+c_bytes_per_word*word<=c_slv_8'RIGHT THEN
r(word)(byte*c_byte_w+c_byte_w-1 DOWNTO byte*c_byte_w) := c_slv_8(byte+c_bytes_per_word*word);
END IF;
END LOOP;
END LOOP;
RETURN r;
END;
-- Overloaded version to match array size to arr_size
FUNCTION str_to_ascii_slv_32_arr(s: STRING; arr_size: NATURAL) RETURN t_slv_32_arr IS
CONSTANT slv_32: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := str_to_ascii_slv_32_arr(s);
VARIABLE r: t_slv_32_arr(0 TO arr_size-1) := (OTHERS=>(OTHERS=>'0'));
BEGIN
FOR word IN slv_32'RANGE LOOP
r(word) := slv_32(word);
END LOOP;
RETURN r;
END;
END common_str_pkg;
hdl_lib_name = common_pkg
hdl_library_clause_name = common_pkg_lib
hdl_lib_uses_synth =
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
common_pkg.vhd
common_str_pkg.vhd
common_lfsr_sequences_pkg.vhd
tb_common_pkg.vhd
test_bench_files =
regression_test_vhdl =
[modelsim_project_file]
modelsim_copy_files =
[quartus_project_file]
This diff is collapsed.
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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_components_lib;
USE IEEE.std_logic_1164.all;
-- Purpose:
-- Hold hld_ctrl active until next ready high when in_ctrl is active while
-- ready went low
-- Description:
-- When ready goes low there may still arrive one new valid data. The control
-- information for this data can then be held with this component. When ready
-- goes high again the held data can then be output and the hld_ctrl is
-- released. After that the subsequent data output can come directly from the
-- up stream source, until ready goes low again.
-- Remarks:
-- . Ready latency RL = 1
-- . The in_ctrl is typically in_valid, in_sop or in_eop
-- . Typically used together with dp_hold_data
ENTITY dp_hold_ctrl IS
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
ready : IN STD_LOGIC;
in_ctrl : IN STD_LOGIC;
hld_ctrl : OUT STD_LOGIC
);
END dp_hold_ctrl;
ARCHITECTURE rtl OF dp_hold_ctrl IS
SIGNAL hi_ctrl : STD_LOGIC;
SIGNAL lo_ctrl : STD_LOGIC;
BEGIN
hi_ctrl <= in_ctrl AND NOT ready; -- capture
lo_ctrl <= NOT in_ctrl AND ready; -- release
u_hld_ctrl : ENTITY common_components_lib.common_switch
PORT MAP (
rst => rst,
clk => clk,
switch_high => hi_ctrl,
switch_low => lo_ctrl,
out_level => hld_ctrl
);
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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, dp_pkg_lib;
USE IEEE.std_logic_1164.all;
USE dp_pkg_lib.dp_stream_pkg.ALL;
-- Purpose:
-- Hold the sink input
-- Description:
-- This dp_hold_input provides the necessary input logic to hold the input
-- data and control to easily register the source output. Compared to
-- dp_pipeling the dp_hold_input is the same except for the output register
-- stage. In this way dp_hold_input can be used in a more complicated stream
-- component where the output is not always the same as the input.
-- The snk_in.valid and hold_in.valid are never high at the same time.
-- If src_in.ready goes low while snk_in.valid is high then this snk_in.valid
-- is held in hold_in.valid and the corresponding snk_in.data will get held
-- in the external src_out_reg.data. When src_in.ready goes high again then
-- the held data becomes valid via src_out_reg.valid and hold_in.valid goes
-- low. Due to the RL=1 the next cycle the snk_in.valid from the sink may go
-- high. The next_src_out control signals are equal to pend_src_out AND
-- src_in.ready, so they can directly be assigned to src_out_reg.data if the
-- snk_in.data needs to be passed on.
-- The internal pend_src_out control signals are available outside, in
-- addition to the next_src_out control signals, to support external control
-- independent of src_in.ready. Use pend_scr_out instead of next_src_out
-- to avoid combinatorial loop when src_in.ready depends on next_src_out.
-- The pend_src_out signals are used to implement show ahead behaviour like
-- with RL=0, but for RL=1. The input can then be stopped based on the snk_in
-- data and later on continued again without losing this snk_in data, because
-- it was held as described above.
-- Remarks:
-- . Ready latency = 1
-- . Without flow control so when src_in.ready = '1' fixed, then dp_hold_input
-- becomes void because the dp_hold_ctrl output then remains '0'.
ENTITY dp_hold_input IS
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
-- ST sink
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
-- ST source
src_in : IN t_dp_siso;
next_src_out : OUT t_dp_sosi;
pend_src_out : OUT t_dp_sosi; -- the SOSI data fields are the same as for next_src_out
src_out_reg : IN t_dp_sosi -- uses only the SOSI data fields
);
END dp_hold_input;
ARCHITECTURE rtl OF dp_hold_input IS
SIGNAL i_pend_src_out : t_dp_sosi;
SIGNAL hold_in : t_dp_sosi; -- uses only the SOSI ctrl fields
BEGIN
pend_src_out <= i_pend_src_out;
-- SISO:
snk_out <= src_in; -- No change in ready latency, pass on xon frame level flow control
-- SOSI:
-- Take care of active snk_in.valid, snk_in.sync, snk_in.sop and snk_in.eop
-- when src_in.ready went low. If hold_in.valid would not be used for
-- pend_src_out.valid and next_src_out.valid, then the pipeline would still
-- work, but the valid snk_in.data that came when src_in.ready went low,
-- will then only get pushed out on the next valid snk_in.valid. Whereas
-- hold_in.valid ensures that it will get pushed out as soon as src_in.ready
-- goes high again. This is typically necessary in case of packetized data
-- where the eop of one packet should not have to wait for the valid (sop)
-- of a next packet to get pushed out.
u_hold_val : ENTITY work.dp_hold_ctrl
PORT MAP (
rst => rst,
clk => clk,
ready => src_in.ready,
in_ctrl => snk_in.valid,
hld_ctrl => hold_in.valid
);
u_hold_sync : ENTITY work.dp_hold_ctrl
PORT MAP (
rst => rst,
clk => clk,
ready => src_in.ready,
in_ctrl => snk_in.sync,
hld_ctrl => hold_in.sync
);
u_hold_sop : ENTITY work.dp_hold_ctrl
PORT MAP (
rst => rst,
clk => clk,
ready => src_in.ready,
in_ctrl => snk_in.sop,
hld_ctrl => hold_in.sop
);
u_hold_eop : ENTITY work.dp_hold_ctrl
PORT MAP (
rst => rst,
clk => clk,
ready => src_in.ready,
in_ctrl => snk_in.eop,
hld_ctrl => hold_in.eop
);
p_pend_src_out : PROCESS(snk_in, src_out_reg, hold_in)
BEGIN
-- Pend data
IF snk_in.valid='1' THEN
i_pend_src_out <= snk_in; -- Input data
ELSE
i_pend_src_out <= src_out_reg; -- Hold data
END IF;
i_pend_src_out.valid <= snk_in.valid OR hold_in.valid;
i_pend_src_out.sync <= snk_in.sync OR hold_in.sync;
i_pend_src_out.sop <= snk_in.sop OR hold_in.sop;
i_pend_src_out.eop <= snk_in.eop OR hold_in.eop;
END PROCESS;
p_next_src_out : PROCESS(i_pend_src_out, src_in)
BEGIN
-- Next data
next_src_out <= i_pend_src_out;
-- Next control
next_src_out.valid <= i_pend_src_out.valid AND src_in.ready;
next_src_out.sync <= i_pend_src_out.sync AND src_in.ready;
next_src_out.sop <= i_pend_src_out.sop AND src_in.ready;
next_src_out.eop <= i_pend_src_out.eop AND src_in.ready;
END PROCESS;
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
-- Purpose:
-- Adapt the g_in_latency input ready to the g_out_latency output latency.
-- A typical application is to use this latency adapter to provide a read
-- ahead interface to a default FIFO with e.g. read latency 1 or 2.
-- Description:
-- If g_in_latency > g_out_latency then the input latency is first adapted
-- to zero latency by means of a latency FIFO. After that a delay line for
-- src_in.ready yields the g_out_latency output latency.
-- If g_in_latency < g_out_latency, then a delay line for src_in.ready yields
-- the g_out_latency output latency.
-- The sync input is also passed on, only if it occurs during valid. The
-- constant c_pass_sync_during_not_valid is defined to preserve the
-- corresponding section of code for passing the sync also during not valid.
-- Remark:
-- . The snk_out.ready is derived combinatorially from the src_in.ready. If for
-- timing performance it is needed to register snk_out.ready, then this can
-- be done by first increasing the ready latency using this adapter with
-- g_in_latency = g_out_latency + 1, followed by a second adapter to reach
-- the required output ready latency latency.
ENTITY dp_latency_adapter IS
GENERIC (
g_in_latency : NATURAL := 3;
g_out_latency : NATURAL := 1
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
-- Monitor internal FIFO filling
fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(2+g_in_latency)-1 DOWNTO 0); -- see description of c_fifo_size, c_usedw_w for explanation of why +2
fifo_ful : OUT STD_LOGIC;
fifo_emp : OUT STD_LOGIC;
-- ST sink
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
-- ST source
src_in : IN t_dp_siso;
src_out : OUT t_dp_sosi
);
END dp_latency_adapter;
ARCHITECTURE rtl OF dp_latency_adapter IS
-- The difference between the input ready latency and the output ready latency
CONSTANT c_diff_latency : INTEGER := g_out_latency - g_in_latency;
-- Define constant to preserve the corresponding section of code, but default keep it at FALSE
CONSTANT c_pass_sync_during_not_valid : BOOLEAN := FALSE;
-- Use g_in_latency+1 words for the FIFO data array, to go to zero latency
CONSTANT c_high : NATURAL := g_in_latency;
CONSTANT c_fifo_size : NATURAL := g_in_latency+1; -- +1 because RL=0 also requires a word
CONSTANT c_usedw_w : NATURAL := ceil_log2(c_fifo_size+1); -- +1 because to store value 2**n requires n+1 bits
SIGNAL fifo_reg : t_dp_sosi_arr(c_high DOWNTO 0);
SIGNAL nxt_fifo_reg : t_dp_sosi_arr(c_high DOWNTO 0);
SIGNAL fifo_reg_valid : STD_LOGIC_VECTOR(c_high DOWNTO 0); -- debug signal for Wave window
SIGNAL nxt_fifo_usedw : STD_LOGIC_VECTOR(c_usedw_w-1 DOWNTO 0);
SIGNAL nxt_fifo_ful : STD_LOGIC;
SIGNAL nxt_fifo_emp : STD_LOGIC;
SIGNAL ff_siso : t_dp_siso; -- SISO ready
SIGNAL ff_sosi : t_dp_sosi; -- SOSI
SIGNAL i_snk_out : t_dp_siso := c_dp_siso_rdy;
BEGIN
-- Use i_snk_out with defaults to force unused snk_out bits and fields to '0'
snk_out <= i_snk_out;
gen_wires : IF c_diff_latency = 0 GENERATE -- g_out_latency = g_in_latency
i_snk_out <= src_in; -- SISO
src_out <= snk_in; -- SOSI
END GENERATE gen_wires;
no_fifo : IF c_diff_latency > 0 GENERATE -- g_out_latency > g_in_latency
-- Go from g_in_latency to required larger g_out_latency
u_latency : ENTITY work.dp_latency_increase
GENERIC MAP (
g_in_latency => g_in_latency,
g_incr_latency => c_diff_latency
)
PORT MAP (
rst => rst,
clk => clk,
-- ST sink
snk_out => i_snk_out,
snk_in => snk_in,
-- ST source
src_in => src_in,
src_out => src_out
);
END GENERATE no_fifo;
gen_fifo : IF c_diff_latency < 0 GENERATE -- g_out_latency < g_in_latency
-- Register [0] contains the FIFO output with zero ready latency
ff_sosi <= fifo_reg(0);
p_clk_fifo : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
fifo_reg <= (OTHERS=>c_dp_sosi_rst);
fifo_usedw <= (OTHERS=>'0');
fifo_ful <= '0';
fifo_emp <= '1';
ELSIF rising_edge(clk) THEN
fifo_reg <= nxt_fifo_reg;
fifo_usedw <= nxt_fifo_usedw;
fifo_ful <= nxt_fifo_ful;
fifo_emp <= nxt_fifo_emp;
END IF;
END PROCESS;
-- Pass on frame level flow control
i_snk_out.xon <= src_in.xon;
p_snk_out_ready : PROCESS(fifo_reg, ff_siso, snk_in)
BEGIN
i_snk_out.ready <= '0';
IF ff_siso.ready='1' THEN
-- Default snk_out ready when the source is ready.
i_snk_out.ready <= '1';
ELSE
-- Extra snk_out ready to look ahead for src_in RL = 0.
-- The fifo_reg[h:0] size is g_in_latency+1 number of SOSI values.
-- . The fifo_reg[h:1] provide free space for h=g_in_latency nof data
-- when snk_out.ready is pulled low, because then there can still
-- arrive g_in_latency nof new data with snk_in.valid asserted.
-- . The [0] is the registered output SOSI value with RL=0. Therefore
-- fifo_reg[0] can still accept a new input when ff_siso.ready is
-- low. If this assignment is omitted then the functionallity is
-- still OK, but the throughtput sligthly reduces.
IF fifo_reg(0).valid='0' THEN
i_snk_out.ready <= '1';
ELSIF fifo_reg(1).valid='0' THEN
i_snk_out.ready <= NOT(snk_in.valid);
END IF;
END IF;
END PROCESS;
p_fifo_reg : PROCESS(fifo_reg, ff_siso, snk_in)
BEGIN
-- Keep or shift the fifo_reg dependent on ff_siso.ready, no need to explicitly check fifo_reg().valid
nxt_fifo_reg <= fifo_reg;
IF ff_siso.ready='1' THEN
nxt_fifo_reg(c_high-1 DOWNTO 0) <= fifo_reg(c_high DOWNTO 1);
nxt_fifo_reg(c_high).valid <= '0';
nxt_fifo_reg(c_high).sync <= '0';
nxt_fifo_reg(c_high).sop <= '0';
nxt_fifo_reg(c_high).eop <= '0';
-- Forcing the nxt_fifo_reg[h] control fields to '0' is robust, but not
-- strictly necessary, because the control fields in fifo_reg[h] will
-- have been set to '0' already earlier due to the snk_in when
-- ff_siso.ready was '0'.
END IF;
-- Put input data at the first available location dependent on ff_siso.ready, no need to explicitly check snk_in.valid
IF fifo_reg(0).valid='0' THEN
nxt_fifo_reg(0) <= snk_in; -- fifo_reg is empty
ELSE
-- The fifo_reg is not empty, so filled to some extend
FOR I IN 1 TO c_high LOOP
IF fifo_reg(I).valid='0' THEN
IF ff_siso.ready='0' THEN
nxt_fifo_reg(I) <= snk_in;
ELSE
nxt_fifo_reg(I-1) <= snk_in;
END IF;
EXIT;
END IF;
END LOOP;
-- Default the input sync during input data valid is only passed on with the valid input data.
-- When c_pass_sync_during_not_valid is enabled then the input sync during input data not valid is passed on via the head fifo_reg(0) if the fifo_reg is empty.
IF c_pass_sync_during_not_valid=TRUE AND snk_in.sync='1' AND snk_in.valid='0' THEN
-- Otherwise for input sync during input data not valid we need to insert the input sync at the last location with valid data independent of ff_siso.ready, to avoid that it gets lost.
-- For streams that do not use the sync this logic will be void and optimize away by synthesis, because then snk_in.sync = '0' fixed.
IF fifo_reg(c_high).valid='1' THEN -- fifo_reg is full
nxt_fifo_reg(c_high).sync <= '1'; -- insert input sync
ELSE
FOR I IN c_high-1 DOWNTO 0 LOOP -- fifo_reg is filled to some extend, so not full and not empty
IF fifo_reg(I).valid='1' THEN
nxt_fifo_reg(I+1).sync <= '0'; -- overrule default sync assignment
nxt_fifo_reg(I).sync <= '1'; -- insert input sync
EXIT;
END IF;
END LOOP;
END IF;
END IF;
END IF;
END PROCESS;
p_fifo_usedw : PROCESS(nxt_fifo_reg)
BEGIN
nxt_fifo_usedw <= (OTHERS=>'0');
FOR I IN c_high DOWNTO 0 LOOP
IF nxt_fifo_reg(I).valid='1' THEN
nxt_fifo_usedw <= TO_UVEC(I+1, c_usedw_w);
EXIT;
END IF;
END LOOP;
END PROCESS;
fifo_reg_valid <= func_dp_stream_arr_get(fifo_reg, "VALID");
nxt_fifo_ful <= '1' WHEN TO_UINT(nxt_fifo_usedw)>=c_high+1 ELSE '0'; -- using >= or = is equivalent here
nxt_fifo_emp <= '1' WHEN TO_UINT(nxt_fifo_usedw) =0 ELSE '0';
-- Go from 0 FIFO latency to required g_out_latency (only wires when g_out_latency=0)
u_latency : ENTITY work.dp_latency_increase
GENERIC MAP (
g_in_latency => 0,
g_incr_latency => g_out_latency
)
PORT MAP (
rst => rst,
clk => clk,
-- ST sink
snk_out => ff_siso,
snk_in => ff_sosi,
-- ST source
src_in => src_in,
src_out => src_out
);
END GENERATE gen_fifo;
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
-- Purpose:
-- Typically used in dp_latency_adapter.
-- Description:
-- Increase the output ready latency by g_incr_latency compared to the input
-- ready latency g_in_latency. Hence the output latency becomes g_in_latency
-- + g_incr_latency.
-- Remark:
-- . The SOSI data stream signals (i.e. data, empty, channel, err) are passed
-- on as wires.
-- . The out_sync, out_val, out_sop and out_eop are internally AND with the
-- delayed src_in.ready, this is only truely necessary if the input ready
-- latency is 0, but it does not harm to do it also when the input ready
-- latency > 0. However to easy achieving P&R timing it is better to not have
-- unnessary logic in the combinatorial path of out_sync, out_val, out_sop
-- and out_eop, therefore the AND with reg_val is only generated when
-- g_in_latency=0.
ENTITY dp_latency_increase IS
GENERIC (
g_in_latency : NATURAL := 0; -- >= 0
g_incr_latency : NATURAL := 2 -- >= 0
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
-- ST sink
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
-- ST source
src_in : IN t_dp_siso;
src_out : OUT t_dp_sosi
);
END dp_latency_increase;
ARCHITECTURE rtl OF dp_latency_increase IS
CONSTANT c_out_latency : NATURAL := g_in_latency + g_incr_latency;
SIGNAL reg_ready : STD_LOGIC_VECTOR(c_out_latency DOWNTO 0);
SIGNAL reg_val : STD_LOGIC;
SIGNAL i_snk_out : t_dp_siso := c_dp_siso_rdy;
BEGIN
-- Use i_snk_out with defaults to force unused snk_out bits and fields to '0'
snk_out <= i_snk_out;
-- Support wires only for g_incr_latency=0
no_latency : IF g_incr_latency=0 GENERATE
i_snk_out <= src_in; -- SISO
src_out <= snk_in; -- SOSI
END GENERATE no_latency;
gen_latency : IF g_incr_latency>0 GENERATE
-- SISO
reg_ready(0) <= src_in.ready; -- use reg_ready(0) to combinatorially store src_in.ready
p_clk : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
reg_ready(c_out_latency DOWNTO 1) <= (OTHERS=>'0');
ELSIF rising_edge(clk) THEN
reg_ready(c_out_latency DOWNTO 1) <= reg_ready(c_out_latency-1 DOWNTO 0);
END IF;
END PROCESS;
i_snk_out.xon <= src_in.xon; -- Pass on frame level flow control
i_snk_out.ready <= reg_ready(g_incr_latency); -- Adjust ready latency
-- SOSI
gen_out : IF g_in_latency/=0 GENERATE
src_out <= snk_in;
END GENERATE;
gen_zero_out : IF g_in_latency=0 GENERATE
reg_val <= reg_ready(c_out_latency);
p_src_out : PROCESS(snk_in, reg_val)
BEGIN
src_out <= snk_in;
src_out.sync <= snk_in.sync AND reg_val;
src_out.valid <= snk_in.valid AND reg_val;
src_out.sop <= snk_in.sop AND reg_val;
src_out.eop <= snk_in.eop AND reg_val;
END PROCESS;
END GENERATE;
END GENERATE gen_latency;
END rtl;
hdl_lib_name = dp_components
hdl_library_clause_name = dp_components_lib
hdl_lib_uses_synth = common_pkg common_components dp_pkg
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
dp_latency_increase.vhd
dp_latency_adapter.vhd
dp_hold_ctrl.vhd
dp_hold_input.vhd
test_bench_files =
tb_dp_latency_adapter.vhd
regression_test_vhdl =
tb_dp_latency_adapter.vhd
[modelsim_project_file]
[quartus_project_file]
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
hdl_lib_name = dp_counter
hdl_library_clause_name = dp_counter_lib
hdl_lib_uses_synth = dp_pipeline
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
dp_counter_func_single.vhd
dp_counter_func.vhd
dp_counter.vhd
test_bench_files =
tb_dp_counter.vhd
tb_tb_dp_counter.vhd
regression_test_vhdl =
tb_dp_counter_func.vhd
tb_tb_dp_counter.vhd
[modelsim_project_file]
[quartus_project_file]
This diff is collapsed.
This diff is collapsed.
-------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.tb_dp_pkg.ALL;
-- Purpose: Verify multiple variations of tb_dp_counter
-- Description:
-- Usage:
-- > as 6
-- > run -all
ENTITY tb_tb_dp_counter IS
END tb_tb_dp_counter;
ARCHITECTURE tb OF tb_tb_dp_counter IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- -- general
-- g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control
-- g_flow_control_verify : t_dp_flow_control_enum := e_pulse; -- always active, random or pulse flow control
-- -- dut
-- g_pipeline_src_out : NATURAL := 1; -- Pipeline source outputs (data,valid,sop,eop etc)
-- g_pipeline_src_in : NATURAL := 0 -- Pipeline source inputs (ready,xon). This will also pipeline src_out.
-- g_nof_counters : NATURAL := 2;
-- -- min range = [0,2,1] => (0,1) 'the Python way'
-- g_range_start : t_nat_natural_arr(9 DOWNTO 0) := (0,0,0,0,0,0,0, 1, 0, 0);
-- g_range_stop : t_nat_natural_arr(9 DOWNTO 0) := (2,2,2,2,2,2,7,16,16,16);
-- g_range_step : t_nat_natural_arr(9 DOWNTO 0) := (1,1,1,1,1,1,2, 2, 2, 1);
u_act_act_comb : ENTITY work.tb_dp_counter GENERIC MAP (e_active, e_active, 0, 0, 3);
u_act_act_pipe_out : ENTITY work.tb_dp_counter GENERIC MAP (e_active, e_active, 1, 0, 3);
u_act_act_pipe_in : ENTITY work.tb_dp_counter GENERIC MAP (e_active, e_active, 0, 1, 3);
u_rnd_rnd_comb : ENTITY work.tb_dp_counter GENERIC MAP (e_random, e_random, 0, 0, 3);
u_rnd_rnd_pipe_out : ENTITY work.tb_dp_counter GENERIC MAP (e_random, e_random, 1, 0, 3);
u_rnd_rnd_pipe_in : ENTITY work.tb_dp_counter GENERIC MAP (e_random, e_random, 0, 1, 3);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment