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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_arbiter_fixedpr.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
-- 210208: Does not use atomic
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);
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
                                        -- pipelined access
145
                                        if mem_in.rdy_cnt = 1 and arb_out(i).rd = '1' then
146
                                                next_state(i) <= read;
147
 
148
                                        elsif (mem_in.rdy_cnt = 0 and (arb_out(i).rd = '1' or arb_out(i).wr = '1')) then
149
 
150
                                                -- check if some master is waiting
151
                                                if masterWaiting = '1' then
152
                                                        if arb_out(i).rd = '1' then
153
                                                                next_state(i) <= waitingR;
154
                                                                waiting(i) <= '1';
155
                                                        elsif arb_out(i).wr = '1' then
156
                                                                next_state(i) <= waitingW;
157
                                                                waiting(i) <= '1';
158
                                                        end if;
159
 
160
                                                -- check if parallel access             
161
                                                else
162
                                                        for j in 0 to cpu_cnt-1 loop
163
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
164
                                                                        if i<=j then
165
                                                                                if arb_out(i).rd = '1' then
166
                                                                                        next_state(i) <= read;
167
                                                                                        exit;
168
                                                                                elsif arb_out(i).wr = '1' then
169
                                                                                        next_state(i) <= write;
170
                                                                                        exit;
171
                                                                                end if;
172
                                                                        else
173
                                                                                if arb_out(i).rd = '1' then
174
                                                                                        next_state(i) <= waitingR;
175
                                                                                        waiting(i) <= '1';
176
                                                                                        exit;
177
                                                                                elsif arb_out(i).wr = '1' then
178
                                                                                        next_state(i) <= waitingW;
179
                                                                                        waiting(i) <= '1';
180
                                                                                        exit;
181
                                                                                end if;
182
                                                                        end if;
183
                                                                end if;
184
                                                        end loop;
185
                                                end if;
186
 
187
                                        -- all other kinds of rdy_cnt
188
                                        else
189
                                                if arb_out(i).rd = '1' then
190
                                                        next_state(i) <= waitingR;
191
                                                        waiting(i) <= '1';
192
                                                elsif arb_out(i).wr = '1' then
193
                                                        next_state(i) <= waitingW;
194
                                                        waiting(i) <= '1';
195
                                                end if;
196
                                        end if;
197
 
198
                                -- CPU is not on turn (no pipelined access possible)
199
                                else
200
                                        if (mem_in.rdy_cnt = 0 and (arb_out(i).rd = '1' or arb_out(i).wr = '1')) then
201
                                                -- check if some master is waiting
202
                                                if masterWaiting = '1' then
203
                                                        if arb_out(i).rd = '1' then
204
                                                                next_state(i) <= waitingR;
205
                                                                waiting(i) <= '1';
206
                                                        elsif arb_out(i).wr = '1' then
207
                                                                next_state(i) <= waitingW;
208
                                                                waiting(i) <= '1';
209
                                                        end if;
210
 
211
                                                -- check if parallel access             
212
                                                else
213
                                                        for j in 0 to cpu_cnt-1 loop
214
                                                                if arb_out(j).rd = '1' or arb_out(j).wr = '1' then
215
                                                                        if i<=j then
216
                                                                                if arb_out(i).rd = '1' then
217
                                                                                        next_state(i) <= read;
218
                                                                                        exit;
219
                                                                                elsif arb_out(i).wr = '1' then
220
                                                                                        next_state(i) <= write;
221
                                                                                        exit;
222
                                                                                end if;
223
                                                                        else
224
                                                                                if arb_out(i).rd = '1' then
225
                                                                                        next_state(i) <= waitingR;
226
                                                                                        waiting(i) <= '1';
227
                                                                                        exit;
228
                                                                                elsif arb_out(i).wr = '1' then
229
                                                                                        next_state(i) <= waitingW;
230
                                                                                        waiting(i) <= '1';
231
                                                                                        exit;
232
                                                                                end if;
233
                                                                        end if;
234
                                                                -- if no parallel access, master can access
235
                                                                else
236
                                                                        if arb_out(i).rd = '1' then
237
                                                                                next_state(i) <= read;
238
                                                                        elsif arb_out(i).wr = '1' then
239
                                                                                next_state(i) <= write;
240
                                                                        end if;
241
                                                                end if;
242
                                                        end loop;
243
                                                end if;
244
 
245
                                        -- rdy_cnt != 0 
246
                                        else
247
                                                if arb_out(i).rd = '1' then
248
                                                        next_state(i) <= waitingR;
249
                                                        waiting(i) <= '1';
250
                                                elsif arb_out(i).wr = '1' then
251
                                                        next_state(i) <= waitingW;
252
                                                        waiting(i) <= '1';
253
                                                end if;
254
                                        end if;
255
                                end if;
256
 
257
 
258
                        when read =>
259
                                next_state(i) <= idle;
260
 
261
                        when write =>
262
                                next_state(i) <= idle;
263
 
264
                        when waitingR =>
265
                                if mem_in.rdy_cnt = 0 then
266
                                -- checks which CPU in waitingR has highest priority
267
                                        for j in 0 to cpu_cnt-1 loop
268
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
269
                                                        if j<i then
270
                                                                next_state(i) <= waitingR;
271
                                                                waiting(i) <= '1';
272
                                                                exit;
273
                                                        elsif j=i then
274
                                                                next_state(i) <= sendR;
275
                                                                exit;
276
                                                        else
277
                                                                next_state(i) <= sendR;
278
                                                                exit;
279
                                                        end if;
280
                                                else
281
                                                        next_state(i) <= sendR;
282
                                                end if;
283
                                        end loop;
284
                                else
285
                                        next_state(i) <= waitingR;
286
                                        waiting(i) <= '1';
287
                                end if;
288
 
289
                        when sendR =>
290
                                next_state(i) <= idle;
291
 
292
                        when waitingW =>
293
 
294
                                if mem_in.rdy_cnt = 0 then
295
                                        for j in 0 to cpu_cnt-1 loop
296
                                                if (state(j) = waitingR) or (state(j) = waitingW) then
297
                                                        if j<i then
298
                                                                next_state(i) <= waitingW;
299
                                                                waiting(i) <= '1';
300
                                                                exit;
301
                                                        elsif j=i then
302
                                                                next_state(i) <= sendW;
303
                                                                exit;
304
                                                        else
305
                                                                next_state(i) <= sendW;
306
                                                                exit;
307
                                                        end if;
308
                                                else
309
                                                        next_state(i) <= sendW;
310
                                                end if;
311
                                        end loop;
312
                                else
313
                                        next_state(i) <= waitingW;
314
                                        waiting(i) <= '1';
315
                                end if;
316
 
317
                        when sendW =>
318
                                next_state(i) <= idle;
319
 
320
                end case;
321
        end process;
322
end generate;
323
 
324
 
325
-- Generates the FSM state for each master
326
gen_state: for i in 0 to cpu_cnt-1 generate
327
        process (clk, reset)
328
        begin
329
                if (reset = '1') then
330
                        state(i) <= idle;
331
        elsif (rising_edge(clk)) then
332
                        state(i) <= next_state(i);
333
                end if;
334
        end process;
335
end generate;
336
 
337
 
338
-- The arbiter output
339
process (arb_out, reg_in, next_state)
340
begin
341
 
342
        mem_out.rd <= '0';
343
        mem_out.wr <= '0';
344
        mem_out.address <= (others => '0');
345
        mem_out.wr_data <= (others => '0');
346
        mem_out.atomic <= '0';
347
 
348
        for i in 0 to cpu_cnt-1 loop
349
                set(i) <= '0';
350
 
351
                case next_state(i) is
352
                        when idle =>
353
 
354
                        when read =>
355
                                set(i) <= '1';
356
                                mem_out.rd <= arb_out(i).rd;
357
                                mem_out.address <= arb_out(i).address;
358
 
359
                        when write =>
360
                                set(i) <= '1';
361
                                mem_out.wr <= arb_out(i).wr;
362
                                mem_out.address <= arb_out(i).address;
363
                                mem_out.wr_data <= arb_out(i).wr_data;
364
 
365
                        when waitingR =>
366
 
367
                        when sendR =>
368
                                set(i) <= '1';
369
                                mem_out.rd <= reg_in(i).rd;
370
                                mem_out.address <= reg_in(i).address;
371
 
372
                        when waitingW =>
373
 
374
                        when sendW =>
375
                                set(i) <= '1';
376
                                mem_out.wr <= reg_in(i).wr;
377
                                mem_out.address <= reg_in(i).address;
378
                                mem_out.wr_data <= reg_in(i).wr_data;
379
 
380
                end case;
381
        end loop;
382
end process;
383
 
384
-- generation of follow_state
385
gen_serve: for i in 0 to cpu_cnt-1 generate
386
        process(mem_in, set, this_state)
387
        begin
388
                case this_state(i) is
389
                        when idl =>
390
                                follow_state(i) <= idl;
391
                                if set(i) = '1' then
392
                                        follow_state(i) <= serv;
393
                                end if;
394
                        when serv =>
395
                                follow_state(i) <= serv;
396
                                if mem_in.rdy_cnt = 0 and set(i) = '0' then
397
                                        follow_state(i) <= idl;
398
                                end if;
399
                end case;
400
        end process;
401
end generate;
402
 
403
gen_serve2: for i in 0 to cpu_cnt-1 generate
404
        process (clk, reset)
405
        begin
406
                if (reset = '1') then
407
                        this_state(i) <= idl;
408
        elsif (rising_edge(clk)) then
409
                        this_state(i) <= follow_state(i);
410
                end if;
411
        end process;
412
end generate;
413
 
414
gen_rdy_cnt: for i in 0 to cpu_cnt-1 generate
415
        process (mem_in, state, this_state)
416
        begin
417
                arb_in(i).rdy_cnt <= mem_in.rdy_cnt;
418
                arb_in(i).rd_data <= mem_in.rd_data;
419
 
420
                case state(i) is
421
                        when idle =>
422
                                case this_state(i) is
423
                                        when idl =>
424
                                                arb_in(i).rdy_cnt <= "00";
425
                                        when serv =>
426
                                end case;
427
 
428
                        when read =>
429
 
430
                        when write =>
431
 
432
                        when waitingR =>
433
                                arb_in(i).rdy_cnt <= "11";
434
 
435
                        when sendR =>
436
 
437
                        when waitingW =>
438
                                arb_in(i).rdy_cnt <= "11";
439
 
440
                        when sendW =>
441
 
442
                end case;
443
        end process;
444
end generate;
445
 
446
end rtl;

powered by: WebSVN 2.1.0

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