仿真过程中访问信号
读写信号
顶层模块的每个接口信号都可以从 Scala 程序中读写:
| 语法 | 描述 | 
|---|---|
| 
 | 将硬件  | 
| 
 | 将硬件  | 
| 
 | 将硬件  | 
| 
 | 将硬件中的  | 
| 
 | 将硬件中的  | 
| 
 | 将 Scala 的  | 
| 
 | 将 Scala 的  | 
| 
 | 将 Scala 的  | 
| 
 | 将 Scala 的  | 
| 
 | 将 Scala 的  | 
| 
 | 将随机值赋值给 SpinalHDL 硬件信号。 | 
dut.io.a #= 42
dut.io.a #= 42l
dut.io.a #= BigInt("101010", 2)
dut.io.a #= BigInt("0123456789ABCDEF", 16)
println(dut.io.b.toInt)
访问组件层次结构内部的信号
要访问组件层次结构内部的信号,您必须首先将给定信号设置为 simPublic。
您可以直接在硬件描述中添加此 simPublic 标签:
object SimAccessSubSignal {
  import spinal.core.sim._
  class TopLevel extends Component {
    val counter = Reg(UInt(8 bits)) init(0) simPublic() // Here we add the simPublic tag on the counter register to make it visible
    counter := counter + 1
  }
  def main(args: Array[String]) {
    SimConfig.compile(new TopLevel).doSim{dut =>
      dut.clockDomain.forkStimulus(10)
      for(i <- 0 to 3) {
        dut.clockDomain.waitSampling()
        println(dut.counter.toInt)
      }
    }
  }
}
或者您可以稍后在实例化仿真的顶层文件中添加它:
object SimAccessSubSignal {
  import spinal.core.sim._
  class TopLevel extends Component {
    val counter = Reg(UInt(8 bits)) init(0)
    counter := counter + 1
  }
  def main(args: Array[String]) {
    SimConfig.compile {
      val dut = new TopLevel
      dut.counter.simPublic()     // Call simPublic() here
      dut
    }.doSim{dut =>
      dut.clockDomain.forkStimulus(10)
      for(i <- 0 to 3) {
        dut.clockDomain.waitSampling()
        println(dut.counter.toInt)
      }
    }
  }
}
仿真中内存的加载和存储
可以在仿真中修改 Mem 硬件接口组件的内容。 data 参数应该是一个字的位宽的值,address 是访问的字的地址。
没有 API 可以将地址和/或单个数据位转换为自然的字位宽以外的单位。
没有 API 可以用仿真中的 `X`(未定义)状态来标记任何内存位置。
| 语法 | 描述 | 
|---|---|
| 
 | 从仿真器的对应地址处读取一个字。 | 
| 
 | 在地址处向仿真器内的存储器写入一个字。 | 
这是一个简单的使用内存的示例:
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
  }
}
设置仿真环境后,我们可以这样访问内存:
  SimConfig.withVcdWave.compile {
    val d = MemoryExample()
    // make memory accessible during simulation
    d.mem.simPublic()
    d
  }.doSim("example") { dut =>
我们可以在仿真期间读取数据,但必须注意确保数据可用(由于仿真器是事件驱动的,这可能会造成一个周期的延迟):
    // 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)
并且可以像这样写入内存:
    // 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)
必须注意的是,由于仿真器是事件驱动的,例如上面描述的读取操作必须延迟到该值在内存中实际可用后进行。