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 |
|
|
|