OpenCores
URL https://opencores.org/ocsvn/tosnet/tosnet/trunk

Subversion Repositories tosnet

[/] [tosnet/] [trunk/] [gateware/] [MicroBlaze_Peripheral_rev3_2/] [pcores/] [tosnet_v3_20_a/] [hdl/] [vhdl/] [tal_top.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sonicwave
----------------------------------------------------------------------------------
2
-- Company:             University of Southern Denmark
3
-- Engineer:            Simon Falsig
4
-- 
5
-- Create Date:         17/3/2008 
6
-- Design Name          TosNet
7
-- Module Name:         tal_top - Behavioral 
8
-- File Name:           tal_top.vhd
9
-- Project Name:        TosNet
10
-- Target Devices:      Spartan3/6
11
-- Tool versions:       Xilinx ISE 12.2
12
-- Description:         The TosNet application layer handles the shared memory block,
13
--                                      and keeps it updated. It also handles the FIFO buffers used 
14
--                                      for the asynchronous communication.
15
--
16
-- Revision: 
17
-- Revision 3.2 -       Initial release
18
--
19
-- Copyright 2010
20
--
21
-- This module is free software: you can redistribute it and/or modify
22
-- it under the terms of the GNU Lesser General Public License as published by
23
-- the Free Software Foundation, either version 3 of the License, or
24
-- (at your option) any later version.
25
--
26
-- This module is distributed in the hope that it will be useful,
27
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
28
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
-- GNU Lesser General Public License for more details.
30
--
31
-- You should have received a copy of the GNU Lesser General Public License
32
-- along with this module.  If not, see <http://www.gnu.org/licenses/>.
33
----------------------------------------------------------------------------------
34
library IEEE;
35
use IEEE.STD_LOGIC_1164.ALL;
36
use IEEE.STD_LOGIC_ARITH.ALL;
37
use IEEE.STD_LOGIC_UNSIGNED.ALL;
38
use IEEE.NUMERIC_STD.ALL;
39
 
40
---- Uncomment the following library declaration if instantiating
41
---- any Xilinx primitives in this code.
42
--library UNISIM;
43
--use UNISIM.VComponents.all;
44
 
45
entity tal_top is
46
        Generic(disable_master                  : in    STD_LOGIC := '0';
47
                        disable_slave                   : in    STD_LOGIC := '1';
48
                        disable_async                   : in    STD_LOGIC := '1');
49
        Port (  node_id                                 : in    STD_LOGIC_VECTOR(3 downto 0);
50
                        max_skipped_writes              : in    STD_LOGIC_VECTOR(15 downto 0);
51
                        max_skipped_reads               : in    STD_LOGIC_VECTOR(15 downto 0);
52
                        data_in                                 : in    STD_LOGIC_VECTOR(7 downto 0);
53
                        data_in_strobe                  : in    STD_LOGIC;
54
                        data_in_enable                  : in    STD_LOGIC;
55
                        data_out                                : out   STD_LOGIC_VECTOR(7 downto 0);
56
                        data_out_strobe                 : out   STD_LOGIC;
57
                        data_out_enable                 : out   STD_LOGIC;
58
                        buffer_full                             : in    STD_LOGIC;
59
                        packet_error                    : in    STD_LOGIC;
60
                        force_packet_error              : out   STD_LOGIC;
61
                        sync_strobe                             : in    STD_LOGIC;
62
                        network_reg_addr                : out   STD_LOGIC_VECTOR(3 downto 0);
63
                        network_reg_data                : in    STD_LOGIC_VECTOR(31 downto 0);
64
                        network_reg_clk                 : out   STD_LOGIC;
65
                        data_reg_addr                   : in    STD_LOGIC_VECTOR(9 downto 0);
66
                        data_reg_data_in                : in    STD_LOGIC_VECTOR(31 downto 0);
67
                        data_reg_data_out               : out   STD_LOGIC_VECTOR(31 downto 0);
68
                        data_reg_clk                    : in    STD_LOGIC;
69
                        data_reg_we                             : in    STD_LOGIC_VECTOR(0 downto 0);
70
                        data_reg_commit_write   : in    STD_LOGIC;
71
                        data_reg_commit_read    : in    STD_LOGIC;
72
                        skip_count_write                : out   STD_LOGIC_VECTOR(15 downto 0);
73
                        skip_count_read                 : out   STD_LOGIC_VECTOR(15 downto 0);
74
                        current_buffer_index    : out   STD_LOGIC_VECTOR(3 downto 0);
75
                        node_address                    : in    STD_LOGIC_VECTOR(3 downto 0);
76
                        is_master                               : in    STD_LOGIC;
77
                        clk_50M                                 : in    STD_LOGIC;
78
                        pause                                   : in    STD_LOGIC;
79
                        pause_ack                               : out   STD_LOGIC;
80
                        reset                                   : in    STD_LOGIC;
81
                        system_halt                             : out   STD_LOGIC;
82
                        reset_counter                   : out   STD_LOGIC_VECTOR(31 downto 0);
83
                        packet_counter                  : out   STD_LOGIC_VECTOR(31 downto 0);
84
                        error_counter                   : out   STD_LOGIC_VECTOR(31 downto 0);
85
                        async_in_data                   : in    STD_LOGIC_VECTOR(37 downto 0);
86
                        async_out_data                  : out   STD_LOGIC_VECTOR(37 downto 0);
87
                        async_in_clk                    : in    STD_LOGIC;
88
                        async_out_clk                   : in    STD_LOGIC;
89
                        async_in_full                   : out   STD_LOGIC;
90
                        async_out_empty                 : out   STD_LOGIC;
91
                        async_in_wr_en                  : in    STD_LOGIC;
92
                        async_out_rd_en                 : in    STD_LOGIC;
93
                        async_out_valid                 : out   STD_LOGIC);
94
end tal_top;
95
 
96
architecture Behavioral of tal_top is
97
        constant ASYNC_M2S_VALID                        : STD_LOGIC_VECTOR := "1001";
98
        constant ASYNC_S2M_VALID                        : STD_LOGIC_VECTOR := "1010";
99
        constant ASYNC_M2S_INVALID                      : STD_LOGIC_VECTOR := "0001";
100
        constant ASYNC_S2M_INVALID                      : STD_LOGIC_VECTOR := "0010";
101
 
102
        type SLV_STATES is (IDLE, ADDR_1, ADDR_2, ADDR_3, DATA, ASYNC_CTL_HEAD, ASYNC, ASYNC_CTL_TAIL);
103
        type MST_TRN_STATES is (IDLE, ADDR_1, ADDR_2, ADDR_3, DATA, ASYNC_CTL_HEAD, ASYNC, ASYNC_CTL_TAIL, WAIT_STATE);
104
        type MST_REC_STATES is (IDLE, ADDR_1, ADDR_2, ADDR_3, DATA, ASYNC_CTL_HEAD, ASYNC, ASYNC_CTL_TAIL);
105
 
106
        signal slv_state                                        : SLV_STATES := IDLE;
107
        signal next_slv_state                           : SLV_STATES := IDLE;
108
 
109
        signal mst_trn_state                            : MST_TRN_STATES := IDLE;
110
        signal next_mst_trn_state                       : MST_TRN_STATES := IDLE;
111
 
112
        signal mst_rec_state                            : MST_REC_STATES := IDLE;
113
        signal next_mst_rec_state                       : MST_REC_STATES := IDLE;
114
 
115
        signal slave_reset                                      : STD_LOGIC;
116
        signal master_reset                                     : STD_LOGIC;
117
 
118
        signal last_data_in_strobe                      : STD_LOGIC := '0';
119
 
120
        signal current_user_reg_write           : STD_LOGIC := '0';
121
        signal current_sys_reg_write            : STD_LOGIC := '1';
122
 
123
        signal current_user_reg_read            : STD_LOGIC := '0';
124
        signal current_sys_reg_read                     : STD_LOGIC := '1';
125
 
126
        signal skip_counter_write                       : STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
127
        signal skip_counter_read                        : STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
128
 
129
        signal write_commited                           : STD_LOGIC := '0';
130
        signal read_commited                            : STD_LOGIC := '0';
131
 
132
        signal last_commit_write                        : STD_LOGIC;
133
        signal last_commit_read                         : STD_LOGIC;
134
 
135
        signal data_reg_addr_user                       : STD_LOGIC_VECTOR(10 downto 0) := "00000000000";
136
 
137
        signal sync_ok                                          : STD_LOGIC := '1';
138
        signal last_sync_strobe                         : STD_LOGIC := '0';
139
 
140
        signal slv_current_node                         : STD_LOGIC_VECTOR(3 downto 0) := "0000";
141
        signal slv_current_reg                          : STD_LOGIC_VECTOR(2 downto 0) := "000";
142
        signal slv_current_rw                           : STD_LOGIC := '0';      --Read: '0', Write: '1'
143
        signal slv_current_var                          : STD_LOGIC_VECTOR(3 downto 0) := "0000";
144
 
145
        signal slv_current_reg_ok                       : STD_LOGIC;
146
 
147
        signal slv_current_node_address                         : STD_LOGIC_VECTOR(3 downto 0);
148
        signal slv_current_node_id                                      : STD_LOGIC_VECTOR(3 downto 0);
149
        signal slv_current_node_read_reg_enable         : STD_LOGIC_VECTOR(7 downto 0);
150
        signal slv_current_node_write_reg_enable        : STD_LOGIC_VECTOR(7 downto 0);
151
 
152
        signal mst_trn_current_node                     : STD_LOGIC_VECTOR(3 downto 0) := "0000";
153
        signal mst_trn_current_reg                      : STD_LOGIC_VECTOR(2 downto 0) := "000";
154
        signal mst_trn_current_rw                       : STD_LOGIC := '0';      --Read: '0', Write: '1'
155
        signal mst_trn_current_var                      : STD_LOGIC_VECTOR(3 downto 0) := "0000";
156
 
157
        signal mst_trn_current_reg_ok           : STD_LOGIC;
158
 
159
        signal mst_trn_current_node_address                     : STD_LOGIC_VECTOR(3 downto 0);
160
        signal mst_trn_current_node_id                          : STD_LOGIC_VECTOR(3 downto 0);
161
        signal mst_trn_current_node_read_reg_enable     : STD_LOGIC_VECTOR(7 downto 0);
162
        signal mst_trn_current_node_write_reg_enable: STD_LOGIC_VECTOR(7 downto 0);
163
 
164
        signal mst_rec_current_node                     : STD_LOGIC_VECTOR(3 downto 0) := "0000";
165
        signal mst_rec_current_reg                      : STD_LOGIC_VECTOR(2 downto 0) := "000";
166
        signal mst_rec_current_rw                       : STD_LOGIC := '0';      --Read: '0', Write: '1'
167
        signal mst_rec_current_var                      : STD_LOGIC_VECTOR(3 downto 0) := "0000";
168
 
169
        signal mst_rec_current_reg_ok           : STD_LOGIC;
170
 
171
        signal mst_rec_current_node_address                     : STD_LOGIC_VECTOR(3 downto 0);
172
        signal mst_rec_current_node_id                          : STD_LOGIC_VECTOR(3 downto 0);
173
        signal mst_rec_current_node_read_reg_enable     : STD_LOGIC_VECTOR(7 downto 0);
174
        signal mst_rec_current_node_write_reg_enable: STD_LOGIC_VECTOR(7 downto 0);
175
 
176
        signal data_in_buffer                           : STD_LOGIC_VECTOR(7 downto 0);
177
        signal waiting_for_trn                          : STD_LOGIC;
178
 
179
        signal data_reg_internal_clk            : STD_LOGIC;
180
        signal data_reg_internal_data_in        : STD_LOGIC_VECTOR(7 downto 0);
181
        signal data_reg_internal_addr           : STD_LOGIC_VECTOR(12 downto 0);
182
        signal data_reg_internal_data_out       : STD_LOGIC_VECTOR(7 downto 0);
183
        signal data_reg_internal_we                     : STD_LOGIC_VECTOR(0 downto 0);
184
 
185
        signal async_rd_en                                      : STD_LOGIC;
186
        signal async_wr_en                                      : STD_LOGIC;
187
        signal async_rd_data                            : STD_LOGIC_VECTOR(37 downto 0);
188
        signal async_wr_data                            : STD_LOGIC_VECTOR(37 downto 0);
189
        signal async_full                                       : STD_LOGIC;
190
        signal async_empty                                      : STD_LOGIC;
191
        signal async_valid                                      : STD_LOGIC;
192
 
193
        signal async_buffer                                     : STD_LOGIC_VECTOR(95 downto 0);
194
        signal async_trn_byte_count                     : STD_LOGIC_VECTOR(3 downto 0);
195
        signal async_trn_valid_byte_count       : STD_LOGIC_VECTOR(3 downto 0);
196
        signal async_rec_byte_count                     : STD_LOGIC_VECTOR(3 downto 0);
197
        signal async_rec_valid_byte_count       : STD_LOGIC_VECTOR(3 downto 0);
198
        signal async_trn_target                         : STD_LOGIC_VECTOR(3 downto 0);
199
        signal async_rec_target                         : STD_LOGIC_VECTOR(3 downto 0);
200
        signal async_trn_done                           : STD_LOGIC;
201
        signal async_wr_be                                      : STD_LOGIC_VECTOR(1 downto 0);
202
        signal async_rec_valid                          : STD_LOGIC;
203
 
204
        signal async_slv_buffer                                 : STD_LOGIC_VECTOR(95 downto 0);
205
        signal async_slv_trn_byte_count                 : STD_LOGIC_VECTOR(3 downto 0);
206
        signal async_slv_trn_valid_byte_count   : STD_LOGIC_VECTOR(3 downto 0);
207
        signal async_slv_rec_byte_count                 : STD_LOGIC_VECTOR(3 downto 0);
208
        signal async_slv_rec_valid_byte_count   : STD_LOGIC_VECTOR(3 downto 0);
209
        signal async_slv_trn_target                             : STD_LOGIC_VECTOR(3 downto 0);
210
        signal async_slv_rec_target                             : STD_LOGIC_VECTOR(3 downto 0);
211
        signal async_slv_trn_done                               : STD_LOGIC;
212
        signal async_slv_wr_be                                  : STD_LOGIC_VECTOR(1 downto 0);
213
        signal async_slv_valid                                  : STD_LOGIC;
214
        signal async_slv_broadcast                              : STD_LOGIC;
215
 
216
 
217
        signal read_done                                        : STD_LOGIC;
218
        signal read_progress                            : STD_LOGIC_VECTOR(1 downto 0);
219
        signal write_done                                       : STD_LOGIC;
220
        signal write_progress                           : STD_LOGIC_VECTOR(1 downto 0);
221
        signal slv_progress                                     : STD_LOGIC_VECTOR(1 downto 0);
222
 
223
        signal rw_arbiter                                       : STD_LOGIC;
224
 
225
        signal reset_counter_int                        : STD_LOGIC_VECTOR(31 downto 0) := "00000000000000000000000000000000";
226
        signal packet_counter_int                       : STD_LOGIC_VECTOR(31 downto 0) := "00000000000000000000000000000000";
227
        signal error_counter_int                        : STD_LOGIC_VECTOR(31 downto 0) := "00000000000000000000000000000000";
228
 
229
        signal reset_counted                            : STD_LOGIC := '0';
230
 
231
        component data_reg is
232
        Port (  clka                            : in    STD_LOGIC;
233
                        dina                            : in    STD_LOGIC_VECTOR(7 downto 0);
234
                        addra                           : in    STD_LOGIC_VECTOR(12 downto 0);
235
                        wea                                     : in    STD_LOGIC_VECTOR(0 downto 0);
236
                        douta                           : out   STD_LOGIC_VECTOR(7 downto 0);
237
                        clkb                            : in    STD_LOGIC;
238
                        dinb                            : in    STD_LOGIC_VECTOR(31 downto 0);
239
                        addrb                           : in    STD_LOGIC_VECTOR(10 downto 0);
240
                        web                                     : in    STD_LOGIC_VECTOR(0 downto 0);
241
                        doutb                           : out   STD_LOGIC_VECTOR(31 downto 0));
242
        end component;
243
 
244
        component async_fifo is
245
        Port (  rst                                     : in    STD_LOGIC;
246
                        wr_clk                          : in    STD_LOGIC;
247
                        rd_clk                          : in    STD_LOGIC;
248
                        din                                     : in    STD_LOGIC_VECTOR(37 downto 0);
249
                        wr_en                           : in    STD_LOGIC;
250
                        rd_en                           : in    STD_LOGIC;
251
                        dout                            : out   STD_LOGIC_VECTOR(37 downto 0);
252
                        full                            : out   STD_LOGIC;
253
                        empty                           : out   STD_LOGIC;
254
                        valid                           : out   STD_LOGIC);
255
        end component;
256
 
257
begin
258
 
259
        data_reg_inst : data_reg
260
        Port map (      clka => data_reg_internal_clk,
261
                                dina => data_reg_internal_data_in,
262
                                addra => data_reg_internal_addr,
263
                                wea => data_reg_internal_we,
264
                                douta => data_reg_internal_data_out,
265
                                clkb => data_reg_clk,
266
                                dinb => data_reg_data_in,
267
                                addrb => data_reg_addr_user,
268
                                web => data_reg_we,
269
                                doutb => data_reg_data_out);
270
 
271
        async_enabled:
272
        if(disable_async = '0') generate
273
                in_fifo : async_fifo
274
                Port map (      rst => reset,
275
                                        wr_clk => async_in_clk,
276
                                        rd_clk => clk_50M,
277
                                        din => async_in_data,
278
                                        wr_en => async_in_wr_en,
279
                                        rd_en => async_rd_en,
280
                                        dout => async_rd_data,
281
                                        full => async_in_full,
282
                                        empty => async_empty,
283
                                        valid => async_valid);
284
 
285
                out_fifo : async_fifo
286
                Port map (      rst => reset,
287
                                        wr_clk => clk_50M,
288
                                        rd_clk => async_out_clk,
289
                                        din => async_wr_data,
290
                                        wr_en => async_wr_en,
291
                                        rd_en => async_out_rd_en,
292
                                        dout => async_out_data,
293
                                        full => async_full,
294
                                        empty => async_out_empty,
295
                                        valid => async_out_valid);
296
        end generate;
297
 
298
        async_disabled:
299
        if(disable_async = '1') generate
300
                async_rd_data <= (others => '0');
301
                async_in_full <= '1';
302
                async_empty <= '1';
303
                async_valid <= '0';
304
                async_out_data <= (others => '0');
305
                async_full <= '1';
306
                async_out_empty <= '1';
307
                async_out_valid <= '0';
308
        end generate;
309
 
310
        data_reg_addr_user <=   current_user_reg_write & data_reg_addr when     --Create the address for the data register depending on the current buffer selection...
311
                                                                        (((data_reg_addr(9 downto 6) = node_id) and data_reg_addr(2) = '0') or
312
                                                                        (not(data_reg_addr(9 downto 6) = node_id) and data_reg_addr(2) = '1')) else
313
                                                                        current_user_reg_read & data_reg_addr;
314
 
315
        slave_reset <= (reset or is_master) or disable_slave;           --The disable switches work by simply making sure that the slave- or master-reset is '1' always
316
        master_reset <= (reset or not is_master) or disable_master;     --XST will thus be able to optimize most of the slave- or master-functionality away...:)
317
 
318
        error_counter <= error_counter_int;
319
        packet_counter <= packet_counter_int;
320
        reset_counter <= reset_counter_int;
321
 
322
        skip_count_write <= skip_counter_write;
323
        skip_count_read <= skip_counter_read;
324
        current_buffer_index <= current_user_reg_write & current_user_reg_read & current_sys_reg_write & current_sys_reg_read;
325
 
326
        force_packet_error <= (packet_error and not is_master) and not reset;   --If we are forwarding a packet (slave only), and the current packet has an error, make sure that the packet is poisoned...
327
 
328
        process(clk_50M)
329
        begin
330
                if(clk_50M = '1' and clk_50M'EVENT) then
331
                        if(reset = '1') then
332
                                write_commited <= '0';
333
                                read_commited <= '0';
334
                                skip_counter_write <= "0000000000000000";
335
                                skip_counter_read <= "0000000000000000";
336
                                system_halt <= '0';
337
                                sync_ok <= '1';         --Make sure that the system starts automagically when it exits reset
338
                                pause_ack <= '0';
339
                                if(reset_counted = '0') then
340
                                        reset_counter_int <= reset_counter_int + 1;
341
                                        reset_counted <= '1';
342
                                end if;
343
                        else
344
                                reset_counted <= '0';
345
                        end if;
346
 
347
                        if(data_reg_commit_write = '1' and last_commit_write = '0') then
348
                                write_commited <= '1';
349
                        end if;
350
 
351
                        if(data_reg_commit_read = '1' and last_commit_read = '0') then
352
                                read_commited <= '1';
353
                        end if;
354
 
355
                        if((sync_strobe = '1') and (last_sync_strobe = '0')) then
356
                                if(write_commited = '1' and packet_error = '0') then             --Handle the doublebuffering for the write buffers
357
                                        if(current_user_reg_write = '1') then
358
                                                current_user_reg_write <= '0';
359
                                        else
360
                                                current_user_reg_write <= '1';
361
                                        end if;
362
                                        if(current_sys_reg_write = '1') then
363
                                                current_sys_reg_write <= '0';
364
                                        else
365
                                                current_sys_reg_write <= '1';
366
                                        end if;
367
                                        write_commited <= '0';
368
                                        skip_counter_write <= "0000000000000000";
369
                                else
370
                                        skip_counter_write <= skip_counter_write + 1;
371
                                end if;
372
 
373
                                if(read_commited = '1' and packet_error = '0') then              --Handle the doublebuffering for the read buffers
374
                                        if(current_user_reg_read = '1') then
375
                                                current_user_reg_read <= '0';
376
                                        else
377
                                                current_user_reg_read <= '1';
378
                                        end if;
379
                                        if(current_sys_reg_read = '1') then
380
                                                current_sys_reg_read <= '0';
381
                                        else
382
                                                current_sys_reg_read <= '1';
383
                                        end if;
384
                                        read_commited <= '0';
385
                                        skip_counter_read <= "0000000000000000";
386
                                else
387
                                        skip_counter_read <= skip_counter_read + 1;
388
                                end if;
389
 
390
                                sync_ok <= '1';
391
 
392
                                packet_counter_int <= packet_counter_int + 1;
393
 
394
                                if(packet_error = '1') then
395
                                        error_counter_int <= error_counter_int + 1;
396
                                end if;
397
 
398
                                if(pause = '1' and is_master = '1') then                                --Handle pause functionality
399
                                        pause_ack <= '1';
400
                                else
401
                                        pause_ack <= '0';
402
                                end if;
403
                        end if;
404
 
405
                        if(((skip_counter_write > max_skipped_writes) and not(max_skipped_writes = 0)) or        --The system only uses the skip counters if they're different from 0. If 0, an unlimited number of skips are allowed...
406
                           ((skip_counter_read > max_skipped_reads) and not (max_skipped_reads = 0))) then
407
                                system_halt <= '1';
408
                        end if;
409
 
410
                        async_wr_en <= '0';
411
------------------------------------------------------------------------
412
-- Slave synchronous part
413
------------------------------------------------------------------------
414
                        if(slave_reset = '1') then
415
                                slv_state <= IDLE;
416
                                slv_current_node <= "0000";
417
                                slv_current_rw <= '0';
418
                                slv_current_var <= "0000";
419
                                async_slv_buffer <= (others => '0');
420
                                async_slv_trn_byte_count <= (others => '0');
421
                                async_slv_trn_valid_byte_count <= (others => '0');
422
                                async_slv_rec_byte_count <= (others => '0');
423
                                async_slv_rec_valid_byte_count <= (others => '0');
424
                                async_slv_trn_target <= (others => '0');
425
                                async_slv_rec_target <= (others => '0');
426
                                async_slv_trn_done <= '0';
427
                                async_slv_wr_be <= (others => '0');
428
                                async_slv_valid <= '0';
429
                                async_slv_broadcast <= '0';
430
                                slv_progress <= "00";
431
                        else
432
                                slv_state <= next_slv_state;
433
 
434
                                case slv_state is
435
                                        when IDLE =>
436
                                                slv_current_node <= "0000";
437
                                                slv_current_rw <= '0';
438
                                                slv_current_var <= "0000";
439
                                                data_out_strobe <= '0';
440
                                                data_out_enable <= '0';
441
                                                async_slv_buffer <= (others => '0');
442
                                                async_slv_trn_byte_count <= (others => '0');
443
                                                async_slv_trn_valid_byte_count <= (others => '0');
444
                                                async_slv_rec_byte_count <= (others => '0');
445
                                                async_slv_rec_valid_byte_count <= (others => '0');
446
                                                async_slv_trn_target <= (others => '0');
447
                                                async_slv_rec_target <= (others => '0');
448
                                                async_slv_trn_done <= '0';
449
                                                async_slv_wr_be <= (others => '0');
450
                                                async_slv_valid <= '0';
451
                                                async_slv_broadcast <= '0';
452
                                                slv_progress <= "00";
453
                                        when ADDR_1 =>                                                                          --Retreive network register entry for node
454
                                                network_reg_addr <= slv_current_node;
455
                                                network_reg_clk <= '0';
456
                                                sync_ok <= '0';
457
                                        when ADDR_2 =>
458
                                                network_reg_clk <= '1';
459
                                        when ADDR_3 =>
460
                                                network_reg_clk <= '0';
461
                                                slv_current_node_address <= network_reg_data(7 downto 4);
462
                                                slv_current_node_id <= network_reg_data(3 downto 0);
463
                                                slv_current_node_read_reg_enable <= network_reg_data(15 downto 8);
464
                                                slv_current_node_write_reg_enable <= network_reg_data(23 downto 16);
465
                                                slv_current_rw <= '0';
466
                                                slv_current_var <= "0000";
467
                                        when DATA =>                                                                            --Receive, store, and forward packet
468
                                                data_out_enable <= '1';
469
 
470
                                                if(slv_current_reg_ok = '0') then                --No more registers for this part
471
                                                        if(slv_current_rw = '0') then                    --If read registers are currently selected,
472
                                                                slv_current_rw <= '1';                          --then switch to write
473
                                                        else                                                                                    --else the node is done,
474
                                                                slv_current_rw <= '0';
475
                                                                slv_current_node <= slv_current_node + 1;       --so go to the next node...
476
                                                                slv_current_var <= "0000";
477
                                                        end if;
478
                                                else
479
                                                        if(data_in_strobe = '1' and last_data_in_strobe = '0') then
480
                                                                if(slv_current_node = node_address) then
481
                                                                        if(slv_current_rw = '1') then                   --Ignore the Read registers from this node, we're only interested in the write registers...
482
                                                                                data_reg_internal_addr <= current_sys_reg_read & slv_current_node_id & slv_current_reg & '1' & slv_current_var;
483
                                                                                data_reg_internal_data_in <= data_in;
484
                                                                                data_reg_internal_we <= "1";
485
                                                                                data_reg_internal_clk <= '0';
486
                                                                                data_out <= data_reg_internal_data_out;
487
                                                                                data_out_strobe <= '1';
488
                                                                        else
489
                                                                                data_out <= data_in;
490
                                                                                data_out_strobe <= '1';
491
                                                                        end if;
492
                                                                else
493
                                                                        data_reg_internal_addr <= current_sys_reg_read & slv_current_node_id & slv_current_reg & slv_current_rw & slv_current_var;
494
                                                                        data_reg_internal_data_in <= data_in;
495
                                                                        data_reg_internal_we <= "1";
496
                                                                        data_reg_internal_clk <= '0';
497
                                                                        data_out <= data_in;
498
                                                                        data_out_strobe <= '1';
499
                                                                end if;
500
                                                        elsif(data_in_strobe = '0' and last_data_in_strobe = '1') then
501
                                                                if(not((slv_current_node = node_address) and (slv_current_rw = '0'))) then
502
                                                                        data_reg_internal_clk <= '1';
503
                                                                end if;
504
 
505
                                                                data_out_strobe <= '0';
506
 
507
                                                                if(slv_current_var = "1111") then                                                       --All vars for this register read, set the reg_enable bit for this register to 0 to go to the next register
508
                                                                        if(slv_current_rw = '0') then
509
                                                                                slv_current_node_read_reg_enable(conv_integer(slv_current_reg)) <= '0';
510
                                                                        else
511
                                                                                slv_current_node_write_reg_enable(conv_integer(slv_current_reg)) <= '0';
512
                                                                        end if;
513
                                                                end if;
514
 
515
                                                                slv_current_var <= slv_current_var + 1;
516
 
517
                                                        elsif((data_reg_internal_clk = '1') and (data_reg_internal_we = "1") and (data_in_strobe = '0')) then
518
                                                                data_reg_internal_clk <= '0';
519
                                                                data_reg_internal_addr <= current_sys_reg_write & slv_current_node_id & slv_current_reg & '0' & slv_current_var;
520
                                                                data_reg_internal_we <= "0";
521
                                                        elsif((data_reg_internal_clk = '0') and (data_reg_internal_we = "0") and (data_in_strobe = '0')) then
522
                                                                data_reg_internal_clk <= '1';
523
                                                        else
524
                                                                data_reg_internal_clk <= '0';
525
                                                                data_reg_internal_we <= "1";
526
                                                        end if;
527
                                                end if;
528
                                        when ASYNC_CTL_HEAD =>
529
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
530
                                                        if(data_in = ASYNC_M2S_VALID & NODE_ID) then            --Data for this node only received
531
                                                                async_slv_valid <= '1';
532
                                                                if(async_valid = '1') then
533
                                                                        data_out <= ASYNC_S2M_VALID & NODE_ID;
534
                                                                else
535
                                                                        data_out <= ASYNC_S2M_INVALID & NODE_ID;
536
                                                                end if;
537
                                                        elsif(data_in = ASYNC_M2S_VALID & "0000") then          --Broadcast received
538
                                                                data_out <= data_in;
539
                                                                async_slv_valid <= '1';
540
                                                                async_trn_done <= '1';
541
                                                                async_slv_broadcast <= '1';
542
                                                        else                                                                                            --Nothing of interest for this node
543
                                                                async_slv_valid <= '0';
544
                                                                data_out <= data_in;
545
                                                        end if;
546
 
547
                                                        data_out_strobe <= '1';
548
                                                end if;
549
                                        when ASYNC =>
550
                                                data_out_strobe <= '0';
551
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
552
                                                        if(async_slv_valid = '0') then
553
                                                                data_out <= data_in;
554
                                                                data_out_strobe <= '1';
555
                                                        else
556
                                                                async_slv_buffer <= async_slv_buffer(87 downto 0) & data_in;
557
                                                                async_slv_rec_byte_count <= async_slv_rec_byte_count + 1;
558
 
559
                                                                if(async_valid = '1') then
560
                                                                        if(async_slv_trn_byte_count = 0) then
561
                                                                                async_slv_trn_target <= async_rd_data(35 downto 32);
562
                                                                        end if;
563
                                                                else
564
                                                                        async_slv_trn_done <= '1';
565
                                                                end if;
566
                                                                slv_progress <= "01";
567
                                                        end if;
568
                                                elsif(slv_progress = "01") then                 --We'll only increase slv_progress if async_slv_valid is true, thus no need for a (redundant) check for validity here...
569
                                                        if(async_slv_trn_done = '0' and async_slv_trn_target = async_rd_data(35 downto 32)) then
570
                                                                case async_slv_trn_byte_count(1 downto 0) is
571
                                                                        when "00" =>
572
                                                                                data_out <= async_rd_data(31 downto 24);
573
                                                                                if(async_rd_data(37 downto 36) = "00") then
574
                                                                                        async_slv_trn_done <= '1';
575
                                                                                end if;
576
                                                                        when "01" =>
577
                                                                                data_out <= async_rd_data(23 downto 16);
578
                                                                                if(async_rd_data(37 downto 36) = "01") then
579
                                                                                        async_slv_trn_done <= '1';
580
                                                                                end if;
581
                                                                        when "10" =>
582
                                                                                data_out <= async_rd_data(15 downto 8);
583
                                                                                if(async_rd_data(37 downto 36) = "10") then
584
                                                                                        async_slv_trn_done <= '1';
585
                                                                                end if;
586
                                                                        when "11" =>
587
                                                                                data_out <= async_rd_data(7 downto 0);
588
                                                                        when others =>
589
                                                                end case;
590
                                                                async_slv_trn_valid_byte_count <= async_slv_trn_valid_byte_count + 1;
591
                                                        else
592
                                                                data_out <= data_in;
593
                                                                async_slv_trn_done <= '1';
594
                                                        end if;
595
                                                        data_out_strobe <= '1';
596
                                                        async_slv_trn_byte_count <= async_slv_trn_byte_count + 1;
597
                                                        slv_progress <= "10";
598
                                                elsif(slv_progress = "10") then
599
                                                        slv_progress <= "00";
600
                                                end if;
601
                                        when ASYNC_CTL_TAIL =>
602
                                                data_out_strobe <= '0';
603
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0' and slv_progress = "00") then
604
                                                        if(async_slv_broadcast = '1') then
605
                                                                data_out <= data_in;
606
                                                        else
607
                                                                data_out <= async_slv_trn_valid_byte_count & NODE_ID;
608
                                                        end if;
609
                                                        data_out_strobe <= '1';
610
                                                        async_slv_rec_valid_byte_count <= data_in(7 downto 4) - 4;
611
                                                        async_slv_rec_target <= data_in(3 downto 0);
612
                                                        slv_progress <= "01";
613
                                                        if(data_in(7 downto 4) > 3) then
614
                                                                async_slv_wr_be <= "11";
615
                                                        else
616
                                                                async_slv_wr_be <= data_in(5 downto 4) - 1;
617
                                                        end if;
618
                                                elsif(slv_progress = "01") then
619
                                                        data_out_strobe <= '0';
620
                                                        if((async_slv_rec_valid_byte_count > 8) and (async_slv_rec_valid_byte_count < 13)) then
621
                                                                slv_progress <= "11";                   --Done
622
                                                        else
623
                                                                slv_progress <= "10";                   --Delay one clock (we've got lots), to make sure we jump out if no data has been received (8 < async_rec_valid_byte_count < 13)
624
                                                        end if;
625
                                                        async_wr_en <= '0';
626
                                                elsif(slv_progress = "10") then
627
                                                        async_wr_data <= async_slv_wr_be & async_slv_rec_target & async_slv_buffer(95 downto 64);
628
                                                        async_wr_en <= '1';
629
                                                        async_slv_buffer(95 downto 32) <= async_slv_buffer(63 downto 0);
630
                                                        async_slv_rec_valid_byte_count <= async_slv_rec_valid_byte_count - 4;
631
                                                        if(async_slv_rec_valid_byte_count > 3) then
632
                                                                async_slv_wr_be <= "11";
633
                                                        else
634
                                                                async_slv_wr_be <= async_slv_rec_valid_byte_count(1 downto 0) - 1;
635
                                                        end if;
636
                                                        slv_progress <= "01";
637
                                                end if;
638
                                end case;
639
                        end if;
640
 
641
------------------------------------------------------------------------
642
-- Master TRN synchronous part
643
------------------------------------------------------------------------
644
                        if(master_reset = '1') then
645
                                mst_trn_state <= IDLE;
646
                                mst_trn_current_node <= "0000";
647
                                mst_trn_current_rw <= '0';
648
                                mst_trn_current_var <= "0000";
649
                                read_progress <= "00";
650
                                read_done <= '1';
651
                                async_trn_byte_count <= (others => '0');
652
                                async_trn_valid_byte_count <= (others => '0');
653
                                async_trn_done <= '0';
654
                                async_trn_target <= (others => '0');
655
                        else
656
                                mst_trn_state <= next_mst_trn_state;
657
 
658
                                case mst_trn_state is
659
                                        when IDLE =>
660
                                                mst_trn_current_node <= "0000";
661
                                                mst_trn_current_rw <= '0';
662
                                                mst_trn_current_var <= "0000";
663
                                                data_out_strobe <= '0';
664
                                                data_out_enable <= '0';
665
                                                read_progress <= "00";
666
                                                read_done <= '1';
667
                                                async_trn_byte_count <= (others => '0');
668
                                                async_trn_valid_byte_count <= (others => '0');
669
                                                async_trn_done <= '0';
670
                                                async_trn_target <= (others => '0');
671
                                        when ADDR_1 =>                                                                          --Retreive network register entry for node
672
                                                network_reg_addr <= mst_trn_current_node;
673
                                                network_reg_clk <= '0';
674
                                                sync_ok <= '0';
675
                                                pause_ack <= '0';
676
                                        when ADDR_2 =>
677
                                                network_reg_clk <= '1';
678
                                        when ADDR_3 =>
679
                                                network_reg_clk <= '0';
680
                                                mst_trn_current_node_address <= network_reg_data(7 downto 4);
681
                                                mst_trn_current_node_id <= network_reg_data(3 downto 0);
682
                                                mst_trn_current_node_read_reg_enable <= network_reg_data(15 downto 8);
683
                                                mst_trn_current_node_write_reg_enable <= network_reg_data(23 downto 16);
684
                                                mst_trn_current_rw <= '0';
685
                                                mst_trn_current_var <= "0000";
686
                                        when DATA =>                                                                            --Receive, store, and forward packet
687
                                                data_out_enable <= '1';
688
 
689
                                                if(mst_trn_current_reg_ok = '0') then            --No more registers for this part
690
                                                        if(mst_trn_current_rw = '0') then                --If read registers are currently selected,
691
                                                                mst_trn_current_rw <= '1';                              --then switch to write
692
                                                        else                                                                                            --else the node is done,
693
                                                                mst_trn_current_rw <= '0';
694
                                                                mst_trn_current_node <= mst_trn_current_node + 1;       --so go to the next node...
695
                                                                mst_trn_current_var <= "0000";
696
                                                        end if;
697
                                                else
698
                                                        if(read_progress = "00" and write_done = '1' and buffer_full = '0' and rw_arbiter = '0') then
699
                                                                if(mst_trn_current_rw = '0' and not(mst_trn_current_node = node_address)) then
700
                                                                        data_reg_internal_addr <= current_sys_reg_read & mst_trn_current_node_id & mst_trn_current_reg & mst_trn_current_rw & mst_trn_current_var;
701
                                                                else
702
                                                                        data_reg_internal_addr <= current_sys_reg_write & mst_trn_current_node_id & mst_trn_current_reg & mst_trn_current_rw & mst_trn_current_var;
703
                                                                end if;
704
                                                                data_reg_internal_we <= "0";
705
                                                                data_reg_internal_clk <= '0';
706
                                                                read_progress <= "01";
707
                                                                read_done <= '0';
708
                                                        elsif(read_progress = "01") then
709
                                                                data_reg_internal_clk <= '1';
710
                                                                read_progress <= "10";
711
                                                        elsif(read_progress = "10") then
712
                                                                data_reg_internal_clk <= '0';
713
                                                                data_out <= data_reg_internal_data_out;
714
                                                                data_out_strobe <= '1';
715
                                                                read_progress <= "11";
716
                                                                read_done <= '1';
717
                                                        elsif(read_progress = "11") then
718
                                                                data_out_strobe <= '0';
719
                                                                read_progress <= "00";
720
 
721
                                                                if(mst_trn_current_var = "1111") then                                                   --All vars for this register read, set the reg_enable bit for this register to 0 to go to the next register
722
                                                                        if(mst_trn_current_rw = '0') then
723
                                                                                mst_trn_current_node_read_reg_enable(conv_integer(mst_trn_current_reg)) <= '0';
724
                                                                        else
725
                                                                                mst_trn_current_node_write_reg_enable(conv_integer(mst_trn_current_reg)) <= '0';
726
                                                                        end if;
727
                                                                end if;
728
 
729
                                                                mst_trn_current_var <= mst_trn_current_var + 1;
730
                                                        end if;
731
                                                end if;
732
                                        when ASYNC_CTL_HEAD =>
733
                                                if(buffer_full = '0' and read_progress <= "00") then
734
                                                        if(async_valid = '1') then
735
                                                                async_trn_target <= async_rd_data(35 downto 32);
736
                                                                data_out <= ASYNC_M2S_VALID & async_rd_data(35 downto 32);
737
                                                        else
738
                                                                data_out <= ASYNC_M2S_INVALID & "0000";
739
                                                                async_trn_done <= '1';
740
                                                        end if;
741
                                                        data_out_strobe <= '1';
742
                                                        read_progress <= "01";
743
                                                else
744
                                                        data_out_strobe <= '0';
745
                                                end if;
746
                                        when ASYNC =>
747
                                                data_out_strobe <= '0';
748
                                                if(read_progress = "00") then
749
                                                        read_progress <= "01";
750
                                                elsif(read_progress = "01" and buffer_full = '0') then
751
                                                        if(async_valid = '0') then
752
                                                                async_trn_done <= '1';
753
                                                        end if;
754
                                                        read_progress <= "10";
755
                                                elsif(read_progress = "10") then
756
                                                        if(async_trn_done = '0' and async_trn_target = async_rd_data(35 downto 32)) then
757
                                                                case async_trn_byte_count(1 downto 0) is
758
                                                                        when "00" =>
759
                                                                                data_out <= async_rd_data(31 downto 24);
760
                                                                                if(async_rd_data(37 downto 36) = "00") then
761
                                                                                        async_trn_done <= '1';
762
                                                                                end if;
763
                                                                        when "01" =>
764
                                                                                data_out <= async_rd_data(23 downto 16);
765
                                                                                if(async_rd_data(37 downto 36) = "01") then
766
                                                                                        async_trn_done <= '1';
767
                                                                                end if;
768
                                                                        when "10" =>
769
                                                                                data_out <= async_rd_data(15 downto 8);
770
                                                                                if(async_rd_data(37 downto 36) = "10") then
771
                                                                                        async_trn_done <= '1';
772
                                                                                end if;
773
                                                                        when "11" =>
774
                                                                                data_out <= async_rd_data(7 downto 0);
775
                                                                        when others =>
776
                                                                end case;
777
                                                                async_trn_valid_byte_count <= async_trn_valid_byte_count + 1;
778
                                                        else
779
                                                                data_out <= (others => '0');
780
                                                                async_trn_done <= '1';
781
                                                        end if;
782
                                                        data_out_strobe <= '1';
783
                                                        async_trn_byte_count <= async_trn_byte_count + 1;
784
                                                        read_progress <= "11";
785
                                                elsif(read_progress = "11") then
786
                                                        data_out_strobe <= '0';
787
                                                        read_progress <= "00";
788
                                                end if;
789
                                        when ASYNC_CTL_TAIL =>
790
                                                if(read_progress = "00" and buffer_full = '0') then
791
                                                        data_out <= async_trn_valid_byte_count & async_trn_target;
792
                                                        data_out_strobe <= '1';
793
                                                        read_progress <= "01";
794
                                                elsif(read_progress = "01") then
795
                                                        data_out_strobe <= '0';
796
                                                        read_progress <= "00";
797
                                                end if;
798
                                        when WAIT_STATE =>
799
                                                --Just do nothing...
800
                                end case;
801
                        end if;
802
 
803
------------------------------------------------------------------------
804
-- Master REC synchronous part
805
------------------------------------------------------------------------
806
                        if(master_reset = '1') then
807
                                mst_rec_state <= IDLE;
808
                                mst_rec_current_node <= "0000";
809
                                mst_rec_current_rw <= '0';
810
                                mst_rec_current_var <= "0000";
811
                                write_progress <= "00";
812
                                write_done <= '1';
813
                                async_rec_byte_count <= (others => '0');
814
                                async_rec_valid_byte_count <= (others => '0');
815
                                async_rec_target <= (others => '0');
816
                                async_wr_be <= "00";
817
                                async_rec_valid <= '0';
818
                        else
819
                                mst_rec_state <= next_mst_rec_state;
820
 
821
                                case mst_rec_state is
822
                                        when IDLE =>
823
                                                mst_rec_current_node <= "0000";
824
                                                mst_rec_current_rw <= '0';
825
                                                mst_rec_current_var <= "0000";
826
                                                write_progress <= "00";
827
                                                write_done <= '1';
828
                                                async_rec_byte_count <= (others => '0');
829
                                                async_rec_valid_byte_count <= (others => '0');
830
                                                async_rec_target <= (others => '0');
831
                                                async_wr_be <= "00";
832
                                                async_rec_valid <= '0';
833
                                        when ADDR_1 =>                                                                          --Retreive network register entry for node
834
                                                network_reg_addr <= mst_rec_current_node;
835
                                                network_reg_clk <= '0';
836
                                                sync_ok <= '0';
837
                                        when ADDR_2 =>
838
                                                network_reg_clk <= '1';
839
                                        when ADDR_3 =>
840
                                                network_reg_clk <= '0';
841
                                                mst_rec_current_node_address <= network_reg_data(7 downto 4);
842
                                                mst_rec_current_node_id <= network_reg_data(3 downto 0);
843
                                                mst_rec_current_node_read_reg_enable <= network_reg_data(15 downto 8);
844
                                                mst_rec_current_node_write_reg_enable <= network_reg_data(23 downto 16);
845
                                                mst_rec_current_rw <= '0';
846
                                                mst_rec_current_var <= "0000";
847
                                        when DATA =>                                                                            --Receive, store, and forward packet
848
                                                if(mst_rec_current_reg_ok = '0') then            --No more registers for this part
849
                                                        if(waiting_for_trn = '0') then
850
                                                                if(mst_rec_current_rw = '0') then        --If read registers are currently selected,
851
                                                                        mst_rec_current_rw <= '1';                      --then switch to write
852
                                                                else                                                                                    --else the node is done,
853
                                                                        mst_rec_current_rw <= '0';
854
                                                                        mst_rec_current_node <= mst_rec_current_node + 1;       --so go to the next node...
855
                                                                        mst_rec_current_var <= "0000";
856
                                                                end if;
857
                                                        end if;
858
                                                else
859
                                                        if(data_in_strobe = '1' and last_data_in_strobe = '0') then
860
                                                                if((mst_rec_current_rw = '1') and not(mst_rec_current_node = node_address)) then                        --Ignore the Read registers for the nodes, we're only interested in the write registers, which hold the newest data...
861
                                                                        data_in_buffer <= data_in;
862
                                                                        write_progress <= "01";
863
                                                                end if;
864
                                                        elsif(data_in_strobe = '0' and last_data_in_strobe = '1') then
865
                                                                if(mst_rec_current_var = "1111") then                                                   --All vars for this register read, set the reg_enable bit for this register to 0 to go to the next register
866
                                                                        if(mst_rec_current_rw = '0') then
867
                                                                                mst_rec_current_node_read_reg_enable(conv_integer(mst_rec_current_reg)) <= '0';
868
                                                                        else
869
                                                                                mst_rec_current_node_write_reg_enable(conv_integer(mst_rec_current_reg)) <= '0';
870
                                                                        end if;
871
                                                                end if;
872
                                                                mst_rec_current_var <= mst_rec_current_var + 1;
873
                                                        elsif(write_progress = "01" and write_done = '1' and read_done = '1' and rw_arbiter = '1') then
874
                                                                data_reg_internal_addr <= current_sys_reg_read & mst_rec_current_node_id & mst_rec_current_reg & '0' & mst_rec_current_var;
875
                                                                data_reg_internal_data_in <= data_in_buffer;
876
                                                                data_reg_internal_we <= "1";
877
                                                                data_reg_internal_clk <= '0';
878
                                                                write_done <= '0';
879
                                                                write_progress <= "10";
880
                                                        elsif(write_progress = "10" and write_done = '0') then
881
                                                                data_reg_internal_clk <= '1';
882
                                                                write_progress <= "11";
883
                                                        elsif(write_progress = "11" and write_done = '0') then
884
                                                                data_reg_internal_clk <= '0';
885
                                                                data_reg_internal_we <= "0";
886
                                                                write_done <= '1';
887
                                                                write_progress <= "00";
888
                                                        end if;
889
                                                end if;
890
                                        when ASYNC_CTL_HEAD =>
891
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
892
                                                        if(data_in(7 downto 4) = ASYNC_S2M_VALID) then
893
                                                                async_rec_valid <= '1';
894
                                                        else
895
                                                                async_rec_valid <= '0';
896
                                                        end if;
897
                                                end if;
898
                                        when ASYNC =>
899
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
900
                                                        async_buffer <= async_buffer(87 downto 0) & data_in;
901
                                                        async_rec_byte_count <= async_rec_byte_count + 1;
902
                                                end if;
903
                                        when ASYNC_CTL_TAIL =>
904
                                                if(data_in_strobe = '1' and last_data_in_strobe = '0' and write_progress = "00") then
905
                                                        async_rec_valid_byte_count <= data_in(7 downto 4) - 4;
906
                                                        async_rec_target <= data_in(3 downto 0);
907
                                                        write_progress <= "01";
908
                                                        if(data_in(7 downto 4) > 3) then
909
                                                                async_wr_be <= "11";
910
                                                        else
911
                                                                async_wr_be <= data_in(5 downto 4) - 1;
912
                                                        end if;
913
                                                elsif(write_progress = "01") then
914
                                                        write_progress <= "10";                 --Delay one clock (we've got lots), to make sure we jump out if no data has been received (async_rec_valid_byte_count > 8)
915
                                                        async_wr_en <= '0';
916
                                                elsif(write_progress = "10") then
917
                                                        async_wr_data <= async_wr_be & async_rec_target & async_buffer(95 downto 64);
918
                                                        async_wr_en <= '1';
919
                                                        async_buffer(95 downto 32) <= async_buffer(63 downto 0);
920
                                                        async_rec_valid_byte_count <= async_rec_valid_byte_count - 4;
921
                                                        if(async_rec_valid_byte_count > 3) then
922
                                                                async_wr_be <= "11";
923
                                                        else
924
                                                                async_wr_be <= async_rec_valid_byte_count(1 downto 0) - 1;
925
                                                        end if;
926
                                                        write_progress <= "01";
927
                                                end if;
928
                                end case;
929
                        end if;
930
 
931
------------------------------------------------------------------------
932
 
933
                        last_data_in_strobe <= data_in_strobe;
934
                        last_sync_strobe <= sync_strobe;
935
                        last_commit_write <= data_reg_commit_write;
936
                        last_commit_read <= data_reg_commit_read;
937
 
938
                        if(rw_arbiter = '0') then
939
                                rw_arbiter <= '1';
940
                        else
941
                                rw_arbiter <= '0';
942
                        end if;
943
 
944
                end if;
945
        end process;
946
 
947
 
948
------------------------------------------------------------------------
949
-- Slave combinatorial next-state logic
950
------------------------------------------------------------------------
951
        process(slv_state, data_in_enable, slv_current_reg_ok, slv_current_rw, slv_current_node, network_reg_data(7 downto 4), slv_progress, async_slv_trn_byte_count, async_slv_rec_valid_byte_count, data_in_strobe, last_data_in_strobe)
952
        begin
953
                case slv_state is
954
                        when IDLE =>
955
                                if(data_in_enable = '1') then
956
                                        next_slv_state <= ADDR_1;
957
                                else
958
                                        next_slv_state <= IDLE;
959
                                end if;
960
                        when ADDR_1 =>
961
                                next_slv_state <= ADDR_2;
962
                        when ADDR_2 =>
963
                                next_slv_state <= ADDR_3;
964
                        when ADDR_3 =>
965
                                if(slv_current_node = network_reg_data(7 downto 4)) then
966
                                        next_slv_state <= DATA;
967
                                else
968
                                        next_slv_state <= ASYNC_CTL_HEAD;
969
                                end if;
970
                        when DATA =>
971
                                if(data_in_enable = '0') then
972
                                        next_slv_state <= IDLE;
973
                                elsif(slv_current_reg_ok = '0' and slv_current_rw = '1') then
974
                                        next_slv_state <= ADDR_1;
975
                                else
976
                                        next_slv_state <= DATA;
977
                                end if;
978
                        when ASYNC_CTL_HEAD =>
979
                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
980
                                        next_slv_state <= ASYNC;
981
                                else
982
                                        next_slv_state <= ASYNC_CTL_HEAD;
983
                                end if;
984
                        when ASYNC =>
985
                                if(data_in_enable = '0') then
986
                                        next_slv_state <= IDLE;
987
                                elsif(slv_progress = "00" and async_slv_trn_byte_count = 12) then
988
                                        next_slv_state <= ASYNC_CTL_TAIL;
989
                                else
990
                                        next_slv_state <= ASYNC;
991
                                end if;
992
                        when ASYNC_CTL_TAIL =>
993
                                if(data_in_enable = '0') then
994
                                        next_slv_state <= IDLE;
995
                                else
996
                                        next_slv_state <= ASYNC_CTL_TAIL;
997
                                end if;
998
                end case;
999
        end process;
1000
 
1001
 
1002
------------------------------------------------------------------------
1003
-- Master TRN combinatorial next-state logic
1004
------------------------------------------------------------------------
1005
        process(mst_trn_state, mst_rec_state, sync_ok, data_in_enable, mst_trn_current_reg_ok, mst_trn_current_rw, mst_trn_current_node, network_reg_data(7 downto 4), pause, read_progress, async_trn_byte_count)
1006
        begin
1007
                case mst_trn_state is
1008
                        when IDLE =>
1009
                                if(mst_rec_state = IDLE and sync_ok = '1' and pause = '0') then                          --Make sure that we're done receiving and sync'ing before sending out the next packet (for synchronization, buffering and a couple of other reasons...)
1010
                                        next_mst_trn_state <= WAIT_STATE;
1011
                                else
1012
                                        next_mst_trn_state <= IDLE;
1013
                                end if;
1014
                        when ADDR_1 =>
1015
                                next_mst_trn_state <= ADDR_2;
1016
                        when ADDR_2 =>
1017
                                next_mst_trn_state <= ADDR_3;
1018
                        when ADDR_3 =>
1019
                                if(mst_trn_current_node = network_reg_data(7 downto 4)) then
1020
                                        next_mst_trn_state <= DATA;
1021
                                else
1022
                                        next_mst_trn_state <= ASYNC_CTL_HEAD;
1023
                                end if;
1024
                        when DATA =>
1025
                                if(mst_trn_current_reg_ok = '0' and mst_trn_current_rw = '1') then
1026
                                        next_mst_trn_state <= WAIT_STATE;
1027
                                else
1028
                                        next_mst_trn_state <= DATA;
1029
                                end if;
1030
                        when ASYNC_CTL_HEAD =>
1031
                                if(read_progress = "01") then
1032
                                        next_mst_trn_state <= ASYNC;
1033
                                else
1034
                                        next_mst_trn_state <= ASYNC_CTL_HEAD;
1035
                                end if;
1036
                        when ASYNC =>
1037
                                if(read_progress = "11" and async_trn_byte_count = 12) then
1038
                                        next_mst_trn_state <= ASYNC_CTL_TAIL;
1039
                                else
1040
                                        next_mst_trn_state <= ASYNC;
1041
                                end if;
1042
                        when ASYNC_CTL_TAIL =>
1043
                                if(read_progress = "01") then
1044
                                        next_mst_trn_state <= IDLE;
1045
                                else
1046
                                        next_mst_trn_state <= ASYNC_CTL_TAIL;
1047
                                end if;
1048
                        when WAIT_STATE =>
1049
                                if(mst_rec_state = DATA or mst_rec_state = IDLE) then
1050
                                        next_mst_trn_state <= ADDR_1;
1051
                                else
1052
                                        next_mst_trn_state <= WAIT_STATE;
1053
                                end if;
1054
                end case;
1055
        end process;
1056
 
1057
 
1058
------------------------------------------------------------------------
1059
-- Master REC combinatorial next-state logic
1060
------------------------------------------------------------------------
1061
        process(mst_rec_state, mst_trn_state, data_in_enable, mst_rec_current_reg_ok, mst_rec_current_rw, mst_rec_current_node, network_reg_data(7 downto 4), async_rec_byte_count, async_rec_valid_byte_count, async_rec_valid, data_in_strobe, last_data_in_strobe)
1062
        begin
1063
                waiting_for_trn <= '0';
1064
 
1065
                case mst_rec_state is
1066
                        when IDLE =>
1067
                                if(data_in_enable = '1' and (mst_trn_state = DATA or mst_trn_state = IDLE or mst_trn_state = ASYNC_CTL_HEAD or mst_trn_state = ASYNC or mst_trn_state = ASYNC_CTL_TAIL)) then
1068
                                        next_mst_rec_state <= ADDR_1;
1069
                                else
1070
                                        next_mst_rec_state <= IDLE;
1071
                                end if;
1072
                        when ADDR_1 =>
1073
                                next_mst_rec_state <= ADDR_2;
1074
                        when ADDR_2 =>
1075
                                next_mst_rec_state <= ADDR_3;
1076
                        when ADDR_3 =>
1077
                                if(mst_rec_current_node = network_reg_data(7 downto 4)) then
1078
                                        next_mst_rec_state <= DATA;
1079
                                else
1080
                                        next_mst_rec_state <= ASYNC_CTL_HEAD;
1081
                                end if;
1082
                        when DATA =>
1083
                                if(data_in_enable = '0') then
1084
                                        next_mst_rec_state <= IDLE;
1085
                                elsif(mst_rec_current_reg_ok = '0' and mst_rec_current_rw = '1' and (mst_trn_state = DATA or mst_trn_state = IDLE or mst_trn_state = ASYNC_CTL_HEAD or mst_trn_state = ASYNC or mst_trn_state = ASYNC_CTL_TAIL)) then
1086
                                        next_mst_rec_state <= ADDR_1;
1087
                                elsif(mst_rec_current_reg_ok = '0' and mst_rec_current_rw = '1') then
1088
                                        waiting_for_trn <= '1';
1089
                                        next_mst_rec_state <= DATA;
1090
                                else
1091
                                        next_mst_rec_state <= DATA;
1092
                                end if;
1093
                        when ASYNC_CTL_HEAD =>
1094
                                if(data_in_strobe = '1' and last_data_in_strobe = '0') then
1095
                                        next_mst_rec_state <= ASYNC;
1096
                                else
1097
                                        next_mst_rec_state <= ASYNC_CTL_HEAD;
1098
                                end if;
1099
                        when ASYNC =>
1100
                                if(async_rec_byte_count = 12) then
1101
                                        next_mst_rec_state <= ASYNC_CTL_TAIL;
1102
                                else
1103
                                        next_mst_rec_state <= ASYNC;
1104
                                end if;
1105
                        when ASYNC_CTL_TAIL =>
1106
                                if(((async_rec_valid_byte_count > 8) and (async_rec_valid_byte_count < 13)) or async_rec_valid <= '0') then
1107
                                        next_mst_rec_state <= IDLE;
1108
                                else
1109
                                        next_mst_rec_state <= ASYNC_CTL_TAIL;
1110
                                end if;
1111
                end case;
1112
        end process;
1113
 
1114
 
1115
------------------------------------------------------------------------
1116
-- Combinatorial logic for address generation
1117
------------------------------------------------------------------------
1118
 
1119
        async_rd_en <= '1' when (((mst_trn_state = ASYNC) and (read_progress = "11") and (async_trn_done = '0') and (async_trn_byte_count(1 downto 0) = "00")) or
1120
                                                         ((mst_trn_state = ASYNC_CTL_TAIL) and (read_progress = "01") and not (async_trn_valid_byte_count(1 downto 0) = "00")) or
1121
                                                         ((slv_state = ASYNC) and (slv_progress = "10") and (async_slv_trn_done = '0') and (async_slv_trn_byte_count(1 downto 0) = "00")) or
1122
                                                         ((slv_state = ASYNC_CTL_TAIL) and (data_in_strobe = '1') and (last_data_in_strobe = '0') and (slv_progress = "00") and not (async_slv_trn_valid_byte_count(1 downto 0) = "00"))) else '0';
1123
 
1124
 
1125
 
1126
 
1127
 
1128
 
1129
        slv_current_reg <= "111" when (slv_current_node_read_reg_enable(7) = '1' and slv_current_rw = '0') or
1130
                                                                                        (slv_current_node_write_reg_enable(7) = '1' and slv_current_rw = '1') else
1131
                                                        "110" when      (slv_current_node_read_reg_enable(6) = '1' and slv_current_rw = '0') or
1132
                                                                                        (slv_current_node_write_reg_enable(6) = '1' and slv_current_rw = '1') else
1133
                                                        "101" when      (slv_current_node_read_reg_enable(5) = '1' and slv_current_rw = '0') or
1134
                                                                                        (slv_current_node_write_reg_enable(5) = '1' and slv_current_rw = '1') else
1135
                                                        "100" when      (slv_current_node_read_reg_enable(4) = '1' and slv_current_rw = '0') or
1136
                                                                                        (slv_current_node_write_reg_enable(4) = '1' and slv_current_rw = '1') else
1137
                                                        "011" when      (slv_current_node_read_reg_enable(3) = '1' and slv_current_rw = '0') or
1138
                                                                                        (slv_current_node_write_reg_enable(3) = '1' and slv_current_rw = '1') else
1139
                                                        "010" when      (slv_current_node_read_reg_enable(2) = '1' and slv_current_rw = '0') or
1140
                                                                                        (slv_current_node_write_reg_enable(2) = '1' and slv_current_rw = '1') else
1141
                                                        "001" when      (slv_current_node_read_reg_enable(1) = '1' and slv_current_rw = '0') or
1142
                                                                                        (slv_current_node_write_reg_enable(1) = '1' and slv_current_rw = '1') else
1143
                                                        "000";
1144
 
1145
        slv_current_reg_ok <= '0' when slv_current_reg = "000" and not ((slv_current_node_read_reg_enable(0) = '1' and slv_current_rw = '0') or
1146
                                                                                                                                                                                (slv_current_node_write_reg_enable(0) = '1' and slv_current_rw = '1')) else
1147
                                                        '1';
1148
 
1149
 
1150
        mst_trn_current_reg <= "111" when       (mst_trn_current_node_read_reg_enable(7) = '1' and mst_trn_current_rw = '0') or
1151
                                                                                                        (mst_trn_current_node_write_reg_enable(7) = '1' and mst_trn_current_rw = '1') else
1152
                                                                        "110" when      (mst_trn_current_node_read_reg_enable(6) = '1' and mst_trn_current_rw = '0') or
1153
                                                                                                        (mst_trn_current_node_write_reg_enable(6) = '1' and mst_trn_current_rw = '1') else
1154
                                                                        "101" when      (mst_trn_current_node_read_reg_enable(5) = '1' and mst_trn_current_rw = '0') or
1155
                                                                                                        (mst_trn_current_node_write_reg_enable(5) = '1' and mst_trn_current_rw = '1') else
1156
                                                                        "100" when      (mst_trn_current_node_read_reg_enable(4) = '1' and mst_trn_current_rw = '0') or
1157
                                                                                                        (mst_trn_current_node_write_reg_enable(4) = '1' and mst_trn_current_rw = '1') else
1158
                                                                        "011" when      (mst_trn_current_node_read_reg_enable(3) = '1' and mst_trn_current_rw = '0') or
1159
                                                                                                        (mst_trn_current_node_write_reg_enable(3) = '1' and mst_trn_current_rw = '1') else
1160
                                                                        "010" when      (mst_trn_current_node_read_reg_enable(2) = '1' and mst_trn_current_rw = '0') or
1161
                                                                                                        (mst_trn_current_node_write_reg_enable(2) = '1' and mst_trn_current_rw = '1') else
1162
                                                                        "001" when      (mst_trn_current_node_read_reg_enable(1) = '1' and mst_trn_current_rw = '0') or
1163
                                                                                                        (mst_trn_current_node_write_reg_enable(1) = '1' and mst_trn_current_rw = '1') else
1164
                                                                        "000";
1165
 
1166
        mst_trn_current_reg_ok <= '0' when mst_trn_current_reg = "000" and not ((mst_trn_current_node_read_reg_enable(0) = '1' and mst_trn_current_rw = '0') or
1167
                                                                                                                                                                                                        (mst_trn_current_node_write_reg_enable(0) = '1' and mst_trn_current_rw = '1')) else
1168
                                                        '1';
1169
 
1170
 
1171
        mst_rec_current_reg <= "111" when       (mst_rec_current_node_read_reg_enable(7) = '1' and mst_rec_current_rw = '0') or
1172
                                                                                                        (mst_rec_current_node_write_reg_enable(7) = '1' and mst_rec_current_rw = '1') else
1173
                                                                        "110" when      (mst_rec_current_node_read_reg_enable(6) = '1' and mst_rec_current_rw = '0') or
1174
                                                                                                        (mst_rec_current_node_write_reg_enable(6) = '1' and mst_rec_current_rw = '1') else
1175
                                                                        "101" when      (mst_rec_current_node_read_reg_enable(5) = '1' and mst_rec_current_rw = '0') or
1176
                                                                                                        (mst_rec_current_node_write_reg_enable(5) = '1' and mst_rec_current_rw = '1') else
1177
                                                                        "100" when      (mst_rec_current_node_read_reg_enable(4) = '1' and mst_rec_current_rw = '0') or
1178
                                                                                                        (mst_rec_current_node_write_reg_enable(4) = '1' and mst_rec_current_rw = '1') else
1179
                                                                        "011" when      (mst_rec_current_node_read_reg_enable(3) = '1' and mst_rec_current_rw = '0') or
1180
                                                                                                        (mst_rec_current_node_write_reg_enable(3) = '1' and mst_rec_current_rw = '1') else
1181
                                                                        "010" when      (mst_rec_current_node_read_reg_enable(2) = '1' and mst_rec_current_rw = '0') or
1182
                                                                                                        (mst_rec_current_node_write_reg_enable(2) = '1' and mst_rec_current_rw = '1') else
1183
                                                                        "001" when      (mst_rec_current_node_read_reg_enable(1) = '1' and mst_rec_current_rw = '0') or
1184
                                                                                                        (mst_rec_current_node_write_reg_enable(1) = '1' and mst_rec_current_rw = '1') else
1185
                                                                        "000";
1186
 
1187
        mst_rec_current_reg_ok <= '0' when mst_rec_current_reg = "000" and not ((mst_rec_current_node_read_reg_enable(0) = '1' and mst_rec_current_rw = '0') or
1188
                                                                                                                                                                                                        (mst_rec_current_node_write_reg_enable(0) = '1' and mst_rec_current_rw = '1')) else
1189
                                                        '1';
1190
 
1191
end Behavioral;
1192
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.