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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_arbiter_fixedpr_int.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 29 martin
--
2
--  This file is part of JOP, the Java Optimized Processor
3
--
4
--  Copyright (C) 2007,2008, Christof Pitter
5
--
6
--  This program is free software: you can redistribute it and/or modify
7
--  it under the terms of the GNU General Public License as published by
8
--  the Free Software Foundation, either version 3 of the License, or
9
--  (at your option) any later version.
10
--
11
--  This program is distributed in the hope that it will be useful,
12
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
--  GNU General Public License for more details.
15
--
16
--  You should have received a copy of the GNU General Public License
17
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
--
19
 
20
 
21
 
22
 
23
-- 150407: first working version with records
24
-- 170407: produce number of registers depending on the cpu_cnt
25
-- 110507: * arbiter that can be used with prefered number of masters
26
--                               * full functional arbiter with two masters
27
--                               * short modelsim test with 3 masters carried out
28
-- 190607: Problem found: Both CPU1 and CPU2 start to read cache line!!!
29
-- 030707: Several bugs are fixed now. CMP with 3 running masters functions!
30
-- 261107: Fixed Priority Interruptive Arbiter
31
 
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.numeric_std.all;
36
 
37
use work.sc_pack.all;
38
use work.sc_arbiter_pack.all;
39
 
40
entity arbiter is
41
generic(
42
                        addr_bits : integer;
43
                        cpu_cnt : integer);             -- number of masters for the arbiter
44
port (
45
                        clk, reset      : in std_logic;
46
                        arb_out                 : in arb_out_type(0 to cpu_cnt-1);
47
                        arb_in                  : out arb_in_type(0 to cpu_cnt-1);
48
                        mem_out                 : out sc_out_type;
49
                        mem_in                  : in sc_in_type
50
);
51
end arbiter;
52
 
53
 
54
architecture rtl of arbiter is
55
 
56
-- signals for the input register of each master
57
 
58
        type reg_type is record
59
                rd : std_logic;
60
                wr : std_logic;
61
                wr_data : std_logic_vector(31 downto 0);
62
                address : std_logic_vector(addr_bits-1 downto 0);
63
        end record;
64
 
65
        type reg_array_type is array (0 to cpu_cnt-1) of reg_type;
66
        signal reg_in : reg_array_type;
67
 
68
-- one fsm for each CPU
69
 
70
        type state_type is (idle, read, write, waitingR, sendR,
71
        waitingW, sendW, pipeBlocked);
72
        type state_array is array (0 to cpu_cnt-1) of state_type;
73
        signal state : state_array;
74
        signal next_state : state_array;
75
 
76
-- one fsm for each serve
77
 
78
        type serve_type is (idl, serv);
79
        type serve_array is array (0 to cpu_cnt-1) of serve_type;
80
        signal this_state : serve_array;
81
        signal follow_state : serve_array;
82
 
83
-- arbiter
84
 
85
        type set_type is array (0 to cpu_cnt-1) of std_logic;
86
        signal set : set_type;
87
        signal waiting : set_type;
88
        signal masterWaiting : std_logic;
89
 
90
 
91
begin
92
 
93
 
94
-- Generates the input register and saves incoming data for each master
95
gen_register: for i in 0 to cpu_cnt-1 generate
96
        process(clk, reset)
97
        begin
98
                if reset = '1' then
99
                        reg_in(i).rd <= '0';
100
                        reg_in(i).wr <= '0';
101
                        reg_in(i).wr_data <= (others => '0');
102
                        reg_in(i).address <= (others => '0');
103
                elsif rising_edge(clk) then
104
                        if arb_out(i).rd = '1' or arb_out(i).wr = '1' then
105
                        reg_in(i).rd <= arb_out(i).rd;
106
                                reg_in(i).wr <= arb_out(i).wr;
107
                                reg_in(i).address <= arb_out(i).address;
108
                                reg_in(i).wr_data <= arb_out(i).wr_data;
109
                        end if;
110
                end if;
111
        end process;
112
end generate;
113
 
114
-- Register for masterWaiting
115
process(clk, reset)
116
        begin
117
                if reset = '1' then
118
                        masterWaiting <= '0';
119
                elsif rising_edge(clk) then
120
                        for i in 0 to cpu_cnt-1 loop
121
                                if waiting(i) = '1' then
122
                                        masterWaiting <= '1';
123
                                        exit;
124
                                else
125
                                        masterWaiting <= '0';
126
                                end if;
127
                        end loop;
128
                end if;
129
        end process;
130
 
131
-- Generates next state of the FSM for each master
132
gen_next_state: for i in 0 to cpu_cnt-1 generate
133
        process(reset, state, arb_out, mem_in, this_state, reg_in, masterWaiting)
134
        begin
135
 
136
                next_state(i) <= state(i);
137
                waiting(i) <= '0';
138
 
139
                case state(i) is
140
                        when idle =>
141
 
142
                                -- checks if this CPU is on turn (pipelined access)
143
                                if this_state(i) = serv then
144
 
145
                                        if mem_in.rdy_cnt = 1 and arb_out(i).rd = '1' then
146
                                                -- check if higher priority CPU wants to access and blocks pipelined access
147
                                                next_state(i) <= read;
148
 
149
                                                if arb_out(i).atomic = '1' then
150
                                                        for j in 0 to cpu_cnt-1 loop
151
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
152
                                                                        if j<i then
153
                                                                                next_state(i) <= pipeBlocked;
154
                                                                                --wait_cycles <= 1;
155
                                                                                exit;
156
                                                                        end if;
157
                                                                end if;
158
                                                        end loop;
159
                                                end if;
160
 
161
                                        elsif (mem_in.rdy_cnt = 0 and (arb_out(i).rd = '1' or arb_out(i).wr = '1')) then
162
 
163
                                                -- check if some master is waiting
164
                                                if masterWaiting = '1' then
165
                                                        if arb_out(i).rd = '1' then
166
                                                                next_state(i) <= waitingR;
167
                                                                waiting(i) <= '1';
168
                                                        elsif arb_out(i).wr = '1' then
169
                                                                next_state(i) <= waitingW;
170
                                                                waiting(i) <= '1';
171
                                                        end if;
172
 
173
                                                -- check if parallel access             
174
                                                else
175
                                                        for j in 0 to cpu_cnt-1 loop
176
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
177
                                                                        if i<=j then
178
                                                                                if arb_out(i).rd = '1' then
179
                                                                                        next_state(i) <= read;
180
                                                                                        exit;
181
                                                                                elsif arb_out(i).wr = '1' then
182
                                                                                        next_state(i) <= write;
183
                                                                                        exit;
184
                                                                                end if;
185
                                                                        else
186
                                                                                if arb_out(i).rd = '1' then
187
                                                                                        next_state(i) <= waitingR;
188
                                                                                        waiting(i) <= '1';
189
                                                                                        exit;
190
                                                                                elsif arb_out(i).wr = '1' then
191
                                                                                        next_state(i) <= waitingW;
192
                                                                                        waiting(i) <= '1';
193
                                                                                        exit;
194
                                                                                end if;
195
                                                                        end if;
196
                                                                end if;
197
                                                        end loop;
198
                                                end if;
199
 
200
                                        -- all other kinds of rdy_cnt
201
                                        else
202
                                                if arb_out(i).rd = '1' then
203
                                                        next_state(i) <= waitingR;
204
                                                        waiting(i) <= '1';
205
                                                elsif arb_out(i).wr = '1' then
206
                                                        next_state(i) <= waitingW;
207
                                                        waiting(i) <= '1';
208
                                                end if;
209
                                        end if;
210
 
211
                                -- CPU is not already pipelined accessing the memory
212
                                else
213
                                        if (mem_in.rdy_cnt = 0 and (arb_out(i).rd = '1' or arb_out(i).wr = '1')) then
214
                                                -- check if some master is waiting
215
                                                if masterWaiting = '1' then
216
                                                        if arb_out(i).rd = '1' then
217
                                                                next_state(i) <= waitingR;
218
                                                                waiting(i) <= '1';
219
                                                        elsif arb_out(i).wr = '1' then
220
                                                                next_state(i) <= waitingW;
221
                                                                waiting(i) <= '1';
222
                                                        end if;
223
 
224
                                                -- check if another CPU wants to access in parallel
225
                                                else
226
                                                        for j in 0 to cpu_cnt-1 loop
227
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
228
                                                                        if i<=j then
229
                                                                                if arb_out(i).rd = '1' then
230
                                                                                        next_state(i) <= read;
231
                                                                                        exit;
232
                                                                                elsif arb_out(i).wr = '1' then
233
                                                                                        next_state(i) <= write;
234
                                                                                        exit;
235
                                                                                end if;
236
                                                                        else
237
                                                                                if arb_out(i).rd = '1' then
238
                                                                                        next_state(i) <= waitingR;
239
                                                                                        waiting(i) <= '1';
240
                                                                                        exit;
241
                                                                                elsif arb_out(i).wr = '1' then
242
                                                                                        next_state(i) <= waitingW;
243
                                                                                        waiting(i) <= '1';
244
                                                                                        exit;
245
                                                                                end if;
246
                                                                        end if;
247
                                                                -- ** cannot ever happen!!!!!!! **
248
                                                                -- if no parallel access, master can access
249
                                                                --else
250
                                                                --      if arb_out(i).rd = '1' then
251
                                                                --              next_state(i) <= read;
252
                                                                --      elsif arb_out(i).wr = '1' then
253
                                                                --              next_state(i) <= write; 
254
                                                                --      end if;
255
                                                                end if;
256
                                                        end loop;
257
                                                end if;
258
 
259
                                        -- rdy_cnt != 0 
260
                                        else
261
                                                if arb_out(i).rd = '1' then
262
                                                        next_state(i) <= waitingR;
263
                                                        waiting(i) <= '1';
264
                                                elsif arb_out(i).wr = '1' then
265
                                                        next_state(i) <= waitingW;
266
                                                        waiting(i) <= '1';
267
                                                end if;
268
                                        end if;
269
                                end if;
270
 
271
 
272
                        when read =>
273
                                next_state(i) <= idle;
274
 
275
                                -- pipelined gets blocked
276
                                if mem_in.rdy_cnt = 2 and arb_out(i).atomic = '1' then
277
                                         for j in 0 to cpu_cnt-1 loop
278
                                                        if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
279
                                                                if j<i then
280
                                                                        next_state(i) <= pipeBlocked;
281
                                                                        --wait_cycles <= 3;
282
                                                                        exit;
283
                                                                end if;
284
                                                        end if;
285
                                         end loop;
286
                                end if;
287
 
288
                        when write =>
289
                                next_state(i) <= idle;
290
 
291
                        when waitingR =>
292
                                if mem_in.rdy_cnt = 0 then
293
                                -- checks which CPU in waitingR has highest priority
294
                                        for j in 0 to cpu_cnt-1 loop
295
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
296
                                                        if j<i then
297
                                                                next_state(i) <= waitingR;
298
                                                                waiting(i) <= '1';
299
                                                                exit;
300
                                                        else
301
                                                                next_state(i) <= sendR;
302
                                                                exit;
303
                                                        end if;
304
                                                else
305
                                                        next_state(i) <= sendR;
306
                                                end if;
307
                                        end loop;
308
                                else
309
                                        next_state(i) <= waitingR;
310
                                        waiting(i) <= '1';
311
                                end if;
312
 
313
                        when sendR =>
314
                                next_state(i) <= idle;
315
 
316
                        when waitingW =>
317
 
318
                                if mem_in.rdy_cnt = 0 then
319
                                        for j in 0 to cpu_cnt-1 loop
320
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
321
                                                        if j<i then
322
                                                                next_state(i) <= waitingW;
323
                                                                waiting(i) <= '1';
324
                                                                exit;
325
                                                        else
326
                                                                next_state(i) <= sendW;
327
                                                                exit;
328
                                                        end if;
329
                                                else
330
                                                        next_state(i) <= sendW;
331
                                                end if;
332
                                        end loop;
333
                                else
334
                                        next_state(i) <= waitingW;
335
                                        waiting(i) <= '1';
336
                                end if;
337
 
338
                        when sendW =>
339
                                next_state(i) <= idle;
340
 
341
                        when pipeBlocked =>
342
                                if mem_in.rdy_cnt = 0 then -- to be in serv Mode until request done
343
                                        next_state(i) <= waitingR; --no waitingW possible because we don't use pipelined write!!!!!
344
                                else
345
                                        next_state(i) <= pipeBlocked;
346
                                end if;
347
 
348
                end case;
349
        end process;
350
end generate;
351
 
352
 
353
-- Generates the FSM state for each master
354
gen_state: for i in 0 to cpu_cnt-1 generate
355
        process (clk, reset)
356
        begin
357
                if (reset = '1') then
358
                        state(i) <= idle;
359
        elsif (rising_edge(clk)) then
360
                        state(i) <= next_state(i);
361
                end if;
362
        end process;
363
end generate;
364
 
365
 
366
-- The arbiter output
367
process (arb_out, reg_in, next_state)
368
begin
369
 
370
        mem_out.rd <= '0';
371
        mem_out.wr <= '0';
372
        mem_out.address <= (others => '0');
373
        mem_out.wr_data <= (others => '0');
374
        mem_out.atomic <= '0';
375
 
376
        for i in 0 to cpu_cnt-1 loop
377
                set(i) <= '0';
378
 
379
                case next_state(i) is
380
                        when idle =>
381
 
382
                        when read =>
383
                                set(i) <= '1';
384
                                mem_out.rd <= arb_out(i).rd;
385
                                mem_out.address <= arb_out(i).address;
386
 
387
                        when write =>
388
                                set(i) <= '1';
389
                                mem_out.wr <= arb_out(i).wr;
390
                                mem_out.address <= arb_out(i).address;
391
                                mem_out.wr_data <= arb_out(i).wr_data;
392
 
393
                        when waitingR =>
394
 
395
                        when sendR =>
396
                                set(i) <= '1';
397
                                mem_out.rd <= reg_in(i).rd;
398
                                mem_out.address <= reg_in(i).address;
399
 
400
                        when waitingW =>
401
 
402
                        when sendW =>
403
                                set(i) <= '1';
404
                                mem_out.wr <= reg_in(i).wr;
405
                                mem_out.address <= reg_in(i).address;
406
                                mem_out.wr_data <= reg_in(i).wr_data;
407
 
408
                        when pipeBlocked =>
409
                                set(i) <= '1';
410
 
411
                end case;
412
        end loop;
413
end process;
414
 
415
-- generation of follow_state
416
gen_serve: for i in 0 to cpu_cnt-1 generate
417
        process(mem_in, set, this_state)
418
        begin
419
                case this_state(i) is
420
                        when idl =>
421
                                follow_state(i) <= idl;
422
                                if set(i) = '1' then
423
                                        follow_state(i) <= serv;
424
                                end if;
425
                        when serv =>
426
                                follow_state(i) <= serv;
427
                                if mem_in.rdy_cnt = 0 and set(i) = '0' then
428
                                        follow_state(i) <= idl;
429
                                end if;
430
                end case;
431
        end process;
432
end generate;
433
 
434
gen_serve2: for i in 0 to cpu_cnt-1 generate
435
        process (clk, reset)
436
        begin
437
                if (reset = '1') then
438
                        this_state(i) <= idl;
439
        elsif (rising_edge(clk)) then
440
                        this_state(i) <= follow_state(i);
441
                end if;
442
        end process;
443
end generate;
444
 
445
gen_rdy_cnt: for i in 0 to cpu_cnt-1 generate
446
        process (mem_in, state, this_state)
447
        begin
448
                arb_in(i).rdy_cnt <= mem_in.rdy_cnt;
449
                arb_in(i).rd_data <= mem_in.rd_data;
450
 
451
                case state(i) is
452
                        when idle =>
453
                                case this_state(i) is
454
                                        when idl =>
455
                                                arb_in(i).rdy_cnt <= "00";
456
                                        when serv =>
457
                                end case;
458
 
459
                        when read =>
460
 
461
                        when write =>
462
 
463
                        when waitingR =>
464
                                arb_in(i).rdy_cnt <= "11";
465
 
466
                        when sendR =>
467
 
468
                        when waitingW =>
469
                                arb_in(i).rdy_cnt <= "11";
470
 
471
                        when sendW =>
472
 
473
                        when pipeBlocked =>
474
                                arb_in(i).rdy_cnt <= "11";
475
 
476
                end case;
477
        end process;
478
end generate;
479
 
480
end rtl;

powered by: WebSVN 2.1.0

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