-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalpus_wb32_pkg.vhd
148 lines (131 loc) · 4.31 KB
/
alpus_wb32_pkg.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
-- alpus_wb32_pkg - package for 32-bit Wishbone bus signalling
--
-- slave select functions for easy slave selection, DOES NOT support addressing multiple slaves within one cycle
--
library ieee;
use ieee.std_logic_1164.all;
package alpus_wb32_pkg is
constant alpus_wb_awid : integer := 32;
-- Wishbone signals to slave direction
type alpus_wb32_tos_t is record
cyc : std_logic; -- bus cycle
we : std_logic; -- wr cycle (rd_n)
stb : std_logic; -- transfer cycle, slave select
adr : std_logic_vector(alpus_wb_awid-1 downto 0); -- BYTE address
data : std_logic_vector(31 downto 0);
sel : std_logic_vector(3 downto 0); -- write enable
--tgd : std_logic;
--tga : std_logic;
--tgc : std_logic;
--lock : std_logic;
end record alpus_wb32_tos_t;
-- Wishbone signals to master direction
type alpus_wb32_tom_t is record
data : std_logic_vector(31 downto 0);
stall : std_logic;
ack : std_logic; -- bus cycle ack
--tgd : std_logic;
--err : std_logic; -- bus cycle nack
--rty : std_logic; -- bus cycle ->retry
end record alpus_wb32_tom_t;
type alpus_wb32_tos_array_t is array (integer range <>) of alpus_wb32_tos_t;
type alpus_wb32_tom_array_t is array (integer range <>) of alpus_wb32_tom_t;
-- Initial/idle values
constant alpus_wb32_tos_init : alpus_wb32_tos_t := ('0', '0', '0', (others => '0'), (others => '0'), (others => '0'));
constant alpus_wb32_tom_init : alpus_wb32_tom_t := ((others => '0'), '0', '0');
-- Select slave by address and mask
function alpus_wb32_slave_select_tos(
adr : std_logic_vector(alpus_wb_awid-1 downto 0);
mask : std_logic_vector(alpus_wb_awid-1 downto 0);
m : alpus_wb32_tos_t
) return alpus_wb32_tos_t;
function alpus_wb32_slave_select_tom(
adr : std_logic_vector(alpus_wb_awid-1 downto 0); --addr for A
mask : std_logic_vector(alpus_wb_awid-1 downto 0);
m : alpus_wb32_tos_t;
a : alpus_wb32_tom_t;
b : alpus_wb32_tom_t
) return alpus_wb32_tom_t;
component alpus_wb32_master_select is
generic(
NUM_MASTERS : integer := 2;
MASTER_PIPELINED : std_logic_vector := "11"
);
port(
clk : in std_logic;
rst : in std_logic;
master_side_tos : in alpus_wb32_tos_array_t(0 to NUM_MASTERS-1);
master_side_tom : out alpus_wb32_tom_array_t(0 to NUM_MASTERS-1);
slave_side_tos : out alpus_wb32_tos_t;
slave_side_tom : in alpus_wb32_tom_t
);
end component;
-- NOTE: Stall is often the critical path, but registering it causes wait states.
-- NOTE: REG_STALL delays master side stb by one clk. Set also REG_REQUEST or REG_RESPONSE, or
-- make otherwise sure that ack latency doesn't become negative.
component alpus_wb32_pipeline_bridge is
generic(
MASTER_PIPELINED : std_logic := '1';
SLAVE_PIPELINED : std_logic := '1';
REG_REQUEST : std_logic := '0';
REG_STALL : std_logic := '0';
REG_RESPONSE : std_logic := '0'
);
port(
clk : in std_logic;
rst : in std_logic;
master_side_tos : in alpus_wb32_tos_t;
master_side_tom : out alpus_wb32_tom_t;
slave_side_tos : out alpus_wb32_tos_t;
slave_side_tom : in alpus_wb32_tom_t
);
end component;
-- Interface to standard mode (non-pipelined) components
component alpus_wb32_stdmode_adapter is
generic(
MASTER_PIPELINED : std_logic := '1';
SLAVE_PIPELINED : std_logic := '1'
);
port(
clk : in std_logic;
rst : in std_logic;
master_side_tos : in alpus_wb32_tos_t;
master_side_tom : out alpus_wb32_tom_t;
slave_side_tos : out alpus_wb32_tos_t;
slave_side_tom : in alpus_wb32_tom_t
);
end component;
end package;
package body alpus_wb32_pkg is
function alpus_wb32_slave_select_tos(
adr : std_logic_vector(alpus_wb_awid-1 downto 0);
mask : std_logic_vector(alpus_wb_awid-1 downto 0);
m : alpus_wb32_tos_t
) return alpus_wb32_tos_t is
variable RET : alpus_wb32_tos_t;
begin
if (adr and mask) = (m.adr and mask) then
return m;
else
RET := m;
RET.cyc := '0';
RET.we := '0'; --not needed but prettier in simulation
RET.stb := '0';
return RET;
end if;
end function;
function alpus_wb32_slave_select_tom(
adr : std_logic_vector(alpus_wb_awid-1 downto 0);
mask : std_logic_vector(alpus_wb_awid-1 downto 0);
m : alpus_wb32_tos_t;
a : alpus_wb32_tom_t;
b : alpus_wb32_tom_t
) return alpus_wb32_tom_t is
begin
if (adr and mask) = (m.adr and mask) then
return a;
else
return b;
end if;
end function;
end;