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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [ambalib/] [types_amba4.vhd.bak] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     Declaration and common methods implementation of the types_nasti
6
--!            package.
7
--! @details   This file defines bus interface constants that have to be
8
--!            used by any periphery device implementation in order
9
--!            to provide compatibility in a wide range of possible settings.
10
--!            For better implementation use the AXI4 register bank and
11
--!            implemented tasks from this file.
12
------------------------------------------------------------------------------
13
 
14
--! Standard library
15
library ieee;
16
--! Standard signal types import
17
use ieee.std_logic_1164.all;
18
--! Standard numerical types import
19
use ieee.numeric_std.all;
20
--! Common constants and data conversion functions library
21
library commonlib;
22
--! Import SoC specific types common for all devices
23
use commonlib.types_common.all;
24
 
25
--! @brief   System bus AMBA AXI(NASTI) types definition.
26
--! @details This package provides general constants, data structures and
27
--!          and functions description that define behaviour of all
28
--!          peripheries devices implementing AXI4 interface.
29
package types_amba4 is
30
 
31
--! @defgroup scala_cfg_group SCALA generated parameters
32
--! @ingroup axi4_config_generic_group
33
--! @details  This constant must correspond to Scala defined ones.
34
--! @{
35
 
36
--! User defined address ID bitwidth (aw_id / ar_id fields).
37
constant CFG_ROCKET_ID_BITS      : integer := 5;
38
--! Data bus bits width.
39
constant CFG_NASTI_DATA_BITS     : integer := 64;--128;
40
--! Data bus bytes width
41
constant CFG_NASTI_DATA_BYTES    : integer := CFG_NASTI_DATA_BITS / 8;
42
--! Address bus bits width.
43
constant CFG_NASTI_ADDR_BITS     : integer := 32;
44
--! Definition of number of bits in address bus per one data transaction.
45
constant CFG_NASTI_ADDR_OFFSET   : integer := log2(CFG_NASTI_DATA_BYTES);
46
--! @brief Number of address bits used for device addressing.
47
--! @details Default is 12 bits = 4 KB of address space minimum per each
48
--!          mapped device.
49
constant CFG_NASTI_CFG_ADDR_BITS : integer := CFG_NASTI_ADDR_BITS-12;
50
--! @brief Global alignment is set 32 bits.
51
constant CFG_ALIGN_BYTES         : integer := 4;
52
--! @brief  Number of parallel access to the atomic data.
53
constant CFG_WORDS_ON_BUS        : integer := CFG_NASTI_DATA_BYTES/CFG_ALIGN_BYTES;
54
--! @}
55
 
56
--! @defgroup slave_id_group AMBA AXI slaves generic IDs.
57
--! @ingroup axi4_config_generic_group
58
--! @details Each module in a SoC has to be indexed by unique identificator.
59
--!          In current implementation it is used sequential indexing for it.
60
--!          Indexes are used to specify a device bus item in a vectors.
61
--! @{
62
 
63
--! @brief Configuration index of the Boot ROM module visible by the firmware.
64
constant CFG_NASTI_SLAVE_BOOTROM  : integer := 0;
65
--! Configuration index of the Firmware ROM Image module.
66
constant CFG_NASTI_SLAVE_ROMIMAGE  : integer := CFG_NASTI_SLAVE_BOOTROM+1;
67
--! Configuration index of the SRAM module visible by the firmware.
68
constant CFG_NASTI_SLAVE_SRAM     : integer := CFG_NASTI_SLAVE_ROMIMAGE+1;
69
--! Configuration index of the UART module.
70
constant CFG_NASTI_SLAVE_UART1    : integer := CFG_NASTI_SLAVE_SRAM+1;
71
--! Configuration index of the GPIO (General Purpose In/Out) module.
72
constant CFG_NASTI_SLAVE_GPIO     : integer := CFG_NASTI_SLAVE_UART1+1;
73
--! Configuration index of the Interrupt Controller module.
74
constant CFG_NASTI_SLAVE_IRQCTRL  : integer := CFG_NASTI_SLAVE_GPIO+1;
75
--! Configuration index of the Satellite Navigation Engine.
76
constant CFG_NASTI_SLAVE_ENGINE   : integer := CFG_NASTI_SLAVE_IRQCTRL+1;
77
--! Configuration index of the RF front-end controller.
78
constant CFG_NASTI_SLAVE_RFCTRL   : integer := CFG_NASTI_SLAVE_ENGINE+1;
79
--! Configuration index of the GPS-CA Fast Search Engine module.
80
constant CFG_NASTI_SLAVE_FSE_GPS  : integer := CFG_NASTI_SLAVE_RFCTRL+1;
81
--! Configuration index of the Ethernet MAC module.
82
constant CFG_NASTI_SLAVE_ETHMAC   : integer := CFG_NASTI_SLAVE_FSE_GPS+1;
83
--! Configuration index of the Debug Support Unit module.
84
constant CFG_NASTI_SLAVE_DSU      : integer := CFG_NASTI_SLAVE_ETHMAC+1;
85
--! Configuration index of the Debug Support Unit module.
86
constant CFG_NASTI_SLAVE_GPTIMERS : integer := CFG_NASTI_SLAVE_DSU+1;
87
--! Configuration index of the Plug-n-Play module.
88
constant CFG_NASTI_SLAVE_PNP      : integer := CFG_NASTI_SLAVE_GPTIMERS+1;
89
--! Total number of the slaves devices.
90
constant CFG_NASTI_SLAVES_TOTAL  : integer := CFG_NASTI_SLAVE_PNP+1;
91
--! @}
92
 
93
--! @defgroup master_id_group AXI4 masters generic IDs.
94
--! @ingroup axi4_config_generic_group
95
--! @details Each master must be assigned to a specific ID that used
96
--!          as an index in the vector array of AXI master bus.
97
--! @{
98
 
99
--! Cached TileLinkIO bus.
100
constant CFG_NASTI_MASTER_CACHED   : integer := 0;
101
--! Uncached TileLinkIO bus.
102
constant CFG_NASTI_MASTER_UNCACHED : integer := CFG_NASTI_MASTER_CACHED+1;
103
--! Ethernet MAC master interface generic index.
104
constant CFG_NASTI_MASTER_ETHMAC   : integer := CFG_NASTI_MASTER_UNCACHED+1;
105
--! Tap via UART (debug port) generic index.
106
constant CFG_NASTI_MASTER_MSTUART    : integer := CFG_NASTI_MASTER_ETHMAC+1;
107
--! Total Number of master devices on system bus.
108
constant CFG_NASTI_MASTER_TOTAL    : integer := CFG_NASTI_MASTER_MSTUART+1;
109
--! @}
110
 
111
 
112
--! @defgroup irq_id_group AXI4 interrupt generic IDs.
113
--! @ingroup axi4_config_generic_group
114
--! @details Unique indentificator of the interrupt pin also used
115
--!          as an index in the interrupts bus.
116
--! @{
117
 
118
--! Zero interrupt index must be unused.
119
constant CFG_IRQ_UNUSED         : integer := 0;
120
--! UART_A interrupt pin.
121
constant CFG_IRQ_UART1          : integer := CFG_IRQ_UNUSED + 1;
122
--! Ethernet MAC interrupt pin.
123
constant CFG_IRQ_ETHMAC         : integer := CFG_IRQ_UART1 + 1;
124
--! GP Timers interrupt pin
125
constant CFG_IRQ_GPTIMERS       : integer := CFG_IRQ_ETHMAC + 1;
126
--! Memory miss access.
127
constant CFG_IRQ_MISS_ACCESS    : integer := CFG_IRQ_GPTIMERS + 1;
128
--! GNSS Engine IRQ pin that generates 1 msec pulses.
129
constant CFG_IRQ_GNSSENGINE     : integer := CFG_IRQ_MISS_ACCESS + 1;
130
--! Total number of used interrupts in a system
131
constant CFG_IRQ_TOTAL          : integer := CFG_IRQ_GNSSENGINE + 1;
132
--! @}
133
 
134
--! @name   AXI Response values
135
--! @brief  AMBA 4.0 specified response types from a slave device.
136
--! @{
137
 
138
--! @brief Normal access success.
139
--! @details Indicates that a normal access has been
140
--! successful. Can also indicate an exclusive access has failed.
141
constant NASTI_RESP_OKAY     : std_logic_vector(1 downto 0) := "00";
142
--! @brief Exclusive access okay.
143
--! @details Indicates that either the read or write
144
--! portion of an exclusive access has been successful.
145
constant NASTI_RESP_EXOKAY   : std_logic_vector(1 downto 0) := "01";
146
--! @brief Slave error.
147
--! @details Used when the access has reached the slave successfully,
148
--! but the slave wishes to return an error condition to the originating
149
--! master.
150
constant NASTI_RESP_SLVERR   : std_logic_vector(1 downto 0) := "10";
151
--! @brief Decode error.
152
--! @details Generated, typically by an interconnect component,
153
--! to indicate that there is no slave at the transaction address.
154
constant NASTI_RESP_DECERR   : std_logic_vector(1 downto 0) := "11";
155
--! @}
156
 
157
--! @name   AXI burst request type.
158
--! @brief  AMBA 4.0 specified burst operation request types.
159
--! @{
160
 
161
--! @brief Fixed address burst operation.
162
--! @details The address is the same for every transfer in the burst
163
--!          (FIFO type)
164
constant NASTI_BURST_FIXED   : std_logic_vector(1 downto 0) := "00";
165
--! @brief Burst operation with address increment.
166
--! @details The address for each transfer in the burst is an increment of
167
--!        the address for the previous transfer. The increment value depends
168
--!        on the size of the transfer.
169
constant NASTI_BURST_INCR    : std_logic_vector(1 downto 0) := "01";
170
--! @brief Burst operation with address increment and wrapping.
171
--! @details A wrapping burst is similar to an incrementing burst, except that
172
--!          the address wraps around to a lower address if an upper address
173
--!          limit is reached
174
constant NASTI_BURST_WRAP    : std_logic_vector(1 downto 0) := "10";
175
--! @}
176
 
177
--! @name Vendor IDs defintion.
178
--! @{
179
 
180
--! GNSS Sensor Ltd. vendor identificator.
181
constant VENDOR_GNSSSENSOR        : std_logic_vector(15 downto 0) := X"00F1";
182
--! @}
183
 
184
--! @name Master Device IDs definition:
185
--! @{
186
 
187
--! Empty master slot device
188
constant MST_DID_EMPTY            : std_logic_vector(15 downto 0) := X"7755";
189
--! RISC-V "Rocket-chip" core Cached TileLink master device.
190
constant RISCV_CACHED_TILELINK    : std_logic_vector(15 downto 0) := X"0500";
191
--! RISC-V "Rocket-chip" core Uncached TileLink master device.
192
constant RISCV_UNCACHED_TILELINK  : std_logic_vector(15 downto 0) := X"0501";
193
--! Ethernet MAC master device.
194
constant GAISLER_ETH_MAC_MASTER   : std_logic_vector(15 downto 0) := X"0502";
195
--! Ethernet MAC master debug interface (EDCL).
196
constant GAISLER_ETH_EDCL_MASTER  : std_logic_vector(15 downto 0) := X"0503";
197
--! "River" CPU Device ID.
198
constant RISCV_RIVER_CPU          : std_logic_vector(15 downto 0) := X"0505";
199
--! UART with DMA: Test Access Point (TAP)
200
constant GNSSSENSOR_UART_TAP      : std_logic_vector(15 downto 0) := X"050A";
201
--! @}
202
 
203
--! @name Slave Device IDs definition:
204
--! @{
205
 
206
--! Empty slave slot device
207
constant SLV_DID_EMPTY           : std_logic_vector(15 downto 0) := X"5577";
208
--! GNSS Engine Stub device
209
constant GNSSSENSOR_ENGINE_STUB   : std_logic_vector(15 downto 0) := X"0068";
210
--! Fast Search Engines Device ID provided by gnsslib
211
constant GNSSSENSOR_FSE_V2_GPS    : std_logic_vector(15 downto 0) := X"0069";
212
--! Boot ROM Device ID
213
constant GNSSSENSOR_BOOTROM       : std_logic_vector(15 downto 0) := X"0071";
214
--! FW ROM image Device ID
215
constant GNSSSENSOR_FWIMAGE       : std_logic_vector(15 downto 0) := X"0072";
216
--! Internal SRAM block Device ID
217
constant GNSSSENSOR_SRAM          : std_logic_vector(15 downto 0) := X"0073";
218
--! Configuration Registers Module Device ID provided by gnsslib
219
constant GNSSSENSOR_PNP           : std_logic_vector(15 downto 0) := X"0074";
220
--! SD-card controller Device ID provided by gnsslib
221
constant GNSSSENSOR_SPI_FLASH     : std_logic_vector(15 downto 0) := X"0075";
222
--! General purpose IOs Device ID provided by gnsslib
223
constant GNSSSENSOR_GPIO          : std_logic_vector(15 downto 0) := X"0076";
224
--! RF front-end controller Device ID provided by gnsslib
225
constant GNSSSENSOR_RF_CONTROL    : std_logic_vector(15 downto 0) := X"0077";
226
--! GNSS Engine Device ID provided by gnsslib
227
constant GNSSSENSOR_ENGINE        : std_logic_vector(15 downto 0) := X"0078";
228
--! rs-232 UART Device ID
229
constant GNSSSENSOR_UART          : std_logic_vector(15 downto 0) := X"007a";
230
--! Accelerometer Device ID provided by gnsslib
231
constant GNSSSENSOR_ACCELEROMETER : std_logic_vector(15 downto 0) := X"007b";
232
--! Gyroscope Device ID provided by gnsslib
233
constant GNSSSENSOR_GYROSCOPE     : std_logic_vector(15 downto 0) := X"007c";
234
--! Interrupt controller
235
constant GNSSSENSOR_IRQCTRL       : std_logic_vector(15 downto 0) := X"007d";
236
--! Ethernet MAC inherited from Gaisler greth module.
237
constant GNSSSENSOR_ETHMAC        : std_logic_vector(15 downto 0) := X"007f";
238
--! Debug Support Unit device id.
239
constant GNSSSENSOR_DSU           : std_logic_vector(15 downto 0) := X"0080";
240
--! GP Timers device id.
241
constant GNSSSENSOR_GPTIMERS      : std_logic_vector(15 downto 0) := X"0081";
242
--! ADC samples recorder
243
constant GNSSSENSOR_ADC_RECORDER  : std_logic_vector(15 downto 0) := X"0082";
244
--! @}
245
 
246
--! @name Decoder of the transaction size.
247
--! @{
248
 
249
--! Burst length size decoder
250
constant XSIZE_TOTAL : integer := 8;
251
--! Definition of the AXI bytes converter.
252
type xsize_type is array (0 to XSIZE_TOTAL-1) of integer;
253
--! Decoder of the transaction bytes from AXI format to Bytes.
254
constant XSizeToBytes : xsize_type := (
255
 
256
   1 => 2,
257
   2 => 4,
258
   3 => 8,
259
   4 => 16,
260
   5 => 32,
261
   6 => 64,
262
   7 => 128
263
);
264
--! @}
265
 
266
--! @name Plug'n'Play descriptor constants.
267
--! @{
268
--! Undefined type of the descriptor (empty device).
269
constant PNP_CFG_TYPE_INVALID   : std_logic_vector := "00";
270
--! AXI slave device standard descriptor.
271
constant PNP_CFG_TYPE_MASTER  : std_logic_vector := "01";
272
--! AXI master device standard descriptor.
273
constant PNP_CFG_TYPE_SLAVE : std_logic_vector := "10";
274
--! @brief Size in bytes of the standard slave descriptor..
275
--! @details Firmware uses this value instead of sizeof(nasti_slave_config_type).
276
constant PNP_CFG_SLAVE_DESCR_BYTES : std_logic_vector(7 downto 0) := X"10";
277
--! @brief Size in bytes of the standard master descriptor.
278
--! @details Firmware uses this value instead of sizeof(nasti_master_config_type).
279
constant PNP_CFG_MASTER_DESCR_BYTES : std_logic_vector(7 downto 0) := X"08";
280
--! @}
281
 
282
 
283
--! @brief   Plug-n-play descriptor structure for slave device.
284
--! @details Each slave device must generates this datatype output that
285
--!          is connected directly to the 'pnp' slave module on system bus.
286
type nasti_slave_config_type is record
287
    --! Descriptor size in bytes.
288
    descrsize : std_logic_vector(7 downto 0);
289
    --! Descriptor type.
290
    descrtype : std_logic_vector(1 downto 0);
291
    --! Descriptor size in bytes.
292
    irq_idx : integer;
293
    --! Base address value.
294
    xaddr  : std_logic_vector(CFG_NASTI_CFG_ADDR_BITS-1 downto 0);
295
    --! Maskable bits of the base address.
296
    xmask  : std_logic_vector(CFG_NASTI_CFG_ADDR_BITS-1 downto 0);
297
    --! Vendor ID.
298
    vid    : std_logic_vector(15 downto 0);
299
    --! Device ID.
300
    did    : std_logic_vector(15 downto 0);
301
end record;
302
 
303
--! @brief   Arrays of the plug-n-play descriptors.
304
--! @details Configuration bus vector from all slaves to plug'n'play
305
--!          NASTI device (pnp).
306
type nasti_slave_cfg_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
307
       of nasti_slave_config_type;
308
 
309
--! @brief Default slave config value.
310
--! @default This value corresponds to an empty device and often used
311
--!          as assignment of outputs for the disabled device.
312
constant nasti_slave_config_none : nasti_slave_config_type := (
313
    PNP_CFG_SLAVE_DESCR_BYTES, PNP_CFG_TYPE_SLAVE, 0,
314
    (others => '0'), (others => '0'), VENDOR_GNSSSENSOR, SLV_DID_EMPTY);
315
 
316
 
317
--! @brief   Plug-n-play descriptor structure for master device.
318
--! @details Each master device must generates this datatype output that
319
--!          is connected directly to the 'pnp' slave module on system bus.
320
type nasti_master_config_type is record
321
    --! Descriptor size in bytes.
322
    descrsize : std_logic_vector(7 downto 0);
323
    --! Descriptor type.
324
    descrtype : std_logic_vector(1 downto 0);
325
    --! Vendor ID.
326
    vid    : std_logic_vector(15 downto 0);
327
    --! Device ID.
328
    did    : std_logic_vector(15 downto 0);
329
end record;
330
 
331
--! @brief   Arrays of the plug-n-play descriptors.
332
--! @details Configuration bus vector from all slaves to plug'n'play
333
--!          NASTI device (pnp).
334
type nasti_master_cfg_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
335
       of nasti_master_config_type;
336
 
337
--! @brief Default master config value.
338
constant nasti_master_config_none : nasti_master_config_type := (
339
    PNP_CFG_MASTER_DESCR_BYTES, PNP_CFG_TYPE_MASTER,
340
    VENDOR_GNSSSENSOR, MST_DID_EMPTY);
341
 
342
 
343
--! @brief AMBA AXI4 compliant data structure.
344
type nasti_metadata_type is record
345
  --! @brief Read address.
346
  --! @details The read address gives the address of the first transfer
347
  --!          in a read burst transaction.
348
  addr   : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
349
  --! @brief   Burst length.
350
  --! @details This signal indicates the exact number of transfers in
351
  --!          a burst. This changes between AXI3 and AXI4. nastiXLenBits=8 so
352
  --!          this is an AXI4 implementation.
353
  --!              Burst_Length = len[7:0] + 1
354
  len    : std_logic_vector(7 downto 0);
355
  --! @brief   Burst size.
356
  --! @details This signal indicates the size of each transfer
357
  --!          in the burst: 0=1 byte; ..., 6=64 bytes; 7=128 bytes;
358
  size   : std_logic_vector(2 downto 0);
359
  --! @brief   Read response.
360
  --! @details This signal indicates the status of the read transfer.
361
  --! The responses are:
362
  --!      0b00 FIXED - In a fixed burst, the address is the same for every transfer
363
  --!                  in the burst. Typically is used for FIFO.
364
  --!      0b01 INCR - Incrementing. In an incrementing burst, the address for each
365
  --!                  transfer in the burst is an increment of the address for the
366
  --!                  previous transfer. The increment value depends on the size of
367
  --!                  the transfer.
368
  --!      0b10 WRAP - A wrapping burst is similar to an incrementing burst, except
369
  --!                  that the address wraps around to a lower address if an upper address
370
  --!                  limit is reached.
371
  --!      0b11 resrved.
372
  burst  : std_logic_vector(1 downto 0);
373
  --! @brief   Lock type.
374
  --! @details Not supported in AXI4.
375
  lock   : std_logic;
376
  --! @brief   Memory type.
377
  --! @details See table for write and read transactions.
378
  cache  : std_logic_vector(3 downto 0);
379
  --! @brief   Protection type.
380
  --! @details This signal indicates the privilege and security level
381
  --!          of the transaction, and whether the transaction is a data access
382
  --!          or an instruction access:
383
  --!  [0] :   0 = Unpriviledge access
384
  --!          1 = Priviledge access
385
  --!  [1] :   0 = Secure access
386
  --!          1 = Non-secure access
387
  --!  [2] :   0 = Data access
388
  --!          1 = Instruction access
389
  prot   : std_logic_vector(2 downto 0);
390
  --! @brief   Quality of Service, QoS.
391
  --! @details QoS identifier sent for each read transaction.
392
  --!          Implemented only in AXI4:
393
  --!              0b0000 - default value. Indicates that the interface is
394
  --!                       not participating in any QoS scheme.
395
  qos    : std_logic_vector(3 downto 0);
396
  --! @brief Region identifier.
397
  --! @details Permits a single physical interface on a slave to be used for
398
  --!          multiple logical interfaces. Implemented only in AXI4. This is
399
  --!          similar to the banks implementation in Leon3 without address
400
  --!          decoding.
401
  region : std_logic_vector(3 downto 0);
402
end record;
403
 
404
--! @brief Empty metadata value.
405
constant META_NONE : nasti_metadata_type := (
406
  (others =>'0'), X"00", "000", NASTI_BURST_INCR, '0', X"0", "000", "0000", "0000"
407
);
408
 
409
--! @brief Master device output signals
410
type nasti_master_out_type is record
411
  --! Write Address channel:
412
  aw_valid : std_logic;
413
  --! metadata of the read channel.
414
  aw_bits : nasti_metadata_type;
415
  --! Write address ID. Identification tag used for a trasaction ordering.
416
  aw_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
417
  --! Optional user defined signal in a write address channel.
418
  aw_user : std_logic;
419
  --! Write Data channel valid flag
420
  w_valid : std_logic;
421
  --! Write channel data value
422
  w_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
423
  --! Write Data channel last address in a burst marker.
424
  w_last : std_logic;
425
  --! Write Data channel strob signals selecting certain bytes.
426
  w_strb : std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
427
  --! Optional user defined signal in write channel.
428
  w_user : std_logic;
429
  --! Write Response channel accepted by master.
430
  b_ready : std_logic;
431
  --! Read Address Channel data valid.
432
  ar_valid : std_logic;
433
  --! Read Address channel metadata.
434
  ar_bits : nasti_metadata_type;
435
  --! Read address ID. Identification tag used for a trasaction ordering.
436
  ar_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
437
  --! Optional user defined signal in read address channel.
438
  ar_user : std_logic;
439
  --! Read Data channel:
440
  r_ready : std_logic;
441
end record;
442
 
443
--! @brief   Master device empty value.
444
--! @warning If the master is not connected to the vector then vector value
445
--!          MUST BE initialized by this value.
446
constant nasti_master_out_none : nasti_master_out_type := (
447
      '0', META_NONE, (others=>'0'), '0',
448
      '0', (others=>'0'), '0', (others=>'0'), '0',
449
      '0', '0', META_NONE, (others=>'0'), '0', '0');
450
 
451
--! @brief Array of all masters outputs.
452
type nasti_master_out_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
453
       of nasti_master_out_type;
454
 
455
 
456
--! @brief Master device input signals.
457
type nasti_master_in_type is record
458
  --! Write Address channel.
459
  aw_ready : std_logic;
460
  --! Write Data channel.
461
  w_ready : std_logic;
462
  --! Write Response channel:
463
  b_valid : std_logic;
464
  b_resp : std_logic_vector(1 downto 0);
465
  b_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
466
  b_user : std_logic;
467
  --! Read Address Channel
468
  ar_ready : std_logic;
469
  --! Read valid.
470
  r_valid : std_logic;
471
  --! @brief Read response.
472
  --! @details This signal indicates the status of the read transfer.
473
  --!  The responses are:
474
  --!      0b00 OKAY - Normal access success. Indicates that a normal access has
475
  --!                  been successful. Can also indicate an exclusive access
476
  --!                  has failed.
477
  --!      0b01 EXOKAY - Exclusive access okay. Indicates that either the read or
478
  --!                  write portion of an exclusive access has been successful.
479
  --!      0b10 SLVERR - Slave error. Used when the access has reached the slave
480
  --!                  successfully, but the slave wishes to return an error
481
  --!                  condition to the originating master.
482
  --!      0b11 DECERR - Decode error. Generated, typically by an interconnect
483
  --!                  component, to indicate that there is no slave at the
484
  --!                  transaction address.
485
  r_resp : std_logic_vector(1 downto 0);
486
  --! Read data
487
  r_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
488
  --! @brief  Read last.
489
  --! @details This signal indicates the last transfer in a read burst.
490
  r_last : std_logic;
491
  --! @brief Read ID tag.
492
  --! @details This signal is the identification tag for the read data
493
  --!          group of signals generated by the slave.
494
  r_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
495
  --! @brief User signal.
496
  --! @details Optional User-defined signal in the read channel. Supported
497
  --!          only in AXI4.
498
  r_user : std_logic;
499
end record;
500
 
501
constant nasti_master_in_none : nasti_master_in_type := (
502
      '0', '0', '0', NASTI_RESP_OKAY, (others=>'0'), '0',
503
      '0', '0', NASTI_RESP_OKAY, (others=>'0'), '0', (others=>'0'), '0');
504
 
505
type nasti_master_in_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
506
       of nasti_master_in_type;
507
 
508
 
509
--! @brief Slave device AMBA AXI input signals.
510
type nasti_slave_in_type is record
511
  --! Write Address channel:
512
  aw_valid : std_logic;
513
  aw_bits : nasti_metadata_type;
514
  aw_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
515
  aw_user : std_logic;
516
  --! Write Data channel:
517
  w_valid : std_logic;
518
  w_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
519
  w_last : std_logic;
520
  w_strb : std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
521
  w_user : std_logic;
522
  --! Write Response channel:
523
  b_ready : std_logic;
524
  --! Read Address Channel:
525
  ar_valid : std_logic;
526
  ar_bits : nasti_metadata_type;
527
  ar_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
528
  ar_user : std_logic;
529
  --! Read Data channel:
530
  r_ready : std_logic;
531
end record;
532
 
533
constant nasti_slave_in_none : nasti_slave_in_type := (
534
      '0', META_NONE, (others=>'0'), '0', '0',
535
      (others=>'0'), '0', (others=>'0'), '0', '0', '0', META_NONE,
536
      (others=>'0'), '0', '0');
537
 
538
type nasti_slave_in_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
539
       of nasti_slave_in_type;
540
 
541
 
542
--! @brief Slave device AMBA AXI output signals.
543
type nasti_slave_out_type is record
544
  --! Write Address channel:
545
  aw_ready : std_logic;
546
  --! Write Data channel:
547
  w_ready : std_logic;
548
  --! Write Response channel:
549
  b_valid : std_logic;
550
  b_resp : std_logic_vector(1 downto 0);
551
  b_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
552
  b_user : std_logic;
553
  --! Read Address Channel
554
  ar_ready : std_logic;
555
  --! Read Data channel:
556
  r_valid : std_logic;
557
  --! @brief Read response.
558
  --! @details This signal indicates the status of the read transfer.
559
  --!  The responses are:
560
  --!      0b00 OKAY - Normal access success. Indicates that a normal access has
561
  --!                  been successful. Can also indicate an exclusive access
562
  --!                  has failed.
563
  --!      0b01 EXOKAY - Exclusive access okay. Indicates that either the read or
564
  --!                  write portion of an exclusive access has been successful.
565
  --!      0b10 SLVERR - Slave error. Used when the access has reached the slave
566
  --!                  successfully, but the slave wishes to return an error
567
  --!                  condition to the originating master.
568
  --!      0b11 DECERR - Decode error. Generated, typically by an interconnect
569
  --!                  component, to indicate that there is no slave at the
570
  --!                  transaction address.
571
  r_resp : std_logic_vector(1 downto 0);
572
  --! Read data
573
  r_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
574
  --! Read last. This signal indicates the last transfer in a read burst.
575
  r_last : std_logic;
576
  --! @brief Read ID tag.
577
  --! @details This signal is the identification tag for the read data
578
  --!           group of signals generated by the slave.
579
  r_id   : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
580
  --! @brief User signal.
581
  --! @details Optinal User-defined signal in the read channel. Supported
582
  --!          only in AXI4.
583
  r_user : std_logic;--_vector(0 downto 0);
584
end record;
585
 
586
--! @brief Slave output signals connected to system bus.
587
--! @details If the slave is not connected to the vector then vector value
588
--! MUST BE initialized by this value.
589
constant nasti_slave_out_none : nasti_slave_out_type := (
590
      '0', '0', '0', NASTI_RESP_EXOKAY,
591
      (others=>'0'), '0', '0', '0', NASTI_RESP_EXOKAY, (others=>'1'),
592
      '0', (others=>'0'), '0');
593
 
594
--! Array of all slaves outputs.
595
type nasti_slaves_out_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
596
       of nasti_slave_out_type;
597
 
598
--! Array of addresses providing word aligned access.
599
type global_addr_array_type is array (0 to CFG_WORDS_ON_BUS-1)
600
       of std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
601
 
602
--! Slave device states during reading value operation.
603
type nasti_slave_rstatetype is (rwait, rtrans);
604
--! Slave device states during writting data operation.
605
type nasti_slave_wstatetype is (wwait, wtrans);
606
 
607
--! @brief Template bank of registers for any slave device.
608
type nasti_slave_bank_type is record
609
    rstate : nasti_slave_rstatetype;
610
    wstate : nasti_slave_wstatetype;
611
 
612
    rburst : std_logic_vector(1 downto 0);
613
    rsize  : integer;
614
    raddr  : global_addr_array_type;
615
    rlen   : integer;                       --! AXI4 supports 256 burst operation
616
    rid    : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
617
    rresp  : std_logic_vector(1 downto 0);  --! OK=0
618
    ruser  : std_logic;
619
    rwait_while_write : std_logic;          --! Writing request has higher priority than read and can interrupt reading
620
    rwaitready : std_logic;                 --! Reading wait state flag: 0=waiting. User's waitstates
621
 
622
    wburst : std_logic_vector(1 downto 0);  -- 0=INCREMENT
623
    wsize  : integer;                       -- code in range 0=1 Bytes upto 7=128 Bytes.
624
    waddr  : global_addr_array_type;        --! 4 KB bank
625
    wlen   : integer;                       --! AXI4 supports 256 burst operation
626
    wid    : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
627
    wresp  : std_logic_vector(1 downto 0);  --! OK=0
628
    wuser  : std_logic;
629
    b_valid : std_logic;
630
end record;
631
 
632
--! Reset value of the template bank of registers of a slave device.
633
constant NASTI_SLAVE_BANK_RESET : nasti_slave_bank_type := (
634
    rwait, wwait,
635
    NASTI_BURST_FIXED, 0, (others=>(others=>'0')), 0, (others=>'0'), NASTI_RESP_OKAY, '0', '0', '1',
636
    NASTI_BURST_FIXED, 0, (others=>(others=>'0')), 0, (others=>'0'), NASTI_RESP_OKAY, '0', '0'
637
);
638
 
639
 
640
  type dma_state_type is (
641
     DMA_STATE_IDLE,
642
     DMA_STATE_R_WAIT_RESP,
643
     DMA_STATE_R_WAIT_NEXT,
644
     DMA_STATE_W,
645
     DMA_STATE_W_WAIT_REQ,
646
     DMA_STATE_B
647
  );
648
 
649
--! @brief Master device to DMA engine request signals
650
  type dma_request_type is record
651
    valid : std_logic; -- response is valid
652
    ready : std_logic; -- ready to accept response
653
    write : std_logic;
654
    addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
655
    bytes : std_logic_vector(10 downto 0);
656
    size  : std_logic_vector(2 downto 0); -- 010=4 bytes; 011=8 bytes
657
    wdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
658
  end record;
659
 
660
--! @brief DMA engine to Master device response signals
661
  type dma_response_type is record
662
    ready : std_logic;  -- ready to accespt request
663
    valid : std_logic;  -- response is valid
664
    rdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
665
  end record;
666
 
667
--! DMA engine registers bank
668
  type dma_bank_type is record
669
    state : dma_state_type;
670
    addr2 : std_logic;            -- addr[2] bits to select low/high dword
671
    len   : integer range 0 to 255; -- burst (length-1)
672
    op32  : std_logic;
673
    wdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
674
  end record;
675
 
676
  constant DMA_BANK_RESET : dma_bank_type := (DMA_STATE_IDLE, '0', 0, '0', (others => '0'));
677
 
678
--! Device's DMA engine template procedure with AXI interface.
679
--! @param [in]  i_request Device to DMA engine request.
680
--! @param [out] o_response DMA Engine to Device response.
681
--! @param [in]  i_bank Bank of registers implemented by master device.
682
--! @param [out] o_bank Updated value for the master bank of registers.
683
--! @param [in]  i_msti AMBA to AXI master device signal.
684
--! @param [out] o_msto AXI master device signal to AMBA controller signals.
685
procedure procedureAxi4DMA(
686
      i_request : in dma_request_type;
687
      o_response : out dma_response_type;
688
      i_bank : in dma_bank_type;
689
      o_bank : out dma_bank_type;
690
      i_msti : in nasti_master_in_type;
691
      o_msto : out nasti_master_out_type
692
);
693
 
694
--! Read/write access state machines implementation for the slave device.
695
--! @param [in] i Slave input signal passed from system bus.
696
--! @param [in] cfg Slave confguration descriptor defining memory base address.
697
--! @param [in] i_bank Bank of registers implemented by each slave device.
698
--! @param [out] o_bank Updated value for the slave bank of registers.
699
procedure procedureAxi4(
700
     i      : in nasti_slave_in_type;
701
     cfg    : in nasti_slave_config_type;
702
     i_bank : in nasti_slave_bank_type;
703
     o_bank : out nasti_slave_bank_type
704
);
705
 
706
--! @brief Reordering elements of the address to provide 4-bytes memory access.
707
--! @param[in] mux Reordering control bits.
708
--! @param[in] iaddr Input addresses array.
709
--! @return Reordered addresses array.
710
function functionAddressReorder(
711
     mux   : std_logic_vector;
712
     iaddr : global_addr_array_type)
713
return global_addr_array_type;
714
 
715
procedure procedureWriteReorder(
716
     ena : in std_logic;
717
     mux   : in std_logic_vector(1 downto 0);
718
     iwaddr : in global_addr_array_type;
719
     iwstrb : in std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
720
     iwdata : in std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
721
     owaddr : out global_addr_array_type;
722
     owstrb : out std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
723
     owdata : out std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0)
724
);
725
 
726
--! @brief Complementary to address data reordring.
727
--! @details This function restore data bus as there wasn't address reordering.
728
--! @param[in] mux Reordering control bits.
729
--! @param[in] idata Input data array.
730
--! @return Restored data array.
731
function functionDataRestoreOrder(
732
     mux   : std_logic_vector;
733
     idata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
734
return std_logic_vector;
735
 
736
--! Convert slave bank registers into bus output signals.
737
--! @param[in] r      Bank of registers of the slave device.
738
--! @param[in] rd_val Formed by slave device read data value.
739
--! @return Slave device output signals connected to system bus.
740
function functionAxi4Output(
741
     r : nasti_slave_bank_type;
742
     rd_val : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
743
return nasti_slave_out_type;
744
 
745
--! @brief   AXI bus controller.
746
--! @param [in] watchdog_memop
747
--! @param [in] i_clk System bus clock.
748
--! @param [in] i_nrst Reset with active LOW level.
749
--! @param [in] i_slvcfg Slaves configuration vector.
750
--! @param [in] i_slvo Vector of slaves output signals.
751
--! @param [in] i_msto Vector of masters output signals.
752
--! @param [out] o_slvi Vector of slave inputs.
753
--! @param [out] o_msti Vector of master inputs.
754
--! @param [out] o_miss_irq Memory miss access signal. May be used as a interrupt or for debugging
755
--! @param [out] o_miss_addr Miss access last address (debug purpose)
756
--! @param [out] o_bus_util_w Write access bus utilization
757
--! @param [out] o_bus_util_r Read access bus utilization
758
--! @todo    Round-robin priority algorithm.
759
component axictrl is
760
  generic (
761
    watchdog_memop : integer := 0
762
  );
763
  port (
764
    i_clk    : in std_logic;
765
    i_nrst   : in std_logic;
766
    i_slvcfg : in  nasti_slave_cfg_vector;
767
    i_slvo   : in  nasti_slaves_out_vector;
768
    i_msto   : in  nasti_master_out_vector;
769
    o_slvi   : out nasti_slave_in_vector;
770
    o_msti   : out nasti_master_in_vector;
771
    o_miss_irq  : out std_logic;
772
    o_miss_addr : out std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
773
    o_bus_util_w : out std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0);
774
    o_bus_util_r : out std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0)
775
  );
776
end component;
777
 
778
end; -- package declaration
779
 
780
--! Implementation of the declared sub-programs (functions and
781
--! procedures).
782
package body types_amba4 is
783
 
784
  --! Device's DMA engine template procedure with AXI interface.
785
  --! @param [in]  i_request Device to DMA engine request.
786
  --! @param [out] o_response DMA Engine to Device response.
787
  --! @param [in]  i_bank Bank of registers implemented by master device.
788
  --! @param [out] o_bank Updated value for the master bank of registers.
789
  --! @param [in]  i_msti AMBA to AXI master device signal.
790
  --! @param [out] o_msto AXI master device signal to AMBA controller signals.
791
  procedure procedureAxi4DMA(
792
      i_request : in dma_request_type;
793
      o_response : out dma_response_type;
794
      i_bank : in dma_bank_type;
795
      o_bank : out dma_bank_type;
796
      i_msti : in nasti_master_in_type;
797
      o_msto : out nasti_master_out_type
798
  ) is
799
    variable tmp_len : integer;
800
  begin
801
    o_bank := i_bank;
802
    o_msto := nasti_master_out_none;
803
    o_msto.ar_user       := '0';
804
    o_msto.ar_id         := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
805
    o_msto.ar_bits.size  := (others => '0');
806
    o_msto.ar_bits.burst := NASTI_BURST_INCR;
807
    o_msto.aw_user       := '0';
808
    o_msto.aw_id         := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
809
    o_msto.aw_bits.size  := (others => '0');
810
    o_msto.aw_bits.burst := NASTI_BURST_INCR;
811
 
812
    o_response.ready := '0';
813
    o_response.valid := '0';
814
    o_response.rdata := (others => '0');
815
 
816
    case i_bank.state is
817
    when DMA_STATE_IDLE =>
818
        o_msto.ar_valid := i_request.valid and not i_request.write;
819
        o_msto.aw_valid := i_request.valid and i_request.write;
820
        tmp_len := conv_integer(i_request.bytes(10 downto 2)) - 1;
821
        if i_request.valid = '1' and i_request.write = '1' then
822
            o_msto.aw_bits.addr  := i_request.addr(CFG_NASTI_ADDR_BITS-1 downto 3) & "000";
823
            o_bank.addr2         := i_request.addr(2);
824
            o_bank.len  := tmp_len;
825
            o_msto.aw_bits.size  := i_request.size; -- 4/8 bytes
826
            o_msto.aw_bits.len := conv_std_logic_vector(tmp_len, 8);
827
            o_bank.wdata := i_request.wdata;
828
            if i_msti.aw_ready = '1' then
829
                o_response.ready := '1';
830
                o_bank.state := DMA_STATE_W;
831
            end if;
832
        elsif i_request.valid = '1' and i_request.write = '0' then
833
            o_msto.ar_bits.addr  := i_request.addr;
834
            o_bank.addr2         := i_request.addr(2);
835
            o_bank.len  := tmp_len;
836
            o_msto.ar_bits.size  := i_request.size; -- 4/8 bytes
837
            o_msto.ar_bits.len := conv_std_logic_vector(tmp_len, 8);
838
            if i_msti.ar_ready = '1' then
839
                o_response.ready := '1';
840
                o_bank.state := DMA_STATE_R_WAIT_RESP;
841
            end if;
842
        end if;
843
        if i_request.size = "010" then
844
           o_bank.op32 := '1';
845
        else
846
           o_bank.op32 := '0';
847
        end if;
848
 
849
    when DMA_STATE_R_WAIT_RESP =>
850
        o_msto.r_ready := i_request.ready;
851
        o_response.valid := i_msti.r_valid;
852
        if (i_request.ready and i_msti.r_valid) = '1' then
853
            if i_bank.op32 = '1' and i_bank.addr2 = '1' then
854
                o_response.rdata := i_msti.r_data(63 downto 32) & i_msti.r_data(31 downto 0);
855
            else
856
                o_response.rdata := i_msti.r_data;
857
            end if;
858
 
859
            if i_msti.r_last = '1' then
860
                o_bank.state := DMA_STATE_IDLE;
861
            else
862
                if i_request.valid = '1' and i_request.write = '0' then
863
                    o_response.ready := '1';
864
                else
865
                    o_bank.state := DMA_STATE_R_WAIT_NEXT;
866
                end if;
867
            end if;
868
        end if;
869
 
870
    when DMA_STATE_R_WAIT_NEXT =>
871
        if i_request.valid = '1' and i_request.write = '0' then
872
            o_response.ready := '1';
873
            o_bank.state := DMA_STATE_R_WAIT_RESP;
874
        end if;
875
 
876
    when DMA_STATE_W =>
877
        o_msto.w_valid := '1';
878
        if i_bank.op32 = '1' then
879
            case i_bank.addr2 is
880
            when '0' => o_msto.w_strb := X"0f";
881
            when '1' => o_msto.w_strb := X"f0";
882
            when others =>
883
            end case;
884
        else
885
            o_msto.w_strb := X"ff";
886
        end if;
887
        o_msto.w_data := i_bank.wdata;
888
 
889
        if i_msti.w_ready = '1' then
890
            if i_bank.len = 0 then
891
                o_bank.state := DMA_STATE_B;
892
                o_msto.w_last := '1';
893
            elsif i_request.valid = '1' and i_request.write = '1' then
894
                o_bank.len := i_bank.len - 1;
895
                o_bank.wdata := i_request.wdata;
896
                o_response.ready := '1';
897
                -- Address will be incremented on slave side
898
                --v.waddr2 := not r.waddr2;
899
            else
900
                o_bank.state := DMA_STATE_W_WAIT_REQ;
901
            end if;
902
        end if;
903
 
904
    when DMA_STATE_W_WAIT_REQ =>
905
        if i_request.valid = '1' and i_request.write = '1' then
906
            o_bank.len := i_bank.len - 1;
907
            o_bank.wdata := i_request.wdata;
908
            o_response.ready := '1';
909
            o_bank.state := DMA_STATE_W;
910
        end if;
911
 
912
    when DMA_STATE_B =>
913
        o_msto.w_last := '0';
914
        o_msto.b_ready := '1';
915
        if i_msti.b_valid = '1' then
916
            o_bank.state := DMA_STATE_IDLE;
917
        end if;
918
    when others =>
919
    end case;
920
  end; -- procedure
921
 
922
  --! Read/write access state machines implementation.
923
  --! @param [in] i Slave input signal passed from system bus.
924
  --! @param [in] cfg Slave confguration descriptor defining memory base address.
925
  --! @param [in] i_bank Bank of registers implemented by each slave device.
926
  --! @param [out] o_bank Updated value for the slave bank of registers.
927
  procedure procedureAxi4(
928
     i      : in nasti_slave_in_type;
929
     cfg    : in nasti_slave_config_type;
930
     i_bank : in nasti_slave_bank_type;
931
     o_bank : out nasti_slave_bank_type
932
  ) is
933
  variable traddr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
934
  variable twaddr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
935
  begin
936
    o_bank := i_bank;
937
 
938
    traddr := (i.ar_bits.addr(CFG_NASTI_ADDR_BITS-1 downto 12) and (not cfg.xmask))
939
             & i.ar_bits.addr(11 downto 0);
940
 
941
    o_bank.rwait_while_write := '0';
942
    -- Reading state machine:
943
    case i_bank.rstate is
944
    when rwait =>
945
        if i.ar_valid = '1' and i_bank.wstate /= wtrans then
946
            o_bank.rstate := rtrans;
947
 
948
            for n in 0 to CFG_WORDS_ON_BUS-1 loop
949
              o_bank.raddr(n) := traddr + n*CFG_ALIGN_BYTES;
950
            end loop;
951
            o_bank.rsize := XSizeToBytes(conv_integer(i.ar_bits.size));
952
            o_bank.rburst := i.ar_bits.burst;
953
            o_bank.rlen := conv_integer(i.ar_bits.len);
954
            o_bank.rid := i.ar_id;
955
            o_bank.rresp := NASTI_RESP_OKAY;
956
            o_bank.ruser := i.ar_user;
957
 
958
            --! No Wait States by default for reading operation.
959
            --!
960
            --! User can re-assign this value directly in module to implement
961
            --! reading wait states.
962
            --! Example: see axi2fse.vhd bridge implementation
963
            o_bank.rwaitready := '1';
964
            o_bank.rwait_while_write := i.aw_valid;
965
        end if;
966
    when rtrans =>
967
        o_bank.rwait_while_write := i.aw_valid or i.w_valid;
968
        if i.r_ready = '1' and i_bank.rwaitready = '1' and i_bank.rwait_while_write = '0' then
969
            o_bank.rlen := i_bank.rlen - 1;
970
            if i_bank.rburst = NASTI_BURST_INCR then
971
              for n in 0 to CFG_WORDS_ON_BUS-1 loop
972
                o_bank.raddr(n) := i_bank.raddr(n) + i_bank.rsize;
973
              end loop;
974
            end if;
975
            -- End of transaction (or process another one):
976
            if i_bank.rlen = 0 then
977
                if i.ar_valid = '0' then
978
                    o_bank.rstate := rwait;
979
                else
980
                    for n in 0 to CFG_WORDS_ON_BUS-1 loop
981
                      o_bank.raddr(n) := traddr + n*CFG_ALIGN_BYTES;
982
                    end loop;
983
                    o_bank.rsize := XSizeToBytes(conv_integer(i.ar_bits.size));
984
                    o_bank.rburst := i.ar_bits.burst;
985
                    o_bank.rlen := conv_integer(i.ar_bits.len);
986
                    o_bank.rid := i.ar_id;
987
                    o_bank.rresp := NASTI_RESP_OKAY;
988
                    o_bank.ruser := i.ar_user;
989
                    o_bank.rwaitready := '1';
990
                end if;
991
            end if;
992
        end if;
993
    end case;
994
 
995
    -- Writting state machine:
996
    case i_bank.wstate is
997
    when wwait =>
998
        if i.aw_valid = '1' then
999
            o_bank.wstate := wtrans;
1000
            twaddr := (i.aw_bits.addr(CFG_NASTI_ADDR_BITS-1 downto 12) and (not cfg.xmask))
1001
                   & i.aw_bits.addr(11 downto 0);
1002
            for n in 0 to CFG_WORDS_ON_BUS-1 loop
1003
               o_bank.waddr(n) := twaddr + n*CFG_ALIGN_BYTES;
1004
            end loop;
1005
            o_bank.wsize := XSizeToBytes(conv_integer(i.aw_bits.size));
1006
            o_bank.wburst := i.aw_bits.burst;
1007
            o_bank.wlen := conv_integer(i.aw_bits.len);
1008
            o_bank.wid := i.aw_id;
1009
            o_bank.wresp := NASTI_RESP_OKAY;
1010
            o_bank.wuser := i.aw_user;
1011
        end if;
1012
    when wtrans =>
1013
        if i.w_valid = '1' then
1014
            o_bank.wlen := i_bank.wlen - 1;
1015
            if i_bank.wburst = NASTI_BURST_INCR then
1016
              for n in 0 to CFG_WORDS_ON_BUS-1 loop
1017
                o_bank.waddr(n) := i_bank.waddr(n) + i_bank.wsize;
1018
              end loop;
1019
            end if;
1020
            -- End of transaction:
1021
            if i_bank.wlen = 0 then
1022
                o_bank.wstate := wwait;
1023
                o_bank.b_valid := '1';
1024
            end if;
1025
        end if;
1026
    end case;
1027
 
1028
    if i.b_ready = '1' and i_bank.b_valid = '1' then
1029
        o_bank.b_valid := '0';
1030
    end if;
1031
  end; -- procedure
1032
 
1033
 
1034
--! @brief Reordering elements of the address to provide 4-bytes memory access.
1035
--! @param[in] mux Reordering control bits.
1036
--! @param[in] iaddr Input addresses array.
1037
--! @return Reordered addresses array.
1038
function functionAddressReorder(
1039
     mux   : std_logic_vector;
1040
     iaddr : global_addr_array_type)
1041
return global_addr_array_type is
1042
variable oaddr :  global_addr_array_type;
1043
begin
1044
  if CFG_NASTI_DATA_BITS = 128 then
1045
    if mux = "00" then
1046
       oaddr := iaddr;
1047
    elsif mux = "01" then
1048
       oaddr(0) := iaddr(3);
1049
       oaddr(1) := iaddr(0);
1050
       oaddr(2) := iaddr(1);
1051
       oaddr(3) := iaddr(2);
1052
    elsif mux = "10" then
1053
       oaddr(0) := iaddr(2);
1054
       oaddr(1) := iaddr(3);
1055
       oaddr(2) := iaddr(0);
1056
       oaddr(3) := iaddr(1);
1057
    else
1058
       oaddr(0) := iaddr(1);
1059
       oaddr(1) := iaddr(2);
1060
       oaddr(2) := iaddr(3);
1061
       oaddr(3) := iaddr(0);
1062
    end if;
1063
  elsif CFG_NASTI_DATA_BITS = 64 then
1064
    if mux(2) = '0' then
1065
       oaddr := iaddr;
1066
    else
1067
       oaddr(0) := iaddr(1);
1068
       oaddr(1) := iaddr(0);
1069
    end if;
1070
  end if;
1071
  return oaddr;
1072
end;
1073
 
1074
--! @brief Reordering elements of the write transaction to provide 4-bytes memory access.
1075
procedure procedureWriteReorder(
1076
     ena : in std_logic;
1077
     mux   : in std_logic_vector(1 downto 0);
1078
     iwaddr : in global_addr_array_type;
1079
     iwstrb : in std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
1080
     iwdata : in std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
1081
     owaddr : out global_addr_array_type;
1082
     owstrb : out std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
1083
     owdata : out std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0)) is
1084
begin
1085
  if CFG_NASTI_DATA_BITS = 128 and ena = '1' then
1086
    if mux = "00" then
1087
       owaddr := iwaddr;
1088
       owdata := iwdata;
1089
       owstrb := iwstrb;
1090
    elsif mux = "01" then
1091
       owaddr(0) := iwaddr(3);
1092
       owaddr(1) := iwaddr(0);
1093
       owaddr(2) := iwaddr(1);
1094
       owaddr(3) := iwaddr(2);
1095
 
1096
       owdata(31 downto 0) := iwdata(127 downto 96);
1097
       owdata(127 downto 32) := iwdata(95 downto 0);
1098
 
1099
       owstrb := iwstrb(11 downto 0) & iwstrb(15 downto 12);
1100
    elsif mux = "10" then
1101
       owaddr(0) := iwaddr(2);
1102
       owaddr(1) := iwaddr(3);
1103
       owaddr(2) := iwaddr(0);
1104
       owaddr(3) := iwaddr(1);
1105
 
1106
       owdata(63 downto 0) := iwdata(127 downto 64);
1107
       owdata(127 downto 64) := iwdata(63 downto 0);
1108
 
1109
       owstrb := iwstrb(7 downto 0) & iwstrb(15 downto 8);
1110
    else
1111
       owaddr(0) := iwaddr(1);
1112
       owaddr(1) := iwaddr(2);
1113
       owaddr(2) := iwaddr(3);
1114
       owaddr(3) := iwaddr(0);
1115
 
1116
       owdata(95 downto 0) := iwdata(127 downto 32);
1117
       owdata(127 downto 96) := iwdata(31 downto 0);
1118
 
1119
       owstrb := iwstrb(3 downto 0) & iwstrb(15 downto 4);
1120
    end if;
1121
  elsif CFG_NASTI_DATA_BITS = 64 and ena = '1' then
1122
    if mux(0) = '0' then
1123
       owaddr := iwaddr;
1124
       owdata := iwdata;
1125
       owstrb := iwstrb;
1126
    else
1127
       owaddr(0) := iwaddr(1);
1128
       owaddr(1) := iwaddr(0);
1129
       owdata(31 downto 0) := iwdata(63 downto 32);
1130
       owdata(63 downto 32) := iwdata(31 downto 0);
1131
       owstrb := iwstrb(3 downto 0) & iwstrb(7 downto 4);
1132
    end if;
1133
  else
1134
    owaddr := (others => (others => '0'));
1135
    owdata := (others => '0');
1136
    owstrb := (others => '0');
1137
  end if;
1138
end;
1139
 
1140
--! @brief Complementary to address data reordring.
1141
--! @details This function restore data bus as there wasn't address reordering.
1142
--! @param[in] mux Reordering control bits.
1143
--! @param[in] idata Input data array.
1144
--! @return Restored data array.
1145
function functionDataRestoreOrder(
1146
     mux   : std_logic_vector;
1147
     idata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
1148
return std_logic_vector is
1149
variable odata :  std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
1150
begin
1151
  if CFG_NASTI_DATA_BITS = 128 then
1152
    if mux = "00" then
1153
       odata := idata;
1154
    elsif mux = "01" then
1155
       odata(95 downto 0) := idata(127 downto 32);
1156
       odata(127 downto 96) := idata(31 downto 0);
1157
    elsif mux = "10" then
1158
       odata(63 downto 0) := idata(127 downto 64);
1159
       odata(127 downto 64) := idata(63 downto 0);
1160
    else
1161
       odata(31 downto 0) := idata(127 downto 96);
1162
       odata(127 downto 32) := idata(95 downto 0);
1163
    end if;
1164
  elsif CFG_NASTI_DATA_BITS = 64 then
1165
    if mux(2) = '0' then
1166
       odata := idata;
1167
    else
1168
       odata(31 downto 0) := idata(63 downto 32);
1169
       odata(63 downto 32) := idata(31 downto 0);
1170
    end if;
1171
  end if;
1172
  return odata;
1173
end;
1174
 
1175
--! @brief Convert bank registers into output signals
1176
--! @param[in] r Registers bank with the AXI4 state machines
1177
--!             implementaitons.
1178
--! @param[in] rd_val Read value from the device's registers bank.
1179
--!                  This value fully depends of device implementation.
1180
--! @return NASTI output signals of the implemented slave device.
1181
function functionAxi4Output(
1182
     r : nasti_slave_bank_type;
1183
     rd_val : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
1184
return nasti_slave_out_type is
1185
variable ret :  nasti_slave_out_type;
1186
begin
1187
    -- Read transfer:
1188
    ret.aw_ready    := '1';
1189
    ret.ar_ready    := '1';
1190
 
1191
    ret.r_id      := r.rid;
1192
    if r.rstate = rtrans and r.rlen = 0 then
1193
      ret.r_last    := '1';
1194
    else
1195
      ret.r_last    := '0';
1196
    end if;
1197
    ret.r_resp    := r.rresp;
1198
    ret.r_user    := r.ruser;
1199
    if r.rwaitready = '1' and r.rstate = rtrans and r.rwait_while_write = '0' then
1200
      ret.r_valid   := '1';
1201
    else
1202
      ret.r_valid   := '0';
1203
    end if;
1204
 
1205
    ret.r_data := rd_val;
1206
 
1207
    -- Write transfer:
1208
    if r.wstate = wtrans then
1209
      ret.w_ready := '1';
1210
      ret.aw_ready    := '0';
1211
      ret.ar_ready    := '0';
1212
    else
1213
      ret.w_ready := '0';
1214
    end if;
1215
 
1216
    -- Write Handshaking:
1217
    ret.b_id := r.wid;
1218
    ret.b_resp := r.wresp;
1219
    ret.b_user := r.wuser;
1220
    ret.b_valid := r.b_valid;
1221
    return (ret);
1222
end;
1223
 
1224
end; -- package body

powered by: WebSVN 2.1.0

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