Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
wr-switch-hdl
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
white-rabbit
wr-switch-hdl
Commits
cabc9d24
Commit
cabc9d24
authored
Apr 19, 2012
by
Maciej Lipinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
swcore: added resource manager for MMU resources (forgot to include it into previous commits)
parent
8f7bad99
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
278 additions
and
0 deletions
+278
-0
swc_alloc_resource_manager.vhd
modules/wrsw_swcore/swc_alloc_resource_manager.vhd
+278
-0
No files found.
modules/wrsw_swcore/swc_alloc_resource_manager.vhd
0 → 100644
View file @
cabc9d24
-------------------------------------------------------------------------------
-- Title : Alloc Resource Manager
-- Project : WhiteRabbit switch
-------------------------------------------------------------------------------
-- File : swc_alloc_resource_manager.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-Co-HT
-- Created : 2012-03-30
-- Last update: 2012-03-30
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-- The available pool of pages can be divided into different resources, e.g:
-- * there will be a reserved number of pages for WR High Priority Traffic
-- * there will be a reserved number of pages for "standard" traffic
--
-- This module manages the count of the useage of different resources:
--
-- The pool of all pages is devided into [resource_num]:
-- 1) [resource_num = 0]
-- unknown resource: unknown_res = (port_number*(max_frame_size/(2*page_size)+2*port_number), where:
-- max_frame_size is in bytes, i.e.: 1518 + oob
-- 2*page_size is in bytes, i.e.: page_size is in 16bits
-- (word written to FBM), so 2 bytes
-- (max_frame_size/(2*page_size) is the number of pgaes used by max size frame
-- 2*port_number is to be able to allocate in advance first page
-- (pckstart_pageaddr) and intermediate page
-- (pckinter_pageaddr) for each port
--
-- [requested number of separate resources, e.g]
-- 2) [resource_num = 1]
-- High priority traffic (e.g broadcast & 7th prio), e.g.: prio_res = page_num -(unknown_res/2)
-- 3) [resource_num = 2]
-- Standard traffic, e.g.: prio_res = page_num -(unknown_res/2)
--
-- If the resource is not known during allocation (which is very likely because we allocte
-- pages in advance), the default resource number (unknown resource, [resource_num = 0])
-- shall be used.
--
-- The information about the resource needs to be stored with the first page of the frame, the
-- inter_pages does not need to store this info
--
-- If page is allocated and the resource number is known, it shall be indicated and an appropriate
-- counter will be changes
--
-- If we make usecnt, it is used only for the first page of the frame. during usecnt also
-- resource_cnt is done, which includes:
-- * resource num - to which resource a provided page should be allocated
-- * resource_cnt - how many pages from the unknown resource ([resource_num = 0]) shall be
-- allocated to the new resource
--
-- In the input block the usecnt is set only for the first page, so this is also the "must" for
-- resource number
--
-- The deallocating process (when deallocating the last usecnt), will receive the information that :
-- * the usecnt is 0 (last_usecnt)
-- * the resource number,
-- so, when freeing the rest of the frame, it will indicate the resource number.
--
-- When freeing page, two sources of resource number can be used:
-- * the one stored in the memory (when res_num_valid_i = LOW) - this should be used for
-- the first page of the frame
-- * the one provided by external soruce (when res_num_valid_i = HIGH) - this should be used for
-- the inter-pages of the frame
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012, Maciej Lipinski / CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-03-30 1.0 mlipinsk Created
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
ieee
.
math_real
.
CEIL
;
use
ieee
.
math_real
.
FLOOR
;
use
work
.
swc_swcore_pkg
.
all
;
use
work
.
genram_pkg
.
all
;
entity
swc_alloc_resource_manager
is
generic
(
--
g_num_ports
:
integer
;
-- max pck size
g_max_pck_size
:
integer
;
-- page size
g_page_size
:
integer
;
-- number of pages in the allocator pool - total number of pages in all resource pools
g_total_num_pages
:
integer
:
=
2048
;
g_total_num_pages_width
:
integer
:
=
11
;
-- here we define the number of pages in a special resource pool [resource = 1]
g_special_res_num_pages
:
integer
:
=
248
;
-- number of separate resources, the number of areas the page pool is divided is always one more
-- (g_resource_num + 1) since we need to have a number of "unknown source" pages
g_resource_num
:
integer
:
=
3
;
-- this include 1 for unknown
g_resource_num_width
:
integer
:
=
2
);
port
(
clk_i
:
in
std_logic
;
-- clock & reset
rst_n_i
:
in
std_logic
;
-- indicates the resource to which the page shall be allocated
resource_i
:
in
std_logic_vector
(
g_resource_num_width
-1
downto
0
);
-- indicate that is allocated
alloc_i
:
in
std_logic
;
-- freeing (completely) page
free_i
:
in
std_logic
;
-- setting resource cnt to already allocated pages (strobe)
rescnt_set_i
:
in
std_logic
;
-- the number to be set
rescnt_page_num_i
:
in
std_logic_vector
(
g_total_num_pages_width
-1
downto
0
);
res_full_o
:
out
std_logic_vector
(
g_resource_num
-
1
downto
0
);
res_almost_full_o
:
out
std_logic_vector
(
g_resource_num
-
1
downto
0
)
);
end
swc_alloc_resource_manager
;
architecture
syn
of
swc_alloc_resource_manager
is
-- the number of pages reserved for unknown source (happens because we allocate pages in advance
-- we don't know RTU decision when we do that, and sometimes we store pages before receiving
-- RTU decision). It should be enough for all the ports to receive single max_size frame and
-- all ports to be ready to receive new pcks
constant
c_unknown_res_page_num
:
integer
:
=
integer
(
CEIL
(
real
(
g_num_ports
*
(
g_max_pck_size
/
g_page_size
))))
+
integer
(
g_num_ports
*
2
)
;
constant
c_special_res_page_num
:
integer
:
=
g_special_res_num_pages
;
-- we can have as many resources as we want, the division of the page pool is following:
-- 0) unknow resources : number of pages = c_unknown_res_page_num
-- 1) special resources : number of pages = c_special_res_page_num
-- 2) normal resources 1 : number of pages = (total - unknown - special)/(resource_num - 1)
-- 3) normal resources 2 : number of pages = (total - unknown - special)/(resource_num - 1)
-- [...]
constant
c_normal_res_page_num
:
integer
:
=
integer
(
FLOOR
(
real
((
g_total_num_pages
-
c_unknown_res_page_num
-
c_special_res_page_num
)
/
(
g_resource_num
-1
))));
-- tells how many pages we need to have for a single max ethernet frame to be stored in FBM
constant
c_page_num_for_max_pck
:
integer
:
=
integer
(
CEIL
(
real
(
g_max_pck_size
/
g_page_size
)));
type
t_resource
is
record
cnt
:
unsigned
(
g_total_num_pages_width
-1
downto
0
);
full
:
std_logic
;
almost_full
:
std_logic
;
end
record
;
type
t_resource_array
is
array
(
integer
range
<>
)
of
t_resource
;
signal
resources
:
t_resource_array
(
g_resource_num
-1
downto
0
);
signal
cur_res
:
integer
range
0
to
g_resource_num
-1
;
-- debugging;
signal
res_page_sum
:
unsigned
(
g_total_num_pages_width
-1
downto
0
);
signal
res_free_blocks
:
unsigned
(
g_total_num_pages_width
-1
downto
0
);
begin
cur_res
<=
to_integer
(
unsigned
(
resource_i
));
process
(
clk_i
)
variable
sum
:
unsigned
(
g_total_num_pages_width
-1
downto
0
);
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
for
i
in
g_resource_num
-1
downto
0
loop
resources
(
i
)
.
cnt
<=
(
others
=>
'0'
);
resources
(
i
)
.
full
<=
'0'
;
resources
(
i
)
.
almost_full
<=
'0'
;
end
loop
;
else
if
(
alloc_i
=
'1'
)
then
resources
(
cur_res
)
.
cnt
<=
resources
(
cur_res
)
.
cnt
+
1
;
elsif
(
free_i
=
'1'
)
then
resources
(
cur_res
)
.
cnt
<=
resources
(
cur_res
)
.
cnt
-
1
;
elsif
(
rescnt_set_i
=
'1'
)
then
-- "resource count set" is used to move a number of pages from "unknown" resources
-- to any other resource pool. Therefore, if the cur_res is different then "unknown" (0),
-- we subtract from unknown pool
resources
(
cur_res
)
.
cnt
<=
resources
(
cur_res
)
.
cnt
+
unsigned
(
rescnt_page_num_i
);
if
(
cur_res
/=
0
)
then
resources
(
0
)
.
cnt
<=
resources
(
0
)
.
cnt
-
unsigned
(
rescnt_page_num_i
);
end
if
;
end
if
;
--------------------- generat ---------------------------------
-- control "unknown" resources
if
(
resources
(
0
)
.
cnt
=
to_unsigned
(
c_unknown_res_page_num
-
1
,
g_total_num_pages_width
-1
))
then
resources
(
0
)
.
full
<=
'1'
;
elsif
(
resources
(
0
)
.
cnt
>
to_unsigned
(
c_unknown_res_page_num
-
c_page_num_for_max_pck
,
g_total_num_pages_width
-1
))
then
resources
(
0
)
.
almost_full
<=
'1'
;
else
resources
(
0
)
.
almost_full
<=
'0'
;
resources
(
0
)
.
full
<=
'0'
;
end
if
;
-- control special resources
if
(
resources
(
1
)
.
cnt
=
to_unsigned
(
c_special_res_page_num
-
1
,
g_total_num_pages_width
-1
))
then
resources
(
1
)
.
full
<=
'1'
;
elsif
(
resources
(
1
)
.
cnt
>
to_unsigned
(
c_special_res_page_num
-
c_page_num_for_max_pck
,
g_total_num_pages_width
-1
))
then
resources
(
1
)
.
almost_full
<=
'1'
;
else
resources
(
1
)
.
almost_full
<=
'0'
;
resources
(
1
)
.
full
<=
'0'
;
end
if
;
-- control "normal" resources
for
i
in
2
to
g_resource_num
-1
loop
if
(
resources
(
i
)
.
cnt
=
to_unsigned
(
c_normal_res_page_num
-
1
,
g_total_num_pages_width
-1
))
then
resources
(
i
)
.
full
<=
'1'
;
elsif
(
resources
(
i
)
.
cnt
>
to_unsigned
(
c_normal_res_page_num
-
c_page_num_for_max_pck
,
g_total_num_pages_width
-1
))
then
resources
(
i
)
.
almost_full
<=
'1'
;
else
resources
(
i
)
.
almost_full
<=
'0'
;
resources
(
i
)
.
full
<=
'0'
;
end
if
;
end
loop
;
------------------------------ debug: ----------------------------------------
sum
:
=
to_unsigned
(
0
,
g_total_num_pages_width
);
for
i
in
0
to
g_resource_num
-1
loop
sum
:
=
sum
+
resources
(
i
)
.
cnt
;
end
loop
;
res_page_sum
<=
sum
;
res_free_blocks
<=
to_unsigned
(
1024
,
g_total_num_pages_width
)
-
sum
;
-------------------------------------------------------------------------------
end
if
;
end
if
;
end
process
;
FULL_OUT
:
for
i
in
0
to
g_resource_num
-1
generate
res_full_o
(
i
)
<=
resources
(
i
)
.
full
;
res_almost_full_o
(
i
)
<=
resources
(
i
)
.
almost_full
;
end
generate
FULL_OUT
;
end
syn
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment