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

Subversion Repositories riscv_vhdl

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

powered by: WebSVN 2.1.0

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