-
Notifications
You must be signed in to change notification settings - Fork 1
/
dram_arbiter.vhd
169 lines (137 loc) · 4.24 KB
/
dram_arbiter.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
---------------------------------------------------------------------
-- Simple WISHBONE interconnect
--
-- Generated by wigen at Wed May 10 21:03:18 2017
--
-- Configuration:
-- Number of masters: 2
-- Number of slaves: 1
-- Master address width: 26
-- Slave address width: 26
-- Port size: 32
-- Port granularity: 8
-- Entity name: dram_arbiter
-- Pipelined arbiter: no
-- Registered feedback: yes
-- Unsafe slave decoder: no
--
-- Command line:
-- wigen -e dram_arbiter -r 2 1 26 26 32 8
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity dram_arbiter is
port(
clk_i: in std_logic;
rst_i: in std_logic;
s0_cyc_i: in std_logic;
s0_stb_i: in std_logic;
s0_we_i: in std_logic;
s0_sel_i: in std_logic_vector(3 downto 0);
s0_cti_i: in std_logic_vector(2 downto 0);
s0_bte_i: in std_logic_vector(1 downto 0);
s0_ack_o: out std_logic;
s0_adr_i: in std_logic_vector(25 downto 2);
s0_dat_i: in std_logic_vector(31 downto 0);
s0_dat_o: out std_logic_vector(31 downto 0);
s1_cyc_i: in std_logic;
s1_stb_i: in std_logic;
s1_we_i: in std_logic;
s1_sel_i: in std_logic_vector(3 downto 0);
s1_cti_i: in std_logic_vector(2 downto 0);
s1_bte_i: in std_logic_vector(1 downto 0);
s1_ack_o: out std_logic;
s1_adr_i: in std_logic_vector(25 downto 2);
s1_dat_i: in std_logic_vector(31 downto 0);
s1_dat_o: out std_logic_vector(31 downto 0);
m0_cyc_o: out std_logic;
m0_stb_o: out std_logic;
m0_we_o: out std_logic;
m0_sel_o: out std_logic_vector(3 downto 0);
m0_cti_o: out std_logic_vector(2 downto 0);
m0_bte_o: out std_logic_vector(1 downto 0);
m0_ack_i: in std_logic;
m0_adr_o: out std_logic_vector(25 downto 2);
m0_dat_o: out std_logic_vector(31 downto 0);
m0_dat_i: in std_logic_vector(31 downto 0)
);
end entity;
architecture rtl of dram_arbiter is
signal request: std_logic_vector(1 downto 0);
signal grant_next: std_logic_vector(1 downto 0);
signal grant: std_logic_vector(1 downto 0);
signal grant_reg: std_logic_vector(1 downto 0):=(others=>'0');
signal cyc_mux: std_logic;
signal stb_mux: std_logic;
signal we_mux: std_logic;
signal sel_mux: std_logic_vector(3 downto 0);
signal cti_mux: std_logic_vector(2 downto 0);
signal bte_mux: std_logic_vector(1 downto 0);
signal adr_mux: std_logic_vector(25 downto 2);
signal wdata_mux: std_logic_vector(31 downto 0);
signal ack_mux: std_logic;
signal rdata_mux: std_logic_vector(31 downto 0);
begin
-- ARBITER
-- Selects the active master. Masters with lower port numbers
-- have higher priority. Ongoing cycles are not interrupted.
request<=s1_cyc_i&s0_cyc_i;
grant_next<="01" when request(0)='1' else
"10" when request(1)='1' else
(others=>'0');
grant<=grant_reg when (request and grant_reg)/="00" else grant_next;
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
grant_reg<=(others=>'0');
else
grant_reg<=grant;
end if;
end if;
end process;
-- MASTER->SLAVE MUX
cyc_mux<=(s0_cyc_i and grant(0)) or
(s1_cyc_i and grant(1));
stb_mux<=(s0_stb_i and grant(0)) or
(s1_stb_i and grant(1));
we_mux<=(s0_we_i and grant(0)) or
(s1_we_i and grant(1));
sel_mux_gen: for i in sel_mux'range generate
sel_mux(i)<=(s0_sel_i(i) and grant(0)) or
(s1_sel_i(i) and grant(1));
end generate;
cti_mux_gen: for i in cti_mux'range generate
cti_mux(i)<=(s0_cti_i(i) and grant(0)) or
(s1_cti_i(i) and grant(1));
end generate;
bte_mux_gen: for i in bte_mux'range generate
bte_mux(i)<=(s0_bte_i(i) and grant(0)) or
(s1_bte_i(i) and grant(1));
end generate;
adr_mux_gen: for i in adr_mux'range generate
adr_mux(i)<=(s0_adr_i(i) and grant(0)) or
(s1_adr_i(i) and grant(1));
end generate;
wdata_mux_gen: for i in wdata_mux'range generate
wdata_mux(i)<=(s0_dat_i(i) and grant(0)) or
(s1_dat_i(i) and grant(1));
end generate;
-- MASTER->SLAVE DEMUX
m0_cyc_o<=cyc_mux;
m0_stb_o<=stb_mux;
m0_we_o<=we_mux;
m0_sel_o<=sel_mux;
m0_cti_o<=cti_mux;
m0_bte_o<=bte_mux;
m0_adr_o<=adr_mux(m0_adr_o'range);
m0_dat_o<=wdata_mux;
-- SLAVE->MASTER MUX
ack_mux<=m0_ack_i;
rdata_mux<=m0_dat_i;
-- SLAVE->MASTER DEMUX
s0_ack_o<=ack_mux and grant(0);
s0_dat_o<=rdata_mux;
s1_ack_o<=ack_mux and grant(1);
s1_dat_o<=rdata_mux;
end architecture;