|
| 1 | +Multi-dimensional arrays are often used to represented dimensionally structured |
| 2 | +data. Packtype's syntax allows any type to be arrayed with an arbitrary number |
| 3 | +of dimensions and dimension sizes. The base type can be a simple [scalar](scalar.md), |
| 4 | +or can reference a more complex type like a [struct](struct.md) or [union](union.md), |
| 5 | +you can even reference another multi-dimensional array! |
| 6 | + |
| 7 | +## Example |
| 8 | + |
| 9 | +The Packtype definition can either use a Python dataclass style or the Packtype |
| 10 | +custom grammar: |
| 11 | + |
| 12 | +=== "Python (.py)" |
| 13 | + |
| 14 | + ```python linenums="1" |
| 15 | + import packtype |
| 16 | + from packtype import Constant, Scalar |
| 17 | + |
| 18 | + @packtype.package() |
| 19 | + class Package1D: |
| 20 | + Scalar1D : Scalar[4] |
| 21 | + |
| 22 | + @Package1D.struct() |
| 23 | + class Struct1D: |
| 24 | + field_a : Scalar[2] |
| 25 | + field_b : Scalar[3] |
| 26 | + |
| 27 | + @packtype.package() |
| 28 | + class Package3D: |
| 29 | + Scalar3D : Package1D.Scalar1D[4][5] |
| 30 | + Struct3D : Package1D.Struct1D[3][2] |
| 31 | + ``` |
| 32 | + |
| 33 | +=== "Packtype (.pt)" |
| 34 | + |
| 35 | + ```sv linenums="1" |
| 36 | + package package_1d { |
| 37 | + scalar_1d_t : scalar[4] |
| 38 | + |
| 39 | + struct struct_1d_t { |
| 40 | + field_a : scalar[2] |
| 41 | + field_b : scalar[3] |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + package package_3d { |
| 46 | + scalar_3d_t : package_1d::scalar_1d_t[4][5] |
| 47 | + struct_3d_t : package_1d::struct_1d_t[3][2] |
| 48 | + } |
| 49 | + ``` |
| 50 | + |
| 51 | +As rendered to SystemVerilog |
| 52 | + |
| 53 | +```sv linenums="1" |
| 54 | +package package_1d; |
| 55 | +
|
| 56 | +typedef logic [3:0] scalar_1d_t; |
| 57 | +
|
| 58 | +typedef struct packed { |
| 59 | + logic [2:0] field_b; |
| 60 | + logic [1:0] field_a; |
| 61 | +} struct_1d_t; |
| 62 | +
|
| 63 | +endpackage : package_1d |
| 64 | +
|
| 65 | +package package_3d; |
| 66 | +
|
| 67 | +import package_1d::scalar_1d_t; |
| 68 | +import package_1d::struct_1d_t; |
| 69 | +
|
| 70 | +typedef scalar_1d_t [4:0][3:0] scalar_3d_t; |
| 71 | +typedef struct_1d_t [1:0][2:0] struct_3d_t; |
| 72 | +
|
| 73 | +endpackage : package_3d |
| 74 | +``` |
| 75 | + |
| 76 | +!!! warning |
| 77 | + |
| 78 | + The order of dimensions is _reversed_ when compared to declaring a packed |
| 79 | + multi-dimensional array in SystemVerilog. For example `scalar[4][5][6]` |
| 80 | + declares a 6x5 array of 4-bit elements, which in SystemVerilog would be |
| 81 | + written `logic [5:0][4:0][3:0]`. This is done to make it easier to parse the |
| 82 | + syntax, as decisions can be made reading left-to-right. |
| 83 | + |
| 84 | +## Helper Properties and Methods |
| 85 | + |
| 86 | +Struct definitions expose a collection of helper functions for properties related |
| 87 | +to the type: |
| 88 | + |
| 89 | + * `<ARRAY>._pt_width` - property that returns the bit width of the entire array; |
| 90 | + * `<ARRAY>._pt_pack()` - packs all values contained within the array into a |
| 91 | + singular integer value (can also be achieved by casting to an int, e.g. |
| 92 | + `int(<ARRAY>)`); |
| 93 | + * `<ARRAY>._pt_unpack(packed: int)` - unpacks an integer value into the entries |
| 94 | + of the array; |
| 95 | + * `len(<ARRAY>)` - returns the size of the outermost dimension of the array; |
| 96 | + * `<ARRAY>[X]` - accesses element X within the array, which may return either |
| 97 | + an instance of the base type _or_ another packed array depending on the |
| 98 | + number of dimensions. |
0 commit comments