|
| 1 | +.. _SVIF: |
| 2 | + |
| 3 | +SVIF |
| 4 | +==== |
| 5 | + |
| 6 | +Description |
| 7 | +^^^^^^^^^^^ |
| 8 | + |
| 9 | +The ``SVIF`` type specifically targets system Verilog designs. This type extends from ``Bundle``. When generating Verilog or VHDL, the behavior of this type is exactly the same as that of ``Bundle``. However, when generating System Verilog and enabling the ``svInterface`` option in SpinalConfig, this type will be generated as an ``Interface``. |
| 10 | + |
| 11 | +This type is still an experimental feature. |
| 12 | + |
| 13 | +Declaration |
| 14 | +^^^^^^^^^^^ |
| 15 | + |
| 16 | +The syntax to declare a SVIF is as follows: |
| 17 | + |
| 18 | +.. code-block:: scala |
| 19 | +
|
| 20 | + case class myBundle extends SVIF { |
| 21 | + val bundleItem0 = AnyType |
| 22 | + val bundleItem1 = AnyType |
| 23 | + val bundleItemN = AnyType |
| 24 | + } |
| 25 | +
|
| 26 | +For example, a SVIF holding a color could be defined as: |
| 27 | + |
| 28 | +.. code-block:: scala |
| 29 | +
|
| 30 | + case class Color(channelWidth: Int) extends SVIF { |
| 31 | + val r, g, b = UInt(channelWidth bits) |
| 32 | + } |
| 33 | +
|
| 34 | +modport |
| 35 | +~~~~~~~ |
| 36 | + |
| 37 | +``modport`` can be implemented through add annotations above functions, with the function name serving as the modport name. |
| 38 | + |
| 39 | +.. code-block:: scala |
| 40 | +
|
| 41 | + case class Color(channelWidth: Int) extends SVIF { |
| 42 | + val r, g, b = UInt(channelWidth bits) |
| 43 | +
|
| 44 | + @modport |
| 45 | + def mst = { |
| 46 | + out(r, g, b) |
| 47 | + } |
| 48 | +
|
| 49 | + @modport |
| 50 | + def slv = { |
| 51 | + in(r, g, b) |
| 52 | + } |
| 53 | + } |
| 54 | +
|
| 55 | +with ``IMasterSlave``: |
| 56 | + |
| 57 | +.. code-block:: scala |
| 58 | +
|
| 59 | + case class Color(channelWidth: Int) extends SVIF with IMasterSlave { |
| 60 | + val r, g, b = UInt(channelWidth bits) |
| 61 | +
|
| 62 | + override def asMaster = { |
| 63 | + out(r, g, b) |
| 64 | + } |
| 65 | +
|
| 66 | + @modport |
| 67 | + def mst = asMaster |
| 68 | +
|
| 69 | + @modport |
| 70 | + def slv = asSlave |
| 71 | + } |
| 72 | +
|
| 73 | +Parameter |
| 74 | +~~~~~~~~~ |
| 75 | + |
| 76 | +.. code-block:: scala |
| 77 | +
|
| 78 | + case class Color(channelWidth: Int) extends SVIF { |
| 79 | + val width = addGeneric("WIDTH", channelWidth) // or addParameter |
| 80 | + val r, g, b = UInt(channelWidth bits) |
| 81 | + tieGeneric(r, width) // or tieParameter |
| 82 | + tieGeneric(g, width) |
| 83 | + tieGeneric(b, width) |
| 84 | +
|
| 85 | + @modport |
| 86 | + def mst = out(r, g, b) |
| 87 | +
|
| 88 | + @modport |
| 89 | + def slv = in(r, g, b) |
| 90 | + } |
| 91 | +
|
| 92 | +.. code-block:: scala |
| 93 | +
|
| 94 | + case class ColorHandShake(Width: Int) extends SVIF with IMasterSlave { |
| 95 | + val w = addGeneric("W", Width, default = "8") |
| 96 | + val valid = Bool() |
| 97 | + val payload = Color(Width) |
| 98 | + val ready = Bool() |
| 99 | + tieIFParameter(payload, "WIDTH", "W") // for generate " .WIDTH (W)" |
| 100 | +
|
| 101 | + override def asMaster = { |
| 102 | + out(valid, payload) |
| 103 | + in(ready) |
| 104 | + } |
| 105 | +
|
| 106 | + @modport |
| 107 | + def mst = asMaster |
| 108 | +
|
| 109 | + @modport |
| 110 | + def slv = asSlave |
| 111 | + } |
| 112 | +
|
| 113 | +This will generate system verilog code as below: |
| 114 | + |
| 115 | +.. code-block:: scala |
| 116 | +
|
| 117 | + interface ColorHandShake #( |
| 118 | + parameter W = 8 |
| 119 | + ) () ; |
| 120 | +
|
| 121 | + logic valid ; |
| 122 | + Color #( |
| 123 | + .WIDTH (W) |
| 124 | + ) payload(); |
| 125 | + logic ready ; |
| 126 | +
|
| 127 | + modport mst ( |
| 128 | + output valid, |
| 129 | + Color.slv payload, |
| 130 | + input ready |
| 131 | + ); |
| 132 | +
|
| 133 | + modport slv ( |
| 134 | + input valid, |
| 135 | + Color.mst payload, |
| 136 | + output ready |
| 137 | + ); |
| 138 | +
|
| 139 | + endinterface |
| 140 | +
|
| 141 | + interface Color #( |
| 142 | + parameter WIDTH |
| 143 | + ) () ; |
| 144 | +
|
| 145 | + logic [WIDTH-1:0] r ; |
| 146 | + logic [WIDTH-1:0] g ; |
| 147 | + logic [WIDTH-1:0] b ; |
| 148 | +
|
| 149 | + modport mst ( |
| 150 | + input r, |
| 151 | + input g, |
| 152 | + input b |
| 153 | + ); |
| 154 | +
|
| 155 | + modport slv ( |
| 156 | + output r, |
| 157 | + output g, |
| 158 | + output b |
| 159 | + ); |
| 160 | +
|
| 161 | + endinterface |
| 162 | +
|
| 163 | +Definition Name |
| 164 | +~~~~~~~~~~~~~~~ |
| 165 | + |
| 166 | +You can use ``setDefinitionName`` to set the definition name. But remember to use it before any clone of this interface. |
| 167 | + |
| 168 | +Not Interface |
| 169 | +~~~~~~~~~~~~~ |
| 170 | + |
| 171 | +If you have used a certain interface in multiple places, and at one of those locations ``mySignal``, you wish to flatten it instead of generating an interface, you can achieve this by calling ``mySignal.notSVIF()`` to fully flatten the signal. If the signal has nested interfaces and you only want to expand the outermost layer, you can use ``mySignal.notSVIFthisLevel()``. |
0 commit comments