OpenCores
URL https://opencores.org/ocsvn/simpcon/simpcon/trunk

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_arbiter_2m.vhd] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 martin
 
2
 
3
-- 150407: first working version with records
4
-- 170407: produce number of registers depending on the cpu_cnt
5
-- 110507: * arbiter that can be used with prefered number of masters
6
--                               * full functional arbiter with two masters
7
--                               * short modelsim test with 3 masters carried out
8
-- 290607: used for JTRES07 submission
9
 
10
 
11
library ieee;
12
use ieee.std_logic_1164.all;
13
use ieee.numeric_std.all;
14
 
15
use work.sc_pack.all;
16
use work.sc_arbiter_pack.all;
17
 
18
entity arbiter is
19
generic(
20
                        addr_bits : integer;
21
                        cpu_cnt : integer);             -- number of masters for the arbiter
22
port (
23
                        clk, reset      : in std_logic;
24
                        arb_out                 : in arb_out_type(0 to cpu_cnt-1);
25
                        arb_in                  : out arb_in_type(0 to cpu_cnt-1);
26
                        mem_out                 : out sc_mem_out_type;
27
                        mem_in                  : in sc_in_type
28
);
29
end arbiter;
30
 
31
 
32
architecture rtl of arbiter is
33
 
34
-- signals for the input register of each master
35
 
36
        type reg_type is record
37
                rd : std_logic;
38
                wr : std_logic;
39
                wr_data : std_logic_vector(31 downto 0);
40
                address : std_logic_vector(addr_bits-1 downto 0);
41
        end record;
42
 
43
        type reg_array_type is array (0 to cpu_cnt-1) of reg_type;
44
        signal reg_in : reg_array_type;
45
 
46
-- one fsm for each CPU
47
 
48
        type state_type is (idle, read, write, waitingR, sendR,
49
        waitingW, sendW);
50
        type state_array is array (0 to cpu_cnt-1) of state_type;
51
        signal state : state_array;
52
        signal next_state : state_array;
53
 
54
-- one fsm for each serve
55
 
56
        type serve_type is (idl, serv);
57
        type serve_array is array (0 to cpu_cnt-1) of serve_type;
58
        signal this_state : serve_array;
59
        signal follow_state : serve_array;
60
 
61
-- arbiter
62
 
63
        type set_type is array (0 to cpu_cnt-1) of std_logic;
64
        signal set : set_type;
65
 
66
 
67
begin
68
 
69
 
70
-- Generates the input register and saves incoming data for each master
71
gen_register: for i in 0 to cpu_cnt-1 generate
72
        process(clk, reset)
73
        begin
74
                if reset = '1' then
75
                        reg_in(i).rd <= '0';
76
                        reg_in(i).wr <= '0';
77
                        reg_in(i).wr_data <= (others => '0');
78
                        reg_in(i).address <= (others => '0');
79
                elsif rising_edge(clk) then
80
                        if arb_out(i).rd = '1' or arb_out(i).wr = '1' then
81
                        reg_in(i).rd <= arb_out(i).rd;
82
                                reg_in(i).wr <= arb_out(i).wr;
83
                                reg_in(i).address <= arb_out(i).address;
84
                                reg_in(i).wr_data <= arb_out(i).wr_data;
85
                        end if;
86
                end if;
87
        end process;
88
end generate;
89
 
90
-- Generates next state of the FSM for each master
91
gen_next_state: for i in 0 to cpu_cnt-1 generate
92
        process(reset, state, arb_out, mem_in, this_state, reg_in)
93
        begin
94
 
95
                next_state(i) <= state(i);
96
 
97
                case state(i) is
98
                        when idle =>
99
 
100
                                if this_state(i) = serv then -- checks if this CPU is on turn
101
                                        if mem_in.rdy_cnt = 1 and arb_out(i).rd = '1' then
102
                                                next_state(i) <= read;
103
                                        elsif (mem_in.rdy_cnt = 0) and (arb_out(i).rd = '1'
104
                                        or arb_out(i).wr = '1') then
105
                                                for k in 0 to cpu_cnt-1 loop
106
                                                        if arb_out(k).rd = '1' or arb_out(k).wr = '1' then
107
                                                                if i<=k then
108
                                                                        if arb_out(i).rd = '1' then
109
                                                                                next_state(i) <= read;
110
                                                                                exit;
111
                                                                        elsif arb_out(i).wr = '1' then
112
                                                                                next_state(i) <= write;
113
                                                                                exit;
114
                                                                        end if;
115
                                                                else
116
                                                                        if arb_out(i).rd = '1' then
117
                                                                                next_state(i) <= waitingR;
118
                                                                                exit;
119
                                                                        elsif arb_out(i).wr = '1' then
120
                                                                                next_state(i) <= waitingW;
121
                                                                                exit;
122
                                                                        end if;
123
                                                                end if;
124
                                                        elsif reg_in(k).rd = '1' or reg_in(k).wr = '1' then
125
                                                                if arb_out(i).rd = '1' then
126
                                                                        next_state(i) <= waitingR;
127
                                                                        exit;
128
                                                                elsif arb_out(i).wr = '1' then
129
                                                                        next_state(i) <= waitingW;
130
                                                                        exit;
131
                                                                end if;
132
                                                        else
133
                                                                if arb_out(i).rd = '1' then
134
                                                                        next_state(i) <= read;
135
                                                                elsif arb_out(i).wr = '1' then
136
                                                                        next_state(i) <= write;
137
                                                                end if;
138
                                                        end if;
139
                                                end loop;
140
                                        end if;
141
                                else
142
                                        for j in 0 to cpu_cnt-1 loop
143
                                                if this_state(j) = serv then
144
                                                        if mem_in.rdy_cnt = 1 and arb_out(j).rd = '1' and
145
                                                        arb_out(i).rd = '1' then
146
                                                                next_state(i) <= waitingR;
147
                                                                exit;
148
                                                        elsif mem_in.rdy_cnt = 1 and arb_out(j).rd = '1' and
149
                                                        arb_out(i).wr = '1' then
150
                                                                next_state(i) <= waitingW;
151
                                                                exit;
152
                                                        end if;
153
                                                else
154
                                                        if mem_in.rdy_cnt = 0 then
155
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
156
                                                                        if i<=j then
157
                                                                                if arb_out(i).rd = '1' then
158
                                                                                        next_state(i) <= read;
159
                                                                                        exit; -- new
160
                                                                                elsif arb_out(i).wr = '1' then
161
                                                                                        next_state(i) <= write;
162
                                                                                        exit; -- new
163
                                                                                end if;
164
                                                                        else
165
                                                                                if arb_out(i).rd = '1' then
166
                                                                                        next_state(i) <= waitingR;
167
                                                                                        exit;
168
                                                                                elsif arb_out(i).wr = '1' then
169
                                                                                        next_state(i) <= waitingW;
170
                                                                                        exit;
171
                                                                                end if;
172
                                                                        end if;
173
                                                                -- new
174
                                                                elsif (state(j) = waitingR) or (state(j) = waitingW) then
175
                                                                        if arb_out(i).rd = '1' then
176
                                                                                next_state(i) <= waitingR;
177
                                                                        elsif arb_out(i).wr = '1' then
178
                                                                                next_state(i) <= waitingW;
179
                                                                                exit;
180
                                                                        end if;
181
                                                                -- new
182
                                                                elsif arb_out(i).rd = '1' then
183
                                                                        next_state(i) <= read;
184
                                                                elsif arb_out(i).wr = '1' then
185
                                                                        next_state(i) <= write;
186
                                                                end if;
187
                                                        else
188
                                                                if arb_out(i).rd = '1' then
189
                                                                        next_state(i) <= waitingR;
190
                                                                        exit;
191
                                                                elsif arb_out(i).wr = '1' then
192
                                                                        next_state(i) <= waitingW;
193
                                                                        exit;
194
                                                                end if;
195
                                                        end if;
196
                                                end if;
197
                                        end loop;
198
                                end if;
199
 
200
                        when read =>
201
                                next_state(i) <= idle;
202
 
203
                        when write =>
204
                                next_state(i) <= idle;
205
 
206
                        when waitingR =>
207
                                if mem_in.rdy_cnt = 0 then
208
                                -- checks which CPU in waitingR has highest priority
209
                                        for j in 0 to cpu_cnt-1 loop
210
                                                --if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
211
                                                --      next_state(i) <= waitingR;
212
                                                --      exit;
213
                                                --els
214
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
215
                                                        if j<i then
216
                                                                next_state(i) <= waitingR;
217
                                                                exit;
218
                                                        elsif j=i then
219
                                                                next_state(i) <= sendR;
220
                                                                exit;
221
                                                        else
222
                                                                next_state(i) <= sendR;
223
                                                                exit;
224
                                                        end if;
225
                                                else
226
                                                        next_state(i) <= sendR;
227
                                                end if;
228
                                        end loop;
229
                                else
230
                                        next_state(i) <= waitingR;
231
                                end if;
232
 
233
                        when sendR =>
234
                                next_state(i) <= idle;
235
 
236
                        when waitingW =>
237
                                if mem_in.rdy_cnt = 0 then
238
                                        for j in 0 to cpu_cnt-1 loop
239
                                                --if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
240
                                                --      next_state(i) <= waitingW;
241
                                                --      exit;
242
                                                --els
243
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
244
                                                        if j<i then
245
                                                                next_state(i) <= waitingW;
246
                                                                exit;
247
                                                        elsif j=i then
248
                                                                next_state(i) <= sendW;
249
                                                                exit;
250
                                                        else
251
                                                                next_state(i) <= sendW;
252
                                                                exit;
253
                                                        end if;
254
                                                else
255
                                                        next_state(i) <= sendW;
256
                                                end if;
257
                                        end loop;
258
                                else
259
                                        next_state(i) <= waitingW;
260
                                end if;
261
 
262
                        when sendW =>
263
                                next_state(i) <= idle;
264
 
265
                end case;
266
        end process;
267
end generate;
268
 
269
 
270
-- Generates the FSM state for each master
271
gen_state: for i in 0 to cpu_cnt-1 generate
272
        process (clk, reset)
273
        begin
274
                if (reset = '1') then
275
                        state(i) <= idle;
276
        elsif (rising_edge(clk)) then
277
                        state(i) <= next_state(i);
278
                end if;
279
        end process;
280
end generate;
281
 
282
 
283
-- The arbiter output
284
process (arb_out, reg_in, next_state)
285
begin
286
 
287
        mem_out.rd <= '0';
288
        mem_out.wr <= '0';
289
        mem_out.address <= (others => '0');
290
        mem_out.wr_data <= (others => '0');
291
 
292
        for i in 0 to cpu_cnt-1 loop
293
                set(i) <= '0';
294
 
295
                case next_state(i) is
296
                        when idle =>
297
 
298
                        when read =>
299
                                set(i) <= '1';
300
                                mem_out.rd <= arb_out(i).rd;
301
                                mem_out.address <= arb_out(i).address;
302
 
303
                        when write =>
304
                                set(i) <= '1';
305
                                mem_out.wr <= arb_out(i).wr;
306
                                mem_out.address <= arb_out(i).address;
307
                                mem_out.wr_data <= arb_out(i).wr_data;
308
 
309
                        when waitingR =>
310
 
311
                        when sendR =>
312
                                set(i) <= '1';
313
                                mem_out.rd <= reg_in(i).rd;
314
                                mem_out.address <= reg_in(i).address;
315
 
316
                        when waitingW =>
317
 
318
                        when sendW =>
319
                                set(i) <= '1';
320
                                mem_out.wr <= reg_in(i).wr;
321
                                mem_out.address <= reg_in(i).address;
322
                                mem_out.wr_data <= reg_in(i).wr_data;
323
 
324
                end case;
325
        end loop;
326
end process;
327
 
328
-- generation of follow_state
329
gen_serve: for i in 0 to cpu_cnt-1 generate
330
        process(mem_in, set, this_state)
331
        begin
332
                case this_state(i) is
333
                        when idl =>
334
                                follow_state(i) <= idl;
335
                                if set(i) = '1' then
336
                                        follow_state(i) <= serv;
337
                                end if;
338
                        when serv =>
339
                                follow_state(i) <= serv;
340
                                if mem_in.rdy_cnt = 0 and set(i) = '0' then
341
                                        follow_state(i) <= idl;
342
                                end if;
343
                end case;
344
        end process;
345
end generate;
346
 
347
gen_serve2: for i in 0 to cpu_cnt-1 generate
348
        process (clk, reset)
349
        begin
350
                if (reset = '1') then
351
                        this_state(i) <= idl;
352
        elsif (rising_edge(clk)) then
353
                        this_state(i) <= follow_state(i);
354
                end if;
355
        end process;
356
end generate;
357
 
358
gen_rdy_cnt: for i in 0 to cpu_cnt-1 generate
359
        process (mem_in, state, this_state)
360
        begin
361
                arb_in(i).rdy_cnt <= mem_in.rdy_cnt;
362
                arb_in(i).rd_data <= mem_in.rd_data;
363
 
364
                case state(i) is
365
                        when idle =>
366
                                case this_state(i) is
367
                                        when idl =>
368
                                                arb_in(i).rdy_cnt <= "00";
369
                                        when serv =>
370
                                end case;
371
 
372
                        when read =>
373
 
374
                        when write =>
375
 
376
                        when waitingR =>
377
                                arb_in(i).rdy_cnt <= "11";
378
 
379
                        when sendR =>
380
 
381
                        when waitingW =>
382
                                arb_in(i).rdy_cnt <= "11";
383
 
384
                        when sendW =>
385
 
386
                end case;
387
        end process;
388
end generate;
389
 
390
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.