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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_arbiter_fair.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
-- 150108: Quasi Round Robin Arbiter -- added sync signal to arbiter
31
-- 160108: First tests running with new Round Robin Arbiter
32
-- 250408: Renaming of this_state to mode, follow_state to next_mode, reg_in to reg_out
33
-- 240708: added data_reg for each CPU in arbiter
34
-- 070808: removed combinatorial loop (pipelined bug)
35
-- 210808: - reg_in_rd_data(i) also gets loaded when rdy_cnt = 3 using pipelined access
36
--                               - arb_in(i).rd_data gets mem_in.rd_data when rdy_cnt 3 using pipelined access
37
 
38
 
39
-- Functioning: See description of SIES08 paper
40
 
41
library ieee;
42
use ieee.std_logic_1164.all;
43
use ieee.numeric_std.all;
44
 
45
use work.sc_pack.all;
46
use work.sc_arbiter_pack.all;
47
use work.jop_types.all;
48
 
49
entity arbiter is
50
generic(
51
                        addr_bits : integer;
52
                        cpu_cnt : integer);             -- number of masters for the arbiter
53
port (
54
                        clk, reset      : in std_logic;
55
                        arb_out                 : in arb_out_type(0 to cpu_cnt-1);
56
                        arb_in                  : out arb_in_type(0 to cpu_cnt-1);
57
                        mem_out                 : out sc_out_type;
58
                        mem_in                  : in sc_in_type
59
);
60
end arbiter;
61
 
62
 
63
architecture rtl of arbiter is
64
 
65
-- stores the signals in a register of each master
66
 
67
        type reg_type is record
68
                rd : std_logic;
69
                wr : std_logic;
70
                wr_data : std_logic_vector(31 downto 0);
71
                address : std_logic_vector(addr_bits-1 downto 0);
72
        end record;
73
 
74
        type reg_out_type is array (0 to cpu_cnt-1) of reg_type;
75
        signal reg_out : reg_out_type;
76
 
77
-- register to CPU for rd_data
78
 
79
        type reg_in_type is array (0 to cpu_cnt-1) of std_logic_vector(31 downto 0);
80
        signal reg_in_rd_data : reg_in_type;
81
 
82
-- one fsm for each CPU
83
 
84
        type state_type is (idle, read, write, waitingR, sendR,
85
        waitingW, sendW);
86
        type state_array is array (0 to cpu_cnt-1) of state_type;
87
        signal state : state_array;
88
        signal next_state : state_array;
89
 
90
-- one fsm for each serve
91
 
92
        type serve_type is (idl, servR, servW);
93
        type serve_array is array (0 to cpu_cnt-1) of serve_type;
94
        signal mode : serve_array;
95
        signal next_mode : serve_array;
96
 
97
-- arbiter 
98
 
99
        type set_type is array (0 to cpu_cnt-1) of std_logic_vector(1 downto 0);
100
        signal set : set_type;
101
        type pipelined_type is array (0 to cpu_cnt-1) of std_logic;
102
        signal pipelined : pipelined_type;
103
        signal next_pipelined : pipelined_type;
104
 
105
-- counter
106
        signal counter : integer;
107
        type slot_type is array (0 to cpu_cnt-1) of std_logic;
108
        signal slot : slot_type; -- defines which CPU is on turn
109
 
110
 
111
begin
112
 
113
 
114
-- Generates the input register and saves incoming data for each master
115
gen_register: for i in 0 to cpu_cnt-1 generate
116
        process(clk, reset)
117
        begin
118
                if reset = '1' then
119
                        reg_out(i).rd <= '0';
120
                        reg_out(i).wr <= '0';
121
                        reg_out(i).wr_data <= (others => '0');
122
                        reg_out(i).address <= (others => '0');
123
                elsif rising_edge(clk) then
124
                        if arb_out(i).rd = '1' or arb_out(i).wr = '1' then
125
                                reg_out(i).rd <= arb_out(i).rd;
126
                                reg_out(i).wr <= arb_out(i).wr;
127
                                reg_out(i).address <= arb_out(i).address;
128
                                reg_out(i).wr_data <= arb_out(i).wr_data;
129
                        end if;
130
                end if;
131
        end process;
132
end generate;
133
 
134
-- Generate Counter
135
process(clk, reset)
136
        begin
137
                if reset = '1' then
138
                        counter <= 0;
139
                elsif rising_edge(clk) then
140
                        counter <= counter + 1;
141
 
142
                        for i in 0 to cpu_cnt-1 loop
143
                                if next_mode(i) = servR or next_mode(i) = servW then
144
                                        if mem_in.rdy_cnt = 1 and arb_out(i).rd = '0' then
145
                                                if counter = cpu_cnt-1 then
146
                                                        counter <= 0;
147
                                                else
148
                                                        counter <= counter+1;
149
                                                end if;
150
                                                exit;
151
                                        else
152
                                                counter <= counter;
153
                                                exit;
154
                                        end if;
155
                                elsif counter = cpu_cnt-1 then
156
                                                counter <= 0;
157
                                end if;
158
                        end loop;
159
                end if;
160
end process;
161
 
162
-- The slot is assigned depending on the counter 
163
process(counter)
164
        begin
165
                for j in 0 to cpu_cnt-1 loop
166
                        if j = counter then
167
                                slot(j) <= '1';
168
                        else
169
                                slot(j) <= '0';
170
                        end if;
171
                end loop;
172
end process;
173
 
174
 
175
-- Generates next state of the FSM for each master
176
gen_next_state: for i in 0 to cpu_cnt-1 generate
177
        process(state, mode, slot, mem_in, arb_out, pipelined)
178
        begin
179
 
180
                next_state(i) <= state(i);
181
 
182
                case state(i) is
183
                        when idle =>
184
                                next_pipelined(i) <= '0';
185
 
186
                                -- is CPU allowed to access
187
                                if (slot(i) = '1') then
188
 
189
                                        -- pipelined read access
190
                                        if (mode(i) = servR) and (mem_in.rdy_cnt = 1) and (arb_out(i).rd = '1') then
191
                                                next_state(i) <= read;
192
                                                next_pipelined(i) <= '1';
193
 
194
                                        elsif (mode(i) = servR) and (mem_in.rdy_cnt = 0) then
195
                                                if arb_out(i).rd = '1' then
196
                                                        next_state(i) <= read;
197
                                                elsif arb_out(i).wr = '1' then
198
                                                        next_state(i) <= write;
199
                                                end if;
200
 
201
                                        elsif (mode(i) = servW) and (mem_in.rdy_cnt = 0) then
202
                                                if arb_out(i).rd = '1' then
203
                                                        next_state(i) <= read;
204
                                                elsif arb_out(i).wr = '1' then
205
                                                        next_state(i) <= write;
206
                                                end if;
207
 
208
                                        elsif (mode(i) = idl) and (mem_in.rdy_cnt = 0) then
209
                                                if arb_out(i).rd = '1' then
210
                                                        next_state(i) <= read;
211
                                                elsif arb_out(i).wr = '1' then
212
                                                        next_state(i) <= write;
213
                                                end if;
214
 
215
                                        -- all other kinds (can that happen at all?)
216
                                        else
217
                                                if arb_out(i).rd = '1' then
218
                                                        next_state(i) <= waitingR;
219
                                                elsif arb_out(i).wr = '1' then
220
                                                        next_state(i) <= waitingW;
221
                                                end if;
222
                                        end if;
223
 
224
                                -- CPU is not allowed to access
225
                                else
226
                                        if arb_out(i).rd = '1' then
227
                                                next_state(i) <= waitingR;
228
                                        elsif arb_out(i).wr = '1' then
229
                                                next_state(i) <= waitingW;
230
                                        end if;
231
                                end if;
232
 
233
                        when read =>
234
                                next_state(i) <= idle;
235
                                next_pipelined(i) <= '0';
236
 
237
                                if pipelined(i) = '1' then
238
                                        next_pipelined(i) <= '1';
239
                                end if;
240
 
241
                        when write =>
242
                                next_state(i) <= idle;
243
                                next_pipelined(i) <= '0';
244
 
245
                        when waitingR =>
246
                                next_pipelined(i) <= '0';
247
                                if ((mem_in.rdy_cnt = 0) and (slot(i) = '1')) then
248
                                        next_state(i) <= sendR;
249
                                else
250
                                        next_state(i) <= waitingR;
251
                                end if;
252
 
253
                        when sendR =>
254
                                next_state(i) <= idle;
255
                                next_pipelined(i) <= '0';
256
 
257
                        when waitingW =>
258
                                next_pipelined(i) <= '0';
259
                                if ((mem_in.rdy_cnt = 0) and (slot(i) = '1')) then
260
                                        next_state(i) <= sendW;
261
                                else
262
                                        next_state(i) <= waitingW;
263
                                end if;
264
 
265
                        when sendW =>
266
                                next_state(i) <= idle;
267
                                next_pipelined(i) <= '0';
268
 
269
                end case;
270
        end process;
271
end generate;
272
 
273
 
274
-- Generates the FSM state for each master
275
gen_state: for i in 0 to cpu_cnt-1 generate
276
        process (clk, reset)
277
        begin
278
                if (reset = '1') then
279
                        state(i) <= idle;
280
                        pipelined(i) <= '0';
281
        elsif (rising_edge(clk)) then
282
                        state(i) <= next_state(i);
283
                        pipelined(i) <= next_pipelined(i);
284
                end if;
285
        end process;
286
end generate;
287
 
288
 
289
-- The arbiter output
290
process (arb_out, reg_out, next_state)
291
begin
292
 
293
        mem_out.rd <= '0';
294
        mem_out.wr <= '0';
295
        mem_out.address <= (others => '0');
296
        mem_out.wr_data <= (others => '0');
297
        mem_out.atomic <= '0';
298
 
299
        for i in 0 to cpu_cnt-1 loop
300
                set(i) <= "00";
301
 
302
                case next_state(i) is
303
                        when idle =>
304
 
305
                        when read =>
306
                                set(i) <= "01";
307
                                mem_out.rd <= arb_out(i).rd;
308
                                mem_out.address <= arb_out(i).address;
309
 
310
                        when write =>
311
                                set(i) <= "10";
312
                                mem_out.wr <= arb_out(i).wr;
313
                                mem_out.address <= arb_out(i).address;
314
                                mem_out.wr_data <= arb_out(i).wr_data;
315
 
316
                        when waitingR =>
317
 
318
                        when sendR =>
319
                                set(i) <= "01";
320
                                mem_out.rd <= reg_out(i).rd;
321
                                mem_out.address <= reg_out(i).address;
322
 
323
                        when waitingW =>
324
 
325
                        when sendW =>
326
                                set(i) <= "10";
327
                                mem_out.wr <= reg_out(i).wr;
328
                                mem_out.address <= reg_out(i).address;
329
                                mem_out.wr_data <= reg_out(i).wr_data;
330
 
331
                end case;
332
        end loop;
333
end process;
334
 
335
-- generation of next_mode
336
gen_serve: for i in 0 to cpu_cnt-1 generate
337
        process(mem_in, set, mode)
338
        begin
339
                case mode(i) is
340
                        when idl =>
341
                                next_mode(i) <= idl;
342
                                if set(i) = "01" then
343
                                        next_mode(i) <= servR;
344
                                elsif set(i) = "10" then
345
                                        next_mode(i) <= servW;
346
                                end if;
347
                        when servR =>
348
                                next_mode(i) <= servR;
349
                                if mem_in.rdy_cnt = 0 and set(i) = "00" then
350
                                        next_mode(i) <= idl;
351
                                end if;
352
                        when servW =>
353
                                next_mode(i) <= servW;
354
                                if mem_in.rdy_cnt = 0 and set(i) = "00" then
355
                                        next_mode(i) <= idl;
356
                                end if;
357
                end case;
358
        end process;
359
end generate;
360
 
361
gen_serve2: for i in 0 to cpu_cnt-1 generate
362
        process (clk, reset)
363
        begin
364
                if (reset = '1') then
365
                        mode(i) <= idl;
366
        elsif (rising_edge(clk)) then
367
                        mode(i) <= next_mode(i);
368
                end if;
369
        end process;
370
end generate;
371
 
372
 
373
 
374
-- Registers rd_data for each CPU
375
gen_reg_in: for i in 0 to cpu_cnt-1 generate
376
        process(clk, reset)
377
        begin
378
                if reset = '1' then
379
                        reg_in_rd_data(i) <= (others => '0');
380
                elsif rising_edge(clk) then
381
                        if mode(i) = servR then
382
                                if mem_in.rdy_cnt = 0 then
383
                                        reg_in_rd_data(i) <= mem_in.rd_data;
384
 
385
                                -- added mem_in.rdy_cnt = 3. 
386
                                -- More correct would be: ((mem_in.rdy_cnt = ram_cnt) or (mem_in.rdy_cnt = 3))
387
                                elsif ((( mem_in.rdy_cnt = 2 ) or ( mem_in.rdy_cnt = 3 )) and (next_pipelined(i) = '1')) then
388
                                        reg_in_rd_data(i) <= mem_in.rd_data;
389
                                end if;
390
                        end if;
391
                end if;
392
        end process;
393
end generate;
394
 
395
 
396
 
397
-- Generates rdy_cnt and rd_data for all CPUs
398
gen_rdy_cnt: for i in 0 to cpu_cnt-1 generate
399
        process (mem_in, state, mode, reg_in_rd_data, next_pipelined)
400
        begin
401
 
402
                arb_in(i).rd_data <= reg_in_rd_data(i);
403
                arb_in(i).rdy_cnt <= mem_in.rdy_cnt;
404
 
405
                case state(i) is
406
                        when idle =>
407
                                if (mode(i) = idl) then
408
                                        arb_in(i).rdy_cnt <= "00";
409
                                elsif (mode(i) = servR) and (mem_in.rdy_cnt = 0) then
410
                                        arb_in(i).rd_data <= mem_in.rd_data;
411
                                end if;
412
 
413
                        when read =>
414
                                if (mode(i) = servR) then
415
                                        if (mem_in.rdy_cnt = 0) then
416
                                                arb_in(i).rd_data <= mem_in.rd_data;
417
                                        -- added mem_in.rdy_cnt = 3
418
                                        elsif ((( mem_in.rdy_cnt = 2 ) or ( mem_in.rdy_cnt = 3 )) and (next_pipelined(i) = '1')) then
419
                                                arb_in(i).rd_data <= mem_in.rd_data;
420
                                        end if;
421
                                end if;
422
 
423
                        when write =>
424
 
425
                        when waitingR =>
426
                                arb_in(i).rdy_cnt <= "11";
427
                                if mode(i) = servR then
428
                                        arb_in(i).rd_data <= mem_in.rd_data;
429
                                end if;
430
 
431
                        when sendR =>
432
 
433
                        when waitingW =>
434
                                arb_in(i).rdy_cnt <= "11";
435
 
436
                        when sendW =>
437
 
438
                end case;
439
        end process;
440
end generate;
441
 
442
end rtl;

powered by: WebSVN 2.1.0

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