1 |
15 |
wzab |
-------------------------------------------------------------------------------
|
2 |
|
|
-- Title : FPGA Ethernet interface - block receiving packets from MII PHY
|
3 |
|
|
-- Project :
|
4 |
|
|
-------------------------------------------------------------------------------
|
5 |
|
|
-- File : eth_receiver4.vhd
|
6 |
|
|
-- Author : Wojciech M. Zabolotny (wzab@ise.pw.edu.pl)
|
7 |
|
|
-- License : BSD License
|
8 |
|
|
-- Company :
|
9 |
|
|
-- Created : 2012-03-30
|
10 |
18 |
wzab |
-- Last update: 2014-10-12
|
11 |
15 |
wzab |
-- Platform :
|
12 |
|
|
-- Standard : VHDL'93
|
13 |
|
|
-------------------------------------------------------------------------------
|
14 |
18 |
wzab |
-- Description: This file implements the state machine, responsible for
|
15 |
|
|
-- reception of packets and passing them to the acknowledgements and commands
|
16 |
|
|
-- FIFO
|
17 |
15 |
wzab |
-------------------------------------------------------------------------------
|
18 |
|
|
-- Copyright (c) 2012
|
19 |
|
|
-------------------------------------------------------------------------------
|
20 |
|
|
-- Revisions :
|
21 |
|
|
-- Date Version Author Description
|
22 |
|
|
-- 2012-03-30 1.0 WZab Created
|
23 |
|
|
-------------------------------------------------------------------------------
|
24 |
|
|
|
25 |
|
|
-- Uwaga! Tu mamy rzeczywiste problemy z obsluga odebranych pakietow!
|
26 |
|
|
--
|
27 |
|
|
|
28 |
|
|
library ieee;
|
29 |
|
|
use ieee.std_logic_1164.all;
|
30 |
|
|
use ieee.numeric_std.all;
|
31 |
|
|
library work;
|
32 |
18 |
wzab |
use work.desc_mgr_pkg.all;
|
33 |
15 |
wzab |
use work.pkt_ack_pkg.all;
|
34 |
|
|
use work.pkg_newcrc32_d64.all;
|
35 |
|
|
use work.pkg_newcrc32_d32.all;
|
36 |
|
|
use work.pkg_newcrc32_d16.all;
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
entity eth_receiver is
|
40 |
|
|
|
41 |
|
|
port (
|
42 |
|
|
-- Configuration
|
43 |
|
|
peer_mac : out std_logic_vector(47 downto 0);
|
44 |
|
|
my_mac : in std_logic_vector(47 downto 0);
|
45 |
|
|
my_ether_type : in std_logic_vector(15 downto 0);
|
46 |
|
|
transmit_data : out std_logic;
|
47 |
|
|
restart : out std_logic;
|
48 |
|
|
-- ACK FIFO interface
|
49 |
|
|
ack_fifo_full : in std_logic;
|
50 |
|
|
ack_fifo_wr_en : out std_logic;
|
51 |
|
|
ack_fifo_din : out std_logic_vector(pkt_ack_width-1 downto 0);
|
52 |
|
|
-- System interface
|
53 |
|
|
clk : in std_logic;
|
54 |
|
|
rst_n : in std_logic;
|
55 |
|
|
dbg : out std_logic_vector(3 downto 0);
|
56 |
|
|
cmd : out std_logic_vector(31 downto 0);
|
57 |
|
|
arg : out std_logic_vector(31 downto 0);
|
58 |
|
|
crc : out std_logic_vector(31 downto 0);
|
59 |
|
|
-- MAC interface
|
60 |
|
|
Rx_Clk : in std_logic;
|
61 |
|
|
RxC : in std_logic_vector(7 downto 0);
|
62 |
|
|
RxD : in std_logic_vector(63 downto 0)
|
63 |
|
|
);
|
64 |
|
|
|
65 |
|
|
end eth_receiver;
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
architecture beh1 of eth_receiver is
|
69 |
|
|
|
70 |
|
|
type T_STATE is (ST_RCV_IDLE, ST_RCV_PREAMB, ST_CHECK_PREAMB,
|
71 |
|
|
ST_RCV_HEADER1, ST_RCV_HEADER2, ST_RCV_CMD,
|
72 |
|
|
ST_RCV_WAIT_IDLE, ST_RCV_ARGS, ST_RCV_PROCESS, ST_RCV_UPDATE,
|
73 |
|
|
ST_RCV_TRAILER);
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
|
77 |
|
|
function rev(a : in std_logic_vector)
|
78 |
|
|
return std_logic_vector is
|
79 |
|
|
variable result : std_logic_vector(a'range);
|
80 |
|
|
alias aa : std_logic_vector(a'reverse_range) is a;
|
81 |
|
|
begin
|
82 |
|
|
for i in aa'range loop
|
83 |
|
|
result(i) := aa(i);
|
84 |
|
|
end loop;
|
85 |
|
|
return result;
|
86 |
|
|
end; -- function reverse_any_bus
|
87 |
|
|
|
88 |
|
|
constant C_PROTO_ID : std_logic_vector(31 downto 0) := x"fade0100";
|
89 |
|
|
|
90 |
|
|
type T_RCV_REGS is record
|
91 |
|
|
state : T_STATE;
|
92 |
|
|
swap_lanes : std_logic;
|
93 |
|
|
transmit_data : std_logic;
|
94 |
|
|
restart : std_logic;
|
95 |
|
|
update_flag : std_logic;
|
96 |
|
|
count : integer;
|
97 |
|
|
dbg : std_logic_vector(3 downto 0);
|
98 |
|
|
crc32 : std_logic_vector(31 downto 0);
|
99 |
|
|
cmd : std_logic_vector(31 downto 0);
|
100 |
|
|
arg : std_logic_vector(31 downto 0);
|
101 |
|
|
mac_addr : std_logic_vector(47 downto 0);
|
102 |
|
|
peer_mac : std_logic_vector(47 downto 0);
|
103 |
|
|
end record;
|
104 |
|
|
|
105 |
|
|
constant RCV_REGS_INI : T_RCV_REGS := (
|
106 |
|
|
state => ST_RCV_IDLE,
|
107 |
|
|
swap_lanes => '0',
|
108 |
|
|
transmit_data => '0',
|
109 |
|
|
restart => '0',
|
110 |
|
|
update_flag => '0',
|
111 |
|
|
count => 0,
|
112 |
|
|
dbg => (others => '0'),
|
113 |
|
|
crc32 => (others => '0'),
|
114 |
|
|
cmd => (others => '0'),
|
115 |
|
|
arg => (others => '0'),
|
116 |
|
|
mac_addr => (others => '0'),
|
117 |
|
|
peer_mac => (others => '0')
|
118 |
|
|
);
|
119 |
|
|
|
120 |
|
|
signal r, r_n : T_RCV_REGS := RCV_REGS_INI;
|
121 |
|
|
|
122 |
|
|
type T_RCV_COMB is record
|
123 |
|
|
ack_fifo_wr_en : std_logic;
|
124 |
|
|
Rx_mac_rd : std_logic;
|
125 |
|
|
ack_fifo_din : std_logic_vector(pkt_ack_width-1 downto 0);
|
126 |
|
|
restart : std_logic;
|
127 |
|
|
end record;
|
128 |
|
|
|
129 |
|
|
constant RCV_COMB_DEFAULT : T_RCV_COMB := (
|
130 |
|
|
ack_fifo_wr_en => '0',
|
131 |
|
|
Rx_mac_rd => '0',
|
132 |
|
|
ack_fifo_din => (others => '0'),
|
133 |
|
|
restart => '0'
|
134 |
|
|
);
|
135 |
|
|
|
136 |
|
|
signal c : T_RCV_COMB := RCV_COMB_DEFAULT;
|
137 |
|
|
|
138 |
|
|
signal rxd_sw, rxd_del : std_logic_vector(63 downto 0);
|
139 |
|
|
signal rxc_sw, rxc_del : std_logic_vector(7 downto 0);
|
140 |
|
|
|
141 |
|
|
signal rx_rst_n, rx_rst_n_0, rx_rst_n_1 : std_logic := '0';
|
142 |
|
|
signal update_flag_0, update_flag_1, update_flag : std_logic := '0';
|
143 |
|
|
|
144 |
|
|
begin -- beh1
|
145 |
|
|
|
146 |
|
|
ack_fifo_din <= c.ack_fifo_din;
|
147 |
|
|
ack_fifo_wr_en <= c.ack_fifo_wr_en;
|
148 |
|
|
|
149 |
|
|
--dbg <= r.dbg;
|
150 |
|
|
crc <= r.crc32;
|
151 |
|
|
cmd <= r.cmd;
|
152 |
|
|
arg <= r.arg;
|
153 |
|
|
-- Lane switcher processes
|
154 |
|
|
lsw_c1 : process (RxC, RxC(3 downto 0), RxC_del(7 downto 4), RxD,
|
155 |
|
|
RxD(31 downto 0), RxD_del(63 downto 32), r.swap_lanes) is
|
156 |
|
|
begin -- process lsw_c1
|
157 |
|
|
if r.swap_lanes = '1' then
|
158 |
|
|
RxD_Sw(63 downto 32) <= RxD(31 downto 0);
|
159 |
|
|
RxD_Sw(31 downto 0) <= RxD_del(63 downto 32);
|
160 |
|
|
RxC_Sw(7 downto 4) <= RxC(3 downto 0);
|
161 |
|
|
RxC_Sw(3 downto 0) <= RxC_del(7 downto 4);
|
162 |
|
|
else
|
163 |
|
|
RxD_Sw <= RxD;
|
164 |
|
|
RxC_Sw <= RxC;
|
165 |
|
|
end if;
|
166 |
|
|
end process lsw_c1;
|
167 |
|
|
|
168 |
|
|
process (Rx_Clk, rx_rst_n) is
|
169 |
|
|
begin -- process
|
170 |
|
|
if rx_rst_n = '0' then -- asynchronous reset (active low)
|
171 |
|
|
RxD_del <= (others => '0');
|
172 |
|
|
RxC_del <= (others => '0');
|
173 |
|
|
elsif Rx_Clk'event and Rx_Clk = '1' then -- rising clock edge
|
174 |
|
|
RxD_del <= RxD;
|
175 |
|
|
RxC_del <= RxC;
|
176 |
|
|
end if;
|
177 |
|
|
end process;
|
178 |
|
|
|
179 |
|
|
-- Reading of ethernet data
|
180 |
|
|
rdp1 : process (Rx_Clk, rx_rst_n)
|
181 |
|
|
begin -- process rdp1
|
182 |
|
|
if rx_rst_n = '0' then -- asynchronous reset (active low)
|
183 |
|
|
r <= RCV_REGS_INI;
|
184 |
|
|
elsif Rx_Clk'event and Rx_Clk = '1' then -- rising clock edge
|
185 |
|
|
r <= r_n;
|
186 |
|
|
end if;
|
187 |
|
|
end process rdp1;
|
188 |
|
|
|
189 |
|
|
rdp2 : process (RxC, RxC_Sw, RxD, RxD_Sw, ack_fifo_full, my_ether_type,
|
190 |
|
|
my_mac, r, r.arg(15 downto 10), r.arg(31 downto 16),
|
191 |
|
|
r.cmd(15 downto 0), r.cmd(31 downto 16), r.crc32, r.dbg(0),
|
192 |
|
|
r.dbg(1), r.dbg(2), r.dbg(3), r.mac_addr, r.state,
|
193 |
|
|
r.update_flag)
|
194 |
|
|
|
195 |
|
|
variable ack_pkt_in : pkt_ack;
|
196 |
|
|
variable v_mac_addr : std_logic_vector(47 downto 0);
|
197 |
|
|
variable v_cmd, v_arg : std_logic_vector(31 downto 0);
|
198 |
|
|
variable v_crc : std_logic_vector(31 downto 0);
|
199 |
|
|
variable v_proto : std_logic_vector(31 downto 0);
|
200 |
|
|
|
201 |
|
|
begin -- process
|
202 |
|
|
c <= RCV_COMB_DEFAULT;
|
203 |
|
|
r_n <= r;
|
204 |
|
|
dbg <= "1111";
|
205 |
|
|
case r.state is
|
206 |
|
|
when ST_RCV_IDLE =>
|
207 |
|
|
dbg <= "0000";
|
208 |
|
|
-- We must be prepared to one of two possible events
|
209 |
|
|
-- Either we receive the SOF in the 0-th lane (and then we proceed
|
210 |
|
|
-- normally) or we receive the SOF in the 4-th lane (and then we have
|
211 |
|
|
-- to switch lanes, delaying 4 of them).
|
212 |
|
|
if RxC = b"00011111" and RxD = x"55_55_55_fb_07_07_07_07" then
|
213 |
|
|
-- shifted lanes
|
214 |
|
|
-- switch on the "lane shifter" and go to the state,
|
215 |
|
|
-- where we can check the proper preamble after lane switching
|
216 |
|
|
r_n.swap_lanes <= '1';
|
217 |
|
|
r_n.state <= ST_CHECK_PREAMB;
|
218 |
|
|
elsif RxC = b"00000001" and RxD = x"d5_55_55_55_55_55_55_fb" then
|
219 |
|
|
-- normal lanes
|
220 |
|
|
r_n.swap_lanes <= '0';
|
221 |
|
|
r_n.crc32 <= (others => '1');
|
222 |
|
|
r_n.state <= ST_RCV_HEADER1;
|
223 |
|
|
end if;
|
224 |
|
|
when ST_CHECK_PREAMB =>
|
225 |
|
|
dbg <= "0001";
|
226 |
|
|
if RxC_Sw = b"00000001" and RxD_Sw = x"d5_55_55_55_55_55_55_fb" then
|
227 |
|
|
r_n.crc32 <= (others => '1');
|
228 |
|
|
r_n.state <= ST_RCV_HEADER1;
|
229 |
|
|
else
|
230 |
|
|
-- interrupted preamble reception
|
231 |
|
|
r_n.state <= ST_RCV_IDLE;
|
232 |
|
|
end if;
|
233 |
|
|
when ST_RCV_HEADER1 =>
|
234 |
|
|
dbg <= "0010";
|
235 |
|
|
if RxC_Sw = b"00000000" then
|
236 |
|
|
r_n.crc32 <= newcrc32_d64(RxD_Sw, r.crc32);
|
237 |
|
|
-- Change the order of bytes!
|
238 |
|
|
for i in 0 to 5 loop
|
239 |
|
|
v_mac_addr(47-i*8 downto 40-i*8) := RxD_Sw(i*8+7 downto i*8);
|
240 |
|
|
end loop; -- i
|
241 |
|
|
if v_mac_addr /= my_mac then
|
242 |
|
|
-- This packet is not for us - ignore it!
|
243 |
|
|
r_n.state <= ST_RCV_WAIT_IDLE;
|
244 |
|
|
else
|
245 |
|
|
-- Our packet!
|
246 |
|
|
r_n.count <= 0;
|
247 |
|
|
-- Read the lower 16 bits of the sender address
|
248 |
|
|
-- Again, we have to change the order of bytes!
|
249 |
|
|
r_n.mac_addr(39 downto 32) <= RxD_Sw(63 downto 56);
|
250 |
|
|
r_n.mac_addr(47 downto 40) <= RxD_Sw(55 downto 48);
|
251 |
|
|
r_n.state <= ST_RCV_HEADER2;
|
252 |
|
|
end if;
|
253 |
|
|
else
|
254 |
|
|
-- packet broken?
|
255 |
|
|
r_n.state <= ST_RCV_IDLE;
|
256 |
|
|
end if;
|
257 |
|
|
when ST_RCV_HEADER2 =>
|
258 |
|
|
dbg <= "0010";
|
259 |
|
|
if RxC_Sw = b"00000000" then
|
260 |
|
|
r_n.crc32 <= newcrc32_d64(RxD_Sw, r.crc32);
|
261 |
|
|
v_mac_addr := r.mac_addr;
|
262 |
|
|
for i in 0 to 3 loop
|
263 |
|
|
v_mac_addr(31-i*8 downto 24-i*8) := RxD_Sw(i*8+7 downto i*8);
|
264 |
|
|
end loop; -- i
|
265 |
|
|
--v_mac_addr(47 downto 16) := RxD_Sw(31 downto 0);
|
266 |
|
|
r_n.mac_addr <= v_mac_addr;
|
267 |
|
|
-- In the rest of this 64-bit word, we receive the protocol ID
|
268 |
|
|
-- and version
|
269 |
|
|
for i in 0 to 3 loop
|
270 |
|
|
v_proto(i*8+7 downto i*8) := RxD_Sw(63-i*8 downto 56-i*8);
|
271 |
|
|
end loop; -- i
|
272 |
|
|
-- Check if the proto id is correct
|
273 |
|
|
if v_proto = C_PROTO_ID then
|
274 |
|
|
r_n.state <= ST_RCV_CMD;
|
275 |
|
|
else
|
276 |
|
|
r_n.state <= ST_RCV_IDLE;
|
277 |
|
|
end if;
|
278 |
|
|
else
|
279 |
|
|
-- packet broken?
|
280 |
|
|
r_n.state <= ST_RCV_IDLE;
|
281 |
|
|
end if;
|
282 |
|
|
when ST_RCV_CMD =>
|
283 |
|
|
if RxC_Sw = b"0000_0000" then
|
284 |
|
|
r_n.crc32 <= newcrc32_d64(RxD_Sw, r.crc32);
|
285 |
|
|
-- Copy the command, changing order of bytes!
|
286 |
|
|
for i in 0 to 3 loop
|
287 |
|
|
r_n.cmd(i*8+7 downto i*8) <= RxD_Sw(31-i*8 downto 24-i*8);
|
288 |
|
|
end loop; -- i
|
289 |
|
|
-- Copy the argument, changing order of bytes!
|
290 |
|
|
for i in 0 to 3 loop
|
291 |
|
|
r_n.arg(i*8+7 downto i*8) <= RxD_Sw(63-i*8 downto 56-i*8);
|
292 |
|
|
end loop; -- i
|
293 |
|
|
r_n.state <= ST_RCV_TRAILER;
|
294 |
|
|
-- Currently we ignore rest of the packet!
|
295 |
|
|
else
|
296 |
|
|
-- packet broken?
|
297 |
|
|
r_n.state <= ST_RCV_IDLE;
|
298 |
|
|
end if;
|
299 |
|
|
when ST_RCV_TRAILER =>
|
300 |
|
|
-- No detection of too long frames!
|
301 |
|
|
dbg <= "0110";
|
302 |
|
|
if RxC_Sw /= b"0000_0000" then
|
303 |
|
|
-- It should be a packet with the checksum
|
304 |
|
|
-- The EOF may be on any of 8th positions.
|
305 |
|
|
-- To avoid too big combinational functions,
|
306 |
|
|
-- we handle it in a few states (but this increases requirements
|
307 |
|
|
-- on IFC!)
|
308 |
|
|
-- Current implementation assumes fixed length of frames
|
309 |
|
|
-- but the optimal one should probably pass received data for further
|
310 |
|
|
-- checking, why this machine continues to receive next frame...
|
311 |
|
|
if RxC_Sw = b"1111_1100" then
|
312 |
|
|
v_crc := r.crc32;
|
313 |
|
|
v_crc := newcrc32_d16(RxD_Sw(15 downto 0), v_crc);
|
314 |
|
|
r_n.crc32 <= v_crc;
|
315 |
|
|
if (RxD_Sw(23 downto 16) = x"fd") and
|
316 |
|
|
(v_crc = x"c704dd7b") then
|
317 |
|
|
-- Correct packet, go to processing
|
318 |
|
|
r_n.peer_mac <= r.mac_addr;
|
319 |
|
|
r_n.state <= ST_RCV_PROCESS;
|
320 |
|
|
else
|
321 |
|
|
-- Wrong CRC or EOF
|
322 |
|
|
r_n.state <= ST_RCV_IDLE;
|
323 |
|
|
end if;
|
324 |
|
|
else
|
325 |
|
|
-- Wrong packet
|
326 |
|
|
r_n.state <= ST_RCV_IDLE;
|
327 |
|
|
end if;
|
328 |
|
|
else
|
329 |
|
|
-- Ignore received data, only updating the checksum
|
330 |
|
|
r_n.crc32 <= newcrc32_d64(RxD_Sw, r.crc32);
|
331 |
|
|
end if;
|
332 |
|
|
when ST_RCV_PROCESS =>
|
333 |
|
|
dbg <= "0111";
|
334 |
|
|
case to_integer(unsigned(r.cmd(31 downto 16))) is
|
335 |
18 |
wzab |
-- Handle commands, which require immediate action
|
336 |
|
|
when FCMD_START =>
|
337 |
15 |
wzab |
r_n.dbg(0) <= not r.dbg(0);
|
338 |
|
|
-- Start transmission command
|
339 |
|
|
r_n.transmit_data <= '1';
|
340 |
18 |
wzab |
when FCMD_STOP =>
|
341 |
15 |
wzab |
r_n.dbg(1) <= not r.dbg(1);
|
342 |
|
|
-- Stop transmission command
|
343 |
|
|
r_n.transmit_data <= '0';
|
344 |
18 |
wzab |
when FCMD_RESET =>
|
345 |
|
|
r_n.dbg(3) <= not r.dbg(3);
|
346 |
|
|
-- Restart the whole block(?)
|
347 |
15 |
wzab |
r_n.restart <= '1';
|
348 |
18 |
wzab |
when others =>
|
349 |
|
|
null;
|
350 |
15 |
wzab |
end case;
|
351 |
18 |
wzab |
-- All commands are written to the acknowledge and commands
|
352 |
|
|
-- FIFO, so that they will be handled by the descriptor manager
|
353 |
|
|
if ack_fifo_full = '0' then
|
354 |
|
|
ack_pkt_in.cmd := unsigned(r.cmd(31 downto 16));
|
355 |
|
|
ack_pkt_in.pkt := unsigned(r.arg);
|
356 |
|
|
ack_pkt_in.seq := unsigned(r.cmd(15 downto 0));
|
357 |
|
|
c.ack_fifo_din <= pkt_ack_to_stlv(ack_pkt_in);
|
358 |
|
|
c.ack_fifo_wr_en <= '1';
|
359 |
|
|
end if;
|
360 |
|
|
r_n.state <= ST_RCV_UPDATE;
|
361 |
15 |
wzab |
when ST_RCV_UPDATE =>
|
362 |
|
|
dbg <= "1000";
|
363 |
|
|
r_n.update_flag <= not r.update_flag;
|
364 |
|
|
r_n.state <= ST_RCV_IDLE;
|
365 |
|
|
when ST_RCV_WAIT_IDLE =>
|
366 |
|
|
dbg <= "1001";
|
367 |
|
|
if RxC_Sw = b"1111_1111" then
|
368 |
|
|
r_n.state <= ST_RCV_IDLE;
|
369 |
|
|
end if;
|
370 |
|
|
when others => null;
|
371 |
|
|
end case;
|
372 |
|
|
end process rdp2;
|
373 |
|
|
|
374 |
|
|
-- Synchronization of the reset signal for the Rx_Clk domain
|
375 |
|
|
process (Rx_Clk, rst_n)
|
376 |
|
|
begin -- process
|
377 |
|
|
if rst_n = '0' then -- asynchronous reset (active low)
|
378 |
|
|
rx_rst_n_0 <= '0';
|
379 |
|
|
rx_rst_n_1 <= '0';
|
380 |
|
|
rx_rst_n <= '0';
|
381 |
|
|
elsif Rx_Clk'event and Rx_Clk = '1' then -- rising clock edge
|
382 |
|
|
rx_rst_n_0 <= rst_n;
|
383 |
|
|
rx_rst_n_1 <= rx_rst_n_0;
|
384 |
|
|
rx_rst_n <= rx_rst_n_1;
|
385 |
|
|
end if;
|
386 |
|
|
end process;
|
387 |
|
|
|
388 |
|
|
|
389 |
|
|
-- Synchronization of output signals between the clock domains
|
390 |
|
|
process (clk, rst_n)
|
391 |
|
|
begin -- process
|
392 |
|
|
if rst_n = '0' then -- asynchronous reset (active low)
|
393 |
|
|
peer_mac <= (others => '0');
|
394 |
|
|
transmit_data <= '0';
|
395 |
|
|
restart <= '0';
|
396 |
|
|
update_flag_0 <= '0';
|
397 |
|
|
update_flag_1 <= '0';
|
398 |
|
|
update_flag <= '0';
|
399 |
|
|
elsif clk'event and clk = '1' then -- rising clock edge
|
400 |
|
|
-- Synchronization of the update_flag
|
401 |
|
|
update_flag_0 <= r.update_flag;
|
402 |
|
|
update_flag_1 <= update_flag_0;
|
403 |
|
|
update_flag <= update_flag_1;
|
404 |
|
|
-- When update flag has changed, rewrite synchronized fields
|
405 |
|
|
if update_flag /= update_flag_1 then
|
406 |
|
|
peer_mac <= r.peer_mac;
|
407 |
|
|
transmit_data <= r.transmit_data;
|
408 |
|
|
restart <= r.restart;
|
409 |
|
|
end if;
|
410 |
|
|
end if;
|
411 |
|
|
end process;
|
412 |
|
|
|
413 |
|
|
end beh1;
|