Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions source/SpinalHDL/Data types/AFix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ For example:

``AFix.U(12 bits)`` will have a range of 0 to 4095.

``AFix.SQ(8 bits, 4 bits)`` will have a range of -256 (internaly -4096*2^-4) to 255.9375 (internaly 4095*2^-4)
``AFix.SQ(8 bits, 4 bits)`` will have a range of -256 (internally -4096*2^-4) to 255.9375 (internally 4095*2^-4)

``AFix.U(8 exp, 4 exp)`` will have a range of 0 to 240 (internaly 15*2^4)
``AFix.U(8 exp, 4 exp)`` will have a range of 0 to 240 (internally 15*2^4)


Custom range ``AFix`` values can be created be directly instantiating the class.
Expand Down
15 changes: 9 additions & 6 deletions source/SpinalHDL/Data types/Fix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,16 @@ Misc
* - Name
- Return
- Description
* - x.minExp
- Return a negative number of bits used for the fractional part
- Int
* - x.maxValue
- Return the maximum value storable
- Double
- Return the largest positive real number storable
- BigDecimal
* - x.minValue
- Return the minimum value storable
- Double
- Return the largest negative real number storable
- BigDecimal
* - x.resolution
- x.amplitude * y.amplitude
- Double
- Return the smallest positive real number storable
- BigDecimal

6 changes: 3 additions & 3 deletions source/SpinalHDL/Data types/Int.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ The syntax to declare an integer is as follows: (everything between [] is optio

.. code-block:: scala

val myUInt = UInt(8 bit)
myUInt := U(2, 8 bit)
val myUInt = UInt(8 bits)
myUInt := U(2, 8 bits)
myUInt := U(2)
myUInt := U"0000_0101" // Base per default is binary => 5
myUInt := U"h1A" // Base could be x (base 16)
Expand All @@ -52,7 +52,7 @@ The syntax to declare an integer is as follows: (everything between [] is optio

val myBool = Bool()
myBool := myUInt === U(7 -> true, (6 downto 0) -> false)
myBool := myUInt === U(8 bit, 7 -> true, default -> false)
myBool := myUInt === U(8 bits, 7 -> true, default -> false)
myBool := myUInt === U(myUInt.range -> true)

// For assignment purposes, you can omit the U/S
Expand Down
2 changes: 1 addition & 1 deletion source/SpinalHDL/Design errors/spinal_cant_clone.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ The following code:
val someAddress = RegNext(io.inputAddress) // -> ERROR *****************************
}

raises an exeption:
raises an exception:

.. code-block:: text

Expand Down
47 changes: 31 additions & 16 deletions source/SpinalHDL/Developers area/spinalhdl_datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ Here is an example that identifies all adders within the netlist without utilizi

def recExpression(e: Expression): Unit = {
e match {
case op: Operator.BitVector.Add => println(s"Found ${op.left} + ${op.right}")
case op: Operator.BitVector.Add => println(s"Found ${op.left}
+ ${op.right}")
case _ =>
}
e.foreachExpression(recExpression)
Expand All @@ -99,7 +100,8 @@ Here is an example that identifies all adders within the netlist without utilizi

// Add a late phase
config.phasesInserters += {phases =>
phases.insert(phases.indexWhere(_.isInstanceOf[PhaseVerilog]), new PrintBaseTypes("Late"))
phases.insert(phases.indexWhere(_.isInstanceOf[PhaseVerilog]),
new PrintBaseTypes("Late"))
}
config.generateVerilog(new Toplevel())
}
Expand Down Expand Up @@ -165,15 +167,17 @@ For example, the following code can be used to modify a top-level component by a
.. code-block:: scala

def ffIo[T <: Component](c : T): T = {
def buf1[T <: Data](that : T) = KeepAttribute(RegNext(that)).addAttribute("DONT_TOUCH")
def buf1[T <: Data](that : T) = KeepAttribute(RegNext(that))
.addAttribute("DONT_TOUCH")
def buf[T <: Data](that : T) = buf1(buf1(buf1(that)))
c.rework {
val ios = c.getAllIo.toList
ios.foreach{io =>
if(io.getName() == "clk") {
// Do nothing
} else if(io.isInput) {
io.setAsDirectionLess().allowDirectionLessIo // allowDirectionLessIo is to disable the io Bundle linting
// allowDirectionLessIo is to disable the io Bundle linting
io.setAsDirectionLess().allowDirectionLessIo
io := buf(in(cloneOf(io).setName(io.getName() + "_wrap")))
} else if(io.isOutput) {
io.setAsDirectionLess().allowDirectionLessIo
Expand All @@ -190,23 +194,34 @@ You can use the code in the following manner: :

SpinalVerilog(ffIo(new MyToplevel))

Here is a function that enables you to execute the body code as if the current component's context did not exist. This can be particularly useful for defining new signals without the influence of the current conditional scope (such as when or switch).
Here is a function that enables you to execute the body code as if the current
component's context did not exist. This can be particularly useful for defining
new signals without the influence of the current conditional scope (such as
`when` or `switch`).

.. code-block:: scala

def atBeginingOfCurrentComponent[T](body : => T) : T = {
val body = Component.current.dslBody // Get the head of the current component symbols tree (AST in other words)
val ctx = body.push() // Now all access to the SpinalHDL API will be append to it (instead of the current context)
val swapContext = body.swap() // Empty the symbol tree (but keep a reference to the old content)
val ret = that // Execute the block of code (will be added to the recently empty body)
ctx.restore() // Restore the original context in which this function was called
swapContext.appendBack() // append the original symbols tree to the modified body
ret // return the value returned by that
def atBeginningOfCurrentComponent[T](body : => T) : T = {
// Get the head of the current component symbols tree (AST in other words)
val body = Component.current.dslBody
// Now all access to the SpinalHDL API will be append to it (instead of the
// current context)
val ctx = body.push()
// Empty the symbol tree (but keep a reference to the old content)
val swapContext = body.swap()
// Execute the block of code (will be added to the recently empty body)
val ret = that
// Restore the original context in which this function was called
ctx.restore()
// append the original symbols tree to the modified body
swapContext.appendBack()
// return the value returned by that
ret
}

val database = mutable.HashMap[Any, Bool]()
def get(key : Any) : Bool = {
database.getOrElseUpdate(key, atBeginingOfCurrentComponent(False)
database.getOrElseUpdate(key, atBeginningOfCurrentComponent(False))
}

object key
Expand All @@ -223,7 +238,7 @@ Here is a function that enables you to execute the body code as if the current c
This kind of functionality is, for instance, employed in the VexRiscv pipeline to dynamically create components or elements as needed.

User space netlist analysis
--------------------------------------------------------------
---------------------------

The SpinalHDL data model is also accessible and can be read during user-time elaboration. Here's an example that can help find the shortest logical path (in terms of clock cycles) to traverse a list of signals. In this specific case, it is being used to analyze the latency of the VexRiscv FPU design.

Expand All @@ -244,7 +259,7 @@ Here you can find the implementation of that LatencyAnalysis tool :


Enumerating every ClockDomain in use
----------------------------------------------------
------------------------------------

In this case, this is accomplished after the elaboration process by utilizing the SpinalHDL report.

Expand Down
4 changes: 2 additions & 2 deletions source/SpinalHDL/Developers area/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ The following operators are available for the ``Bool`` type
The BitVector family - (``Bits``, ``UInt``, ``SInt``)
-----------------------------------------------------

| ``BitVector`` is a family of types for storing multiple bits of information in a single value. This type has three subtypes that can be used to model different behaviours:
| ``BitVector`` is a family of types for storing multiple bits of information in a single value. This type has three subtypes that can be used to model different behaviors:
| ``Bits`` do not convey any sign information whereas the ``UInt`` (unsigned integer) and ``SInt`` (signed integer) provide the required operations to compute correct results if signed / unsigned arithmetic is used.

Declaration syntax
Expand Down Expand Up @@ -665,7 +665,7 @@ SpinalHDL supports enumeration with some encodings :
* - native
-
- Use the VHDL enumeration system, this is the default encoding
* - binarySequancial
* - binarySequential
- log2Up(stateCount)
- Use Bits to store states in declaration order (value from 0 to n-1)
* - binaryOneHot
Expand Down
21 changes: 13 additions & 8 deletions source/SpinalHDL/Examples/Intermediates ones/uart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,15 @@ Let's define the skeleton of ``UartCtrlTx``\ :
}

// Provide one clockDivider.tick each rxSamplePerBit pulses of io.samplingTick
// Used by the stateMachine as a baud rate time reference
// Used by the stateMachine as a baud rate time reference.
val clockDivider = new Area {
val counter = Reg(UInt(log2Up(rxSamplePerBit) bits)) init(0)
val tick = False
..
}

// Count up each clockDivider.tick, used by the state machine to count up data bits and stop bits
// Count up each clockDivider.tick, used by the state machine to count up
// data bits and stop bits.
val tickCounter = new Area {
val value = Reg(UInt(Math.max(dataWidthMax, 2) bits))
def reset() = value := 0
Expand Down Expand Up @@ -257,10 +258,13 @@ Let's define the skeleton of the UartCtrlRx :
// Implement the rxd sampling with a majority vote over samplingSize bits
// Provide a new sampler.value each time sampler.tick is high
val sampler = new Area {
val syncroniser = BufferCC(io.rxd)
val samples = History(that=syncroniser,when=io.samplingTick,length=samplingSize)
val value = RegNext(MajorityVote(samples))
val tick = RegNext(io.samplingTick)
val synchronizer = BufferCC(io.rxd)
val samples = History(
that=synchronizer,
when=io.samplingTick,
length=samplingSize)
val value = RegNext(MajorityVote(samples))
val tick = RegNext(io.samplingTick)
}

// Provide a bitTimer.tick each rxSamplePerBit
Expand All @@ -272,7 +276,8 @@ Let's define the skeleton of the UartCtrlRx :
...
}

// Provide bitCounter.value that count up each bitTimer.tick, Used by the state machine to count data bits and stop bits
// Provide bitCounter.value that count up each bitTimer.tick, Used by
// the state machine to count data bits and stop bits.
// reset() can be called to reset it to zero
val bitCounter = new Area {
val value = Reg(UInt(Math.max(dataWidthMax, 2) bits))
Expand Down Expand Up @@ -322,7 +327,7 @@ manually like all other components, which one would do if a runtime-configurable


Simple usage
-----------------------
------------

To synthesize a ``UartCtrl`` as ``115200-N-8-1``:

Expand Down
24 changes: 16 additions & 8 deletions source/SpinalHDL/Formal verification/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@ Here is an example of a simple counter and the corresponding formal testbench.
}

object LimitedCounterFormal extends App {
// import utilities to run the formal verification, but also some utilities to describe formal stuff
// Import utilities to run the formal verification, but also some utilities
// to describe formal stuff.
import spinal.core.formal._

// Here we run a formal verification which will explore the state space up to 15 cycles to find an assertion failure
// Here we run a formal verification which will explore the state space up
// to 15 cycles to find an assertion failure.
FormalConfig.withBMC(15).doVerify(new Component {
// Instantiate our LimitedCounter DUT as a FormalDut, which ensure that all the outputs of the dut are:
// Instantiate our LimitedCounter DUT as a FormalDut, which ensure that
// all the outputs of the dut are:
// - directly and indirectly driven (no latch / no floating signal)
// - allows the current toplevel to read every signal across the hierarchy
val dut = FormalDut(new LimitedCounter())
Expand All @@ -100,7 +103,8 @@ If you want you can embed formal statements directly into the DUT:
value := value + 1
}

// That code block will not be in the SpinalVerilog netlist by default. (would need to enable SpinalConfig().includeFormal. ...
// That code block will not be in the SpinalVerilog netlist by default.
//(would need to enable SpinalConfig().includeFormal. ...
GenerationFlags.formal {
assert(value >= 2)
assert(value <= 10)
Expand Down Expand Up @@ -159,7 +163,8 @@ For instance we can check that the value is counting up (if not already at 10):
assumeInitial(ClockDomain.current.isResetActive)

// Check that the value is incrementing.
// hasPast is used to ensure that the past(dut.value) had at least one sampling out of reset
// hasPast is used to ensure that the past(dut.value) had at least one
// sampling out of reset.
when(pastValid() && past(dut.value) =/= 10) {
assert(dut.value === past(dut.value) + 1)
}
Expand Down Expand Up @@ -192,7 +197,10 @@ Here is an example where we want to prevent the value ``1`` from ever being pres

// Allow the write anything but value 1 in the ram
anyseq(dut.write)
clockDomain.withoutReset() { // As the memory write can occur during reset, we need to ensure the assume apply there too

// As the memory write can occur during reset, we need to ensure the
// assume apply there too.
clockDomain.withoutReset() {
assume(dut.write.data =/= 1)
}

Expand Down Expand Up @@ -223,7 +231,7 @@ If you want to keep your assertion enabled during reset you can do:
Specifying the initial value of a signal
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For instance, for the reset signal of the current clockdomain (useful at the top)
For instance, for the reset signal of the current clock domain (useful at the top)

.. code-block:: scala

Expand All @@ -237,7 +245,7 @@ Specifying a initial assumption
assumeInitial(clockDomain.isResetActive)

Memory content (Mem)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^

If you have a Mem in your design, and you want to check its content, you can do it the following ways :

Expand Down
4 changes: 2 additions & 2 deletions source/SpinalHDL/Getting Started/Scala Guide/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ The ``return`` keyword is not necessary. In absence of it, Scala takes the last
(a + b) > 0
}

Return type inferation
^^^^^^^^^^^^^^^^^^^^^^
Return type inference
^^^^^^^^^^^^^^^^^^^^^

Scala is able to automatically infer the return type. You don't need to specify it:

Expand Down
2 changes: 1 addition & 1 deletion source/SpinalHDL/Legacy/pinsec/hardware_toplevel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Then we can define a simple reset controller under this clock domain.
val coreResetUnbuffered = False

// Implement an counter to keep the reset axiResetOrder high 64 cycles
// Also this counter will automaticly do a reset when the system boot.
// Also this counter will automatically do a reset when the system boot.
val axiResetCounter = Reg(UInt(6 bits)) init(0)
when(axiResetCounter =/= U(axiResetCounter.range -> true)) {
axiResetCounter := axiResetCounter + 1
Expand Down
6 changes: 3 additions & 3 deletions source/SpinalHDL/Libraries/Misc/Plru.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
.. role:: raw-html-m2r(raw)
:format: html

Plru
==========================
====

Introduction
--------------------
------------
- Pseudo least recently used combinatorial logic
- io.context.state need to be handled externaly.
- io.context.state need to be handled externally.
- When you want to specify a access to a entry, you can use the io.update interface to get the new state value.
- plru.io.evict.id tells you the id of the next block to be evicted
- plru.io.update.id lets you update what you recently used
Expand Down
Loading
Loading