Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Platform-independent core collection
Manage
Activity
Members
Labels
Plan
Issues
15
Issue boards
Milestones
Wiki
Code
Merge requests
5
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
Platform-independent core collection
Commits
069ac755
Commit
069ac755
authored
11 years ago
by
Wesley W. Terpstra
Browse files
Options
Downloads
Patches
Plain Diff
wishbone: sdb auto crossbar mapping support
parent
ad44cee9
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
modules/wishbone/wishbone_pkg.vhd
+138
-3
138 additions, 3 deletions
modules/wishbone/wishbone_pkg.vhd
with
138 additions
and
3 deletions
modules/wishbone/wishbone_pkg.vhd
+
138
−
3
View file @
069ac755
...
...
@@ -92,7 +92,7 @@ package wishbone_pkg is
constant
c_sdb_device_length
:
natural
:
=
512
;
-- bits
subtype
t_sdb_record
is
std_logic_vector
(
c_sdb_device_length
-1
downto
0
);
type
t_sdb_record_array
is
array
(
natural
range
<>
)
of
t_sdb_record
;
type
t_sdb_product
is
record
vendor_id
:
std_logic_vector
(
63
downto
0
);
device_id
:
std_logic_vector
(
31
downto
0
);
...
...
@@ -139,9 +139,8 @@ package wishbone_pkg is
syn_date
:
std_logic_vector
(
31
downto
0
);
syn_username
:
string
(
1
to
15
);
end
record
t_sdb_synthesis
;
-- general crossbar building functions
function
f_sdb_create_array
(
g_enum_dev_id
:
boolean
:
=
false
;
g_dev_id_offs
:
natural
:
=
0
;
...
...
@@ -170,6 +169,12 @@ package wishbone_pkg is
function
f_sdb_extract_repo_url
(
sdb_record
:
t_sdb_record
)
return
t_sdb_repo_url
;
function
f_sdb_extract_synthesis
(
sdb_record
:
t_sdb_record
)
return
t_sdb_synthesis
;
-- Automatic crossbar mapping functions
function
f_sdb_auto_device
(
device
:
t_sdb_device
;
enable
:
boolean
:
=
true
)
return
t_sdb_record
;
function
f_sdb_auto_bridge
(
bridge
:
t_sdb_bridge
;
enable
:
boolean
:
=
true
)
return
t_sdb_record
;
function
f_sdb_auto_layout
(
records
:
t_sdb_record_array
)
return
t_sdb_record_array
;
function
f_sdb_auto_sdb
(
records
:
t_sdb_record_array
)
return
t_wishbone_address
;
-- For internal use by the crossbar
function
f_sdb_embed_product
(
product
:
t_sdb_product
)
return
std_logic_vector
;
-- (319 downto 8)
function
f_sdb_embed_component
(
sdb_component
:
t_sdb_component
;
address
:
t_wishbone_address
)
return
std_logic_vector
;
-- (447 downto 8)
...
...
@@ -1130,6 +1135,136 @@ package body wishbone_pkg is
return
result
;
end
;
function
f_sdb_auto_device
(
device
:
t_sdb_device
;
enable
:
boolean
)
return
t_sdb_record
is
constant
c_zero
:
t_wishbone_address
:
=
(
others
=>
'0'
);
variable
v_empty
:
t_sdb_record
:
=
(
others
=>
'0'
);
begin
v_empty
(
7
downto
0
)
:
=
(
others
=>
'1'
);
if
enable
then
return
f_sdb_embed_device
(
device
,
c_zero
);
else
return
v_empty
;
end
if
;
end
f_sdb_auto_device
;
function
f_sdb_auto_bridge
(
bridge
:
t_sdb_bridge
;
enable
:
boolean
)
return
t_sdb_record
is
constant
c_zero
:
t_wishbone_address
:
=
(
others
=>
'0'
);
variable
v_empty
:
t_sdb_record
:
=
(
others
=>
'0'
);
begin
v_empty
(
7
downto
0
)
:
=
(
others
=>
'1'
);
if
enable
then
return
f_sdb_embed_bridge
(
bridge
,
c_zero
);
else
return
v_empty
;
end
if
;
end
f_sdb_auto_bridge
;
subtype
t_usdb_address
is
unsigned
(
63
downto
0
);
type
t_usdb_address_array
is
array
(
natural
range
<>
)
of
t_usdb_address
;
-- We map devices by placing the smallest ones first.
-- This is guaranteed to pack the maximum number of devices in the smallest space.
-- If a device has an address != 0, we leave it alone and let the crossbar confirm
-- that the address does not cause a conflict.
function
f_sdb_auto_layout_helper
(
records
:
t_sdb_record_array
)
return
t_usdb_address_array
is
alias
c_records
:
t_sdb_record_array
(
records
'length
-1
downto
0
)
is
records
;
constant
c_zero
:
t_usdb_address
:
=
(
others
=>
'0'
);
constant
c_used_entries
:
natural
:
=
c_records
'length
+
1
;
constant
c_rom_entries
:
natural
:
=
2
**
f_ceil_log2
(
c_used_entries
);
constant
c_rom_bytes
:
natural
:
=
c_rom_entries
*
c_sdb_device_length
/
8
;
variable
v_component
:
t_sdb_component
;
variable
v_sizes
:
t_usdb_address_array
(
c_records
'length
downto
0
);
variable
v_address
:
t_usdb_address_array
(
c_records
'length
downto
0
);
variable
v_map
:
std_logic_vector
(
c_records
'length
downto
0
)
:
=
(
others
=>
'0'
);
variable
v_cursor
:
unsigned
(
63
downto
0
)
:
=
(
others
=>
'0'
);
variable
v_increment
:
unsigned
(
63
downto
0
)
:
=
(
others
=>
'0'
);
begin
-- First, extract the length of the devices, ignoring those not to be mapped
for
i
in
c_records
'range
loop
v_component
:
=
f_sdb_extract_component
(
c_records
(
i
)(
447
downto
8
));
v_sizes
(
i
)
:
=
unsigned
(
v_component
.
addr_last
);
v_address
(
i
)
:
=
unsigned
(
v_component
.
addr_first
);
-- Silently round up to a power of two; the crossbar will give a warning for us
for
j
in
62
downto
0
loop
v_sizes
(
i
)(
j
)
:
=
v_sizes
(
i
)(
j
+
1
)
or
v_sizes
(
i
)(
j
);
end
loop
;
-- Only map devices/bridges at address zero
if
v_address
(
i
)
=
c_zero
then
case
c_records
(
i
)(
7
downto
0
)
is
when
x"01"
=>
v_map
(
i
)
:
=
'1'
;
when
x"02"
=>
v_map
(
i
)
:
=
'1'
;
when
others
=>
null
;
end
case
;
end
if
;
end
loop
;
-- Assign the SDB record a spot as well
v_address
(
c_records
'length
)
:
=
(
others
=>
'0'
);
v_sizes
(
c_records
'length
)
:
=
to_unsigned
(
c_rom_bytes
-1
,
64
);
v_map
(
c_records
'length
)
:
=
'1'
;
-- Start assigning addresses
for
j
in
0
to
63
loop
v_increment
:
=
(
j
=>
'1'
,
others
=>
'0'
);
for
i
in
0
to
c_records
'length
loop
if
v_map
(
i
)
=
'1'
and
v_sizes
(
i
)(
j
)
=
'0'
then
v_map
(
i
)
:
=
'0'
;
v_address
(
i
)
:
=
v_cursor
;
v_cursor
:
=
v_cursor
+
v_increment
;
end
if
;
end
loop
;
-- Round up to the next required alignment
if
v_cursor
(
j
)
=
'1'
then
v_cursor
:
=
v_cursor
+
v_increment
;
end
if
;
end
loop
;
return
v_address
;
end
f_sdb_auto_layout_helper
;
function
f_sdb_auto_layout
(
records
:
t_sdb_record_array
)
return
t_sdb_record_array
is
alias
c_records
:
t_sdb_record_array
(
records
'length
-1
downto
0
)
is
records
;
variable
v_result
:
t_sdb_record_array
(
c_records
'range
)
:
=
c_records
;
constant
c_address
:
t_usdb_address_array
:
=
f_sdb_auto_layout_helper
(
c_records
);
variable
v_address
:
t_wishbone_address
;
begin
-- Put the addresses into the mapping
for
i
in
v_result
'range
loop
v_address
:
=
std_logic_vector
(
c_address
(
i
)(
t_wishbone_address
'range
));
if
c_records
(
i
)(
7
downto
0
)
=
x"01"
then
v_result
(
i
)
:
=
f_sdb_embed_device
(
f_sdb_extract_device
(
v_result
(
i
)),
v_address
);
end
if
;
if
c_records
(
i
)(
7
downto
0
)
=
x"02"
then
v_result
(
i
)
:
=
f_sdb_embed_bridge
(
f_sdb_extract_bridge
(
v_result
(
i
)),
v_address
);
end
if
;
end
loop
;
return
v_result
;
end
f_sdb_auto_layout
;
function
f_sdb_auto_sdb
(
records
:
t_sdb_record_array
)
return
t_wishbone_address
is
alias
c_records
:
t_sdb_record_array
(
records
'length
-1
downto
0
)
is
records
;
constant
c_address
:
t_usdb_address_array
(
c_records
'length
downto
0
)
:
=
f_sdb_auto_layout_helper
(
c_records
);
begin
return
std_logic_vector
(
c_address
(
c_records
'length
)(
t_wishbone_address
'range
));
end
f_sdb_auto_sdb
;
--**************************************************************************************************************************--
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment