1 |
42 |
lmaarsen |
--------------------------------------------------------------------------------
|
2 |
|
|
---- ----
|
3 |
|
|
---- Ethernet Switch on Configurable Logic IP Core ----
|
4 |
|
|
---- ----
|
5 |
|
|
---- This file is part of the ESoCL project ----
|
6 |
|
|
---- http://www.opencores.org/cores/esoc/ ----
|
7 |
|
|
---- ----
|
8 |
|
|
---- Description: see design description ESoCL_dd_71022001.pdf ----
|
9 |
|
|
---- ----
|
10 |
|
|
---- To Do: see roadmap description ESoCL_dd_71022001.pdf ----
|
11 |
|
|
---- and/or release bulleting ESoCL_rb_71022001.pdf ----
|
12 |
|
|
---- ----
|
13 |
|
|
---- Author(s): L.Maarsen ----
|
14 |
|
|
---- Bert Maarsen, lmaarsen@opencores.org ----
|
15 |
|
|
---- ----
|
16 |
|
|
--------------------------------------------------------------------------------
|
17 |
|
|
---- ----
|
18 |
|
|
---- Copyright (C) 2009 Authors and OPENCORES.ORG ----
|
19 |
|
|
---- ----
|
20 |
|
|
---- This source file may be used and distributed without ----
|
21 |
|
|
---- restriction provided that this copyright statement is not ----
|
22 |
|
|
---- removed from the file and that any derivative work contains ----
|
23 |
|
|
---- the original copyright notice and the associated disclaimer. ----
|
24 |
|
|
---- ----
|
25 |
|
|
---- This source file is free software; you can redistribute it ----
|
26 |
|
|
---- and/or modify it under the terms of the GNU Lesser General ----
|
27 |
|
|
---- Public License as published by the Free Software Foundation; ----
|
28 |
|
|
---- either version 2.1 of the License, or (at your option) any ----
|
29 |
|
|
---- later version. ----
|
30 |
|
|
---- ----
|
31 |
|
|
---- This source is distributed in the hope that it will be ----
|
32 |
|
|
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
|
33 |
|
|
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
|
34 |
|
|
---- PURPOSE. See the GNU Lesser General Public License for more ----
|
35 |
|
|
---- details. ----
|
36 |
|
|
---- ----
|
37 |
|
|
---- You should have received a copy of the GNU Lesser General ----
|
38 |
|
|
---- Public License along with this source; if not, download it ----
|
39 |
|
|
---- from http://www.opencores.org/lgpl.shtml ----
|
40 |
|
|
---- ----
|
41 |
|
|
--------------------------------------------------------------------------------
|
42 |
|
|
-- Object : Entity work.esoc_tb
|
43 |
|
|
-- Last modified : Mon Apr 14 12:50:20 2014.
|
44 |
|
|
--------------------------------------------------------------------------------
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
|
48 |
|
|
library ieee, std, work;
|
49 |
|
|
use ieee.std_logic_1164.all;
|
50 |
|
|
use std.textio.all;
|
51 |
|
|
use ieee.numeric_std.all;
|
52 |
|
|
use work.package_crc32_8b.all;
|
53 |
|
|
use work.package_esoc_configuration.all;
|
54 |
|
|
use work.package_txt_utilities.all;
|
55 |
|
|
|
56 |
|
|
entity esoc_tb is
|
57 |
|
|
end entity esoc_tb;
|
58 |
|
|
|
59 |
|
|
--------------------------------------------------------------------------------
|
60 |
|
|
-- Object : Architecture work.esoc_tb.esoc_tb
|
61 |
|
|
-- Last modified : Mon Apr 14 12:50:20 2014.
|
62 |
|
|
--------------------------------------------------------------------------------
|
63 |
|
|
|
64 |
|
|
architecture esoc_tb of esoc_tb is
|
65 |
|
|
|
66 |
|
|
type smi_states is (start, preamble, cmd, dev_addr, reg_addr, ta_cycles, data,store);
|
67 |
|
|
|
68 |
|
|
signal esoc_wait_timer_start : std_logic; -- Used by CONTROL testbench to protect bus cycles from freezing
|
69 |
|
|
signal esoc_wait_time_enable : std_logic;
|
70 |
|
|
signal esoc_wait_timer : integer; -- Used by CONTROL testbench to protect bus cycles from freezing
|
71 |
|
|
signal esoc_wait_timeout : std_logic; -- Used by CONTROL testbench to protect bus cycles from freezing
|
72 |
|
|
signal esoc_rgmii_rxc_int : std_logic; -- Used by RGMII testbench
|
73 |
|
|
signal esoc_rgmii_txc_int : std_logic_vector(esoc_port_count-1 downto 0); -- Used by RGMII testbench
|
74 |
|
|
signal reg_rgmii_port_enable : std_logic_vector(31 downto 0); -- Used by RGMII testbench, under control of CONTROL testbench
|
75 |
|
|
signal reg_rgmii_port_enable2 : std_logic_vector(31 downto 0); -- Used by RGMII testbench, under control of CONTROL testbench
|
76 |
|
|
signal smi_mdio : std_logic_vector(esoc_port_count-1 downto 0);
|
77 |
|
|
signal smi_mdio_ena : std_logic_vector(esoc_port_count-1 downto 0);
|
78 |
|
|
signal esoc_wait : std_logic;
|
79 |
|
|
signal esoc_rgmii_txc : std_logic_vector(esoc_port_count-1 downto 0);
|
80 |
|
|
signal esoc_rgmii_rxd : std_logic_vector(3+4*(esoc_port_count-1) downto 0);
|
81 |
|
|
signal esoc_rgmii_rxctl : std_logic_vector(esoc_port_count-1 downto 0);
|
82 |
|
|
signal esoc_rgmii_rxc : std_logic_vector(esoc_port_count-1 downto 0);
|
83 |
|
|
signal esoc_address : std_logic_vector(15 downto 0);
|
84 |
|
|
signal esoc_wr : std_logic;
|
85 |
|
|
signal esoc_data : std_logic_vector(31 downto 0);
|
86 |
|
|
signal esoc_rd : std_logic;
|
87 |
|
|
signal esoc_areset : std_logic;
|
88 |
|
|
signal esoc_cs : std_logic;
|
89 |
|
|
signal esoc_clk : std_logic;
|
90 |
|
|
signal esoc_rgmii_txctl : std_logic_vector(esoc_port_count-1 downto 0);
|
91 |
|
|
signal esoc_rgmii_txd : std_logic_vector(3+4*(esoc_port_count-1) downto 0);
|
92 |
|
|
signal esoc_boot_complete : std_logic;
|
93 |
|
|
signal esoc_mdio : std_logic_vector(esoc_port_count-1 downto 0);
|
94 |
|
|
signal esoc_mdc : std_logic_vector(esoc_port_count-1 downto 0);
|
95 |
|
|
|
96 |
|
|
component esoc
|
97 |
|
|
port(
|
98 |
|
|
esoc_address : in std_logic_vector(15 downto 0);
|
99 |
|
|
esoc_areset : in std_logic;
|
100 |
|
|
esoc_boot_complete : out std_logic;
|
101 |
|
|
esoc_clk : in std_logic;
|
102 |
|
|
esoc_cs : in std_logic;
|
103 |
|
|
esoc_data : inout std_logic_vector(31 downto 0);
|
104 |
|
|
esoc_mdc : out std_logic_vector(esoc_port_count-1 downto 0);
|
105 |
|
|
esoc_mdio : inout std_logic_vector(esoc_port_count-1 downto 0);
|
106 |
|
|
esoc_rd : in std_logic;
|
107 |
|
|
esoc_rgmii_rxc : in std_logic_vector(esoc_port_count-1 downto 0);
|
108 |
|
|
esoc_rgmii_rxctl : in std_logic_vector(esoc_port_count-1 downto 0);
|
109 |
|
|
esoc_rgmii_rxd : in std_logic_vector(3+4*(esoc_port_count-1) downto 0);
|
110 |
|
|
esoc_rgmii_txc : out std_logic_vector(esoc_port_count-1 downto 0);
|
111 |
|
|
esoc_rgmii_txctl : out std_logic_vector(esoc_port_count-1 downto 0);
|
112 |
|
|
esoc_rgmii_txd : out std_logic_vector(3+4*(esoc_port_count-1) downto 0);
|
113 |
|
|
esoc_wait : out std_logic;
|
114 |
|
|
esoc_wr : in std_logic);
|
115 |
|
|
end component esoc;
|
116 |
|
|
|
117 |
|
|
begin
|
118 |
|
|
esoc_test_rgmii_loggers: for esoc_port_nr in esoc_port_count-1 downto 0 generate
|
119 |
|
|
begin
|
120 |
|
|
|
121 |
|
|
esoc_test_rgmii_logger: process -- EASE/HDL sens.list
|
122 |
|
|
begin
|
123 |
|
|
wait;
|
124 |
|
|
end process esoc_test_rgmii_logger ;
|
125 |
|
|
-- create shifted txc clock
|
126 |
|
|
esoc_rgmii_txc_int <= esoc_rgmii_txc after 2 ns;
|
127 |
|
|
|
128 |
|
|
--=============================================================================================================
|
129 |
|
|
-- Process : store all packets on RGMII RX interfaces
|
130 |
|
|
-- Description :
|
131 |
|
|
--=============================================================================================================
|
132 |
|
|
esoc_rgmii_rx_logging: process(esoc_rgmii_rxc, esoc_areset)
|
133 |
|
|
-- declare file for rgmii interface logging
|
134 |
|
|
file esoc_rgmii_rx_log : TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_rx_port_" & to_string(esoc_port_nr) & "_log.txt";
|
135 |
|
|
|
136 |
|
|
variable esoc_rgmii_rx_buffer: LINE;
|
137 |
|
|
|
138 |
|
|
variable byte: std_logic_vector(7 downto 0);
|
139 |
|
|
variable byte_counter: integer;
|
140 |
|
|
variable rx_state: std_logic;
|
141 |
|
|
|
142 |
|
|
begin
|
143 |
|
|
if esoc_areset = '1' then
|
144 |
|
|
byte_counter := 0;
|
145 |
|
|
rx_state := '0';
|
146 |
|
|
|
147 |
|
|
elsif esoc_rgmii_rxc(esoc_port_nr)'event and esoc_rgmii_rxc(esoc_port_nr) = '1' then
|
148 |
|
|
if esoc_rgmii_rxctl(esoc_port_nr) = '1' then
|
149 |
|
|
rx_state := '1';
|
150 |
|
|
byte(3 downto 0) := esoc_rgmii_rxd(esoc_port_nr*4+3 downto esoc_port_nr*4);
|
151 |
|
|
|
152 |
|
|
elsif rx_state = '1' then
|
153 |
|
|
rx_state := '0';
|
154 |
|
|
byte_counter := 0;
|
155 |
|
|
write(esoc_rgmii_rx_buffer,string'(""));
|
156 |
|
|
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
|
157 |
|
|
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
|
158 |
|
|
end if;
|
159 |
|
|
|
160 |
|
|
elsif esoc_rgmii_rxc(esoc_port_nr)'event and esoc_rgmii_rxc(esoc_port_nr) = '0' then
|
161 |
|
|
if esoc_rgmii_rxctl(esoc_port_nr) = '1' and rx_state = '1' then
|
162 |
|
|
byte(7 downto 4) := esoc_rgmii_rxd(esoc_port_nr*4+3 downto esoc_port_nr*4);
|
163 |
|
|
write(esoc_rgmii_rx_buffer, to_hexstring(byte) & " ");
|
164 |
|
|
|
165 |
|
|
if byte_counter = 15 then
|
166 |
|
|
byte_counter := 0;
|
167 |
|
|
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
|
168 |
|
|
else
|
169 |
|
|
byte_counter := byte_counter + 1;
|
170 |
|
|
end if;
|
171 |
|
|
end if;
|
172 |
|
|
end if;
|
173 |
|
|
end process esoc_rgmii_rx_logging;
|
174 |
|
|
|
175 |
|
|
--=============================================================================================================
|
176 |
|
|
-- Process : store all packets on RGMII TX interfaces
|
177 |
|
|
-- Description :
|
178 |
|
|
--=============================================================================================================
|
179 |
|
|
esoc_rgmii_tx_logging: process(esoc_rgmii_txc_int, esoc_areset)
|
180 |
|
|
-- declare file for rgmii interface logging
|
181 |
|
|
file esoc_rgmii_tx_log : TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_tx_port_" & to_string(esoc_port_nr) & "_log.txt";
|
182 |
|
|
|
183 |
|
|
variable esoc_rgmii_tx_buffer: LINE;
|
184 |
|
|
|
185 |
|
|
variable byte: std_logic_vector(7 downto 0);
|
186 |
|
|
variable byte_counter: integer;
|
187 |
|
|
variable tx_state: std_logic;
|
188 |
|
|
|
189 |
|
|
begin
|
190 |
|
|
if esoc_areset = '1' then
|
191 |
|
|
byte_counter := 0;
|
192 |
|
|
tx_state := '0';
|
193 |
|
|
|
194 |
|
|
elsif esoc_rgmii_txc_int(esoc_port_nr)'event and esoc_rgmii_txc_int(esoc_port_nr) = '1' then
|
195 |
|
|
if esoc_rgmii_txctl(esoc_port_nr) = '1' then
|
196 |
|
|
tx_state := '1';
|
197 |
|
|
byte(3 downto 0) := esoc_rgmii_txd(esoc_port_nr*4+3 downto esoc_port_nr*4);
|
198 |
|
|
|
199 |
|
|
elsif tx_state = '1' then
|
200 |
|
|
tx_state := '0';
|
201 |
|
|
byte_counter := 0;
|
202 |
|
|
write(esoc_rgmii_tx_buffer,string'(""));
|
203 |
|
|
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
|
204 |
|
|
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
|
205 |
|
|
|
206 |
|
|
end if;
|
207 |
|
|
|
208 |
|
|
elsif esoc_rgmii_txc_int(esoc_port_nr)'event and esoc_rgmii_txc_int(esoc_port_nr) = '0' then
|
209 |
|
|
if esoc_rgmii_txctl(esoc_port_nr) = '1' and tx_state = '1' then
|
210 |
|
|
byte(7 downto 4) := esoc_rgmii_txd(esoc_port_nr*4+3 downto esoc_port_nr*4);
|
211 |
|
|
write(esoc_rgmii_tx_buffer, to_hexstring(byte) & " ");
|
212 |
|
|
|
213 |
|
|
if byte_counter = 15 then
|
214 |
|
|
byte_counter := 0;
|
215 |
|
|
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
|
216 |
|
|
else
|
217 |
|
|
byte_counter := byte_counter + 1;
|
218 |
|
|
end if;
|
219 |
|
|
end if;
|
220 |
|
|
end if;
|
221 |
|
|
end process esoc_rgmii_tx_logging;
|
222 |
|
|
end generate esoc_test_rgmii_loggers;
|
223 |
|
|
esoc_test_smi: for esoc_port_nr in esoc_port_count-1 downto 0 generate
|
224 |
|
|
begin
|
225 |
|
|
|
226 |
|
|
esoc_test_smi: process (esoc_mdio, esoc_mdc, esoc_areset) is -- EASE/HDL sens.list
|
227 |
|
|
variable smi_cmd : std_logic_vector(1 downto 0);
|
228 |
|
|
variable smi_dev_addr : std_logic_vector(4 downto 0);
|
229 |
|
|
variable smi_dev_reg : std_logic_vector(4 downto 0);
|
230 |
|
|
variable smi_data : std_logic_vector(15 downto 0);
|
231 |
|
|
|
232 |
|
|
variable smi_counter : integer;
|
233 |
|
|
|
234 |
|
|
variable smi_registers: std_logic_vector(511 downto 0);
|
235 |
|
|
|
236 |
|
|
|
237 |
|
|
variable smi_state : smi_states;
|
238 |
|
|
|
239 |
|
|
begin
|
240 |
|
|
if esoc_areset = '1' then
|
241 |
|
|
smi_cmd := (others => '0');
|
242 |
|
|
smi_dev_addr := (others => '0');
|
243 |
|
|
smi_dev_reg := (others => '0');
|
244 |
|
|
smi_data := (others => '0');
|
245 |
|
|
|
246 |
|
|
smi_registers := (others => '0');
|
247 |
|
|
|
248 |
|
|
smi_mdio(esoc_port_nr) <= '0';
|
249 |
|
|
smi_mdio_ena(esoc_port_nr) <= '0';
|
250 |
|
|
|
251 |
|
|
smi_counter := 31;
|
252 |
|
|
smi_state := preamble;
|
253 |
|
|
|
254 |
|
|
elsif esoc_mdc(esoc_port_nr)'event and esoc_mdc(esoc_port_nr) = '1' then
|
255 |
|
|
|
256 |
|
|
case smi_state is
|
257 |
|
|
when preamble => -- detect preamble of 32 ones
|
258 |
|
|
if esoc_mdio(esoc_port_nr) = '1' then
|
259 |
|
|
if smi_counter = 0 then
|
260 |
|
|
smi_counter := 1;
|
261 |
|
|
smi_state := start;
|
262 |
|
|
else
|
263 |
|
|
smi_counter := smi_counter - 1;
|
264 |
|
|
end if;
|
265 |
|
|
|
266 |
|
|
else
|
267 |
|
|
smi_counter := 31;
|
268 |
|
|
end if;
|
269 |
|
|
|
270 |
|
|
when start => -- detect two start bits, if valid continue else back
|
271 |
|
|
if smi_counter = 1 then
|
272 |
|
|
if esoc_mdio(esoc_port_nr) = '0' then
|
273 |
|
|
smi_counter := smi_counter - 1;
|
274 |
|
|
end if;
|
275 |
|
|
|
276 |
|
|
elsif smi_counter = 0 then
|
277 |
|
|
if esoc_mdio(esoc_port_nr) = '1' then
|
278 |
|
|
smi_counter := 1;
|
279 |
|
|
smi_state := cmd;
|
280 |
|
|
|
281 |
|
|
else
|
282 |
|
|
smi_counter := 31;
|
283 |
|
|
smi_state := preamble;
|
284 |
|
|
end if;
|
285 |
|
|
end if;
|
286 |
|
|
|
287 |
|
|
when cmd => smi_cmd(smi_counter) := esoc_mdio(esoc_port_nr);
|
288 |
|
|
|
289 |
|
|
if smi_counter = 0 then
|
290 |
|
|
smi_counter := 4;
|
291 |
|
|
smi_state := dev_addr;
|
292 |
|
|
else
|
293 |
|
|
smi_counter := smi_counter - 1;
|
294 |
|
|
end if;
|
295 |
|
|
|
296 |
|
|
|
297 |
|
|
when dev_addr => smi_dev_addr(smi_counter) := esoc_mdio(esoc_port_nr);
|
298 |
|
|
|
299 |
|
|
if smi_counter = 0 then
|
300 |
|
|
smi_counter := 4;
|
301 |
|
|
smi_state := reg_addr;
|
302 |
|
|
else
|
303 |
|
|
smi_counter := smi_counter - 1;
|
304 |
|
|
end if;
|
305 |
|
|
|
306 |
|
|
when reg_addr => smi_dev_reg(smi_counter) := esoc_mdio(esoc_port_nr);
|
307 |
|
|
|
308 |
|
|
if smi_counter = 0 then
|
309 |
|
|
smi_counter := 1;
|
310 |
|
|
smi_state := ta_cycles;
|
311 |
|
|
else
|
312 |
|
|
smi_counter := smi_counter - 1;
|
313 |
|
|
end if;
|
314 |
|
|
|
315 |
|
|
when ta_cycles => -- check device address
|
316 |
|
|
if smi_dev_addr /= std_logic_vector(to_unsigned(esoc_port_nr,smi_dev_addr'length)) then
|
317 |
|
|
smi_counter := 31;
|
318 |
|
|
smi_state := preamble;
|
319 |
|
|
|
320 |
|
|
elsif smi_counter = 0 then
|
321 |
|
|
smi_mdio(esoc_port_nr) <= smi_data(smi_data'high);
|
322 |
|
|
smi_data := smi_data(smi_data'high-1 downto 0) & '0';
|
323 |
|
|
smi_counter := 15;
|
324 |
|
|
smi_state := data;
|
325 |
|
|
|
326 |
|
|
else
|
327 |
|
|
-- SMI Read, prepare
|
328 |
|
|
if smi_cmd = "10" then
|
329 |
|
|
smi_data := smi_registers((to_integer(unsigned(smi_dev_reg))*16)+15 downto (to_integer(unsigned(smi_dev_reg))*16));
|
330 |
|
|
smi_mdio(esoc_port_nr) <= '0';
|
331 |
|
|
smi_mdio_ena(esoc_port_nr) <= '1';
|
332 |
|
|
end if;
|
333 |
|
|
|
334 |
|
|
smi_counter := smi_counter - 1;
|
335 |
|
|
end if;
|
336 |
|
|
|
337 |
|
|
when data => -- SMI Read, provide data
|
338 |
|
|
if smi_cmd = "10" then
|
339 |
|
|
smi_mdio(esoc_port_nr) <= smi_data(smi_data'high);
|
340 |
|
|
smi_data := smi_data(smi_data'high-1 downto 0) & '0';
|
341 |
|
|
|
342 |
|
|
-- SMI Write, store data
|
343 |
|
|
else
|
344 |
|
|
smi_data := smi_data(smi_data'high-1 downto 0) & esoc_mdio(esoc_port_nr);
|
345 |
|
|
end if;
|
346 |
|
|
|
347 |
|
|
if smi_counter = 0 then
|
348 |
|
|
smi_counter := 31;
|
349 |
|
|
smi_mdio_ena(esoc_port_nr) <= '0';
|
350 |
|
|
|
351 |
|
|
-- SMI Read, return to preamble; SMI Write, store data
|
352 |
|
|
if smi_cmd = "10" then
|
353 |
|
|
smi_state := preamble;
|
354 |
|
|
else
|
355 |
|
|
smi_state := store;
|
356 |
|
|
end if;
|
357 |
|
|
|
358 |
|
|
else
|
359 |
|
|
smi_counter := smi_counter - 1;
|
360 |
|
|
end if;
|
361 |
|
|
|
362 |
|
|
when store => -- store received data
|
363 |
|
|
smi_registers((to_integer(unsigned(smi_dev_reg))*16)+15 downto (to_integer(unsigned(smi_dev_reg))*16)) := smi_data;
|
364 |
|
|
smi_state := preamble;
|
365 |
|
|
|
366 |
|
|
when others => smi_state := preamble;
|
367 |
|
|
end case;
|
368 |
|
|
|
369 |
|
|
end if;
|
370 |
|
|
end process esoc_test_smi ;
|
371 |
|
|
|
372 |
|
|
-- drive the mdio line when enabled
|
373 |
|
|
esoc_mdio(esoc_port_nr) <= smi_mdio(esoc_port_nr) when smi_mdio_ena(esoc_port_nr) = '1' else 'Z';
|
374 |
|
|
end generate esoc_test_smi;
|
375 |
|
|
esoc_tb: esoc
|
376 |
|
|
port map(
|
377 |
|
|
esoc_address => esoc_address,
|
378 |
|
|
esoc_areset => esoc_areset,
|
379 |
|
|
esoc_boot_complete => esoc_boot_complete,
|
380 |
|
|
esoc_clk => esoc_clk,
|
381 |
|
|
esoc_cs => esoc_cs,
|
382 |
|
|
esoc_data => esoc_data,
|
383 |
|
|
esoc_mdc => esoc_mdc,
|
384 |
|
|
esoc_mdio => esoc_mdio,
|
385 |
|
|
esoc_rd => esoc_rd,
|
386 |
|
|
esoc_rgmii_rxc => esoc_rgmii_rxc,
|
387 |
|
|
esoc_rgmii_rxctl => esoc_rgmii_rxctl,
|
388 |
|
|
esoc_rgmii_rxd => esoc_rgmii_rxd,
|
389 |
|
|
esoc_rgmii_txc => esoc_rgmii_txc,
|
390 |
|
|
esoc_rgmii_txctl => esoc_rgmii_txctl,
|
391 |
|
|
esoc_rgmii_txd => esoc_rgmii_txd,
|
392 |
|
|
esoc_wait => esoc_wait,
|
393 |
|
|
esoc_wr => esoc_wr);
|
394 |
|
|
|
395 |
|
|
|
396 |
|
|
|
397 |
|
|
--=============================================================================================================
|
398 |
|
|
-- Process :
|
399 |
|
|
-- Description :
|
400 |
|
|
--=============================================================================================================
|
401 |
|
|
esoc_test_control: process -- EASE/HDL sens.list
|
402 |
|
|
begin
|
403 |
|
|
wait;
|
404 |
|
|
end process esoc_test_control ;
|
405 |
|
|
|
406 |
|
|
--=============================================================================================================
|
407 |
|
|
-- Process : generate esoc input reset
|
408 |
|
|
-- Description :
|
409 |
|
|
--=============================================================================================================
|
410 |
|
|
esoc_reset: process
|
411 |
|
|
-- EASE/HDL sens.list
|
412 |
|
|
begin
|
413 |
|
|
esoc_areset <= '1';
|
414 |
|
|
wait for 1 us;
|
415 |
|
|
esoc_areset <= '0';
|
416 |
|
|
assert false report "ESOC Reset -> reset released" severity note;
|
417 |
|
|
wait;
|
418 |
|
|
end process esoc_reset ;
|
419 |
|
|
|
420 |
|
|
--=============================================================================================================
|
421 |
|
|
-- Process : generate esoc control input clock
|
422 |
|
|
-- Description :
|
423 |
|
|
--=============================================================================================================
|
424 |
|
|
esoc_ctrl_clock: process
|
425 |
|
|
-- EASE/HDL sens.list
|
426 |
|
|
begin
|
427 |
|
|
esoc_clk <= '1';
|
428 |
|
|
wait for 10 ns;
|
429 |
|
|
esoc_clk <= '0';
|
430 |
|
|
wait for 10 ns;
|
431 |
|
|
end process esoc_ctrl_clock ;
|
432 |
|
|
|
433 |
|
|
--=============================================================================================================
|
434 |
|
|
-- Process : generate input for the esoc control interface
|
435 |
|
|
-- Description :
|
436 |
|
|
--=============================================================================================================
|
437 |
|
|
esoc_ctrl: process
|
438 |
|
|
-- EASE/HDL sens.list
|
439 |
|
|
-- declare files for control interface stimuli and logging
|
440 |
|
|
file esoc_ctrl_out: TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_control_test_log.txt";
|
441 |
|
|
file esoc_ctrl_in : TEXT open READ_MODE is "../../Simulation/Scripts/esoc_control_test_stim.txt";
|
442 |
|
|
file esoc_control_auto_log : TEXT open APPEND_MODE is "../../Simulation/Logs/auto/esoc_control_auto_log.txt";
|
443 |
|
|
|
444 |
|
|
-- declare buffers for a complete line from file
|
445 |
|
|
variable esoc_ctrl_in_buffer: LINE;
|
446 |
|
|
variable esoc_ctrl_out_buffer: LINE;
|
447 |
|
|
variable esoc_control_auto_log_buffer: LINE;
|
448 |
|
|
|
449 |
|
|
-- define fields in a line (only white spaces before first field are skipped)
|
450 |
|
|
variable esoc_ctrl_in_id : string(7 downto 1);
|
451 |
|
|
variable esoc_ctrl_in_cmd : string(2 downto 1);
|
452 |
|
|
variable esoc_ctrl_in_addr: string(5 downto 1);
|
453 |
|
|
variable esoc_ctrl_in_val : string(9 downto 1);
|
454 |
|
|
variable esoc_ctrl_out_val : string(9 downto 1);
|
455 |
|
|
variable esoc_ctrl_in_info : string(40 downto 1);
|
456 |
|
|
variable esoc_ctrl_wait : integer;
|
457 |
|
|
|
458 |
|
|
variable error_counter: integer;
|
459 |
|
|
|
460 |
|
|
begin
|
461 |
|
|
|
462 |
|
|
-- init control interface inputs
|
463 |
|
|
esoc_cs <= '0';
|
464 |
|
|
esoc_wr <= '0';
|
465 |
|
|
esoc_rd <= '0';
|
466 |
|
|
esoc_address <= (others => '0');
|
467 |
|
|
esoc_data <= (others => 'Z');
|
468 |
|
|
esoc_wait_timer_start <= '0';
|
469 |
|
|
error_counter := 0;
|
470 |
|
|
|
471 |
|
|
-- wait for de-assertion of external reset
|
472 |
|
|
wait until esoc_areset = '0';
|
473 |
|
|
|
474 |
|
|
-- wait for assertion of boot status
|
475 |
|
|
wait until esoc_boot_complete = '1';
|
476 |
|
|
wait for 1 us;
|
477 |
|
|
|
478 |
|
|
-- read stimuli ID
|
479 |
|
|
readline(esoc_ctrl_in, esoc_ctrl_in_buffer);
|
480 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_cmd);
|
481 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_id);
|
482 |
|
|
|
483 |
|
|
-- start access on control interface
|
484 |
|
|
assert false report "ESOC Control -> generate read/write cycles on control interface" severity note;
|
485 |
|
|
write(esoc_ctrl_out_buffer, string'("ESOC Control -> start generating read/write cycles on control interface"));
|
486 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
487 |
|
|
|
488 |
|
|
-- read file until end of file is reached
|
489 |
|
|
loop
|
490 |
|
|
exit when endfile(esoc_ctrl_in);
|
491 |
|
|
-- read command before reading the arguments
|
492 |
|
|
readline(esoc_ctrl_in, esoc_ctrl_in_buffer);
|
493 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_cmd);
|
494 |
|
|
|
495 |
|
|
--
|
496 |
|
|
-- start WRITE CYCLE
|
497 |
|
|
--
|
498 |
|
|
if esoc_ctrl_in_cmd = "mw" then
|
499 |
|
|
-- read address and data from file
|
500 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_addr);
|
501 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_val);
|
502 |
|
|
|
503 |
|
|
-- drive the control interface
|
504 |
|
|
wait for 30 ns;
|
505 |
|
|
esoc_cs <= '1';
|
506 |
|
|
esoc_wr <= '1';
|
507 |
|
|
esoc_address <= hex_string_to_std_logic_vector(esoc_ctrl_in_addr(4 downto 1));
|
508 |
|
|
esoc_data <= hex_string_to_std_logic_vector(esoc_ctrl_in_val(8 downto 1));
|
509 |
|
|
|
510 |
|
|
-- enable timer to avoid lockup
|
511 |
|
|
esoc_wait_timer_start <= '1';
|
512 |
|
|
wait until esoc_wait = '0' or esoc_wait_timeout = '1';
|
513 |
|
|
|
514 |
|
|
-- check for timeout
|
515 |
|
|
if esoc_wait_timeout = '0' then
|
516 |
|
|
esoc_wait_timer_start <= '0';
|
517 |
|
|
end if;
|
518 |
|
|
|
519 |
|
|
-- finalize cycle
|
520 |
|
|
wait for 20 ns;
|
521 |
|
|
esoc_cs <= '0';
|
522 |
|
|
esoc_wr <= '0';
|
523 |
|
|
esoc_data <= (others => 'Z');
|
524 |
|
|
|
525 |
|
|
-- report time out
|
526 |
|
|
if esoc_wait_timeout = '1' then
|
527 |
|
|
esoc_wait_timer_start <= '0';
|
528 |
|
|
-- write control bus access to output file
|
529 |
|
|
assert false report "ESOC Control -> write to address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, status: TIMEOUT" severity error;
|
530 |
|
|
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", status: TIMEOUT");
|
531 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
532 |
|
|
|
533 |
|
|
else
|
534 |
|
|
-- write control bus access to output file
|
535 |
|
|
assert false report "ESOC Control -> write" & esoc_ctrl_in_val & "h" & " to address" & esoc_ctrl_in_addr & "h" severity note;
|
536 |
|
|
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_in_val);
|
537 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
538 |
|
|
end if;
|
539 |
|
|
|
540 |
|
|
--
|
541 |
|
|
-- start READ CYCLE
|
542 |
|
|
--
|
543 |
|
|
elsif esoc_ctrl_in_cmd = "mr" then
|
544 |
|
|
-- read address and data from file
|
545 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_addr);
|
546 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_in_val);
|
547 |
|
|
|
548 |
|
|
-- drive the control interface
|
549 |
|
|
wait for 30 ns;
|
550 |
|
|
esoc_cs <= '1';
|
551 |
|
|
esoc_rd <= '1';
|
552 |
|
|
esoc_address <= hex_string_to_std_logic_vector(esoc_ctrl_in_addr(4 downto 1));
|
553 |
|
|
|
554 |
|
|
-- enable timer to avoid lockup
|
555 |
|
|
esoc_wait_timer_start <= '1';
|
556 |
|
|
wait until esoc_wait = '0' or esoc_wait_timeout = '1';
|
557 |
|
|
|
558 |
|
|
-- check for timeout
|
559 |
|
|
if esoc_wait_timeout = '0' then
|
560 |
|
|
esoc_wait_timer_start <= '0';
|
561 |
|
|
end if;
|
562 |
|
|
|
563 |
|
|
-- finalize cycle
|
564 |
|
|
wait for 20 ns;
|
565 |
|
|
esoc_cs <= '0';
|
566 |
|
|
esoc_rd <= '0';
|
567 |
|
|
|
568 |
|
|
-- store read data, add space in front to be able to compare to expected value from file
|
569 |
|
|
esoc_ctrl_out_val(8 downto 1) := to_hexstring(esoc_data);
|
570 |
|
|
esoc_ctrl_out_val := " " & esoc_ctrl_out_val(8 downto 1);
|
571 |
|
|
|
572 |
|
|
-- check expected read value with actual read value or report time out
|
573 |
|
|
if esoc_wait_timeout = '1' then
|
574 |
|
|
esoc_wait_timer_start <= '0';
|
575 |
|
|
-- write control bus access to output file
|
576 |
|
|
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & ", status: TIMEOUT" severity error;
|
577 |
|
|
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", status: TIMEOUT");
|
578 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
579 |
|
|
|
580 |
|
|
elsif esoc_ctrl_in_val = esoc_ctrl_out_val then
|
581 |
|
|
-- write control bus access to output file
|
582 |
|
|
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & esoc_ctrl_in_val & "h, status: OK" severity note;
|
583 |
|
|
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", expected" & esoc_ctrl_in_val & ", status: OK");
|
584 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
585 |
|
|
else
|
586 |
|
|
-- write control bus access to output file
|
587 |
|
|
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & esoc_ctrl_in_val & "h, status: ERROR" severity note;
|
588 |
|
|
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", expected" & esoc_ctrl_in_val & ", status: ERROR");
|
589 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
590 |
|
|
error_counter := error_counter + 1;
|
591 |
|
|
end if;
|
592 |
|
|
|
593 |
|
|
--
|
594 |
|
|
-- create delay
|
595 |
|
|
--
|
596 |
|
|
elsif esoc_ctrl_in_cmd = "wt" then
|
597 |
|
|
read(esoc_ctrl_in_buffer, esoc_ctrl_wait);
|
598 |
|
|
for i in esoc_ctrl_wait downto 0 loop
|
599 |
|
|
wait until esoc_clk'event and esoc_clk = '1';
|
600 |
|
|
end loop;
|
601 |
|
|
|
602 |
|
|
--
|
603 |
|
|
-- process information
|
604 |
|
|
--
|
605 |
|
|
elsif esoc_ctrl_in_cmd = "--" then
|
606 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_in_buffer);
|
607 |
|
|
|
608 |
|
|
-- ignore other commands
|
609 |
|
|
else
|
610 |
|
|
assert false report "ESOC Control -> illegal command for read/write cycles on control interface" severity error;
|
611 |
|
|
write(esoc_ctrl_out_buffer, string'("ESOC Control -> illegal command for read/write cycles on control interface"));
|
612 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
613 |
|
|
end if;
|
614 |
|
|
end loop;
|
615 |
|
|
|
616 |
|
|
if error_counter = 1 then
|
617 |
|
|
assert false report "ESOC Control -> end of stimuli for control interface (" & to_string(error_counter,10) & " error)" severity note;
|
618 |
|
|
else
|
619 |
|
|
assert false report "ESOC Control -> end of stimuli for control interface (" & to_string(error_counter,10) & " errors)" severity note;
|
620 |
|
|
end if;
|
621 |
|
|
|
622 |
|
|
--write(esoc_ctrl_out_buffer, string'("ESOC Control -> end of stimuli for control interface")& error_counter & " errors)");
|
623 |
|
|
write(esoc_ctrl_out_buffer, string'("ESOC Control -> end of stimuli for control interface (") & to_string(error_counter,10) & " errors)");
|
624 |
|
|
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
|
625 |
|
|
|
626 |
|
|
write(esoc_control_auto_log_buffer, "Test script" & esoc_ctrl_in_id & " - " & to_string(error_counter,10) & " errors");
|
627 |
|
|
writeline(esoc_control_auto_log, esoc_control_auto_log_buffer);
|
628 |
|
|
|
629 |
|
|
wait;
|
630 |
|
|
end process esoc_ctrl ;
|
631 |
|
|
|
632 |
|
|
--=============================================================================================================
|
633 |
|
|
-- Process : start timer when previous process waits for signal from esoc
|
634 |
|
|
-- Description :
|
635 |
|
|
--=============================================================================================================
|
636 |
|
|
esoc_ctrl_timer: process (esoc_areset, esoc_clk)
|
637 |
|
|
begin
|
638 |
|
|
if esoc_areset = '1' then
|
639 |
|
|
esoc_wait_timer <= 3000;
|
640 |
|
|
esoc_wait_timeout <= '0';
|
641 |
|
|
esoc_wait_time_enable <= '1';
|
642 |
|
|
|
643 |
|
|
elsif esoc_clk = '1' and esoc_clk'event then
|
644 |
|
|
if esoc_wait_time_enable = '1' then
|
645 |
|
|
-- start timer on command of read/write process
|
646 |
|
|
if esoc_wait_timer_start = '1' then
|
647 |
|
|
-- assert time out signal when timer expires
|
648 |
|
|
if esoc_wait_timer = 0 then
|
649 |
|
|
esoc_wait_timeout <= '1';
|
650 |
|
|
else
|
651 |
|
|
esoc_wait_timer <= esoc_wait_timer - 1;
|
652 |
|
|
end if;
|
653 |
|
|
|
654 |
|
|
-- reset timer settings when timer is stopped by read/write process
|
655 |
|
|
else
|
656 |
|
|
esoc_wait_timeout <= '0';
|
657 |
|
|
esoc_wait_timer <= 3000;
|
658 |
|
|
end if;
|
659 |
|
|
end if;
|
660 |
|
|
end if;
|
661 |
|
|
end process esoc_ctrl_timer;
|
662 |
|
|
|
663 |
|
|
|
664 |
|
|
|
665 |
|
|
--=============================================================================================================
|
666 |
|
|
-- Process :
|
667 |
|
|
-- Description :
|
668 |
|
|
--=============================================================================================================
|
669 |
|
|
esoc_test_rgmii: process -- EASE/HDL sens.list
|
670 |
|
|
begin
|
671 |
|
|
wait;
|
672 |
|
|
end process esoc_test_rgmii ;
|
673 |
|
|
|
674 |
|
|
--=============================================================================================================
|
675 |
|
|
-- Process : generate esoc rgmii input clock
|
676 |
|
|
-- Description :
|
677 |
|
|
--=============================================================================================================
|
678 |
|
|
esoc_rgmii_clock: process
|
679 |
|
|
-- EASE/HDL sens.list
|
680 |
|
|
begin
|
681 |
|
|
-- create internal and external RGMII clock, phase shift of 90 degrees
|
682 |
|
|
for i in esoc_port_count-1 downto 0 loop
|
683 |
|
|
esoc_rgmii_rxc_int <= '1';
|
684 |
|
|
esoc_rgmii_rxc(i) <= '1' after 2 ns;
|
685 |
|
|
end loop;
|
686 |
|
|
|
687 |
|
|
wait for 4 ns;
|
688 |
|
|
|
689 |
|
|
for i in esoc_port_count-1 downto 0 loop
|
690 |
|
|
esoc_rgmii_rxc_int <= '0';
|
691 |
|
|
esoc_rgmii_rxc(i) <= '0' after 2 ns;
|
692 |
|
|
end loop;
|
693 |
|
|
|
694 |
|
|
wait for 4 ns;
|
695 |
|
|
end process esoc_rgmii_clock ;
|
696 |
|
|
|
697 |
|
|
--=============================================================================================================
|
698 |
|
|
-- Process : access registers of testbench
|
699 |
|
|
-- Description :
|
700 |
|
|
--=============================================================================================================
|
701 |
|
|
registers: process(esoc_areset, esoc_cs, esoc_rd, esoc_wr)
|
702 |
|
|
variable esoc_rd_pending: std_logic;
|
703 |
|
|
variable esoc_wr_pending: std_logic;
|
704 |
|
|
begin
|
705 |
|
|
if esoc_areset = '1' then
|
706 |
|
|
reg_rgmii_port_enable <= (others => '0');
|
707 |
|
|
esoc_wait <= 'Z';
|
708 |
|
|
esoc_data <= (others => 'Z');
|
709 |
|
|
esoc_rd_pending := '0';
|
710 |
|
|
esoc_wr_pending := '0';
|
711 |
|
|
|
712 |
|
|
-- continu if memory space of this entity is addressed
|
713 |
|
|
elsif to_integer(unsigned(esoc_address)) >= esoc_testbench_base and to_integer(unsigned(esoc_address)) < esoc_testbench_base + esoc_testbench_size then
|
714 |
|
|
--
|
715 |
|
|
-- READ CYCLE started, unit addressed?
|
716 |
|
|
--
|
717 |
|
|
if esoc_cs = '1' and esoc_rd = '1' and esoc_rd_pending = '0' then
|
718 |
|
|
-- Check register address and provide data when addressed
|
719 |
|
|
case to_integer(unsigned(esoc_address)) - esoc_testbench_base is
|
720 |
|
|
when 0 => esoc_data <= reg_rgmii_port_enable after 40 ns;
|
721 |
|
|
|
722 |
|
|
when others => esoc_data <= (others => '0');
|
723 |
|
|
end case;
|
724 |
|
|
|
725 |
|
|
esoc_rd_pending := '1';
|
726 |
|
|
esoc_wait <= '0' after 40 ns;
|
727 |
|
|
|
728 |
|
|
-- wait until cycle is finished
|
729 |
|
|
elsif esoc_cs = '0' and esoc_rd = '0' and esoc_rd_pending = '1' then
|
730 |
|
|
esoc_rd_pending := '0';
|
731 |
|
|
|
732 |
|
|
-- finalize cycle
|
733 |
|
|
esoc_wait <= 'Z' after 20 ns;
|
734 |
|
|
esoc_data <= (others => 'Z') after 20 ns;
|
735 |
|
|
|
736 |
|
|
--
|
737 |
|
|
-- WRITE CYCLE started, unit addressed?
|
738 |
|
|
--
|
739 |
|
|
elsif esoc_cs = '1' and esoc_wr = '1' and esoc_wr_pending = '0' then
|
740 |
|
|
-- Check register address and accept data when addressed
|
741 |
|
|
case to_integer(unsigned(esoc_address)) - esoc_testbench_base is
|
742 |
|
|
when 0 => reg_rgmii_port_enable <= esoc_data;
|
743 |
|
|
|
744 |
|
|
when others => NULL;
|
745 |
|
|
end case;
|
746 |
|
|
|
747 |
|
|
esoc_wr_pending := '1';
|
748 |
|
|
esoc_wait <= '0' after 40 ns;
|
749 |
|
|
|
750 |
|
|
-- wait until cycle is finished
|
751 |
|
|
elsif esoc_cs = '0' and esoc_wr = '0' and esoc_wr_pending = '1' then
|
752 |
|
|
-- finalize cycle
|
753 |
|
|
esoc_wr_pending := '0';
|
754 |
|
|
esoc_wait <= 'Z' after 20 ns;
|
755 |
|
|
end if;
|
756 |
|
|
end if;
|
757 |
|
|
end process;
|
758 |
|
|
|
759 |
|
|
--=============================================================================================================
|
760 |
|
|
-- Process : fill packet transmit buffers for all ports
|
761 |
|
|
-- Description :
|
762 |
|
|
--=============================================================================================================
|
763 |
|
|
esoc_rgmii_tx: process
|
764 |
|
|
-- declare files for rgmii interface stimuli and logging
|
765 |
|
|
file esoc_rgmii_in : TEXT open READ_MODE is "../../Simulation/Scripts/esoc_rgmii_test_stim.txt";
|
766 |
|
|
file esoc_rgmii_out: TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_log.txt";
|
767 |
|
|
|
768 |
|
|
-- declare buffer for a complete line from file
|
769 |
|
|
variable esoc_rgmii_in_buffer: LINE;
|
770 |
|
|
variable esoc_rgmii_out_buffer: LINE;
|
771 |
|
|
|
772 |
|
|
-- define fields in a line
|
773 |
|
|
variable esoc_rgmii_in_port : string(2 downto 1);
|
774 |
|
|
variable esoc_rgmii_in_dmac : string(12 downto 1);
|
775 |
|
|
variable esoc_rgmii_in_smac : string(12 downto 1);
|
776 |
|
|
variable esoc_rgmii_in_vid : string(8 downto 1);
|
777 |
|
|
variable esoc_rgmii_in_type : string(4 downto 1);
|
778 |
|
|
variable esoc_rgmii_in_plen : string(4 downto 1);
|
779 |
|
|
variable esoc_rgmii_in_pstart : string(2 downto 1);
|
780 |
|
|
variable esoc_rgmii_in_gap : string(8 downto 1);
|
781 |
|
|
variable esoc_rgmii_in_white_space : string(1 downto 1);
|
782 |
|
|
|
783 |
|
|
variable esoc_rgmii_in_wait : integer;
|
784 |
|
|
|
785 |
|
|
-- create packet buffers for all ports (use variable to avoid slow simulations)
|
786 |
|
|
constant packet_buffer_size : integer := 64*1024;
|
787 |
|
|
|
788 |
|
|
type packet_buffer_array is array (esoc_port_count-1 downto 0, packet_buffer_size-1 downto 0) of std_logic_vector(8 downto 0);
|
789 |
|
|
variable packet_buffers : packet_buffer_array;
|
790 |
|
|
|
791 |
|
|
constant pck_type_ipg: std_logic := '0';
|
792 |
|
|
constant pck_type_pck: std_logic := '1';
|
793 |
|
|
|
794 |
|
|
-- create packet counter for all ports (use variable to avoid slow simulations)
|
795 |
|
|
type packet_buffer_bytes_array is array (esoc_port_count-1 downto 0) of integer;
|
796 |
|
|
variable packet_buffer_bytes : packet_buffer_bytes_array;
|
797 |
|
|
variable packet_buffer_bytes_sent : packet_buffer_bytes_array;
|
798 |
|
|
|
799 |
|
|
-- create inter packet gap counter for all ports (use variable to avoid slow simulations)
|
800 |
|
|
type packet_ipg_array is array (esoc_port_count-1 downto 0) of integer;
|
801 |
|
|
variable packet_ipg : packet_ipg_array;
|
802 |
|
|
|
803 |
|
|
-- signals and variables for inside process
|
804 |
|
|
variable esoc_rgmii_port : integer;
|
805 |
|
|
variable esoc_rgmii_count : integer;
|
806 |
|
|
variable esoc_rgmii_data : std_logic_vector(47 downto 0);
|
807 |
|
|
|
808 |
|
|
variable esoc_rgmii_crc : std_logic_vector(31 downto 0);
|
809 |
|
|
|
810 |
|
|
begin
|
811 |
|
|
--
|
812 |
|
|
-- initialize signals, buffers and clear counters
|
813 |
|
|
--
|
814 |
|
|
for i in esoc_port_count-1 downto 0 loop
|
815 |
|
|
packet_buffer_bytes(i) := 0;
|
816 |
|
|
packet_buffer_bytes_sent(i) := 0;
|
817 |
|
|
|
818 |
|
|
esoc_rgmii_rxctl(i) <= '0';
|
819 |
|
|
esoc_rgmii_rxd(i*4+3 downto i*4) <= (others => '0');
|
820 |
|
|
|
821 |
|
|
packet_ipg(i) := 0;
|
822 |
|
|
|
823 |
|
|
for j in packet_buffer_size-1 downto 0 loop
|
824 |
|
|
packet_buffers(i,j) := '0' & X"00";
|
825 |
|
|
end loop;
|
826 |
|
|
end loop;
|
827 |
|
|
|
828 |
|
|
reg_rgmii_port_enable2 <= (others => '0');
|
829 |
|
|
|
830 |
|
|
-- wait for de-assertion of external reset
|
831 |
|
|
wait until esoc_areset = '0';
|
832 |
|
|
wait for 1 us;
|
833 |
|
|
|
834 |
|
|
--
|
835 |
|
|
-- start preprocessing of Ethernet packets
|
836 |
|
|
--
|
837 |
|
|
assert false report "ESOC RGMII Preprocessing -> start of processing stimuli for RGMII interfaces" severity note;
|
838 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> start of processng stimuli for RGMII interfaces"));
|
839 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
840 |
|
|
|
841 |
|
|
loop
|
842 |
|
|
exit when endfile(esoc_rgmii_in);
|
843 |
|
|
|
844 |
|
|
-- read packet information, read away the post white space
|
845 |
|
|
readline(esoc_rgmii_in, esoc_rgmii_in_buffer);
|
846 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_port);
|
847 |
|
|
|
848 |
|
|
-- skip comment
|
849 |
|
|
if esoc_rgmii_in_port = "--" then
|
850 |
|
|
|
851 |
|
|
-- check packet information
|
852 |
|
|
elsif to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_port))) > esoc_port_count-1 then
|
853 |
|
|
assert false report "ESOC RGMII Preprocessing -> " & esoc_rgmii_in_port & " is illegal port number in RGMII stimuli (max ESOC Port count is " & to_string(esoc_port_count-1, 10) & ")" severity error;
|
854 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> " & esoc_rgmii_in_port & " is illegal port number in RGMII stimuli (max ESOC Port count is " & to_string(esoc_port_count-1, 10) & ")");
|
855 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
856 |
|
|
|
857 |
|
|
-- write packet into buffer of correct port
|
858 |
|
|
else
|
859 |
|
|
-- read packet information, read away the pre white space
|
860 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_dmac);
|
861 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_smac);
|
862 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_vid);
|
863 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_type);
|
864 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_plen);
|
865 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_pstart);
|
866 |
|
|
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_gap);
|
867 |
|
|
|
868 |
|
|
-- convert port number to have index inside the buffer and counter arrays, counter itself is also index inside buffer array
|
869 |
|
|
esoc_rgmii_port := to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_port)));
|
870 |
|
|
|
871 |
|
|
-- store current value of byte counter of port before new packet is written
|
872 |
|
|
esoc_rgmii_count := packet_buffer_bytes(esoc_rgmii_port);
|
873 |
|
|
|
874 |
|
|
-- reset CRC storage
|
875 |
|
|
esoc_rgmii_crc := (others => '0');
|
876 |
|
|
|
877 |
|
|
-- store preamble and SFD
|
878 |
|
|
for i in 7 downto 0 loop
|
879 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
880 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
881 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
882 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
883 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
884 |
|
|
|
885 |
|
|
else
|
886 |
|
|
-- write sfd as last byte, write preamble bytes before
|
887 |
|
|
if i = 0 then
|
888 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & X"D5";
|
889 |
|
|
else
|
890 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & X"55";
|
891 |
|
|
end if;
|
892 |
|
|
|
893 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
894 |
|
|
end if;
|
895 |
|
|
end loop;
|
896 |
|
|
|
897 |
|
|
-- store DMAC in buffer
|
898 |
|
|
esoc_rgmii_data := hex_string_to_std_logic_vector(esoc_rgmii_in_dmac);
|
899 |
|
|
|
900 |
|
|
for i in 5 downto 0 loop
|
901 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
902 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
903 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
904 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
905 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
906 |
|
|
|
907 |
|
|
else
|
908 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
|
909 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
910 |
|
|
|
911 |
|
|
|
912 |
|
|
-- invert first four bytes of packet (32 bits of DMAC) before CRC calculation
|
913 |
|
|
if i > 1 then
|
914 |
|
|
esoc_rgmii_data(i*8+7 downto i*8) := INVERT_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
|
915 |
|
|
end if;
|
916 |
|
|
|
917 |
|
|
-- swap bit order in accordance with bit order at physical interface before CRC calculation
|
918 |
|
|
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
|
919 |
|
|
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
|
920 |
|
|
end if;
|
921 |
|
|
end loop;
|
922 |
|
|
|
923 |
|
|
-- store SMAC in buffer
|
924 |
|
|
esoc_rgmii_data := hex_string_to_std_logic_vector(esoc_rgmii_in_smac);
|
925 |
|
|
|
926 |
|
|
for i in 5 downto 0 loop
|
927 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
928 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
929 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
930 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
931 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
932 |
|
|
|
933 |
|
|
else
|
934 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
|
935 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
936 |
|
|
|
937 |
|
|
-- swap bit order in accordance with bit order at physical interface before CRC calculation
|
938 |
|
|
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
|
939 |
|
|
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
|
940 |
|
|
end if;
|
941 |
|
|
end loop;
|
942 |
|
|
|
943 |
|
|
-- store VID in buffer (0x8100**** is VLAN tagged packet)
|
944 |
|
|
esoc_rgmii_data(31 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_vid);
|
945 |
|
|
|
946 |
|
|
if esoc_rgmii_data(31 downto 16) = X"8100" then
|
947 |
|
|
for i in 3 downto 0 loop
|
948 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
949 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
950 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
951 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
952 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
953 |
|
|
|
954 |
|
|
else
|
955 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
|
956 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
957 |
|
|
|
958 |
|
|
-- swap bit order in accordance with bit order at physical interface before CRC calculation
|
959 |
|
|
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
|
960 |
|
|
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
|
961 |
|
|
end if;
|
962 |
|
|
end loop;
|
963 |
|
|
end if;
|
964 |
|
|
|
965 |
|
|
-- store TYPE/LEN in buffer
|
966 |
|
|
esoc_rgmii_data(15 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_type);
|
967 |
|
|
|
968 |
|
|
for i in 1 downto 0 loop
|
969 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
970 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
971 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
972 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
973 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
974 |
|
|
|
975 |
|
|
else
|
976 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
|
977 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
978 |
|
|
|
979 |
|
|
-- swap bit order in accordance with bit order at physical interface before CRC calculation
|
980 |
|
|
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
|
981 |
|
|
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
|
982 |
|
|
end if;
|
983 |
|
|
end loop;
|
984 |
|
|
|
985 |
|
|
-- store payload (if length is sufficient)
|
986 |
|
|
if to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_plen))) < 46 then
|
987 |
|
|
assert false report "ESOC RGMII Preprocessing -> payload field too short, should be at least 46 bytes." severity error;
|
988 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> payload field too short, should be at least 46 bytes."));
|
989 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
990 |
|
|
|
991 |
|
|
else
|
992 |
|
|
esoc_rgmii_data(7 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_pstart);
|
993 |
|
|
|
994 |
|
|
for i in to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_plen)))-1 downto 0 loop
|
995 |
|
|
-- check and update byte counter related to the port, store data if space available, update crc
|
996 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
997 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
998 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
999 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1000 |
|
|
|
1001 |
|
|
else
|
1002 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(7 downto 0);
|
1003 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
1004 |
|
|
|
1005 |
|
|
-- swap bit order in accordance with bit order at physical interface before CRC calculation
|
1006 |
|
|
esoc_rgmii_data(7 downto 0) := SWAP_CRC32_DATA(esoc_rgmii_data(7 downto 0));
|
1007 |
|
|
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(7 downto 0),esoc_rgmii_crc);
|
1008 |
|
|
esoc_rgmii_data(7 downto 0) := SWAP_CRC32_DATA(esoc_rgmii_data(7 downto 0));
|
1009 |
|
|
end if;
|
1010 |
|
|
|
1011 |
|
|
esoc_rgmii_data(7 downto 0) := std_logic_vector(to_unsigned(to_integer(unsigned(esoc_rgmii_data(7 downto 0)))+1, 8));
|
1012 |
|
|
end loop;
|
1013 |
|
|
end if;
|
1014 |
|
|
|
1015 |
|
|
-- store CRC, invert and change order before ...
|
1016 |
|
|
esoc_rgmii_crc := SWAP_CRC32_RESULT(esoc_rgmii_crc);
|
1017 |
|
|
esoc_rgmii_crc := INVERT_CRC32_RESULT(esoc_rgmii_crc);
|
1018 |
|
|
esoc_rgmii_data(31 downto 0) := esoc_rgmii_crc;
|
1019 |
|
|
|
1020 |
|
|
for i in 3 downto 0 loop
|
1021 |
|
|
-- check and update byte counter related to the port, store data if space available
|
1022 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
1023 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
1024 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
1025 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1026 |
|
|
|
1027 |
|
|
else
|
1028 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
|
1029 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
1030 |
|
|
end if;
|
1031 |
|
|
end loop;
|
1032 |
|
|
|
1033 |
|
|
-- store GAP (if length is sufficient)
|
1034 |
|
|
esoc_rgmii_data(31 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_gap);
|
1035 |
|
|
|
1036 |
|
|
if to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_gap))) < 12 then
|
1037 |
|
|
assert false report "ESOC RGMII Preprocessing -> Inter Packet Gap too short, should be at least 12 bytes." severity error;
|
1038 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> Inter Packet Gap too short, should be at least 12 bytes."));
|
1039 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1040 |
|
|
|
1041 |
|
|
else
|
1042 |
|
|
for i in 3 downto 0 loop
|
1043 |
|
|
-- check and update byte counter related to the port, store data if space available
|
1044 |
|
|
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
|
1045 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
|
1046 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
|
1047 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1048 |
|
|
|
1049 |
|
|
else
|
1050 |
|
|
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_ipg & esoc_rgmii_data(i*8+7 downto i*8);
|
1051 |
|
|
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
|
1052 |
|
|
end if;
|
1053 |
|
|
end loop;
|
1054 |
|
|
end if;
|
1055 |
|
|
|
1056 |
|
|
|
1057 |
|
|
-- log packet information in file
|
1058 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet with length of " & to_string(packet_buffer_bytes(esoc_rgmii_port) - esoc_rgmii_count) & " bytes written to port " & esoc_rgmii_in_port severity note;
|
1059 |
|
|
assert false report "ESOC RGMII Preprocessing -> packet details -> dmac: 0x" & esoc_rgmii_in_dmac & " smac: 0x" & esoc_rgmii_in_smac & " vid: 0x" & esoc_rgmii_in_vid & " type: 0x" & esoc_rgmii_in_type & " plen: 0x" & esoc_rgmii_in_plen & " pstart: 0x" & esoc_rgmii_in_pstart & " crc: 0x" & to_hexstring(esoc_rgmii_crc) & " ipg: 0x" & esoc_rgmii_in_gap severity note;
|
1060 |
|
|
|
1061 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet with length of " & to_string(packet_buffer_bytes(esoc_rgmii_port) - esoc_rgmii_count) & " bytes written to port " & esoc_rgmii_in_port);
|
1062 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1063 |
|
|
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet details -> dmac: 0x" & esoc_rgmii_in_dmac & " smac: 0x" & esoc_rgmii_in_smac & " vid: 0x" & esoc_rgmii_in_vid & " type: 0x" & esoc_rgmii_in_type & " plen: 0x" & esoc_rgmii_in_plen & " pstart: 0x" & esoc_rgmii_in_pstart & " crc: 0x" & to_hexstring(esoc_rgmii_crc) & " ipg: 0x" & esoc_rgmii_in_gap);
|
1064 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1065 |
|
|
end if;
|
1066 |
|
|
end loop;
|
1067 |
|
|
|
1068 |
|
|
assert false report "ESOC RGMII Preprocessing -> end of processing stimuli for RGMII interfaces" severity note;
|
1069 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> end of processng stimuli for RGMII interfaces"));
|
1070 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1071 |
|
|
write(esoc_rgmii_out_buffer, string'(""));
|
1072 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1073 |
|
|
|
1074 |
|
|
--
|
1075 |
|
|
-- start transmitting of Ethernet packets
|
1076 |
|
|
--
|
1077 |
|
|
assert false report "ESOC RGMII Transmit -> start of transmitting stimuli to RGMII interfaces" severity note;
|
1078 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Transmit -> start of transmitting stimuli to RGMII interfaces"));
|
1079 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1080 |
|
|
|
1081 |
|
|
while true loop
|
1082 |
|
|
|
1083 |
|
|
|
1084 |
|
|
|
1085 |
|
|
-- get data for each port from their buffer and send on rising edge
|
1086 |
|
|
wait until esoc_rgmii_rxc_int'event and esoc_rgmii_rxc_int = '1';
|
1087 |
|
|
|
1088 |
|
|
for i in esoc_port_count-1 downto 0 loop
|
1089 |
|
|
reg_rgmii_port_enable2(i) <= reg_rgmii_port_enable(i);
|
1090 |
|
|
-- check whether the port is enabled or not
|
1091 |
|
|
if reg_rgmii_port_enable(i) = '1' then
|
1092 |
|
|
-- check whether there are still bytes to send
|
1093 |
|
|
if packet_buffer_bytes_sent(i) < packet_buffer_bytes(i) then
|
1094 |
|
|
-- start inter packet gap delay period?
|
1095 |
|
|
if packet_buffers(i,packet_buffer_bytes_sent(i))(8) = pck_type_ipg and packet_ipg(i) = 0 then
|
1096 |
|
|
esoc_rgmii_rxd(i*4+3 downto i*4) <= X"0";
|
1097 |
|
|
esoc_rgmii_rxctl(i) <= '0';
|
1098 |
|
|
|
1099 |
|
|
packet_ipg(i) := to_integer(unsigned(packet_buffers(i,packet_buffer_bytes_sent(i))(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+1)(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+2)(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+3)(7 downto 0)));
|
1100 |
|
|
packet_buffer_bytes_sent(i) := packet_buffer_bytes_sent(i) + 4;
|
1101 |
|
|
|
1102 |
|
|
-- inter packet gap delay passed?
|
1103 |
|
|
elsif packet_ipg(i) /= 0 then
|
1104 |
|
|
|
1105 |
|
|
-- inter packet gap delay passed, send data
|
1106 |
|
|
else
|
1107 |
|
|
esoc_rgmii_rxd(i*4+3 downto i*4) <= packet_buffers(i,packet_buffer_bytes_sent(i))(3 downto 0);
|
1108 |
|
|
esoc_rgmii_rxctl(i) <= '1';
|
1109 |
|
|
end if;
|
1110 |
|
|
end if;
|
1111 |
|
|
end if;
|
1112 |
|
|
end loop;
|
1113 |
|
|
|
1114 |
|
|
-- get data for each port from their buffer and send on falling edge
|
1115 |
|
|
wait until esoc_rgmii_rxc_int'event and esoc_rgmii_rxc_int = '0';
|
1116 |
|
|
|
1117 |
|
|
for i in esoc_port_count-1 downto 0 loop
|
1118 |
|
|
-- check whether the port is enabled or not
|
1119 |
|
|
if reg_rgmii_port_enable2(i) = pck_type_pck then
|
1120 |
|
|
-- check whether there are still bytes to send
|
1121 |
|
|
if packet_buffer_bytes_sent(i) < packet_buffer_bytes(i) then
|
1122 |
|
|
-- inter packet gap delay passed?
|
1123 |
|
|
if packet_ipg(i) /= 0 then
|
1124 |
|
|
packet_ipg(i) := packet_ipg(i) - 1;
|
1125 |
|
|
-- inter packet gap delay passed, send data
|
1126 |
|
|
else
|
1127 |
|
|
esoc_rgmii_rxd(i*4+3 downto i*4) <= packet_buffers(i,packet_buffer_bytes_sent(i))(7 downto 4);
|
1128 |
|
|
packet_buffer_bytes_sent(i) := packet_buffer_bytes_sent(i) + 1;
|
1129 |
|
|
end if;
|
1130 |
|
|
end if;
|
1131 |
|
|
end if;
|
1132 |
|
|
end loop;
|
1133 |
|
|
|
1134 |
|
|
end loop;
|
1135 |
|
|
|
1136 |
|
|
assert false report "ESOC RGMII Transmit -> end of transmitting stimuli to RGMII interfaces" severity note;
|
1137 |
|
|
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Transmit -> end of transmitting stimuli to RGMII interfaces"));
|
1138 |
|
|
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
|
1139 |
|
|
|
1140 |
|
|
wait;
|
1141 |
|
|
end process esoc_rgmii_tx;
|
1142 |
|
|
end architecture esoc_tb ; -- of esoc_tb
|
1143 |
|
|
|