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

Subversion Repositories wb_vga

[/] [wb_vga/] [tags/] [a01/] [wb_tk.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tantos
--
2
--  Wishbone bus toolkit.
3
--
4
--  (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
5
--  This code is distributed under the terms and conditions of the GNU General Public Lince.
6
--
7
--
8
-- ELEMENTS:
9
--   wb_bus_upsize: bus upsizer. Currently only 8->16 bit bus resize is supported
10
--   wb_async_slave: Wishbone bus to async (SRAM-like) bus slave bridge.
11
--   wb_arbiter: two-way bus arbiter. Asyncronous logic ensures 0-ws operation on shared bus
12
--   wb_out_reg: Wishbone bus compatible output register.
13
 
14
library IEEE;
15
use IEEE.std_logic_1164.all;
16
 
17
package wb_tk is
18
        component wb_bus_upsize is
19
                generic (
20
                        m_bus_width: positive := 8; -- master bus width
21
                        m_addr_width: positive := 21; -- master bus width
22
                        s_bus_width: positive := 16; -- slave bus width
23
                        s_addr_width: positive := 20; -- master bus width
24
                        little_endien: boolean := true -- if set to false, big endien
25
                );
26
                port (
27
        --              clk_i: in std_logic;
28
        --              rst_i: in std_logic := '0';
29
 
30
                        -- Master bus interface
31
                        m_adr_i: in std_logic_vector (m_addr_width-1 downto 0);
32
                        m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1');
33
                        m_dat_i: in std_logic_vector (m_bus_width-1 downto 0);
34
                        m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-');
35
                        m_dat_o: out std_logic_vector (m_bus_width-1 downto 0);
36
                        m_cyc_i: in std_logic;
37
                        m_ack_o: out std_logic;
38
                        m_ack_oi: in std_logic := '-';
39
                        m_err_o: out std_logic;
40
                        m_err_oi: in std_logic := '-';
41
                        m_rty_o: out std_logic;
42
                        m_rty_oi: in std_logic := '-';
43
                        m_we_i: in std_logic;
44
                        m_stb_i: in std_logic;
45
 
46
                        -- Slave bus interface
47
                        s_adr_o: out std_logic_vector (s_addr_width-1 downto 0);
48
                        s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0);
49
                        s_dat_i: in std_logic_vector (s_bus_width-1 downto 0);
50
                        s_dat_o: out std_logic_vector (s_bus_width-1 downto 0);
51
                        s_cyc_o: out std_logic;
52
                        s_ack_i: in std_logic;
53
                        s_err_i: in std_logic := '-';
54
                        s_rty_i: in std_logic := '-';
55
                        s_we_o: out std_logic;
56
                        s_stb_o: out std_logic
57
                );
58
        end component;
59
 
60
        component wb_async_master is
61
                generic (
62
                        width: positive := 16;
63
                        addr_width: positive := 20
64
                );
65
                port (
66
                        clk_i: in std_logic;
67
                        rst_i: in std_logic := '0';
68
 
69
                        -- interface to wb slave devices
70
                        s_adr_o: out std_logic_vector (addr_width-1 downto 0);
71
                        s_sel_o: out std_logic_vector ((width/8)-1 downto 0);
72
                        s_dat_i: in std_logic_vector (width-1 downto 0);
73
                        s_dat_o: out std_logic_vector (width-1 downto 0);
74
                        s_cyc_o: out std_logic;
75
                        s_ack_i: in std_logic;
76
                        s_err_i: in std_logic := '-';
77
                        s_rty_i: in std_logic := '-';
78
                        s_we_o: out std_logic;
79
                        s_stb_o: out std_logic;
80
 
81
                        -- interface to asyncron master device
82
                        a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
83
                        a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U');
84
                        a_rdn: in std_logic := '1';
85
                        a_wrn: in std_logic := '1';
86
                        a_cen: in std_logic := '1';
87
                        a_byen: in std_logic_vector ((width/8)-1 downto 0);
88
                        a_waitn: out std_logic
89
                );
90
        end component;
91
 
92
        component wb_async_slave is
93
                generic (
94
                        width: positive := 16;
95
                        addr_width: positive := 20
96
                );
97
                port (
98
                        clk_i: in std_logic;
99
                        rst_i: in std_logic := '0';
100
 
101
                        -- interface for wait-state generator state-machine
102
                        wait_state: in std_logic_vector (3 downto 0);
103
 
104
                        -- interface to wishbone master device
105
                        adr_i: in std_logic_vector (addr_width-1 downto 0);
106
                        sel_i: in std_logic_vector ((addr_width/8)-1 downto 0);
107
                        dat_i: in std_logic_vector (width-1 downto 0);
108
                        dat_o: out std_logic_vector (width-1 downto 0);
109
                        dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-');
110
                        we_i: in std_logic;
111
                        stb_i: in std_logic;
112
                        ack_o: out std_logic := '0';
113
                        ack_oi: in std_logic := '-';
114
 
115
                        -- interface to async slave
116
                        a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
117
                        a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U');
118
                        a_rdn: out std_logic := '1';
119
                        a_wrn: out std_logic := '1';
120
                        a_cen: out std_logic := '1';
121
                        -- byte-enable signals
122
                        a_byen: out std_logic_vector ((width/8)-1 downto 0)
123
                );
124
        end component;
125
 
126
        component wb_arbiter is
127
                port (
128
        --              clk_i: in std_logic;
129
                        rst_i: in std_logic := '0';
130
 
131
                        -- interface to master device a
132
                        a_we_i: in std_logic;
133
                        a_stb_i: in std_logic;
134
                        a_cyc_i: in std_logic;
135
                        a_ack_o: out std_logic;
136
                        a_ack_oi: in std_logic := '-';
137
                        a_err_o: out std_logic;
138
                        a_err_oi: in std_logic := '-';
139
                        a_rty_o: out std_logic;
140
                        a_rty_oi: in std_logic := '-';
141
 
142
                        -- interface to master device b
143
                        b_we_i: in std_logic;
144
                        b_stb_i: in std_logic;
145
                        b_cyc_i: in std_logic;
146
                        b_ack_o: out std_logic;
147
                        b_ack_oi: in std_logic := '-';
148
                        b_err_o: out std_logic;
149
                        b_err_oi: in std_logic := '-';
150
                        b_rty_o: out std_logic;
151
                        b_rty_oi: in std_logic := '-';
152
 
153
                        -- interface to shared devices
154
                        s_we_o: out std_logic;
155
                        s_stb_o: out std_logic;
156
                        s_cyc_o: out std_logic;
157
                        s_ack_i: in std_logic;
158
                        s_err_i: in std_logic := '-';
159
                        s_rty_i: in std_logic := '-';
160
 
161
                        mux_signal: out std_logic; -- 0: select A signals, 1: select B signals
162
 
163
                        -- misc control lines
164
                        priority: in std_logic -- 0: A have priority over B, 1: B have priority over A
165
                );
166
        end component;
167
 
168
        component wb_out_reg is
169
                generic (
170
                        width : positive := 8;
171
                        bus_width: positive := 8;
172
                        offset: integer := 0
173
                );
174
                port (
175
                        clk_i: in std_logic;
176
                        rst_i: in std_logic;
177
                        rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
178
 
179
                        dat_i: in std_logic_vector (bus_width-1 downto 0);
180
                        dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
181
                        dat_o: out std_logic_vector (bus_width-1 downto 0);
182
                        q: out std_logic_vector (width-1 downto 0);
183
                        we_i: in std_logic;
184
                        stb_i: in std_logic;
185
                        ack_o: out std_logic;
186
                        ack_oi: in std_logic := '-'
187
                );
188
        end component;
189
end wb_tk;
190
 
191
-------------------------------------------------------------------------------
192
--
193
--  wb_bus_upsize
194
--
195
-------------------------------------------------------------------------------
196
 
197
library IEEE;
198
library synopsys;
199
use IEEE.std_logic_1164.all;
200
use synopsys.std_logic_arith.all;
201
 
202
library work;
203
use work.technology.all;
204
 
205
entity wb_bus_upsize is
206
        generic (
207
                m_bus_width: positive := 8; -- master bus width
208
                m_addr_width: positive := 21; -- master bus width
209
                s_bus_width: positive := 16; -- slave bus width
210
                s_addr_width: positive := 20; -- master bus width
211
                little_endien: boolean := true -- if set to false, big endien
212
        );
213
        port (
214
--              clk_i: in std_logic;
215
--              rst_i: in std_logic := '0';
216
 
217
                -- Master bus interface
218
                m_adr_i: in std_logic_vector (m_addr_width-1 downto 0);
219
                m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1');
220
                m_dat_i: in std_logic_vector (m_bus_width-1 downto 0);
221
                m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-');
222
                m_dat_o: out std_logic_vector (m_bus_width-1 downto 0);
223
                m_cyc_i: in std_logic;
224
                m_ack_o: out std_logic;
225
                m_ack_oi: in std_logic := '-';
226
                m_err_o: out std_logic;
227
                m_err_oi: in std_logic := '-';
228
                m_rty_o: out std_logic;
229
                m_rty_oi: in std_logic := '-';
230
                m_we_i: in std_logic;
231
                m_stb_i: in std_logic;
232
 
233
                -- Slave bus interface
234
                s_adr_o: out std_logic_vector (s_addr_width-1 downto 0);
235
                s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0);
236
                s_dat_i: in std_logic_vector (s_bus_width-1 downto 0);
237
                s_dat_o: out std_logic_vector (s_bus_width-1 downto 0);
238
                s_cyc_o: out std_logic;
239
                s_ack_i: in std_logic;
240
                s_err_i: in std_logic := '-';
241
                s_rty_i: in std_logic := '-';
242
                s_we_o: out std_logic;
243
                s_stb_o: out std_logic
244
        );
245
end wb_bus_upsize;
246
 
247
architecture wb_bus_upsize of wb_bus_upsize is
248
        function log2(inp : integer) return integer is
249
        begin
250
                if (inp < 1) then return 0; end if;
251
                if (inp < 2) then return 0; end if;
252
                if (inp < 4) then return 1; end if;
253
                if (inp < 8) then return 2; end if;
254
                if (inp < 16) then return 3; end if;
255
                if (inp < 32) then return 4; end if;
256
                if (inp < 64) then return 5; end if;
257
                if (inp < 128) then return 6; end if;
258
                if (inp < 256) then return 7; end if;
259
                if (inp < 512) then return 8; end if;
260
                if (inp < 1024) then return 9; end if;
261
                if (inp < 2048) then return 10; end if;
262
                if (inp < 4096) then return 11; end if;
263
                if (inp < 8192) then return 12; end if;
264
                if (inp < 16384) then return 13; end if;
265
                if (inp < 32768) then return 14; end if;
266
                if (inp < 65538) then return 15; end if;
267
                return 16;
268
        end;
269
        function equ(a : std_logic_vector; b : integer) return boolean is
270
                variable b_s : std_logic_vector(a'RANGE);
271
        begin
272
                b_s := CONV_STD_LOGIC_VECTOR(b,a'HIGH+1);
273
                return (a = b_s);
274
        end;
275
        constant addr_diff: integer := log2(s_bus_width/m_bus_width);
276
        signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0);
277
begin
278
        assert (m_addr_width = s_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE;
279
        s_adr_o <= m_adr_i(m_addr_width-addr_diff downto addr_diff);
280
        s_we_o <= m_we_i;
281
        m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi);
282
        m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi);
283
        m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi);
284
        s_stb_o <= m_stb_i;
285
        s_cyc_o <= m_cyc_i;
286
 
287
 
288
        sel_dat_mux: process is
289
        begin
290
                wait on s_dat_i, m_adr_i;
291
                if (little_endien) then
292
                        for i in s_sel_o'RANGE loop
293
                                if (equ(m_adr_i(addr_diff-1 downto 0),i)) then
294
                                        s_sel_o(i) <= '1';
295
                                        i_m_dat_o <= s_dat_i(8*i+7 downto 8*i+0);
296
                                else
297
                                        s_sel_o(i) <= '0';
298
                                end if;
299
                        end loop;
300
                else
301
                        for i in s_sel_o'RANGE loop
302
                                if (equ(m_adr_i(addr_diff-1 downto 0),i)) then
303
                                        s_sel_o(s_sel_o'HIGH-i) <= '1';
304
                                        i_m_dat_o <= s_dat_i(s_dat_i'HIGH-8*i downto s_dat_i'HIGH-8*i-7);
305
                                else
306
                                        s_sel_o(s_sel_o'HIGH-i) <= '0';
307
                                end if;
308
                        end loop;
309
                end if;
310
        end process;
311
 
312
        d_i_for: for i in m_dat_o'RANGE generate
313
        m_dat_o(i) <= (m_stb_i and i_m_dat_o(i)) or (not m_stb_i and m_dat_oi(i));
314
        end generate;
315
 
316
        d_o_for: for i in s_sel_o'RANGE generate
317
                s_dat_o(8*i+7 downto 8*i+0) <= m_dat_i;
318
        end generate;
319
end wb_bus_upsize;
320
 
321
-------------------------------------------------------------------------------
322
--
323
--  wb_async_master
324
--
325
-------------------------------------------------------------------------------
326
 
327
library IEEE;
328
use IEEE.std_logic_1164.all;
329
 
330
library work;
331
use work.technology.all;
332
 
333
entity wb_async_master is
334
        generic (
335
                width: positive := 16;
336
                addr_width: positive := 20
337
        );
338
        port (
339
                clk_i: in std_logic;
340
                rst_i: in std_logic := '0';
341
 
342
                -- interface to wb slave devices
343
                s_adr_o: out std_logic_vector (addr_width-1 downto 0);
344
                s_sel_o: out std_logic_vector ((width/8)-1 downto 0);
345
                s_dat_i: in std_logic_vector (width-1 downto 0);
346
                s_dat_o: out std_logic_vector (width-1 downto 0);
347
                s_cyc_o: out std_logic;
348
                s_ack_i: in std_logic;
349
                s_err_i: in std_logic := '-';
350
                s_rty_i: in std_logic := '-';
351
                s_we_o: out std_logic;
352
                s_stb_o: out std_logic;
353
 
354
                -- interface to asyncron master device
355
                a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
356
                a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U');
357
                a_rdn: in std_logic := '1';
358
                a_wrn: in std_logic := '1';
359
                a_cen: in std_logic := '1';
360
                a_byen: in std_logic_vector ((width/8)-1 downto 0);
361
                a_waitn: out std_logic
362
        );
363
end wb_async_master;
364
 
365
architecture wb_async_master of wb_async_master is
366
        component d_ff
367
                port (  d  :  in STD_LOGIC;
368
                                clk:  in STD_LOGIC;
369
                        ena:  in STD_LOGIC := '1';
370
                        clr:  in STD_LOGIC := '0';
371
                        pre:  in STD_LOGIC := '0';
372
                                q  :  out STD_LOGIC
373
                );
374
        end component;
375
        signal wg_clk, wg_pre, wg_q: std_logic;
376
        signal i_cyc_o, i_stb_o, i_we_o: std_logic;
377
        signal i_waitn: std_logic;
378
begin
379
        ctrl: process is
380
        begin
381
                wait until clk_i'EVENT and clk_i = '1';
382
                if (rst_i = '1') then
383
                        i_cyc_o <= '0';
384
                        i_stb_o <= '0';
385
                        i_we_o <= '0';
386
                else
387
                        if (a_cen = '0') then
388
                                i_stb_o <= not (a_rdn and a_wrn);
389
                                i_we_o <= not a_wrn;
390
                                i_cyc_o <= '1';
391
                        else
392
                                i_cyc_o <= '0';
393
                                i_stb_o <= '0';
394
                                i_we_o <= '0';
395
                        end if;
396
                end if;
397
        end process;
398
        s_cyc_o <= i_cyc_o and not i_waitn;
399
        s_stb_o <= i_stb_o and not i_waitn;
400
        s_we_o <= i_we_o and not i_waitn;
401
 
402
        w_ff1: d_ff port map (
403
                d => s_ack_i,
404
                clk => clk_i,
405
                ena => '1',
406
                clr => rst_i,
407
                pre => '0',
408
                q => wg_q
409
        );
410
 
411
        wg_clk <= not a_cen;
412
        wg_pre <= wg_q or rst_i;
413
        w_ff2: d_ff port map (
414
                d => '0',
415
                clk => wg_clk,
416
                ena => '1',
417
                clr => '0',
418
                pre => wg_pre,
419
                q => i_waitn
420
        );
421
        a_waitn <= i_waitn;
422
 
423
        s_adr_o <= a_addr;
424
        negate: for i in s_sel_o'RANGE generate s_sel_o(i) <= not a_byen(i); end generate;
425
        s_dat_o <= a_data;
426
 
427
        a_data_out: process is
428
        begin
429
                wait on s_dat_i, a_rdn, a_cen;
430
                if (a_rdn = '0' and a_cen = '0') then
431
                        a_data <= s_dat_i;
432
                else
433
                        a_data <= (others => 'Z');
434
                end if;
435
        end process;
436
end wb_async_master;
437
 
438
-------------------------------------------------------------------------------
439
--
440
--  wb_async_slave
441
--
442
-------------------------------------------------------------------------------
443
 
444
library IEEE;
445
use IEEE.std_logic_1164.all;
446
 
447
library work;
448
use work.technology.all;
449
 
450
entity wb_async_slave is
451
        generic (
452
                width: positive := 16;
453
                addr_width: positive := 20
454
        );
455
        port (
456
                clk_i: in std_logic;
457
                rst_i: in std_logic := '0';
458
 
459
                -- interface for wait-state generator state-machine
460
                wait_state: in std_logic_vector (3 downto 0);
461
 
462
                -- interface to wishbone master device
463
                adr_i: in std_logic_vector (addr_width-1 downto 0);
464
                sel_i: in std_logic_vector ((addr_width/8)-1 downto 0);
465
                dat_i: in std_logic_vector (width-1 downto 0);
466
                dat_o: out std_logic_vector (width-1 downto 0);
467
                dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-');
468
                we_i: in std_logic;
469
                stb_i: in std_logic;
470
                ack_o: out std_logic := '0';
471
                ack_oi: in std_logic := '-';
472
 
473
                -- interface to async slave
474
                a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
475
                a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U');
476
                a_rdn: out std_logic := '1';
477
                a_wrn: out std_logic := '1';
478
                a_cen: out std_logic := '1';
479
                -- byte-enable signals
480
                a_byen: out std_logic_vector ((width/8)-1 downto 0)
481
        );
482
end wb_async_slave;
483
 
484
architecture wb_async_slave of wb_async_slave is
485
        -- multiplexed access signals to memory
486
        signal i_ack: std_logic;
487
        signal sm_ack: std_logic;
488
 
489
        type states is (sm_idle, sm_wait, sm_deact);
490
        signal state: states;
491
        signal cnt: std_logic_vector(3 downto 0);
492
begin
493
        ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi);
494
        dat_o_gen: for i in dat_o'RANGE generate
495
            dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i));
496
        end generate;
497
 
498
        -- For 0WS operation i_ack is an async signal otherwise it's a sync one.
499
        i_ack_gen: process is
500
        begin
501
                wait on sm_ack, stb_i, wait_state, state;
502
                if (wait_state = "0000") then
503
                        case (state) is
504
                                when sm_deact => i_ack <= '0';
505
                                when others => i_ack <= stb_i;
506
                        end case;
507
                else
508
                        i_ack <= sm_ack;
509
                end if;
510
        end process;
511
 
512
        -- SRAM signal-handler process
513
        sram_signals: process is
514
        begin
515
                wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i;
516
                if (rst_i = '1') then
517
                        a_wrn <= '1';
518
                        a_rdn <= '1';
519
                        a_cen <= '1';
520
                        a_addr <= (others => '-');
521
                        a_data <= (others => 'Z');
522
                a_byen <= (others => '1');
523
                else
524
                        case (state) is
525
                                when sm_deact =>
526
                                        a_wrn <= '1';
527
                                        a_rdn <= '1';
528
                                        a_cen <= '1';
529
                                        a_addr <= (others => '-');
530
                                        a_data <= (others => 'Z');
531
                        a_byen <= (others => '1');
532
                                when others =>
533
                                        a_addr <= adr_i;
534
                                        a_rdn <= not (not we_i and stb_i);
535
                                        a_wrn <= not (we_i and stb_i);
536
                                        a_cen <= not stb_i;
537
                        a_byen <= not sel_i;
538
                                        if (we_i = '1') then
539
                                                a_data <= dat_i;
540
                                        else
541
                                                a_data <= (others => 'Z');
542
                                        end if;
543
                        end case;
544
                end if;
545
        end process;
546
 
547
        -- Aysnc access state-machine.
548
        async_sm: process is
549
--              variable cnt: std_logic_vector(3 downto 0) := "0000";
550
--              variable state: states := init;
551
        begin
552
                wait until clk_i'EVENT and clk_i = '1';
553
                if (rst_i = '1') then
554
                        state <= sm_idle;
555
                        cnt <= ((0) => '1', others => '0');
556
                        sm_ack <= '0';
557
                else
558
                        case (state) is
559
                                when sm_idle =>
560
                                        -- Check if anyone needs access to the memory.
561
                                        -- it's rdy signal will already be pulled low, so we only have to start the access
562
                                        if (stb_i = '1') then
563
                                                case wait_state is
564
                                                        when "0000" =>
565
                                                                sm_ack <= '1';
566
                                                                state <= sm_deact;
567
                                                        when "0001" =>
568
                                                                sm_ack <= '1';
569
                                                                cnt <= "0001";
570
                                                                state <= sm_wait;
571
                                                        when others =>
572
                                                                sm_ack <= '0';
573
                                                                cnt <= "0001";
574
                                                                state <= sm_wait;
575
                                                end case;
576
                                        end if;
577
                                when sm_wait =>
578
                                        if (cnt = wait_state) then
579
                                                -- wait cycle completed.
580
                                                state <= sm_deact;
581
                                                sm_ack <= '0';
582
                                                cnt <= "0000";
583
                                        else
584
                                                if (add_one(cnt) = wait_state) then
585
                                                        sm_ack <= '1';
586
                                                else
587
                                                        sm_ack <= '0';
588
                                                end if;
589
                                                cnt <= add_one(cnt);
590
                                        end if;
591
                                when sm_deact =>
592
                                        if (stb_i = '1') then
593
                                                case wait_state is
594
                                                        when "0000" =>
595
                                                                cnt <= "0000";
596
                                                                sm_ack <= '0';
597
                                                                state <= sm_wait;
598
                                                        when others =>
599
                                                                sm_ack <= '0';
600
                                                                cnt <= "0000";
601
                                                                state <= sm_wait;
602
                                                end case;
603
                                        else
604
                                                sm_ack <= '0';
605
                                                state <= sm_idle;
606
                                        end if;
607
                        end case;
608
                end if;
609
        end process;
610
end wb_async_slave;
611
 
612
-------------------------------------------------------------------------------
613
--
614
--  wb_arbiter
615
--
616
-------------------------------------------------------------------------------
617
 
618
library IEEE;
619
use IEEE.std_logic_1164.all;
620
 
621
library work;
622
use work.technology.all;
623
 
624
entity wb_arbiter is
625
        port (
626
--              clk: in std_logic;
627
                rst_i: in std_logic := '0';
628
 
629
                -- interface to master device a
630
                a_we_i: in std_logic;
631
                a_stb_i: in std_logic;
632
                a_cyc_i: in std_logic;
633
                a_ack_o: out std_logic;
634
                a_ack_oi: in std_logic := '-';
635
                a_err_o: out std_logic;
636
                a_err_oi: in std_logic := '-';
637
                a_rty_o: out std_logic;
638
                a_rty_oi: in std_logic := '-';
639
 
640
                -- interface to master device b
641
                b_we_i: in std_logic;
642
                b_stb_i: in std_logic;
643
                b_cyc_i: in std_logic;
644
                b_ack_o: out std_logic;
645
                b_ack_oi: in std_logic := '-';
646
                b_err_o: out std_logic;
647
                b_err_oi: in std_logic := '-';
648
                b_rty_o: out std_logic;
649
                b_rty_oi: in std_logic := '-';
650
 
651
                -- interface to shared devices
652
                s_we_o: out std_logic;
653
                s_stb_o: out std_logic;
654
                s_cyc_o: out std_logic;
655
                s_ack_i: in std_logic;
656
                s_err_i: in std_logic := '-';
657
                s_rty_i: in std_logic := '-';
658
 
659
                mux_signal: out std_logic; -- 0: select A signals, 1: select B signals
660
 
661
                -- misc control lines
662
                priority: in std_logic -- 0: A have priority over B, 1: B have priority over A
663
        );
664
end wb_arbiter;
665
 
666
-- This acthitecture is a clean asyncron state-machine. However it cannot be mapped to FPGA architecture
667
architecture behaviour of wb_arbiter is
668
        type states is (idle,aa,ba);
669
        signal i_mux_signal: std_logic;
670
 
671
        signal e_state: states;
672
begin
673
        mux_signal <= i_mux_signal;
674
 
675
        sm: process is
676
                variable state: states;
677
        begin
678
                wait on a_cyc_i, b_cyc_i, priority, rst_i;
679
                if (rst_i = '1') then
680
                        state := idle;
681
                        i_mux_signal <= priority;
682
                else
683
                        case (state) is
684
                                when idle =>
685
                                        if (a_cyc_i = '1' and (priority = '0' or b_cyc_i = '0')) then
686
                                                state := aa;
687
                                                i_mux_signal <= '0';
688
                                        elsif (b_cyc_i = '1' and (priority = '1' or a_cyc_i = '0')) then
689
                                                state := ba;
690
                                                i_mux_signal <= '1';
691
                                        else
692
                                                i_mux_signal <= priority;
693
                                        end if;
694
                                when aa =>
695
                                        if (a_cyc_i = '0') then
696
                                                if (b_cyc_i = '1') then
697
                                                        state := ba;
698
                                                        i_mux_signal <= '1';
699
                                                else
700
                                                        state := idle;
701
                                                        i_mux_signal <= priority;
702
                                                end if;
703
                                        else
704
                                                i_mux_signal <= '0';
705
                                        end if;
706
                                when ba =>
707
                                        if (b_cyc_i = '0') then
708
                                                if (a_cyc_i = '1') then
709
                                                        state := aa;
710
                                                        i_mux_signal <= '0';
711
                                                else
712
                                                        state := idle;
713
                                                        i_mux_signal <= priority;
714
                                                end if;
715
                                        else
716
                                                i_mux_signal <= '1';
717
                                        end if;
718
                        end case;
719
                end if;
720
                e_state <= state;
721
        end process;
722
 
723
        signal_mux: process is
724
        begin
725
                wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i,
726
                                b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i,
727
                                s_ack_i, s_err_i, s_rty_i, i_mux_signal;
728
                if (i_mux_signal = '0') then
729
                        s_we_o <= a_we_i;
730
                        s_stb_o <= a_stb_i;
731
                        s_cyc_o <= a_cyc_i;
732
                        a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi);
733
                        a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi);
734
                        a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi);
735
                        b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi);
736
                        b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi);
737
                        b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi);
738
                else
739
                        s_we_o <= b_we_i;
740
                        s_stb_o <= b_stb_i;
741
                        s_cyc_o <= b_cyc_i;
742
                        b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi);
743
                        b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi);
744
                        b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi);
745
                        a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi);
746
                        a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi);
747
                        a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi);
748
                end if;
749
        end process;
750
end behaviour;
751
 
752
-- This acthitecture is a more-or-less structural implementation. Fits for FPGA realization.
753
architecture FPGA of wb_arbiter is
754
        component d_ff
755
                port (  d  :  in STD_LOGIC;
756
                                clk:  in STD_LOGIC;
757
                        ena:  in STD_LOGIC := '1';
758
                        clr:  in STD_LOGIC := '0';
759
                        pre:  in STD_LOGIC := '0';
760
                                q  :  out STD_LOGIC
761
                );
762
        end component;
763
 
764
        signal i_mux_signal: std_logic;
765
 
766
        type states is (idle,aa,ba,XX);
767
        signal e_state: states;
768
 
769
        -- signals for a DFF in FPGA
770
        signal idle_s, aa_s, ba_s: std_logic;
771
 
772
        signal aa_clk, aa_ena, aa_clr, aa_pre: std_logic;
773
        signal ba_clk, ba_ena, ba_clr, ba_pre: std_logic;
774
 
775
begin
776
        mux_signal <= i_mux_signal;
777
 
778
        idle_s <= not (a_cyc_i or b_cyc_i);
779
 
780
        aa_clr <= rst_i or not a_cyc_i;
781
        aa_clk <= a_cyc_i;
782
        aa_ena <= not b_cyc_i and priority;
783
        aa_pre <= (a_cyc_i and not priority and not ba_s) or (a_cyc_i and not b_cyc_i);
784
        aa_ff: d_ff port map (
785
                d => '1',
786
                clk => aa_clk,
787
                ena => aa_ena,
788
                clr => aa_clr,
789
                pre => aa_pre,
790
                q => aa_s
791
        );
792
 
793
        ba_clr <= rst_i or not b_cyc_i;
794
        ba_clk <= b_cyc_i;
795
        ba_ena <= not a_cyc_i and not priority;
796
        ba_pre <= (b_cyc_i and priority and not aa_s) or (b_cyc_i and not a_cyc_i);
797
        ba_ff: d_ff port map (
798
                d => '1',
799
                clk => ba_clk,
800
                ena => ba_ena,
801
                clr => ba_clr,
802
                pre => ba_pre,
803
                q => ba_s
804
        );
805
 
806
        i_mux_signal <= (priority and idle_s) or ba_s;
807
 
808
        signal_mux: process is
809
        begin
810
                wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i,
811
                                b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i,
812
                                s_ack_i, s_err_i, s_rty_i, i_mux_signal;
813
                if (i_mux_signal = '0') then
814
                        s_we_o <= a_we_i;
815
                        s_stb_o <= a_stb_i;
816
                        s_cyc_o <= a_cyc_i;
817
                        a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi);
818
                        a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi);
819
                        a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi);
820
                        b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi);
821
                        b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi);
822
                        b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi);
823
                else
824
                        s_we_o <= b_we_i;
825
                        s_stb_o <= b_stb_i;
826
                        s_cyc_o <= b_cyc_i;
827
                        b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi);
828
                        b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi);
829
                        b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi);
830
                        a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi);
831
                        a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi);
832
                        a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi);
833
                end if;
834
        end process;
835
 
836
        gen_e_state: process is
837
        begin
838
                wait on idle_s,aa_s,ba_s;
839
                   if (idle_s = '1' and ba_s = '0' and aa_s = '0') then e_state <= idle;
840
                elsif (idle_s = '0' and ba_s = '1' and aa_s = '0') then e_state <= aa;
841
                elsif (idle_s = '0' and ba_s = '0' and aa_s = '1') then e_state <= ba;
842
                else                                                    e_state <= XX;
843
                end if;
844
        end process;
845
end FPGA;
846
 
847
-------------------------------------------------------------------------------
848
--
849
--  wb_out_reg
850
--
851
-------------------------------------------------------------------------------
852
 
853
library IEEE;
854
use IEEE.std_logic_1164.all;
855
 
856
library work;
857
use work.technology.all;
858
 
859
entity wb_out_reg is
860
        generic (
861
                width : positive := 8;
862
                bus_width: positive := 8;
863
                offset: integer := 0
864
        );
865
        port (
866
                clk_i: in std_logic;
867
                rst_i: in std_logic;
868
                rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
869
 
870
                dat_i: in std_logic_vector (bus_width-1 downto 0);
871
                dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
872
                dat_o: out std_logic_vector (bus_width-1 downto 0);
873
                q: out std_logic_vector (width-1 downto 0);
874
                we_i: in std_logic;
875
                stb_i: in std_logic;
876
                ack_o: out std_logic;
877
                ack_oi: in std_logic := '-'
878
        );
879
end wb_out_reg;
880
 
881
architecture wb_out_reg of wb_out_reg is
882
        signal content : std_logic_vector (width-1 downto 0);
883
begin
884
        -- output bus handling with logic
885
        gen_dat_o: process is
886
                variable rd_sel: std_logic;
887
        begin
888
                wait on dat_oi, we_i, stb_i, content;
889
                rd_sel := stb_i and not we_i;
890
                for i in bus_width-1 downto 0 loop
891
                        if (i >= offset and i < offset+width) then
892
                                dat_o(i) <= (dat_oi(i) and not rd_sel) or (content(i-offset) and rd_sel);
893
                        else
894
                                dat_o(i) <= dat_oi(i);
895
                        end if;
896
                end loop;
897
        end process;
898
 
899
  -- this item never generates any wait-states  
900
        ack_o <= stb_i or ack_oi;
901
 
902
        reg: process is
903
        begin
904
                wait until clk_i'EVENT and clk_i='1';
905
                if (rst_i = '1') then
906
                        content <= rst_val;
907
                else
908
                        if (stb_i = '1' and we_i = '1') then
909
                                content <=  dat_i(width+offset-1 downto offset);
910
                        end if;
911
                end if;
912
        end process;
913
        q <= content;
914
end wb_out_reg;

powered by: WebSVN 2.1.0

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