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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_port_processor_control.vhd] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 42 lmaarsen
--------------------------------------------------------------------------------
2
----                                                                        ----
3
---- Ethernet Switch on Configurable Logic IP Core                          ----
4
----                                                                        ----
5
---- This file is part of the ESoCL project                                 ----
6
---- http://www.opencores.org/cores/esoc/                                   ----
7
----                                                                        ----
8
---- Description: see design description ESoCL_dd_71022001.pdf              ----
9
----                                                                        ----
10
---- To Do: see roadmap description ESoCL_dd_71022001.pdf                   ----
11
----        and/or release bulleting ESoCL_rb_71022001.pdf                  ----
12
----                                                                        ----
13
---- Author(s): L.Maarsen                                                   ----
14
---- Bert Maarsen, lmaarsen@opencores.org                                   ----
15
----                                                                        ----
16
--------------------------------------------------------------------------------
17
----                                                                        ----
18
---- Copyright (C) 2009 Authors and OPENCORES.ORG                           ----
19
----                                                                        ----
20
---- This source file may be used and distributed without                   ----
21
---- restriction provided that this copyright statement is not              ----
22
---- removed from the file and that any derivative work contains            ----
23
---- the original copyright notice and the associated disclaimer.           ----
24
----                                                                        ----
25
---- This source file is free software; you can redistribute it             ----
26
---- and/or modify it under the terms of the GNU Lesser General             ----
27
---- Public License as published by the Free Software Foundation;           ----
28
---- either version 2.1 of the License, or (at your option) any             ----
29
---- later version.                                                         ----
30
----                                                                        ----
31
---- This source is distributed in the hope that it will be                 ----
32
---- useful, but WITHOUT ANY WARRANTY; without even the implied             ----
33
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR                ----
34
---- PURPOSE. See the GNU Lesser General Public License for more            ----
35
---- details.                                                               ----
36
----                                                                        ----
37
---- You should have received a copy of the GNU Lesser General              ----
38
---- Public License along with this source; if not, download it             ----
39
---- from http://www.opencores.org/lgpl.shtml                               ----
40
----                                                                        ----
41
--------------------------------------------------------------------------------
42
-- Object        : Entity work.esoc_port_processor_control
43
-- Last modified : Mon Apr 14 12:49:26 2014.
44
--------------------------------------------------------------------------------
45
 
46
 
47
 
48
library ieee, std, work;
49
use ieee.std_logic_1164.all;
50
use std.textio.all;
51
use ieee.numeric_std.all;
52
use work.package_esoc_configuration.all;
53
 
54
entity esoc_port_processor_control is
55
  generic(
56
    esoc_port_nr : integer := 0);
57
  port(
58
    clk_control             : in     std_logic;
59
    clk_data                : in     std_logic;
60
    clk_search              : in     std_logic;
61
    ctrl_address            : in     std_logic_vector(15 downto 0);
62
    ctrl_rd                 : in     std_logic;
63
    ctrl_rddata             : out    std_logic_vector(31 downto 0);
64
    ctrl_vlan_id            : out    std_logic_vector(11 downto 0);
65
    ctrl_vlan_id_member_in  : in     std_logic_vector(0 downto 0);
66
    ctrl_vlan_id_member_out : out    std_logic_vector(0 downto 0);
67
    ctrl_vlan_id_wr         : out    std_logic;
68
    ctrl_wait               : out    std_logic;
69
    ctrl_wr                 : in     std_logic;
70
    ctrl_wrdata             : in     std_logic_vector(31 downto 0);
71
    inbound_done_cnt        : in     std_logic;
72
    inbound_drop_cnt        : in     std_logic;
73
    outbound_done_cnt       : in     std_logic;
74
    outbound_drop_cnt       : in     std_logic;
75
    reset                   : in     STD_LOGIC := '0';
76
    search_done_cnt         : in     std_logic;
77
    search_drop_cnt         : in     std_logic);
78
end entity esoc_port_processor_control;
79
 
80
--------------------------------------------------------------------------------
81
-- Object        : Architecture work.esoc_port_processor_control.esoc_port_processor_control
82
-- Last modified : Mon Apr 14 12:49:26 2014.
83
--------------------------------------------------------------------------------
84
 
85
 
86
architecture esoc_port_processor_control of esoc_port_processor_control is
87
 
88
---------------------------------------------------------------------------------------------------------------
89
-- registers
90
---------------------------------------------------------------------------------------------------------------
91
constant reg_port_proc_vlan_control_add: integer                                := 407;
92
 
93
constant reg_port_proc_outbound_done_count_add: integer                         := 406;
94
signal reg_port_proc_outbound_done_count: std_logic_vector(31 downto 0);
95
signal reg_port_proc_outbound_done_count_i: std_logic_vector(31 downto 0);
96
constant reg_port_proc_outbound_done_count_rst: std_logic_vector(31 downto 0)   := X"00000000";
97
 
98
constant reg_port_proc_outbound_drop_count_add: integer                         := 405;
99
signal reg_port_proc_outbound_drop_count: std_logic_vector(31 downto 0);
100
signal reg_port_proc_outbound_drop_count_i: std_logic_vector(31 downto 0);
101
constant reg_port_proc_outbound_drop_count_rst: std_logic_vector(31 downto 0)   := X"00000000";
102
 
103
constant reg_port_proc_inbound_done_count_add: integer                          := 404;
104
signal reg_port_proc_inbound_done_count: std_logic_vector(31 downto 0);
105
signal reg_port_proc_inbound_done_count_i: std_logic_vector(31 downto 0);
106
constant reg_port_proc_inbound_done_count_rst: std_logic_vector(31 downto 0)    := X"00000000";
107
 
108
constant reg_port_proc_inbound_drop_count_add: integer                          := 403;
109
signal reg_port_proc_inbound_drop_count: std_logic_vector(31 downto 0);
110
signal reg_port_proc_inbound_drop_count_i: std_logic_vector(31 downto 0);
111
constant reg_port_proc_inbound_drop_count_rst: std_logic_vector(31 downto 0)    := X"00000000";
112
 
113
constant reg_port_proc_search_done_count_add: integer                           := 402;
114
signal reg_port_proc_search_done_count: std_logic_vector(31 downto 0);
115
signal reg_port_proc_search_done_count_i: std_logic_vector(31 downto 0);
116
constant reg_port_proc_search_done_count_rst: std_logic_vector(31 downto 0)     := X"00000000";
117
 
118
constant reg_port_proc_search_drop_count_add: integer                           := 401;
119
signal reg_port_proc_search_drop_count: std_logic_vector(31 downto 0);
120
signal reg_port_proc_search_drop_count_i: std_logic_vector(31 downto 0);
121
constant reg_port_proc_search_drop_count_rst: std_logic_vector(31 downto 0)     := X"00000000";
122
 
123
constant reg_port_proc_stat_ctrl_add: integer                                   := 400;
124
signal reg_port_proc_stat_ctrl: std_logic_vector(31 downto 0);
125
constant reg_port_proc_stat_ctrl_rst: std_logic_vector(31 downto 0)             := X"00000000";
126
 
127
---------------------------------------------------------------------------------------------------------------
128
-- signals
129
---------------------------------------------------------------------------------------------------------------
130
signal search_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
131
signal search_cnt_update_sync    : std_logic_vector(esoc_meta_ffs-1 downto 0);
132
signal search_cnt_update         : std_logic;
133
signal search_cnt_update_ack     : std_logic;
134
 
135
signal inbound_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
136
signal inbound_cnt_update_sync    : std_logic_vector(esoc_meta_ffs-1 downto 0);
137
signal inbound_cnt_update         : std_logic;
138
signal inbound_cnt_update_ack     : std_logic;
139
 
140
signal outbound_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
141
signal outbound_cnt_update_sync    : std_logic_vector(esoc_meta_ffs-1 downto 0);
142
signal outbound_cnt_update         : std_logic;
143
signal outbound_cnt_update_ack     : std_logic;
144
 
145
signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0);
146
signal ctrl_wait_i: std_logic;
147
signal ctrl_bus_enable: std_logic;
148
 
149
begin
150
 
151
--=============================================================================================================
152
-- Process                : access registers when addressed or provide data  to the ctrl_rddata_i bus
153
-- Description  : 
154
--=============================================================================================================    
155
registers:  process(clk_control, reset)
156
            begin
157
              if reset = '1' then
158
                reg_port_proc_stat_ctrl <= reg_port_proc_stat_ctrl_rst;
159
 
160
                ctrl_vlan_id <= (others => '0');
161
                ctrl_vlan_id_member_out <= (others => '0');
162
                ctrl_vlan_id_wr <= '0';
163
 
164
                ctrl_rddata_i   <= (others => '0');
165
                ctrl_wait_i     <= '1';
166
                ctrl_bus_enable <= '0';
167
 
168
              elsif clk_control'event and clk_control = '1' then
169
                ctrl_wait_i     <= '1';
170
                ctrl_bus_enable <= '0';
171
                ctrl_vlan_id_wr <= '0';
172
 
173
                -- continu if memory space of this entity is addressed
174
                if (to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_proc_base) and (to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_proc_base + esoc_port_proc_size) then
175
                  -- claim the bus for ctrl_wait and ctrl_rddata
176
                  ctrl_bus_enable <= '1';
177
 
178
                  -- 
179
                        -- READ CYCLE started, unit addressed?
180
                        --
181
                        if ctrl_rd = '1' then
182
                                -- Check register address and provide data when addressed
183
                          case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
184
                      when reg_port_proc_vlan_control_add           =>  ctrl_rddata_i <= (others => '0');
185
                                                                        ctrl_rddata_i(30 downto 30) <= ctrl_vlan_id_member_in;
186
                                                                        ctrl_wait_i <= '0';
187
 
188
                      when reg_port_proc_outbound_done_count_add    =>  if outbound_cnt_update_ack = '1' then
189
                                                                          ctrl_rddata_i <= reg_port_proc_outbound_done_count;
190
                                                                          ctrl_wait_i <= '0';
191
                                                                        end if;
192
 
193
                      when reg_port_proc_outbound_drop_count_add    =>  if outbound_cnt_update_ack = '1' then
194
                                                                          ctrl_rddata_i <= reg_port_proc_outbound_drop_count;
195
                                                                          ctrl_wait_i <= '0';
196
                                                                        end if;
197
 
198
                      when reg_port_proc_inbound_done_count_add     =>  if inbound_cnt_update_ack = '1' then
199
                                                                          ctrl_rddata_i <= reg_port_proc_inbound_done_count;
200
                                                                          ctrl_wait_i <= '0';
201
                                                                        end if;
202
 
203
                      when reg_port_proc_inbound_drop_count_add     =>  if inbound_cnt_update_ack = '1' then
204
                                                                          ctrl_rddata_i <= reg_port_proc_inbound_drop_count;
205
                                                                          ctrl_wait_i <= '0';
206
                                                                        end if;
207
 
208
                      when reg_port_proc_search_done_count_add      =>  if search_cnt_update_ack = '1' then
209
                                                                          ctrl_rddata_i <= reg_port_proc_search_done_count;
210
                                                                          ctrl_wait_i <= '0';
211
                                                                        end if;
212
 
213
                      when reg_port_proc_search_drop_count_add      =>  if search_cnt_update_ack = '1' then
214
                                                                          ctrl_rddata_i <= reg_port_proc_search_drop_count;
215
                                                                          ctrl_wait_i <= '0';
216
                                                                        end if;
217
 
218
                      when reg_port_proc_stat_ctrl_add              =>  ctrl_rddata_i <= reg_port_proc_stat_ctrl;
219
                                                                        ctrl_wait_i <= '0';
220
 
221
                      when others                                   =>  NULL;
222
                    end case;
223
 
224
                  --
225
                  -- WRITE CYCLE started, unit addressed?
226
                  --
227
                  elsif ctrl_wr = '1' then
228
                        -- Check address and accept data when addressed
229
                        case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
230
                      when reg_port_proc_vlan_control_add           =>  ctrl_vlan_id_wr  <= ctrl_wrdata(31);
231
                                                                        ctrl_vlan_id_member_out <= ctrl_wrdata(30 downto 30);
232
                                                                        ctrl_vlan_id <= ctrl_wrdata(11 downto 0);
233
                                                                        ctrl_wait_i <= '0';
234
 
235
                      when reg_port_proc_stat_ctrl_add              =>  reg_port_proc_stat_ctrl <= ctrl_wrdata;
236
                                                                        ctrl_wait_i <= '0';
237
 
238
                      when others                                   =>  NULL;
239
                    end case;
240
                  end if;
241
                end if;
242
              end if;
243
            end process;
244
 
245
            -- Create tristate outputs
246
            ctrl_wait   <= ctrl_wait_i    when ctrl_bus_enable = '1' else 'Z';
247
            ctrl_rddata <= ctrl_rddata_i  when ctrl_bus_enable = '1' else (others => 'Z');
248
 
249
--=============================================================================================================
250
-- Process                : Update counters and transfer values from search clock domain to control clock domain
251
-- Description  : 
252
--=============================================================================================================    
253
sync1a: process(clk_search, reset)
254
        begin
255
          if reset = '1' then
256
            reg_port_proc_search_done_count_i <= reg_port_proc_search_done_count_rst;
257
            reg_port_proc_search_drop_count_i <= reg_port_proc_search_drop_count_rst;
258
 
259
          elsif clk_search'event and clk_search = '1' then
260
            -- Update DONE counter
261
            if search_done_cnt = '1' then
262
              reg_port_proc_search_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_search_done_count_i)) + 1,reg_port_proc_search_done_count_i'length));
263
            end if;
264
 
265
            -- Update DROP counter
266
            if search_drop_cnt = '1' then
267
              reg_port_proc_search_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_search_drop_count_i)) + 1,reg_port_proc_search_drop_count_i'length));
268
            end if;
269
          end if;
270
        end process;
271
 
272
sync1b: process(clk_search, reset)
273
        begin
274
          if reset = '1' then
275
            search_cnt_update  <= '0';
276
            search_cnt_update_ack_sync <= (others => '0');
277
            reg_port_proc_search_done_count <= reg_port_proc_search_done_count_rst;
278
            reg_port_proc_search_drop_count <= reg_port_proc_search_drop_count_rst;
279
 
280
          elsif clk_search'event and clk_search = '1' then
281
            -- synchronise update acknowledge indication
282
            search_cnt_update_ack_sync <= search_cnt_update_ack & search_cnt_update_ack_sync(search_cnt_update_ack_sync'high downto 1);
283
 
284
            -- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
285
            if search_cnt_update = '0' and search_cnt_update_ack_sync(0) = '0' then
286
              search_cnt_update <= '1';
287
              reg_port_proc_search_done_count <= reg_port_proc_search_done_count_i;
288
              reg_port_proc_search_drop_count <= reg_port_proc_search_drop_count_i;
289
 
290
            -- finalize update when acknowledge is received
291
            elsif search_cnt_update_ack_sync(0) = '1' then
292
              search_cnt_update <= '0';
293
            end if;
294
          end if;
295
        end process;
296
 
297
sync1c: process(clk_control, reset)
298
        begin
299
          if reset = '1' then
300
            search_cnt_update_sync  <= (others => '0');
301
 
302
          -- synchronise counter update indication
303
          elsif clk_control'event and clk_control = '1' then
304
            search_cnt_update_sync <= search_cnt_update & search_cnt_update_sync(search_cnt_update_sync'high downto 1);
305
          end if;
306
        end process;
307
 
308
        -- send update acknowledge
309
        search_cnt_update_ack <=  search_cnt_update_sync(0);
310
 
311
--=============================================================================================================
312
-- Process                : Update counters and transfer values from data clock domain to control clock domain
313
-- Description  : 
314
--=============================================================================================================    
315
sync2a: process(clk_data, reset)
316
        begin
317
          if reset = '1' then
318
            reg_port_proc_inbound_done_count_i <= reg_port_proc_inbound_done_count_rst;
319
            reg_port_proc_inbound_drop_count_i <= reg_port_proc_inbound_drop_count_rst;
320
 
321
          elsif clk_data'event and clk_data = '1' then
322
            -- Update DONE counter
323
            if inbound_done_cnt = '1' then
324
              reg_port_proc_inbound_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_inbound_done_count_i)) + 1,reg_port_proc_inbound_done_count_i'length));
325
            end if;
326
 
327
            -- Update DROP counter
328
            if inbound_drop_cnt = '1' then
329
              reg_port_proc_inbound_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_inbound_drop_count_i)) + 1,reg_port_proc_inbound_drop_count_i'length));
330
            end if;
331
          end if;
332
        end process;
333
 
334
sync2b: process(clk_data, reset)
335
        begin
336
          if reset = '1' then
337
            inbound_cnt_update  <= '0';
338
            inbound_cnt_update_ack_sync <= (others => '0');
339
            reg_port_proc_inbound_done_count <= reg_port_proc_inbound_done_count_rst;
340
            reg_port_proc_inbound_drop_count <= reg_port_proc_inbound_drop_count_rst;
341
 
342
          elsif clk_data'event and clk_data = '1' then
343
            -- synchronise update acknowledge indication
344
            inbound_cnt_update_ack_sync <= inbound_cnt_update_ack & inbound_cnt_update_ack_sync(inbound_cnt_update_ack_sync'high downto 1);
345
 
346
            -- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
347
            if inbound_cnt_update = '0' and inbound_cnt_update_ack_sync(0) = '0' then
348
              inbound_cnt_update <= '1';
349
              reg_port_proc_inbound_done_count <= reg_port_proc_inbound_done_count_i;
350
              reg_port_proc_inbound_drop_count <= reg_port_proc_inbound_drop_count_i;
351
 
352
            -- finalize update when acknowledge is received
353
            elsif inbound_cnt_update_ack_sync(0) = '1' then
354
              inbound_cnt_update <= '0';
355
            end if;
356
          end if;
357
        end process;
358
 
359
sync2c: process(clk_control, reset)
360
        begin
361
          if reset = '1' then
362
            inbound_cnt_update_sync  <= (others => '0');
363
 
364
          -- synchronise counter update indication
365
          elsif clk_control'event and clk_control = '1' then
366
            inbound_cnt_update_sync <= inbound_cnt_update & inbound_cnt_update_sync(inbound_cnt_update_sync'high downto 1);
367
          end if;
368
        end process;
369
 
370
        -- send update acknowledge
371
        inbound_cnt_update_ack <=  inbound_cnt_update_sync(0);
372
 
373
--=============================================================================================================
374
-- Process                : Update counters and transfer values from data clock domain to control clock domain
375
-- Description  : 
376
--=============================================================================================================    
377
sync3a: process(clk_data, reset)
378
        begin
379
          if reset = '1' then
380
            reg_port_proc_outbound_done_count_i <= reg_port_proc_outbound_done_count_rst;
381
            reg_port_proc_outbound_drop_count_i <= reg_port_proc_outbound_drop_count_rst;
382
 
383
          elsif clk_data'event and clk_data = '1' then
384
            -- Update DONE counter
385
            if outbound_done_cnt = '1' then
386
              reg_port_proc_outbound_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_outbound_done_count_i)) + 1,reg_port_proc_outbound_done_count_i'length));
387
            end if;
388
 
389
            -- Update DROP counter
390
            if outbound_drop_cnt = '1' then
391
              reg_port_proc_outbound_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_outbound_drop_count_i)) + 1,reg_port_proc_outbound_drop_count_i'length));
392
            end if;
393
          end if;
394
        end process;
395
 
396
sync3b: process(clk_data, reset)
397
        begin
398
          if reset = '1' then
399
            outbound_cnt_update  <= '0';
400
            outbound_cnt_update_ack_sync <= (others => '0');
401
            reg_port_proc_outbound_done_count <= reg_port_proc_outbound_done_count_rst;
402
            reg_port_proc_outbound_drop_count <= reg_port_proc_outbound_drop_count_rst;
403
 
404
          elsif clk_data'event and clk_data = '1' then
405
            -- synchronise update acknowledge indication
406
            outbound_cnt_update_ack_sync <= outbound_cnt_update_ack & outbound_cnt_update_ack_sync(outbound_cnt_update_ack_sync'high downto 1);
407
 
408
            -- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
409
            if outbound_cnt_update = '0' and outbound_cnt_update_ack_sync(0) = '0' then
410
              outbound_cnt_update <= '1';
411
              reg_port_proc_outbound_done_count <= reg_port_proc_outbound_done_count_i;
412
              reg_port_proc_outbound_drop_count <= reg_port_proc_outbound_drop_count_i;
413
 
414
            -- finalize update when acknowledge is received
415
            elsif outbound_cnt_update_ack_sync(0) = '1' then
416
              outbound_cnt_update <= '0';
417
            end if;
418
          end if;
419
        end process;
420
 
421
sync3c: process(clk_control, reset)
422
        begin
423
          if reset = '1' then
424
            outbound_cnt_update_sync  <= (others => '0');
425
 
426
          -- synchronise counter update indication
427
          elsif clk_control'event and clk_control = '1' then
428
            outbound_cnt_update_sync <= outbound_cnt_update & outbound_cnt_update_sync(outbound_cnt_update_sync'high downto 1);
429
          end if;
430
        end process;
431
 
432
        -- send update acknowledge
433
        outbound_cnt_update_ack <=  outbound_cnt_update_sync(0);
434
end architecture esoc_port_processor_control ; -- of esoc_port_processor_control
435
 

powered by: WebSVN 2.1.0

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