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

Subversion Repositories spacewire_light

[/] [spacewire_light/] [trunk/] [rtl/] [vhdl/] [spwahbmst.vhd] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 jorisvr
--
2
--  AHB master for AMBA interface.
3
--
4
--  This is a helper entity for the SpaceWire AMBA interface.
5
--  It implements the AHB master which transfers data from/to main memory.
6
--
7
--  Descriptor flag bits on input:
8
--    bit 15:0      (RX) max nr of bytes to receive (must be a multiple of 4)
9
--                  (TX) nr of bytes to transmit
10
--    bit 16        EN: '1' = descriptor enabled
11
--    bit 17        WR: wrap to beginning of descriptor table
12
--    bit 18        IE: interrupt at end of descriptor
13
--    bit 19        '0'
14
--    bit 20        (TX only) send EOP after end of data
15
--    bit 21        (TX only) send EEP after end of data
16
--
17
--  Descriptor flag bits after completion of frame:
18
--    bit 15:0      (RX only) LEN: nr of bytes received
19
--                  (TX) undefined
20
--    bit 16        '0'
21
--    bit 18:17     undefined
22
--    bit 19        '1' to indicate descriptor completed       
23
---   bit 20        (RX only) received EOP after end of data
24
--    bit 21        (RX only) received EEP after end of data
25
--
26
 
27
library ieee;
28
use ieee.std_logic_1164.all;
29
use ieee.numeric_std.all;
30
library grlib;
31
use grlib.amba.all;
32
use grlib.stdlib.all;
33
use work.spwambapkg.all;
34
 
35
 
36
entity spwahbmst is
37
 
38
    generic (
39
        -- AHB master index.
40
        hindex:         integer;
41
 
42
        -- AHB plug&play information.
43
        hconfig:        ahb_config_type;
44
 
45
        -- Maximum burst length as the 2-logarithm of the number of words.
46
        maxburst:       integer range 1 to 8
47
    );
48
 
49
    port (
50
        -- System clock.
51
        clk:        in  std_logic;
52
 
53
        -- Synchronous reset (active-low).
54
        rstn:       in  std_logic;
55
 
56
        -- Inputs from SpaceWire core.
57
        msti:       in  spw_ahbmst_in_type;
58
 
59
        -- Outputs to SpaceWire core.
60
        msto:       out spw_ahbmst_out_type;
61
 
62
        -- AHB master input signals.
63
        ahbi:       in  ahb_mst_in_type;
64
 
65
        -- AHB master output signals.
66
        ahbo:       out ahb_mst_out_type
67
    );
68
 
69
end entity spwahbmst;
70
 
71
architecture spwahbmst_arch of spwahbmst is
72
 
73
    --
74
    -- Registers.
75
    --
76
 
77
    type state_type is (
78
        st_idle,
79
        st_rxgetdesc, st_rxgetptr, st_rxtransfer, st_rxfinal, st_rxputdesc,
80
        st_txgetdesc, st_txgetptr, st_txtransfer, st_txfinal, st_txputdesc, st_txskip );
81
 
82
    type burst_state_type is ( bs_idle, bs_setup, bs_active, bs_end );
83
 
84
    type regs_type is record
85
        -- dma state
86
        rxdma_act:      std_ulogic;
87
        txdma_act:      std_ulogic;
88
        ahberror:       std_ulogic;
89
        -- main state machine
90
        mstate:         state_type;
91
        firstword:      std_ulogic;
92
        prefertx:       std_ulogic;
93
        -- rx descriptor state
94
        rxdes_en:       std_ulogic;
95
        rxdes_wr:       std_ulogic;
96
        rxdes_ie:       std_ulogic;
97
        rxdes_eop:      std_ulogic;
98
        rxdes_eep:      std_ulogic;
99
        rxdes_len:      std_logic_vector(13 downto 0);  -- in 32-bit words
100
        rxdes_pos:      std_logic_vector(15 downto 0);  -- in bytes
101
        rxaddr:         std_logic_vector(31 downto 2);
102
        rxdesc_next:    std_ulogic;
103
        -- tx descriptor state
104
        txdes_en:       std_ulogic;
105
        txdes_wr:       std_ulogic;
106
        txdes_ie:       std_ulogic;
107
        txdes_eop:      std_ulogic;
108
        txdes_eep:      std_ulogic;
109
        txdes_len:      std_logic_vector(15 downto 0);  -- in bytes
110
        txaddr:         std_logic_vector(31 downto 2);
111
        txdesc_next:    std_ulogic;
112
        -- interrupts
113
        int_rxdesc:     std_ulogic;
114
        int_txdesc:     std_ulogic;
115
        int_rxpacket:   std_ulogic;
116
        -- burst state
117
        burststat:      burst_state_type;
118
        hbusreq:        std_ulogic;
119
        hwrite:         std_ulogic;
120
        haddr:          std_logic_vector(31 downto 2);
121
        hwdata:         std_logic_vector(31 downto 0);
122
    end record;
123
 
124
    constant regs_reset: regs_type := (
125
        rxdma_act       => '0',
126
        txdma_act       => '0',
127
        ahberror        => '0',
128
        mstate          => st_idle,
129
        firstword       => '0',
130
        prefertx        => '0',
131
        rxdes_en        => '0',
132
        rxdes_wr        => '0',
133
        rxdes_ie        => '0',
134
        rxdes_eop       => '0',
135
        rxdes_eep       => '0',
136
        rxdes_len       => (others => '0'),
137
        rxdes_pos       => (others => '0'),
138
        rxaddr          => (others => '0'),
139
        rxdesc_next     => '0',
140
        txdes_en        => '0',
141
        txdes_wr        => '0',
142
        txdes_ie        => '0',
143
        txdes_eop       => '0',
144
        txdes_eep       => '0',
145
        txdes_len       => (others => '0'),
146
        txaddr          => (others => '0'),
147
        txdesc_next     => '0',
148
        int_rxdesc      => '0',
149
        int_txdesc      => '0',
150
        int_rxpacket    => '0',
151
        burststat       => bs_idle,
152
        hbusreq         => '0',
153
        hwrite          => '0',
154
        haddr           => (others => '0'),
155
        hwdata          => (others => '0') );
156
 
157
    signal r: regs_type := regs_reset;
158
    signal rin: regs_type;
159
 
160
begin
161
 
162
    --
163
    -- Combinatorial process
164
    --
165
    process (r, rstn, msti, ahbi)  is
166
        variable v:             regs_type;
167
        variable v_burstreq:    std_logic;
168
        variable v_burstack:    std_logic;
169
        variable v_rxfifo_read: std_logic;
170
        variable v_txfifo_write: std_logic;
171
        variable v_txfifo_wdata: std_logic_vector(35 downto 0);
172
    begin
173
        v           := r;
174
 
175
        -- Assume no burst request.
176
        v_burstreq  := '0';
177
 
178
        -- Detect request from burst state machine for next data word.
179
        v_burstack  := ahbi.hready and
180
                       conv_std_logic(r.burststat = bs_active or r.burststat = bs_end);
181
 
182
        -- Assume no fifo activity; take data for TX fifo from AHB bus.
183
        v_rxfifo_read   := '0';
184
        v_txfifo_write  := '0';
185
        v_txfifo_wdata(35 downto 32) := (others => '0');
186
        v_txfifo_wdata(31 downto 0)  := ahbi.hrdata;
187
 
188
        -- Reset registers for interrupts and descriptor updates.
189
        v.int_rxdesc    := '0';
190
        v.int_txdesc    := '0';
191
        v.int_rxpacket  := '0';
192
        v.rxdesc_next   := '0';
193
        v.txdesc_next   := '0';
194
 
195
        -- Start DMA on external request.
196
        if msti.rxdma_start = '1' then v.rxdma_act := '1'; end if;
197
        if msti.txdma_start = '1' then v.txdma_act := '1'; end if;
198
 
199
        --
200
        -- Main state machine.
201
        --
202
        case r.mstate is
203
 
204
            when st_idle =>
205
                -- Waiting for something to do.
206
                v.prefertx  := '0';
207
                v.firstword := '1';
208
                if msti.txdma_cancel = '1' then
209
                    v.txdma_act := '0';
210
                    v.txdes_en  := '0';
211
                end if;
212
                if r.rxdma_act = '1' and msti.rxfifo_empty = '0' and
213
                   (r.prefertx = '0' or r.txdma_act = '0' or msti.txfifo_highw = '1') then
214
                    -- Start RX transfer.
215
                    if r.rxdes_en = '1' then
216
                        -- Transfer RX data to current descriptor.
217
                        v_burstreq  := '1';
218
                        v.hwrite    := '1';
219
                        v.haddr     := r.rxaddr;
220
                        v.mstate    := st_rxtransfer;
221
                    else
222
                        -- Must fetch new RX descriptor.
223
                        v_burstreq  := '1';
224
                        v.hwrite    := '0';
225
                        v.haddr     := msti.rxdesc_ptr & "0";
226
                        v.mstate    := st_rxgetdesc;
227
                    end if;
228
                elsif r.txdma_act = '1' and msti.txdma_cancel = '0' and msti.txfifo_highw = '0' then
229
                    -- Start TX transfer.
230
                    if r.txdes_en = '1' then
231
                        -- Transfer TX data from current descriptor.
232
                        if unsigned(r.txdes_len) = 0 then
233
                            -- Only send EOP/EEP and write back descriptor.
234
                            v_burstreq  := '1';
235
                            v.hwrite    := '1';
236
                            v.haddr     := msti.txdesc_ptr & "0";
237
                            v.txdesc_next := '1';
238
                            v.mstate    := st_txputdesc;
239
                        else
240
                            -- Start burst transfer.
241
                            v_burstreq  := '1';
242
                            v.hwrite    := '0';
243
                            v.haddr     := r.txaddr;
244
                            if unsigned(r.txdes_len) <= 4 then
245
                                -- Transfer only one word.
246
                                v.mstate    := st_txfinal;
247
                            else
248
                                v.mstate    := st_txtransfer;
249
                            end if;
250
                        end if;
251
                    else
252
                        -- Must fetch new TX descriptor.
253
                        v_burstreq  := '1';
254
                        v.hwrite    := '0';
255
                        v.haddr     := msti.txdesc_ptr & "0";
256
                        v.mstate    := st_txgetdesc;
257
                    end if;
258
                end if;
259
 
260
            when st_rxgetdesc =>
261
                -- Read RX descriptor flags from memory.
262
                v_burstreq  := '1';
263
                v.hwrite    := '0';
264
                v.rxdes_len := ahbi.hrdata(15 downto 2);
265
                v.rxdes_en  := ahbi.hrdata(16);
266
                v.rxdes_wr  := ahbi.hrdata(17);
267
                v.rxdes_ie  := ahbi.hrdata(18);
268
                v.rxdes_eop := '0';
269
                v.rxdes_eep := '0';
270
                v.rxdes_pos := (others => '0');
271
                if v_burstack = '1' then
272
                    -- Got descriptor flags.
273
                    v_burstreq  := '0';
274
                    v.mstate    := st_rxgetptr;
275
                end if;
276
 
277
            when st_rxgetptr =>
278
                -- Read RX data pointer from memory.
279
                v.rxaddr    := ahbi.hrdata(31 downto 2);
280
                v.haddr     := ahbi.hrdata(31 downto 2);
281
                v.firstword := '1';
282
                if v_burstack = '1' then
283
                    -- Got data pointer.
284
                    if r.rxdes_en = '1' then
285
                        -- Start transfer.
286
                        v_burstreq  := '1';
287
                        v.hwrite    := '1';
288
                        v.mstate    := st_rxtransfer;
289
                    else
290
                        -- Reached end of valid descriptors; stop.
291
                        v.rxdma_act := '0';
292
                        v.mstate    := st_idle;
293
                    end if;
294
                end if;
295
 
296
            when st_rxtransfer =>
297
                -- Continue an RX transfer.
298
                v_burstreq  := '1';
299
                v.hwrite    := '1';
300
                v.firstword := '0';
301
                if v_burstack = '1' or r.firstword = '1' then
302
                    -- Setup first/next data word.
303
                    v.hwdata    := msti.rxfifo_rdata(31 downto 0);
304
                    v_rxfifo_read := '1';
305
                    -- Update pointers.
306
                    v.rxdes_len := std_logic_vector(unsigned(r.rxdes_len) - 1);
307
                    v.rxdes_pos := std_logic_vector(unsigned(r.rxdes_pos) + 4);
308
                    v.rxaddr    := std_logic_vector(unsigned(r.rxaddr) + 1);
309
                    -- Detect EOP/EEP.
310
                    v.rxdes_eop :=
311
                        (msti.rxfifo_rdata(35) and not msti.rxfifo_rdata(24)) or
312
                        (msti.rxfifo_rdata(34) and not msti.rxfifo_rdata(16)) or
313
                        (msti.rxfifo_rdata(33) and not msti.rxfifo_rdata(8)) or
314
                        (msti.rxfifo_rdata(32) and not msti.rxfifo_rdata(0));
315
                    v.rxdes_eep :=
316
                        (msti.rxfifo_rdata(35) and msti.rxfifo_rdata(24)) or
317
                        (msti.rxfifo_rdata(34) and msti.rxfifo_rdata(16)) or
318
                        (msti.rxfifo_rdata(33) and msti.rxfifo_rdata(8)) or
319
                        (msti.rxfifo_rdata(32) and msti.rxfifo_rdata(0));
320
                    -- Adjust frame length in case of EOP/EEP.
321
                    if msti.rxfifo_rdata(35) = '1' then
322
                        v.rxdes_pos := r.rxdes_pos(r.rxdes_pos'high downto 2) & "00";
323
                    elsif msti.rxfifo_rdata(34) = '1' then
324
                        v.rxdes_pos := r.rxdes_pos(r.rxdes_pos'high downto 2) & "01";
325
                    elsif msti.rxfifo_rdata(33) = '1' then
326
                        v.rxdes_pos := r.rxdes_pos(r.rxdes_pos'high downto 2) & "10";
327
                    elsif msti.rxfifo_rdata(32) = '1' then
328
                        v.rxdes_pos := r.rxdes_pos(r.rxdes_pos'high downto 2) & "11";
329
                    end if;
330
                    -- Stop at end of requested length or end of packet or fifo empty.
331
                    if msti.rxfifo_nxempty = '1' or
332
                       orv(msti.rxfifo_rdata(35 downto 32)) = '1' or
333
                       unsigned(r.rxdes_len) = 1 then
334
                        v_burstreq  := '0';
335
                        v.mstate    := st_rxfinal;
336
                    end if;
337
                    -- Stop at max burst length boundary.
338 6 jorisvr
                    if (andv(r.rxaddr(maxburst+1 downto 2)) = '1') then
339 5 jorisvr
                        v_burstreq  := '0';
340
                        v.mstate    := st_rxfinal;
341
                    end if;
342
                end if;
343
 
344
            when st_rxfinal =>
345
                -- Last data cycle of an RX transfer.
346
                if v_burstack = '1' then
347
                    if unsigned(r.rxdes_len) = 0 or
348
                       r.rxdes_eop = '1' or r.rxdes_eep = '1' then
349
                        -- End of frame; write back descriptor.
350
                        v_burstreq  := '1';
351
                        v.hwrite    := '1';
352
                        v.haddr     := msti.rxdesc_ptr & "0";
353
                        v.rxdesc_next := '1';
354
                        v.mstate    := st_rxputdesc;
355
                    else
356
                        -- Go through st_idle to pick up more work.
357
                        v.mstate    := st_idle;
358
                    end if;
359
                end if;
360
                -- Give preference to TX work since we just did some RX work.
361
                v.prefertx  := '1';
362
 
363
            when st_rxputdesc =>
364
                -- Write back RX descriptor.
365
                v.hwdata(15 downto 0) := r.rxdes_pos;
366
                v.hwdata(16)  := '0';
367
                v.hwdata(17)  := r.rxdes_wr;
368
                v.hwdata(18)  := r.rxdes_ie;
369
                v.hwdata(19)  := '1';
370
                v.hwdata(20)  := r.rxdes_eop;
371
                v.hwdata(21)  := r.rxdes_eep;
372
                v.hwdata(31 downto 22) := (others => '0');
373
                if v_burstack = '1' then
374
                    -- Frame done.
375
                    v.rxdes_en      := '0';
376
                    v.int_rxdesc    := r.rxdes_ie;
377
                    v.int_rxpacket  := r.rxdes_eop or r.rxdes_eep;
378
                    -- Go to st_idle.
379
                    v.mstate    := st_idle;
380
                end if;
381
 
382
            when st_txgetdesc =>
383
                -- Read TX descriptor flags from memory.
384
                v_burstreq  := '1';
385
                v.hwrite    := '0';
386
                v.txdes_len := ahbi.hrdata(15 downto 0);
387
                v.txdes_en  := ahbi.hrdata(16);
388
                v.txdes_wr  := ahbi.hrdata(17);
389
                v.txdes_ie  := ahbi.hrdata(18);
390
                v.txdes_eop := ahbi.hrdata(20);
391
                v.txdes_eep := ahbi.hrdata(21);
392
                if v_burstack = '1' then
393
                    -- Got descriptor flags.
394
                    v_burstreq  := '0';
395
                    v.mstate    := st_txgetptr;
396
                end if;
397
 
398
            when st_txgetptr =>
399
                -- Read TX data pointer from memory.
400
                v.txaddr    := ahbi.hrdata(31 downto 2);
401
                if v_burstack = '1' then
402
                    -- Got data pointer.
403
                    if r.txdes_en = '1' then
404
                        -- Start transfer.
405
                        if unsigned(r.txdes_len) = 0 then
406
                            -- Only send EOP/EEP and write back descriptor.
407
                            v_burstreq  := '1';
408
                            v.hwrite    := '1';
409
                            v.haddr     := msti.txdesc_ptr & "0";
410
                            v.txdesc_next := '1';
411
                            v.mstate    := st_txputdesc;
412
                        else
413
                            v_burstreq  := '1';
414
                            v.hwrite    := '0';
415
                            v.haddr     := ahbi.hrdata(31 downto 2);
416
                            if unsigned(r.txdes_len) <= 4 then
417
                                -- Transfer only one word.
418
                                v.mstate    := st_txfinal;
419
                            else
420
                                v.mstate    := st_txtransfer;
421
                            end if;
422
                        end if;
423
                    else
424
                        -- Reached end of valid descriptors; stop.
425
                        v.txdma_act := '0';
426
                        v.mstate    := st_idle;
427
                    end if;
428
                end if;
429
 
430
            when st_txtransfer =>
431
                -- Continue an TX transfer.
432
                v_burstreq  := '1';
433
                v.hwrite    := '0';
434
                if v_burstack = '1' then
435
                    -- Got next data word from memory.
436
                    v_txfifo_write  := '1';
437
                    -- Update pointers.
438
                    v.txdes_len := std_logic_vector(unsigned(r.txdes_len) - 4);
439
                    v.txaddr    := std_logic_vector(unsigned(r.txaddr) + 1);
440
                    -- Handle end of burst/transfer.
441 6 jorisvr
                    if andv(r.txaddr(maxburst+1 downto 2)) = '1' then
442 5 jorisvr
                        -- This was the last data cycle before the max burst boundary.
443
                        -- Go through st_idle to pick up more work.
444
                        v_burstreq  := '0';
445
                        v.mstate    := st_idle;
446
                    elsif msti.txfifo_nxfull = '1' then
447
                        -- Fifo full; stop transfer, ignore final data cycle.
448
                        v_burstreq  := '0';
449
                        v.mstate    := st_txskip;
450
                    elsif unsigned(r.txdes_len) <= 8 then
451
                        -- Stop at end of requested length (one more data cycle).
452
                        v_burstreq  := '0';
453
                        v.mstate    := st_txfinal;
454 6 jorisvr
                    elsif andv(r.txaddr(maxburst+1 downto 3)) = '1' then
455 5 jorisvr
                        -- Stop at max burst length boundary (one more data cycle).
456
                        v_burstreq  := '0';
457
                    end if;
458
                else
459 6 jorisvr
                    if andv(r.txaddr(maxburst+1 downto 2)) = '1' then
460 5 jorisvr
                        -- Stop at max burst length boundary (just one more data cycle).
461
                        v_burstreq  := '0';
462
                    end if;
463
                end if;
464
 
465
            when st_txfinal =>
466
                -- Last data cycle of a TX descriptor (1 <= txdes_len <= 4).
467
                if v_burstack = '1' then
468
                    -- Got last data word from memory.
469
                    v_txfifo_write  := '1';
470
                    v.txdes_len := std_logic_vector(unsigned(r.txdes_len) - 4);
471
                    -- Insert EOP in last word if needed.
472
                    -- (Or set bit 7 in the flag byte to indicate that the
473
                    --  frame ends while the packet continues.)
474
                    case r.txdes_len(1 downto 0) is
475
                        when "01" =>
476
                            v_txfifo_wdata(34)  := '1';
477
                            v_txfifo_wdata(23)  := not (r.txdes_eop or r.txdes_eep);
478
                            v_txfifo_wdata(22 downto 17) := "000000";
479
                            v_txfifo_wdata(16)  := r.txdes_eep;
480
                        when "10" =>
481
                            v_txfifo_wdata(33)  := '1';
482
                            v_txfifo_wdata(15)  := not (r.txdes_eop or r.txdes_eep);
483
                            v_txfifo_wdata(14 downto 9) := "000000";
484
                            v_txfifo_wdata(8)   := r.txdes_eep;
485
                        when "11" =>
486
                            v_txfifo_wdata(32)  := '1';
487
                            v_txfifo_wdata(7)   := not (r.txdes_eop or r.txdes_eep);
488
                            v_txfifo_wdata(6 downto 1) := "000000";
489
                            v_txfifo_wdata(0)   := r.txdes_eep;
490
                        when others =>
491
                            -- txdes_len = 4
492
                            -- Store 4 data bytes now; store EOP in st_txputdesc (if needed).
493
                    end case;
494
                    if msti.txfifo_nxfull = '1' and r.txdes_len(1 downto 0) = "00" then
495
                        -- Fifo full so no room to store EOP.
496
                        v.mstate    := st_idle;
497
                        v.haddr     := msti.txdesc_ptr & "0";
498
                    else
499
                        -- Prepare to write back descriptor.
500
                        v_burstreq  := '1';
501
                        v.hwrite    := '1';
502
                        v.haddr     := msti.txdesc_ptr & "0";
503
                        v.txdesc_next := '1';
504
                        v.mstate    := st_txputdesc;
505
                    end if;
506
                end if;
507
 
508
            when st_txputdesc =>
509
                -- Write back TX descriptor.
510
                v.hwdata(15 downto 0) := (others => '0');
511
                v.hwdata(16)  := '0';
512
                v.hwdata(17)  := r.txdes_wr;
513
                v.hwdata(18)  := r.txdes_ie;
514
                v.hwdata(19)  := '1';
515
                v.hwdata(20)  := r.txdes_eop;
516
                v.hwdata(21)  := r.txdes_eep;
517
                v.hwdata(31 downto 22) := (others => '0');
518
                if v_burstack = '1' then
519
                    if r.txdes_len(1 downto 0) = "00" and
520
                       (r.txdes_eop = '1' or r.txdes_eep = '1') then
521
                        -- Store EOP in TX fifo.
522
                        v_txfifo_write  := '1';
523
                        v_txfifo_wdata(35)  := '1';
524
                        v_txfifo_wdata(31 downto 25) := "0000000";
525
                        v_txfifo_wdata(24)  := r.txdes_eep;
526
                    end if;
527
                    -- Frame done.
528
                    v.txdes_en  := '0';
529
                    v.int_txdesc  := r.txdes_ie;
530
                    -- Go to st_idle and give preference to RX work.
531
                    v.mstate    := st_idle;
532
                end if;
533
 
534
            when st_txskip =>
535
                -- Ignore last data cycle of burst because TX fifo is full.
536
                if v_burstack = '1' then
537
                    v.mstate    := st_idle;
538
                end if;
539
 
540
        end case;
541
 
542
        -- Abort DMA when an AHB error occurs.
543
        if r.ahberror = '1' then
544
            v.rxdma_act := '0';
545
            v.txdma_act := '0';
546
            v.mstate    := st_idle;
547
        end if;
548
 
549
 
550
        --
551
        -- Burst state machine.
552
        --
553
        -- A transfer starts when the main state machine combinatorially pulls
554
        -- v_burstreq high and assigns v.haddr and v.hwrite (i.e. r.haddr and
555
        -- r.hwrite must be valid in the first clock cycle AFTER rising v_burstreq).
556
        -- In case of a write transfer, r.hwdata must be valid in the second
557
        -- clock cycle after rising v_burstreq.
558
        --
559
        -- During the transfer, the burst state machine announces each word
560
        -- with a v_burstack pulse. During a read transfer, ahbi.hrdata is
561
        -- valid when v_burstack is high. During a write transfer, a next
562
        -- word must be assigned to v.hwdata on the v_burstack pulse.
563
        --
564
        -- For a single-word transfer, v_burstreq should be high for only one
565
        -- clock cycle. For a multi-word transfer, v_burstreq should be high
566
        -- until the last-but-one v_burstack pulse. I.e. after v_burstreq is
567
        -- released combinatorially on a v_burstack pulse, one last v_burstack
568
        -- pulse will follow.
569
        --
570
        -- The burst state machine transparently handles bus arbitration and
571
        -- retrying of transfers. In case of a non-retryable error, r.ahberror
572
        -- is set high and further transfers are blocked. The main state
573
        -- machine is responsible for ensuring that bursts do not cross a
574
        -- forbidden address boundary.
575
        --
576
        case r.burststat is
577
 
578
            when bs_idle =>
579
                -- Wait for request and bus grant.
580
                -- (htrans = HTRANS_IDLE)
581
                v.hbusreq   := r.hbusreq or v_burstreq;
582
                if (r.hbusreq = '1' or v_burstreq = '1') and
583
                   ahbi.hready = '1' and
584
                   ahbi.hgrant(hindex) = '1' then
585
                    -- Start burst.
586
                    v.burststat := bs_setup;
587
                end if;
588
                -- Block new bursts after an error occurred.
589
                if r.ahberror = '1' then
590
                    v.hbusreq   := '0';
591
                    v.burststat := bs_idle;
592
                end if;
593
 
594
            when bs_setup =>
595
                -- First address cycle.
596
                -- (htrans = HTRANS_NONSEQ)
597
                v.hbusreq   := '1';
598
                if ahbi.hready = '1' then
599
                    -- Increment address and continue burst in bs_active.
600 6 jorisvr
                    v.haddr(maxburst+1 downto 2) := std_logic_vector(unsigned(r.haddr(maxburst+1 downto 2)) + 1);
601 5 jorisvr
                    v.burststat := bs_active;
602
                    -- Stop burst when application ends the transfer.
603
                    v.hbusreq   := v_burstreq;
604
                    if v_burstreq = '0' then
605
                        v.burststat := bs_end;
606
                    end if;
607
                    -- Stop burst when we are kicked off the bus.
608
                    if ahbi.hgrant(hindex) = '0' then
609
                        v.burststat := bs_end;
610
                    end if;
611
                end if;
612
 
613
            when bs_active =>
614
                -- Continue burst.
615
                -- (htrans = HTRANS_SEQ)
616
                v.hbusreq   := '1';
617
                if ahbi.hresp /= HRESP_OKAY then
618
                    -- Error response from slave.
619 6 jorisvr
                    v.haddr(maxburst+1 downto 2) := std_logic_vector(unsigned(r.haddr(maxburst+1 downto 2)) - 1);
620 5 jorisvr
                    if ahbi.hresp = HRESP_ERROR then
621
                        -- Permanent error.
622
                        v.ahberror  := '1';
623
                        v.hbusreq   := '0';
624
                    else
625
                        -- Must retry request.
626
                        v.hbusreq   := '1';
627
                    end if;
628
                    v.burststat := bs_idle;
629
                elsif ahbi.hready = '1' then
630
                    -- Increment address.
631 6 jorisvr
                    v.haddr(maxburst+1 downto 2) := std_logic_vector(unsigned(r.haddr(maxburst+1 downto 2)) + 1);
632 5 jorisvr
                    -- Stop burst when application ends the transfer.
633
                    v.hbusreq   := v_burstreq;
634
                    if v_burstreq = '0' then
635
                        v.burststat := bs_end;
636
                    end if;
637
                    -- Stop burst when we are kicked off the bus.
638
                    if ahbi.hgrant(hindex) = '0' then
639
                        v.burststat := bs_end;
640
                    end if;
641
                end if;
642
 
643
            when bs_end =>
644
                -- Last data cycle of burst.
645
                -- (htrans = HTRANS_IDLE)
646
                v.hbusreq   := r.hbusreq or v_burstreq;
647
                if ahbi.hresp /= HRESP_OKAY then
648
                    -- Error response from slave.
649 6 jorisvr
                    v.haddr(maxburst+1 downto 2) := std_logic_vector(unsigned(r.haddr(maxburst+1 downto 2)) - 1);
650 5 jorisvr
                    if ahbi.hresp = HRESP_ERROR then
651
                        -- Permanent error.
652
                        v.ahberror  := '1';
653
                        v.hbusreq   := '0';
654
                    else
655
                        -- Must retry request.
656
                        v.hbusreq   := '1';
657
                    end if;
658
                    v.burststat := bs_idle;
659
                elsif ahbi.hready = '1' then
660
                    -- Burst complete.
661
                    if (r.hbusreq = '1' or v_burstreq = '1') and
662
                       ahbi.hgrant(hindex) = '1' then
663
                        -- Immediately start next burst.
664
                        v.burststat := bs_setup;
665
                    else
666
                        v.burststat := bs_idle;
667
                    end if;
668
                end if;
669
 
670
        end case;
671
 
672
 
673
        --
674
        -- Drive output signals.
675
        --
676
        ahbo.hbusreq    <= r.hbusreq;
677
        if r.burststat = bs_setup then
678
            ahbo.htrans     <= HTRANS_NONSEQ;
679
        elsif r.burststat = bs_active then
680
            ahbo.htrans     <= HTRANS_SEQ;
681
        else
682
            ahbo.htrans     <= HTRANS_IDLE;
683
        end if;
684
        ahbo.haddr      <= r.haddr & "00";
685
        ahbo.hwrite     <= r.hwrite;
686
        ahbo.hwdata     <= r.hwdata;
687
        ahbo.hlock      <= '0';             -- never lock the bus
688
        ahbo.hsize      <= HSIZE_DWORD;     -- always 32-bit words
689
        ahbo.hburst     <= HBURST_INCR;     -- undetermined incremental burst
690
        ahbo.hprot      <= "0011";          -- not cacheable, privileged, data
691
        ahbo.hirq       <= (others => '0'); -- no interrupts via AHB bus
692
        ahbo.hconfig    <= hconfig;         -- AHB plug&play data
693
        ahbo.hindex     <= hindex;          -- index feedback
694
 
695
        msto.rxdma_act      <= r.rxdma_act;
696
        msto.txdma_act      <= r.txdma_act;
697
        msto.ahberror       <= r.ahberror;
698
        msto.int_rxdesc     <= r.int_rxdesc;
699
        msto.int_txdesc     <= r.int_txdesc;
700
        msto.int_rxpacket   <= r.int_rxpacket;
701
        msto.rxdesc_next    <= r.rxdesc_next;
702
        msto.rxdesc_wrap    <= r.rxdesc_next and r.rxdes_wr;
703
        msto.txdesc_next    <= r.txdesc_next;
704
        msto.txdesc_wrap    <= r.txdesc_next and r.txdes_wr;
705
        msto.rxfifo_read    <= v_rxfifo_read;
706
        msto.txfifo_write   <= v_txfifo_write;
707
        msto.txfifo_wdata   <= v_txfifo_wdata;
708
 
709
 
710
        --
711
        -- Reset.
712
        --
713
        if rstn = '0' then
714
            v   := regs_reset;
715
        end if;
716
 
717
 
718
        --
719
        -- Update registers.
720
        --
721
        rin <= v;
722
    end process;
723
 
724
 
725
    --
726
    -- Synchronous process: update registers.
727
    --
728
    process (clk) is
729
    begin
730
        if rising_edge(clk) then
731
            r <= rin;
732
        end if;
733
    end process;
734
 
735
end architecture spwahbmst_arch;

powered by: WebSVN 2.1.0

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