1 |
2 |
danv |
-------------------------------------------------------------------------------
|
2 |
|
|
--
|
3 |
3 |
danv |
-- Copyright 2020
|
4 |
2 |
danv |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
|
5 |
|
|
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
|
6 |
3 |
danv |
--
|
7 |
|
|
-- Licensed under the Apache License, Version 2.0 (the "License");
|
8 |
|
|
-- you may not use this file except in compliance with the License.
|
9 |
|
|
-- You may obtain a copy of the License at
|
10 |
|
|
--
|
11 |
|
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
12 |
|
|
--
|
13 |
|
|
-- Unless required by applicable law or agreed to in writing, software
|
14 |
|
|
-- distributed under the License is distributed on an "AS IS" BASIS,
|
15 |
|
|
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16 |
|
|
-- See the License for the specific language governing permissions and
|
17 |
|
|
-- limitations under the License.
|
18 |
2 |
danv |
--
|
19 |
|
|
-------------------------------------------------------------------------------
|
20 |
|
|
|
21 |
|
|
LIBRARY IEEE, common_pkg_lib, common_components_lib;
|
22 |
|
|
USE IEEE.std_logic_1164.ALL;
|
23 |
|
|
USE IEEE.numeric_std.ALL;
|
24 |
|
|
USE common_pkg_lib.common_pkg.ALL;
|
25 |
|
|
USE common_pkg_lib.common_lfsr_sequences_pkg.ALL;
|
26 |
|
|
USE common_pkg_lib.tb_common_pkg.ALL;
|
27 |
|
|
|
28 |
|
|
-- Purpose: Test bench for common_multiplexer.vhd and common_demultiplexer.vhd
|
29 |
|
|
-- Usage:
|
30 |
|
|
-- > as 6
|
31 |
|
|
-- > run -all
|
32 |
|
|
-- The tb p_verify self-checks the output by using first a 1->g_nof_streams
|
33 |
|
|
-- demultiplexer and then a g_nof_streams->1 multiplexer. Both the use the
|
34 |
|
|
-- same output and input selection so that the expected output data is again
|
35 |
|
|
-- the same as the input stimuli data.
|
36 |
|
|
-- Remark:
|
37 |
|
|
|
38 |
|
|
ENTITY tb_common_multiplexer IS
|
39 |
|
|
GENERIC (
|
40 |
|
|
g_pipeline_demux_in : NATURAL := 1;
|
41 |
|
|
g_pipeline_demux_out : NATURAL := 1;
|
42 |
|
|
g_nof_streams : NATURAL := 3;
|
43 |
|
|
g_pipeline_mux_in : NATURAL := 1;
|
44 |
|
|
g_pipeline_mux_out : NATURAL := 1;
|
45 |
|
|
g_dat_w : NATURAL := 8;
|
46 |
|
|
g_random_in_val : BOOLEAN := FALSE;
|
47 |
|
|
g_test_nof_cycles : NATURAL := 500
|
48 |
|
|
);
|
49 |
|
|
END tb_common_multiplexer;
|
50 |
|
|
|
51 |
|
|
ARCHITECTURE tb OF tb_common_multiplexer IS
|
52 |
|
|
|
53 |
|
|
CONSTANT clk_period : TIME := 10 ns;
|
54 |
|
|
|
55 |
|
|
CONSTANT c_rl : NATURAL := 1;
|
56 |
|
|
CONSTANT c_init : NATURAL := 0;
|
57 |
|
|
|
58 |
|
|
-- DUT constants
|
59 |
|
|
CONSTANT c_pipeline_demux : NATURAL := g_pipeline_demux_in + g_pipeline_demux_out;
|
60 |
|
|
CONSTANT c_pipeline_mux : NATURAL := g_pipeline_mux_in + g_pipeline_mux_out;
|
61 |
|
|
CONSTANT c_pipeline_total : NATURAL := c_pipeline_demux + c_pipeline_mux;
|
62 |
|
|
|
63 |
|
|
CONSTANT c_sel_w : NATURAL := ceil_log2(g_nof_streams);
|
64 |
|
|
|
65 |
|
|
-- Stimuli
|
66 |
|
|
SIGNAL tb_end : STD_LOGIC := '0';
|
67 |
|
|
SIGNAL rst : STD_LOGIC;
|
68 |
|
|
SIGNAL clk : STD_LOGIC := '1';
|
69 |
|
|
SIGNAL ready : STD_LOGIC := '1';
|
70 |
|
|
SIGNAL verify_en : STD_LOGIC := '0';
|
71 |
|
|
SIGNAL random_0 : STD_LOGIC_VECTOR(14 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
|
72 |
|
|
SIGNAL cnt_en : STD_LOGIC := '1';
|
73 |
|
|
|
74 |
|
|
-- DUT input
|
75 |
|
|
SIGNAL in_dat : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0) := (OTHERS => '0');
|
76 |
|
|
SIGNAL in_val : STD_LOGIC;
|
77 |
|
|
SIGNAL in_sel : STD_LOGIC_VECTOR(c_sel_w-1 DOWNTO 0) := (OTHERS => '0');
|
78 |
|
|
|
79 |
|
|
-- Demux-Mux interface
|
80 |
|
|
SIGNAL demux_dat_vec : STD_LOGIC_VECTOR(g_nof_streams*g_dat_w-1 DOWNTO 0);
|
81 |
|
|
SIGNAL demux_val_vec : STD_LOGIC_VECTOR(g_nof_streams -1 DOWNTO 0);
|
82 |
|
|
SIGNAL demux_val : STD_LOGIC;
|
83 |
|
|
SIGNAL demux_sel : STD_LOGIC_VECTOR(c_sel_w-1 DOWNTO 0);
|
84 |
|
|
|
85 |
|
|
-- DUT output
|
86 |
|
|
SIGNAL out_dat : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
|
87 |
|
|
SIGNAL out_val : STD_LOGIC;
|
88 |
|
|
|
89 |
|
|
-- Verify
|
90 |
|
|
SIGNAL prev_out_dat : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
|
91 |
|
|
SIGNAL pipe_dat_vec : STD_LOGIC_VECTOR(0 TO (c_pipeline_total+1)*g_dat_w-1);
|
92 |
|
|
SIGNAL pipe_val_vec : STD_LOGIC_VECTOR(0 TO (c_pipeline_total+1)*1 -1);
|
93 |
|
|
|
94 |
|
|
BEGIN
|
95 |
|
|
|
96 |
|
|
------------------------------------------------------------------------------
|
97 |
|
|
-- Stimuli
|
98 |
|
|
------------------------------------------------------------------------------
|
99 |
|
|
|
100 |
|
|
-- . tb
|
101 |
|
|
clk <= NOT clk OR tb_end AFTER clk_period/2;
|
102 |
|
|
rst <= '1', '0' AFTER 3*clk_period;
|
103 |
|
|
tb_end <= '0', '1' AFTER g_test_nof_cycles*clk_period;
|
104 |
|
|
|
105 |
|
|
-- . data
|
106 |
|
|
random_0 <= func_common_random(random_0) WHEN rising_edge(clk);
|
107 |
|
|
|
108 |
|
|
cnt_en <= '1' WHEN g_random_in_val=FALSE ELSE random_0(random_0'HIGH);
|
109 |
|
|
|
110 |
|
|
proc_common_gen_data(c_rl, c_init, rst, clk, cnt_en, ready, in_dat, in_val);
|
111 |
|
|
|
112 |
|
|
-- . selection
|
113 |
|
|
in_sel <= INCR_UVEC(in_sel, 1) WHEN rising_edge(clk) AND TO_UINT(in_sel)<g_nof_streams-1 ELSE
|
114 |
|
|
TO_UVEC(0, c_sel_w) WHEN rising_edge(clk); -- periodic selection over all demultiplexer output and multiplexer input streams
|
115 |
|
|
|
116 |
|
|
-- . verification
|
117 |
|
|
p_verify_en : PROCESS
|
118 |
|
|
BEGIN
|
119 |
|
|
proc_common_wait_until_high(clk, in_val);
|
120 |
|
|
proc_common_wait_some_cycles(clk, c_pipeline_total);
|
121 |
|
|
|
122 |
|
|
verify_en <= '1';
|
123 |
|
|
WAIT;
|
124 |
|
|
END PROCESS;
|
125 |
|
|
|
126 |
|
|
------------------------------------------------------------------------------
|
127 |
|
|
-- DUT : 1 --> g_nof_streams --> 1
|
128 |
|
|
------------------------------------------------------------------------------
|
129 |
|
|
|
130 |
|
|
-- . Demultiplex single input to output[in_sel]
|
131 |
|
|
u_demux : ENTITY work.common_demultiplexer
|
132 |
|
|
GENERIC MAP (
|
133 |
|
|
g_pipeline_in => g_pipeline_demux_in,
|
134 |
|
|
g_pipeline_out => g_pipeline_demux_out,
|
135 |
|
|
g_nof_out => g_nof_streams,
|
136 |
|
|
g_dat_w => g_dat_w
|
137 |
|
|
)
|
138 |
|
|
PORT MAP(
|
139 |
|
|
rst => rst,
|
140 |
|
|
clk => clk,
|
141 |
|
|
|
142 |
|
|
in_dat => in_dat,
|
143 |
|
|
in_val => in_val,
|
144 |
|
|
|
145 |
|
|
out_sel => in_sel,
|
146 |
|
|
out_dat => demux_dat_vec,
|
147 |
|
|
out_val => demux_val_vec
|
148 |
|
|
);
|
149 |
|
|
|
150 |
|
|
-- . pipeline in_sel to align demux_sel to demux_*_vec
|
151 |
|
|
u_pipe_sel : ENTITY common_components_lib.common_pipeline
|
152 |
|
|
GENERIC MAP (
|
153 |
|
|
g_pipeline => c_pipeline_demux,
|
154 |
|
|
g_in_dat_w => c_sel_w,
|
155 |
|
|
g_out_dat_w => c_sel_w
|
156 |
|
|
)
|
157 |
|
|
PORT MAP (
|
158 |
|
|
rst => rst,
|
159 |
|
|
clk => clk,
|
160 |
|
|
in_dat => in_sel,
|
161 |
|
|
out_dat => demux_sel
|
162 |
|
|
);
|
163 |
|
|
|
164 |
|
|
demux_val <= demux_val_vec(TO_UINT(demux_sel));
|
165 |
|
|
|
166 |
|
|
-- . Multiplex input[demux_sel] back to a single output
|
167 |
|
|
u_mux : ENTITY work.common_multiplexer
|
168 |
|
|
GENERIC MAP (
|
169 |
|
|
g_pipeline_in => g_pipeline_mux_in,
|
170 |
|
|
g_pipeline_out => g_pipeline_mux_out,
|
171 |
|
|
g_nof_in => g_nof_streams,
|
172 |
|
|
g_dat_w => g_dat_w
|
173 |
|
|
)
|
174 |
|
|
PORT MAP (
|
175 |
|
|
rst => rst,
|
176 |
|
|
clk => clk,
|
177 |
|
|
|
178 |
|
|
in_sel => demux_sel,
|
179 |
|
|
in_dat => demux_dat_vec,
|
180 |
|
|
in_val => demux_val,
|
181 |
|
|
|
182 |
|
|
out_dat => out_dat,
|
183 |
|
|
out_val => out_val
|
184 |
|
|
);
|
185 |
|
|
|
186 |
|
|
|
187 |
|
|
------------------------------------------------------------------------------
|
188 |
|
|
-- Verification
|
189 |
|
|
------------------------------------------------------------------------------
|
190 |
|
|
|
191 |
|
|
proc_common_verify_data(c_rl, clk, verify_en, ready, out_val, out_dat, prev_out_dat); -- verify out_dat assuming incrementing data
|
192 |
|
|
proc_common_verify_latency("data", c_pipeline_total, clk, verify_en, in_dat, pipe_dat_vec, out_dat); -- verify out_dat using delayed input
|
193 |
|
|
proc_common_verify_latency("valid", c_pipeline_total, clk, verify_en, in_val, pipe_val_vec, out_val); -- verify out_val using delayed input
|
194 |
|
|
|
195 |
|
|
END tb;
|