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
191bb247
Commit
191bb247
authored
13 years ago
by
Tomasz Wlostowski
Committed by
Tomasz Wlostowski
12 years ago
Browse files
Options
Downloads
Patches
Plain Diff
wishbone: added xwb_crossbar by Wesley
parent
ae6a85fe
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
modules/wishbone/wb_crossbar/Manifest.py
+1
-0
1 addition, 0 deletions
modules/wishbone/wb_crossbar/Manifest.py
modules/wishbone/wb_crossbar/xwb_crossbar.vhd
+265
-0
265 additions, 0 deletions
modules/wishbone/wb_crossbar/xwb_crossbar.vhd
with
266 additions
and
0 deletions
modules/wishbone/wb_crossbar/Manifest.py
0 → 100644
+
1
−
0
View file @
191bb247
files
=
[
"
xwb_crossbar.vhd
"
];
This diff is collapsed.
Click to expand it.
modules/wishbone/wb_crossbar/xwb_crossbar.vhd
0 → 100644
+
265
−
0
View file @
191bb247
-------------------------------------------------------------------------------
-- Title : An MxS Wishbone crossbar switch
-- Project : General Cores Library (gencores)
-------------------------------------------------------------------------------
-- File : xwb_crossbar.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2011-06-08
-- Last update: 2011-09-22
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description:
--
-- An MxS Wishbone crossbar switch
--
-- All masters, slaves, and the crossbar itself must share the same WB clock.
-- All participants must support the same data bus width.
--
-- If a master raises STB_O with an address not mapped by the crossbar,
-- ERR_I will be raised. If the crossbar has overlapping address ranges,
-- the lowest numbered slave is selected. If two masters address the same
-- slave simultaneously, the lowest numbered master is granted access.
--
-- The implementation of this crossbar locks a master to a slave so long as
-- CYC_O is held high. If the master tries to address outside the slave's
-- address range, ERR_I will be raised.
--
-------------------------------------------------------------------------------
-- Copyright (c) 2011 GSI / Wesley W. Terpstra
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-06-08 1.0 wterpstra import from SVN
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
work
.
wishbone_pkg
.
all
;
entity
xwb_crossbar
is
generic
(
g_num_masters
:
integer
:
=
2
;
g_num_slaves
:
integer
:
=
1
;
g_registered
:
boolean
:
=
false
);
port
(
clk_sys_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
-- Master connections (INTERCON is a slave)
slave_i
:
in
t_wishbone_slave_in_array
(
g_num_masters
-1
downto
0
);
slave_o
:
out
t_wishbone_slave_out_array
(
g_num_masters
-1
downto
0
);
-- Slave connections (INTERCON is a master)
master_i
:
in
t_wishbone_master_in_array
(
g_num_slaves
-1
downto
0
);
master_o
:
out
t_wishbone_master_out_array
(
g_num_slaves
-1
downto
0
);
-- Address of the slaves connected
cfg_address_i
:
in
t_wishbone_address_array
(
g_num_slaves
-1
downto
0
);
cfg_mask_i
:
in
t_wishbone_address_array
(
g_num_slaves
-1
downto
0
)
);
end
xwb_crossbar
;
architecture
rtl
of
xwb_crossbar
is
type
matrix
is
array
(
g_num_masters
-1
downto
0
,
g_num_slaves
downto
0
)
of
std_logic
;
type
column
is
array
(
g_num_masters
-1
downto
0
)
of
std_logic
;
type
row
is
array
(
g_num_slaves
downto
0
)
of
std_logic
;
-- synchronous signals:
signal
previous
:
matrix
;
-- Previously connected pairs
-- (a)synchronous signals (depending on generic):
signal
granted
:
matrix
;
-- The connections to form this cycle selected previous bus
signal
issue
:
column
;
-- Did last cycle issue a request
procedure
main_logic
(
signal
granted
:
out
matrix
;
signal
issue
:
out
column
;
signal
slave_i
:
in
t_wishbone_slave_in_array
(
g_num_masters
-1
downto
0
);
signal
previous
:
in
matrix
)
is
variable
acc
,
tmp
:
std_logic
;
variable
request
:
matrix
;
-- Which slaves do the masters address log(S)
variable
selected
:
matrix
;
-- Which master wins arbitration log(M) request
variable
sbusy
:
row
;
-- Does the slave's previous connection persist?
variable
mbusy
:
column
;
-- Does the master's previous connection persist?
begin
-- A slave is busy iff it services an in-progress cycle
for
slave
in
g_num_slaves
-1
downto
0
loop
acc
:
=
'0'
;
for
master
in
g_num_masters
-1
downto
0
loop
acc
:
=
acc
or
(
previous
(
master
,
slave
)
and
slave_i
(
master
)
.
CYC
);
end
loop
;
sbusy
(
slave
)
:
=
acc
;
end
loop
;
sbusy
(
g_num_slaves
)
:
=
'0'
;
-- Special case because the 'error device' supports multiple masters
-- A master is busy iff it services an in-progress cycle
for
master
in
g_num_masters
-1
downto
0
loop
acc
:
=
'0'
;
for
slave
in
g_num_slaves
downto
0
loop
acc
:
=
acc
or
previous
(
master
,
slave
);
end
loop
;
mbusy
(
master
)
:
=
acc
and
slave_i
(
master
)
.
CYC
;
end
loop
;
-- Decode the request address to see if master wants access
for
master
in
g_num_masters
-1
downto
0
loop
acc
:
=
'0'
;
for
slave
in
g_num_slaves
-1
downto
0
loop
if
(
slave_i
(
master
)
.
ADR
and
cfg_mask_i
(
slave
))
=
cfg_address_i
(
slave
)
then
tmp
:
=
'1'
;
else
tmp
:
=
'0'
;
end
if
;
acc
:
=
acc
or
tmp
;
request
(
master
,
slave
)
:
=
slave_i
(
master
)
.
CYC
and
slave_i
(
master
)
.
STB
and
tmp
;
end
loop
;
-- If no slaves match request, bind to 'error device'
request
(
master
,
g_num_slaves
)
:
=
slave_i
(
master
)
.
CYC
and
slave_i
(
master
)
.
STB
and
not
acc
;
end
loop
;
-- Arbitrate among the requesting masters
-- Policy: lowest numbered master first
for
slave
in
g_num_slaves
-1
downto
0
loop
acc
:
=
'0'
;
-- It is possible to break the chain of LUTs here using a sort of kogge-stone network
-- This probably only makes sense if you have more than 32 masters
for
master
in
0
to
g_num_masters
-1
loop
selected
(
master
,
slave
)
:
=
request
(
master
,
slave
)
and
not
acc
;
acc
:
=
acc
or
request
(
master
,
slave
);
end
loop
;
end
loop
;
-- Multiple masters can be granted access to the 'error device'
for
master
in
g_num_masters
-1
downto
0
loop
selected
(
master
,
g_num_slaves
)
:
=
request
(
master
,
g_num_slaves
);
end
loop
;
-- Determine the master granted access
-- Policy: if cycle still in progress, preserve the previous choice
for
slave
in
g_num_slaves
downto
0
loop
for
master
in
g_num_masters
-1
downto
0
loop
if
sbusy
(
slave
)
=
'1'
or
mbusy
(
master
)
=
'1'
then
granted
(
master
,
slave
)
<=
previous
(
master
,
slave
);
else
granted
(
master
,
slave
)
<=
selected
(
master
,
slave
);
end
if
;
end
loop
;
end
loop
;
-- Record strobe status for virtual error device
for
master
in
g_num_masters
-1
downto
0
loop
issue
(
master
)
<=
slave_i
(
master
)
.
CYC
and
slave_i
(
master
)
.
STB
;
end
loop
;
end
main_logic
;
-- Select the master pins the slave will receive
procedure
slave_logic
(
signal
o
:
out
t_wishbone_master_out
;
signal
slave_i
:
in
t_wishbone_slave_in_array
(
g_num_masters
-1
downto
0
);
signal
granted
:
in
matrix
;
slave
:
integer
)
is
variable
acc
:
t_wishbone_master_out
;
variable
granted_address
:
t_wishbone_address
;
variable
granted_select
:
t_wishbone_byte_select
;
variable
granted_data
:
t_wishbone_data
;
begin
acc
:
=
(
CYC
=>
'0'
,
STB
=>
'0'
,
ADR
=>
(
others
=>
'0'
),
SEL
=>
(
others
=>
'0'
),
WE
=>
'0'
,
DAT
=>
(
others
=>
'0'
));
for
master
in
g_num_masters
-1
downto
0
loop
granted_address
:
=
(
others
=>
granted
(
master
,
slave
));
granted_select
:
=
(
others
=>
granted
(
master
,
slave
));
granted_data
:
=
(
others
=>
granted
(
master
,
slave
));
acc
:
=
(
CYC
=>
acc
.
CYC
or
(
slave_i
(
master
)
.
CYC
and
granted
(
master
,
slave
)),
STB
=>
acc
.
STB
or
(
slave_i
(
master
)
.
STB
and
granted
(
master
,
slave
)),
ADR
=>
acc
.
ADR
or
(
slave_i
(
master
)
.
ADR
and
granted_address
),
SEL
=>
acc
.
SEL
or
(
slave_i
(
master
)
.
SEL
and
granted_select
),
WE
=>
acc
.
WE
or
(
slave_i
(
master
)
.
WE
and
granted
(
master
,
slave
)),
DAT
=>
acc
.
DAT
or
(
slave_i
(
master
)
.
DAT
and
granted_data
));
end
loop
;
o
<=
acc
;
end
slave_logic
;
-- Select the slave pins the master will receive
procedure
master_logic
(
signal
o
:
out
t_wishbone_slave_out
;
signal
master_i
:
in
t_wishbone_master_in_array
(
g_num_slaves
-1
downto
0
);
signal
issue
:
in
column
;
signal
previous
:
in
matrix
;
signal
granted
:
in
matrix
;
master
:
integer
)
is
variable
acc
:
t_wishbone_slave_out
;
variable
granted_data
:
t_wishbone_data
;
begin
acc
:
=
(
ACK
=>
'0'
,
ERR
=>
issue
(
master
)
and
previous
(
master
,
g_num_slaves
),
-- Error device connected and strobed?
RTY
=>
'0'
,
STALL
=>
granted
(
master
,
g_num_slaves
),
DAT
=>
(
others
=>
'0'
),
INT
=>
'0'
);
-- We use inverted logic on STALL so that if no slave granted => stall
for
slave
in
g_num_slaves
-1
downto
0
loop
granted_data
:
=
(
others
=>
granted
(
master
,
slave
));
acc
:
=
(
ACK
=>
acc
.
ACK
or
(
master_i
(
slave
)
.
ACK
and
granted
(
master
,
slave
)),
ERR
=>
acc
.
ERR
or
(
master_i
(
slave
)
.
ERR
and
granted
(
master
,
slave
)),
RTY
=>
acc
.
RTY
or
(
master_i
(
slave
)
.
RTY
and
granted
(
master
,
slave
)),
STALL
=>
acc
.
STALL
or
(
not
master_i
(
slave
)
.
STALL
and
granted
(
master
,
slave
)),
DAT
=>
acc
.
DAT
or
(
master_i
(
slave
)
.
DAT
and
granted_data
),
INT
=>
'0'
);
end
loop
;
acc
.
STALL
:
=
not
acc
.
STALL
;
o
<=
acc
;
end
master_logic
;
begin
-- If async determine granted devices
granted_matrix
:
if
not
g_registered
generate
main_logic
(
granted
,
issue
,
slave_i
,
previous
);
end
generate
;
granted_driver
:
if
g_registered
generate
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
granted
<=
(
others
=>
(
others
=>
'0'
));
issue
<=
(
others
=>
'0'
);
else
main_logic
(
granted
,
issue
,
slave_i
,
previous
);
end
if
;
end
if
;
end
process
;
end
generate
;
-- Make the slave connections
slave_matrix
:
for
slave
in
g_num_slaves
-1
downto
0
generate
slave_logic
(
master_o
(
slave
),
slave_i
,
granted
,
slave
);
end
generate
;
-- Make the master connections
master_matrix
:
for
master
in
g_num_masters
-1
downto
0
generate
master_logic
(
slave_o
(
master
),
master_i
,
issue
,
previous
,
granted
,
master
);
end
generate
;
-- Store the current grant to the previous registers
main
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
previous
<=
(
others
=>
(
others
=>
'0'
));
else
previous
<=
granted
;
end
if
;
end
if
;
end
process
main
;
end
rtl
;
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