chipsalliance / chipsalliance/chisel

Wrong memory initialization with ChiselSim

Open
#4,340 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Scala
Stars
4.8k
Forks
658
Avg merge
18h 59m
Merged PRs (30d)
14

Description

I am trying to use `chisel3.util.experimental.loadMemoryFromFileInline` to initialize memory.
When I use it with ChiselSim, the memory seems to not be initialized properly, so I inspected the output VCD and I made some tests. Here is what I found:

- **Case 1**: When I don't use any `peek`/`poke` or `step` function the memory is initialized properly.
- **Case 2**: When I use any `peek`/`poke` or `step` function the memory seems to be initialized at the end. I inspected the VCD file and the initial value is available only at the end of the simulation. However, the Verilog code generated has a proper `initial` block with the correct path.

## Respective Chisel/ChiselSim code

```scala
import chisel3._
import tywaves.simulator.TywavesSimulator._
import tywaves.simulator.simulatorSettings._

import org.scalatest.flatspec.AnyFlatSpec

import chisel3.util.experimental.loadMemoryFromFileInline // <<-- new import here
class UsesMem(memoryDepth: Int, memoryType: Data, filename: String) extends Module {
val io = IO(new Bundle {
val address = Input(UInt(memoryType.getWidth.W))
val value = Output(memoryType)
})
val memory = Mem(memoryDepth, memoryType)
io.value := memory(io.address)
loadMemoryFromFileInline(memory, filename) // <<-- Note the annotation here
}
class LoadMemory extends AnyFlatSpec {
val bits = 64
val words = 4
val filename = System.getProperty("user.dir") + "/MemoryInit.hex"
val frequency = 50000000

scala.reflect.io.File(filename).writeAll("0001020304050607\r\n08090A0B0C0D0E0F\r\n0F0E0D0C0B0A0908\r\n8080808080808080\r\n")

behavior of "LoadMemory"
it should "pass a unit test" in {
simulate(new UsesMem(words, UInt(bits.W), filename), Seq(VcdTrace, WithTywavesWaveforms(true), WithFirtoolArgs(Seq("--disable-all-randomization")), SaveWorkdirFile("workDir")))
{ m =>
m.clock.step()
m.reset.poke(true.B)
m.clock.step()
m.reset.poke(false.B)
m.clock.step()
m.clock.step()
m.clock.step()
m.io.address.poke(0.U)
m.clock.step()
m.io.address.poke(2.U)
}
}
}
```

## VCD Case 1: No `peek`/`poke` or `step`
```
// ...
$scope module memory_ext $end
$var wire 64 # Memory[0] [63:0] $end
$var wire 64 % Memory[1] [63:0] $end
$var wire 64 ' Memory[2] [63:0] $end
$var wire 64 ) Memory[3] [63:0] $end
$var wire 2 / R0_addr [1:0] $end
$var wire 1 0 R0_clk $end
$var wire 64 + R0_data [63:0] $end
$var wire 1 2 R0_en $end
$upscope $end
// ...
#0
b0000000000000001000000100000001100000100000001010000011000000111 #
b0000100000001001000010100000101100001100000011010000111000001111 %
b0000111100001110000011010000110000001011000010100000100100001000 '
b1000000010000000100000001000000010000000100000001000000010000000 )
b0000000000000001000000100000001100000100000001010000011000000111 +
b0000000000000000000000000000000000000000000000000000000000000000 -
b00 /
00
01
12
```

## VCD Case 2: using any `peek`/`poke` or `step` causes initialization in the end
```
// ...
$scope module memory_ext $end
$var wire 64 # Memory[0] [63:0] $end
$var wire 64 % Memory[1] [63:0] $end
$var wire 64 ' Memory[2] [63:0] $end
$var wire 64 ) Memory[3] [63:0] $end
$var wire 2 / R0_addr [1:0] $end
$var wire 1 0 R0_clk $end
$var wire 64 + R0_data [63:0] $end
$var wire 1 2 R0_en $end
$upscope $end
// ...

#0
b0000000000000000000000000000000000000000000000000000000000000000 #
b0000000000000000000000000000000000000000000000000000000000000000 %
b0000000000000000000000000000000000000000000000000000000000000000 '
b0000000000000000000000000000000000000000000000000000000000000000 )
b0000000000000000000000000000000000000000000000000000000000000000 +
b0000000000000000000000000000000000000000000000000000000000000000 -
b00 /
00
01
12
#1
10
#2
b0000000000000001000000100000001100000100000001010000011000000111 #
b0000100000001001000010100000101100001100000011010000111000001111 %
b0000111100001110000011010000110000001011000010100000100100001000 '
b1000000010000000100000001000000010000000100000001000000010000000 )
b0000000000000001000000100000001100000100000001010000011000000111 +
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.