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 12

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

powered by: WebSVN 2.1.0

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