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
6933ea22
Commit
6933ea22
authored
Mar 19, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
swcore: old allocator with fixed RAM models
parent
c2408157
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
326 additions
and
0 deletions
+326
-0
swc_multiport_page_allocator.vhd
...rsw_swcore/old_allocator/swc_multiport_page_allocator.vhd
+326
-0
No files found.
modules/wrsw_swcore/old_allocator/swc_multiport_page_allocator.vhd
0 → 100644
View file @
6933ea22
-------------------------------------------------------------------------------
-- Title : multiport page allocator
-- Project : WhiteRabbit switch
-------------------------------------------------------------------------------
-- File : swc_multiport_page_allocator.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-04-08
-- Last update: 2012-03-19
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
--
-- Copyright (c) 2010 Tomasz Wlostowski, 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-04-08 1.0 twlostow Created
-- 2010-10-11 1.1 mlipinsk comments added !!!!!
-- 2010-10-11 1.1 twlostow changed allocator
-- 2012-02-02 2.0 mlipinsk generic-azed
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
ieee
.
math_real
.
CEIL
;
use
ieee
.
math_real
.
log2
;
library
work
;
use
work
.
swc_swcore_pkg
.
all
;
entity
swc_multiport_page_allocator
is
generic
(
g_page_addr_width
:
integer
;
--:= c_swc_page_addr_width;
g_num_ports
:
integer
;
--:= c_swc_num_ports
g_page_num
:
integer
;
--:= c_swc_packet_mem_num_pages
g_usecount_width
:
integer
--:= c_swc_usecount_width
);
port
(
rst_n_i
:
in
std_logic
;
clk_i
:
in
std_logic
;
alloc_i
:
in
std_logic_vector
(
g_num_ports
-
1
downto
0
);
free_i
:
in
std_logic_vector
(
g_num_ports
-
1
downto
0
);
force_free_i
:
in
std_logic_vector
(
g_num_ports
-
1
downto
0
);
set_usecnt_i
:
in
std_logic_vector
(
g_num_ports
-
1
downto
0
);
alloc_done_o
:
out
std_logic_vector
(
g_num_ports
-
1
downto
0
);
free_done_o
:
out
std_logic_vector
(
g_num_ports
-
1
downto
0
);
force_free_done_o
:
out
std_logic_vector
(
g_num_ports
-
1
downto
0
);
set_usecnt_done_o
:
out
std_logic_vector
(
g_num_ports
-
1
downto
0
);
pgaddr_free_i
:
in
std_logic_vector
(
g_num_ports
*
g_page_addr_width
-
1
downto
0
);
pgaddr_force_free_i
:
in
std_logic_vector
(
g_num_ports
*
g_page_addr_width
-
1
downto
0
);
pgaddr_usecnt_i
:
in
std_logic_vector
(
g_num_ports
*
g_page_addr_width
-
1
downto
0
);
usecnt_i
:
in
std_logic_vector
(
g_num_ports
*
g_usecount_width
-
1
downto
0
);
pgaddr_alloc_o
:
out
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
free_last_usecnt_o
:
out
std_logic_vector
(
g_num_ports
-
1
downto
0
);
nomem_o
:
out
std_logic
);
end
swc_multiport_page_allocator
;
architecture
syn
of
swc_multiport_page_allocator
is
constant
c_arbiter_vec_width
:
integer
:
=
4
*
g_num_ports
;
constant
c_arbiter_vec_width_log2
:
integer
:
=
integer
(
CEIL
(
LOG2
(
real
(
4
*
g_num_ports
-1
))));
signal
pg_alloc
:
std_logic
;
signal
pg_free
:
std_logic
;
signal
pg_force_free
:
std_logic
;
signal
pg_set_usecnt
:
std_logic
;
signal
pg_usecnt
:
std_logic_vector
(
g_usecount_width
-1
downto
0
);
signal
pg_addr_alloc
:
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
signal
pg_addr_free
:
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
signal
pg_addr_force_free
:
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
signal
pg_addr_usecnt
:
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
signal
pg_addr
:
std_logic_vector
(
g_page_addr_width
-1
downto
0
);
signal
pg_addr_valid
:
std_logic
;
-- used by symulation , don't remove
-- signal pg_idle : std_logic;
signal
pg_done
:
std_logic
;
signal
pg_nomem
:
std_logic
;
-- vector of requests to the Round Robin arbiter
-- both alloc and free request
-- the address of the bit :
-- * representing alloc request - is even [i*2]
-- * representing free request - is odd [i*2 + 1]
signal
request_vec
:
std_logic_vector
(
c_arbiter_vec_width
-1
downto
0
);
-- address of the request which has been granted access
-- to page alloation core. the LSB bit indicates the kind of
-- operation:
-- * '0' - even address, so alloc operation
-- * '1' - odd address, so free operation
signal
request_grant
:
std_logic_vector
(
c_arbiter_vec_width_log2
-1
downto
0
);
-- used to indicate to the RR arbiter to start
-- processing next request,
signal
request_next
:
std_logic
;
-- indicates that the granted request is valid
signal
request_grant_valid
:
std_logic
;
-- the number of the port to which request has been granted
signal
in_sel
:
integer
range
0
to
g_num_ports
-1
;
-- >????
signal
in_sel_prev
:
integer
range
0
to
g_num_ports
-1
;
-- ??
signal
af_prev
:
std_logic
;
-- OR of two different free_i signals, they are functionally exclusive
-- which means that it's not possible for them to be high simultaneously
signal
any_free_i
:
std_logic
;
-- indicates that an alloc has been performed successfully for the
-- given port. Used to prevent considering the currently process
-- port for request to RR arbiter
signal
alloc_done_feedback
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
alloc_done
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
-- indicates that an free has been performed successfully for the
-- given port. Used to prevent considering the currently process
-- port for request to RR arbiter
signal
free_done_feedback
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
free_done
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
free_last_usecnt
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
free_last_usecnt_feedback
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
force_free_done_feedback
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
force_free_done
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
signal
set_usecnt_done_feedback
:
std_logic_vector
(
g_num_ports
-1
downto
0
);
-- signal set_usecnt_done : std_logic_vector(g_num_ports-1 downto 0);
signal
pg_free_last_usecnt
:
std_logic
;
begin
-- syn
-- one allocator/deallocator for all ports
--ALLOC_CORE : swc_page_allocator_new -- tom's new allocator, not debugged, looses pages :(
ALLOC_CORE
:
swc_page_allocator
generic
map
(
g_num_pages
=>
g_page_num
,
g_page_addr_width
=>
g_page_addr_width
,
g_num_ports
=>
g_num_ports
,
g_usecount_width
=>
g_usecount_width
)
port
map
(
clk_i
=>
clk_i
,
rst_n_i
=>
rst_n_i
,
alloc_i
=>
pg_alloc
,
free_i
=>
pg_free
,
free_last_usecnt_o
=>
pg_free_last_usecnt
,
force_free_i
=>
pg_force_free
,
set_usecnt_i
=>
pg_set_usecnt
,
usecnt_i
=>
pg_usecnt
,
pgaddr_i
=>
pg_addr
,
--pg_addr_free,
pgaddr_o
=>
pg_addr_alloc
,
-- pgaddr_valid_o => pg_addr_valid,
-- idle_o => open, --pg_idle,
done_o
=>
pg_done
,
nomem_o
=>
pg_nomem
);
-- creating request vector with 'alloc' requests at even addresses
-- and 'free' requests on odd addresses. The condition prevents
-- considertion of actually processed port for the request to arbiter
gen_request_vec
:
for
i
in
0
to
g_num_ports
-
1
generate
request_vec
(
4
*
i
+
0
)
<=
alloc_i
(
i
)
and
(
not
(
alloc_done_feedback
(
i
)
or
alloc_done
(
i
)))
and
(
not
pg_nomem
);
request_vec
(
4
*
i
+
1
)
<=
free_i
(
i
)
and
(
not
(
free_done_feedback
(
i
)
or
free_done
(
i
)));
request_vec
(
4
*
i
+
2
)
<=
set_usecnt_i
(
i
)
and
(
not
(
set_usecnt_done_feedback
(
i
)));
-- or set_usecnt_done(i)));
request_vec
(
4
*
i
+
3
)
<=
force_free_i
(
i
)
and
(
not
(
force_free_done_feedback
(
i
)
or
force_free_done
(
i
)));
end
generate
gen_request_vec
;
-- Round Robin arbiter, quite specific for the usage, since it has the "next"
-- input. It is used to start processing next request well in advance, to prevent
-- unnecessary delays
ARB
:
swc_rr_arbiter
generic
map
(
g_num_ports
=>
c_arbiter_vec_width
,
g_num_ports_log2
=>
c_arbiter_vec_width_log2
)
port
map
(
clk_i
=>
clk_i
,
rst_n_i
=>
rst_n_i
,
next_i
=>
request_next
,
request_i
=>
request_vec
,
grant_o
=>
request_grant
,
grant_valid_o
=>
request_grant_valid
);
-- port number to which request has been granted.
in_sel
<=
to_integer
(
unsigned
(
request_grant
(
request_grant
'length
-1
downto
2
)));
-- if the granted request has even address (LSB = '0'), it means that
-- the request was of 'alloc' type
pg_alloc
<=
'1'
when
((
request_grant
(
1
downto
0
)
=
b"00"
)
and
request_grant_valid
=
'1'
)
else
'0'
;
pg_free
<=
'1'
when
((
request_grant
(
1
downto
0
)
=
b"01"
)
and
request_grant_valid
=
'1'
)
else
'0'
;
pg_set_usecnt
<=
'1'
when
((
request_grant
(
1
downto
0
)
=
b"10"
)
and
request_grant_valid
=
'1'
)
else
'0'
;
pg_force_free
<=
'1'
when
((
request_grant
(
1
downto
0
)
=
b"11"
)
and
request_grant_valid
=
'1'
)
else
'0'
;
-- This is special to prevent unnecessary delays.
-- The allocator indicates that the arbiter may start
-- processing next request as in 2 cycles, net allocator
-- will finish the current job and will be ready for the next one
request_next
<=
pg_done
;
-- the address of the allocated page
pgaddr_alloc_o
<=
pg_addr_alloc
;
-- Getting the address of the page we want to free
pg_addr_free
<=
pgaddr_free_i
(
in_sel
*
g_page_addr_width
+
g_page_addr_width
-
1
downto
in_sel
*
g_page_addr_width
);
pg_addr_force_free
<=
pgaddr_force_free_i
(
in_sel
*
g_page_addr_width
+
g_page_addr_width
-
1
downto
in_sel
*
g_page_addr_width
);
pg_addr_usecnt
<=
pgaddr_usecnt_i
(
in_sel
*
g_page_addr_width
+
g_page_addr_width
-
1
downto
in_sel
*
g_page_addr_width
);
---
pg_addr
<=
pg_addr_force_free
when
(
pg_force_free
=
'1'
)
else
pg_addr_free
when
(
pg_free
=
'1'
)
else
pg_addr_usecnt
when
(
pg_set_usecnt
=
'1'
)
else
(
others
=>
'0'
);
-- getting the ouser count which should be assigned to freshly allocated page
pg_usecnt
<=
usecnt_i
(
in_sel
*
g_usecount_width
+
g_usecount_width
-
1
downto
in_sel
*
g_usecount_width
);
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
alloc_done_feedback
<=
(
others
=>
'0'
);
free_done_feedback
<=
(
others
=>
'0'
);
set_usecnt_done_feedback
<=
(
others
=>
'0'
);
force_free_done_feedback
<=
(
others
=>
'0'
);
free_last_usecnt
<=
(
others
=>
'0'
);
else
-- recognizing on which port the allocation/deallocation/freeing process
-- is about to finish. It's solely for request vector composition purpose
for
i
in
0
to
g_num_ports
-1
loop
if
(
pg_done
=
'1'
and
(
in_sel
=
i
))
then
if
(
request_grant
(
1
downto
0
)
=
b"00"
)
then
alloc_done_feedback
(
i
)
<=
'1'
;
else
alloc_done_feedback
(
i
)
<=
'0'
;
end
if
;
if
(
request_grant
(
1
downto
0
)
=
b"01"
)
then
free_done_feedback
(
i
)
<=
'1'
;
free_last_usecnt_feedback
(
i
)
<=
pg_free_last_usecnt
;
else
free_done_feedback
(
i
)
<=
'0'
;
free_last_usecnt_feedback
(
i
)
<=
'0'
;
end
if
;
if
(
request_grant
(
1
downto
0
)
=
b"10"
)
then
set_usecnt_done_feedback
(
i
)
<=
'1'
;
else
set_usecnt_done_feedback
(
i
)
<=
'0'
;
end
if
;
if
(
request_grant
(
1
downto
0
)
=
b"11"
)
then
force_free_done_feedback
(
i
)
<=
'1'
;
else
force_free_done_feedback
(
i
)
<=
'0'
;
end
if
;
else
alloc_done_feedback
(
i
)
<=
'0'
;
free_done_feedback
(
i
)
<=
'0'
;
free_last_usecnt_feedback
(
i
)
<=
'0'
;
set_usecnt_done_feedback
(
i
)
<=
'0'
;
force_free_done_feedback
(
i
)
<=
'0'
;
end
if
;
end
loop
;
-- i
alloc_done
<=
alloc_done_feedback
;
free_done
<=
free_done_feedback
;
free_last_usecnt
<=
free_last_usecnt_feedback
;
-- set_usecnt_done <= set_usecnt_done_feedback;
force_free_done
<=
force_free_done_feedback
;
end
if
;
end
if
;
end
process
;
alloc_done_o
<=
alloc_done
;
free_done_o
<=
free_done
;
free_last_usecnt_o
<=
free_last_usecnt
;
set_usecnt_done_o
<=
set_usecnt_done_feedback
;
--set_usecnt_done;
force_free_done_o
<=
force_free_done
;
nomem_o
<=
pg_nomem
;
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