diff --git a/examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala b/examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala new file mode 100644 index 00000000000..c35da1b506e --- /dev/null +++ b/examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala @@ -0,0 +1,56 @@ +package spinaldoc.libraries.sequential_logic + +import spinal.core._ +import spinal.lib._ +import spinal.core.sim._ + +import scala.language.postfixOps + +case class MemoryExample() extends Component { + val wordCount = 64 + val io = new Bundle { + val address = in port UInt(log2Up(wordCount) bit) + val i = in port Bits(8 bit) + val o = out port Bits(8 bit) + val we = in port Bool() + } + + val mem = Mem(Bits(8 bit), wordCount=wordCount) + io.o := mem(io.address) + when(io.we) { + mem(io.address) := io.i + } +} +// end case class MemoryExample + +object MemorySim extends App { + SimConfig.withVcdWave.compile { + val d = MemoryExample() + // make memory accessible during simulation + d.mem.simPublic() + d + }.doSim("example") { dut => + dut.io.we #= false + dut.clockDomain.forkStimulus(10) + dut.clockDomain.waitSampling(2) + + // do a write + dut.io.we #= true + dut.io.address #= 10 + dut.io.i #= 0xaf + dut.clockDomain.waitSampling(2) + // check written data is there + assert(dut.mem.getBigInt(10) == 0xaf) + + dut.io.we #= false + dut.clockDomain.waitSampling(1) + + // set some data in memory + dut.mem.setBigInt(15, 0xfe) + // do a read to check if it's there + dut.io.address #= 15 + dut.clockDomain.waitSampling(1) + assert(dut.io.o.toBigInt == 0xfe) + } +} + diff --git a/source/SpinalHDL/Sequential logic/memory.rst b/source/SpinalHDL/Sequential logic/memory.rst index fe5b6a31240..d29f2ed03d6 100644 --- a/source/SpinalHDL/Sequential logic/memory.rst +++ b/source/SpinalHDL/Sequential logic/memory.rst @@ -1,5 +1,5 @@ -RAM/ROM -======= +RAM/ROM Memory +============== To create a memory in SpinalHDL, the ``Mem`` class should be used. It allows you to define a memory and add read and write ports to it. diff --git a/source/SpinalHDL/Simulation/signal.rst b/source/SpinalHDL/Simulation/signal.rst index ecd85e92ab9..6e50d68798f 100644 --- a/source/SpinalHDL/Simulation/signal.rst +++ b/source/SpinalHDL/Simulation/signal.rst @@ -44,34 +44,6 @@ Each interface signal of the toplevel can be read and written from Scala: dut.io.a #= BigInt("0123456789ABCDEF", 16) println(dut.io.b.toInt) - -.. _simulation_of_memory: - -Load and Store of Memory in Simulation --------------------------------------- - -It is possible to modify the contents of ``Mem`` hardware interface -components in simulation. The `data` argument should be a word-width -value with the `address` being the word-address within. - -There is no API to convert address and/or individual data bits into -units other than the natural word size. - -There is no API to mark any memory location with simulation `X` (undefined) -state. - -.. list-table:: - :header-rows: 1 - :widths: 3 5 - - * - Syntax - - Description - * - ``Mem.getBigInt(address: Long): BigInt`` - - Read a word from simulator at the word-address. - * - ``Mem.setBigInt(address: Long, data: BigInt)`` - - Write a word to simulator at the word-address. - - Accessing signals inside the component's hierarchy -------------------------------------------------- @@ -129,3 +101,61 @@ Or you can add it later, after having instantiated your toplevel for the simulat } } + +.. _simulation_of_memory: + +Load and Store of Memory in Simulation +-------------------------------------- + +It is possible to modify the contents of ``Mem`` hardware interface +components in simulation. The `data` argument should be a word-width +value with the `address` being the word-address within. + +There is no API to convert address and/or individual data bits into +units other than the natural word size. + +There is no API to mark any memory location with simulation `X` (undefined) +state. + +.. list-table:: + :header-rows: 1 + :widths: 1 1 + + * - Syntax + - Description + * - ``Mem.getBigInt(address: Long): BigInt`` + - Read a word from simulator at the word-address. + * - ``Mem.setBigInt(address: Long, data: BigInt)`` + - Write a word to simulator at the word-address. + +Using this simple example using a memory: + +.. literalinclude:: /../examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala + :language: scala + :start-at: case class MemoryExample + :end-before: // end case class MemoryExample + +Setting up the simulation we make the memory accessible: + +.. literalinclude:: /../examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala + :language: scala + :start-at: SimConfig + :end-at: doSim + +We can read data during simulation, but have to take care that the data is already available (might be +a cycle late due to simulation event ordering): + +.. literalinclude:: /../examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala + :language: scala + :start-at: // do a write + :end-at: assert(dut.mem + +And can write to memory like so: + +.. literalinclude:: /../examples/src/main/scala/spinaldoc/sequential_logic/memory_sim.scala + :language: scala + :start-at: // set some data in memory + :end-at: assert(dut.io + +Care has to be taken that due to event ordering in simulation e.g. the read depicted above has to be delayed +to when the value is actually available in the memory. \ No newline at end of file diff --git a/source/SpinalHDL/miscelenea/core/core_components.rst b/source/SpinalHDL/miscelenea/core/core_components.rst index 90a992ac322..e5202a1757a 100644 --- a/source/SpinalHDL/miscelenea/core/core_components.rst +++ b/source/SpinalHDL/miscelenea/core/core_components.rst @@ -444,39 +444,6 @@ There is a small component and a ``main`` that generate the corresponding VHDL. } } -Memory ------- - -.. list-table:: - :header-rows: 1 - :widths: 2 1 - - * - Syntax - - Description - * - Mem(type : Data,size : Int) - - Create a RAM - * - Mem(type : Data,initialContent : Array[Data]) - - Create a ROM - - -.. list-table:: - :header-rows: 1 - :widths: 3 2 1 - - * - Syntax - - Description - - Return - * - mem(x) - - Asynchronous read - - T - * - mem(x) := y - - Synchronous write - - - * - mem.readSync(address,enable) - - Synchronous read - - T - - Instantiate VHDL and Verilog IP -------------------------------