Compare commits

..

8 commits

Author SHA1 Message Date
Artturin fa03829139 Use newer ghc
Old output of
`cabal run main --ghc-options="-D_RAM_DEPTH=2048" -- --firmware=./rv_tests/hello_world/hello.bin`

```
Simulating Machine
Decoded instruction: AUIPC (UTypeFields 23 11 0) | Binary: 0b0000_0000_0000_0000_0000_0101_1001_0111 (1431)
Decoded instruction: ADDI (ITypeFields 19 11 0 11 28) | Binary: 0b0000_0001_1100_0101_1000_0101_1001_0011 (29722003)
Decoded instruction: LBU (ITypeFields 3 10 4 11 0) | Binary: 0b0000_0000_0000_0101_1100_0101_0000_0011 (378115)
Decoded instruction: Unimplemented | Binary: 0b0000_0010_1011_0111_1100_0101_0001_1001 (45597977)
Decoded instruction: Unimplemented | Binary: 0b1000_0000_0010_0011_0001_0000_0000_0000 (2149781504)
Decoded instruction: Unimplemented | Binary: 0b0000_0101_1000_0101_0000_0000_1010_0010 (92602530)
Decoded instruction: Unimplemented | Binary: 0b1010_0000_0000_0001_1011_1111_1100_0101 (2684469189)
Decoded instruction: Unimplemented | Binary: 0b0110_1100_0110_1100_0110_0101_0100_1000 (1819043144)
Decoded instruction: JAL (JTypeFields 111 24 975876) | Binary: 0b0111_0111_0010_0000_0010_1100_0110_1111 (1998597231)
Decoded instruction: JAL (JTypeFields 111 4 822670) | Binary: 0b0110_0100_0110_1100_0111_0010_0110_1111 (1684828783)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_1010_0010_0001 (2593)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Last state: Machine {cpu = RISCVCPU {pc = 60, gpr = 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil, fpr = 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0:> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil, privilegeLevel = MachineMode}, peripherals = Peripherals {ram = 3 :> 29722003 :> 378115 :> 45597977 :> 2149781504 :> 92602530 :> 2684469189 :> 1819043144 :> 1998597231 :> 1684828783 :> 2593 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil}}
Executed for 16 cycles
Simulation complete
```

New output

```
Simulating Machine
Decoded instruction: AUIPC (UTypeFields 23 11 0) | Binary: 0b0000_0000_0000_0000_0000_0101_1001_0111 (1431)
Decoded instruction: ADDI (ITypeFields 19 11 0 11 28) | Binary: 0b0000_0001_1100_0101_1000_0101_1001_0011 (29722003)
Decoded instruction: LBU (ITypeFields 3 10 4 11 0) | Binary: 0b0000_0000_0000_0101_1100_0101_0000_0011 (378115)
Decoded instruction: Unimplemented | Binary: 0b0000_0010_1011_0111_1100_0101_0001_1001 (45597977)
Decoded instruction: Unimplemented | Binary: 0b1000_0000_0010_0011_0001_0000_0000_0000 (2149781504)
Decoded instruction: Unimplemented | Binary: 0b0000_0101_1000_0101_0000_0000_1010_0010 (92602530)
Decoded instruction: Unimplemented | Binary: 0b1010_0000_0000_0001_1011_1111_1100_0101 (2684469189)
Decoded instruction: Unimplemented | Binary: 0b0110_1100_0110_1100_0110_0101_0100_1000 (1819043144)
Decoded instruction: JAL (JTypeFields 111 24 975876) | Binary: 0b0111_0111_0010_0000_0010_1100_0110_1111 (1998597231)
Decoded instruction: JAL (JTypeFields 111 4 822670) | Binary: 0b0110_0100_0110_1100_0111_0010_0110_1111 (1684828783)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_1010_0010_0001 (2593)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Decoded instruction: Unimplemented | Binary: 0b0000_0000_0000_0000_0000_0000_0000_0000 (0)
Last state: Machine {cpu = RISCVCPU {pc = 60, gpr = 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil, fpr = 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0:> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil, privilegeLevel = MachineMode}, peripherals = Peripherals {ram = 3 :> 29722003 :> 378115 :> 45597977 :> 2149781504 :> 92602530 :> 2684469189 :> 1819043144 :> 1998597231 :> 1684828783 :> 2593 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil}}
Executed for 16 cycles
Simulation complete
```

As you can see both are the same
2025-02-22 22:37:54 +02:00
Artturin 783ec90a45 Remove stack.yaml
Seems unneeded

```
trace: haskell-nix.project : both 'stack.yaml' and 'cabal.project' files exist.  Using 'cabal.project'. set 'projectFileName = "stack.yaml";' to override this.'
```
2025-02-22 22:37:54 +02:00
Artturin 67fcd15f42 After make clean and make, this file changes
`make run` works

I think it is due to a compiler update.

nixpkgs gcc is 14

https://chatgpt.com/share/67ba3552-3434-800d-a9cf-bf246b8619db

`diffoscope old-hello.elf new-hello.elf`

```
--- old-hello.elf
+++ new-hello.elf
├── readelf --wide --file-header {}
│ @@ -6,15 +6,15 @@
│    OS/ABI:                            UNIX - System V
│    ABI Version:                       0
│    Type:                              EXEC (Executable file)
│    Machine:                           RISC-V
│    Version:                           0x1
│    Entry point address:               0x80000000
│    Start of program headers:          64 (bytes into file)
│ -  Start of section headers:          4600 (bytes into file)
│ +  Start of section headers:          4632 (bytes into file)
│    Flags:                             0x1, RVC, soft-float ABI
│    Size of this header:               64 (bytes)
│    Size of program headers:           56 (bytes)
│    Number of program headers:         2
│    Size of section headers:           64 (bytes)
│    Number of section headers:         7
│    Section header string table index: 6
├── readelf --wide --program-header {}
│ @@ -1,14 +1,14 @@
│
│  Elf file type is EXEC (Executable file)
│  Entry point 0x80000000
│  There are 2 program headers, starting at offset 64
│
│  Program Headers:
│    Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
│ -  RISCV_ATTRIBUT 0x00102b 0x0000000000000000 0x0000000000000000 0x000032 0x000000 R   0x1
│ +  RISCV_ATTRIBUT 0x00102b 0x0000000000000000 0x0000000000000000 0x000045 0x000000 R   0x1
│    LOAD           0x001000 0x0000000080000000 0x0000000080000000 0x00002b 0x00002b R E 0x1000
│
│   Section to Segment mapping:
│    Segment Sections...
│     00     .riscv.attributes
│     01     .text .rodata
├── readelf --wide --sections {}
│ @@ -1,16 +1,16 @@
│ -There are 7 section headers, starting at offset 0x11f8:
│ +There are 7 section headers, starting at offset 0x1218:
│
│  Section Headers:
│    [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
│    [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
│    [ 1] .text             PROGBITS        0000000080000000 001000 00001c 00  AX  0   0  2
│    [ 2] .rodata           PROGBITS        000000008000001c 00101c 00000f 00   A  0   0  1
│ -  [ 3] .riscv.attributes RISCV_ATTRIBUTES 0000000000000000 00102b 000032 00      0   0  1
│ -  [ 4] .symtab           SYMTAB          0000000000000000 001060 000108 18      5  10  8
│ -  [ 5] .strtab           STRTAB          0000000000000000 001168 00004f 00      0   0  1
│ -  [ 6] .shstrtab         STRTAB          0000000000000000 0011b7 00003b 00      0   0  1
│ +  [ 3] .riscv.attributes RISCV_ATTRIBUTES 0000000000000000 00102b 000045 00      0   0  1
│ +  [ 4] .symtab           SYMTAB          0000000000000000 001070 000108 18      5  10  8
│ +  [ 5] .strtab           STRTAB          0000000000000000 001178 000062 00      0   0  1
│ +  [ 6] .shstrtab         STRTAB          0000000000000000 0011da 00003b 00      0   0  1
│  Key to Flags:
│    W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
│    L (link order), O (extra OS processing required), G (group), T (TLS),
│    C (compressed), x (unknown), o (OS specific), E (exclude),
│    D (mbind), p (processor specific)
├── readelf --wide --symbols {}
│ @@ -3,12 +3,12 @@
│     Num:    Value          Size Type    Bind   Vis      Ndx Name
│       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
│       1: 0000000080000000     0 SECTION LOCAL  DEFAULT    1 .text
│       2: 000000008000001c     0 SECTION LOCAL  DEFAULT    2 .rodata
│       3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 .riscv.attributes
│       4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.o
│       5: 0000000010000000     0 NOTYPE  LOCAL  DEFAULT  ABS UART_BASE
│ -     6: 0000000080000000     0 NOTYPE  LOCAL  DEFAULT    1 $xrv64i2p1_m2p0_a2p1_c2p0_zmmul1p0
│ +     6: 0000000080000000     0 NOTYPE  LOCAL  DEFAULT    1 $xrv64i2p1_m2p0_a2p1_c2p0_zmmul1p0_zaamo1p0_zalrsc1p0
│       7: 000000008000001c     0 NOTYPE  LOCAL  DEFAULT    2 message
│       8: 0000000080000008     0 NOTYPE  LOCAL  DEFAULT    1 loop
│       9: 000000008000001a     0 NOTYPE  LOCAL  DEFAULT    1 exit
│      10: 0000000080000000     0 NOTYPE  GLOBAL DEFAULT    1 _start
├── strings --all --bytes=8 {}
│ @@ -1,6 +1,6 @@
│  Hello, world!
│ -rv64i2p1_m2p0_a2p1_c2p0_zmmul1p0
│ +rv64i2p1_m2p0_a2p1_c2p0_zmmul1p0_zaamo1p0_zalrsc1p0
│  UART_BASE
│ -$xrv64i2p1_m2p0_a2p1_c2p0_zmmul1p0
│ +$xrv64i2p1_m2p0_a2p1_c2p0_zmmul1p0_zaamo1p0_zalrsc1p0
│  .shstrtab
│  .riscv.attributes
├── readelf --wide --decompress --hex-dump=.riscv.attributes {}
│ @@ -1,7 +1,8 @@
│
│  Hex dump of section '.riscv.attributes':
│ -  0x00000000 41310000 00726973 63760001 27000000 A1...riscv..'...
│ +  0x00000000 41440000 00726973 63760001 3a000000 AD...riscv..:...
│    0x00000010 05727636 34693270 315f6d32 70305f61 .rv64i2p1_m2p0_a
│    0x00000020 3270315f 63327030 5f7a6d6d 756c3170 2p1_c2p0_zmmul1p
│ -  0x00000030 3000                                0.
│ +  0x00000030 305f7a61 616d6f31 70305f7a 616c7273 0_zaamo1p0_zalrs
│ +  0x00000040 63317030 00                         c1p0.
├── readelf --wide --decompress --hex-dump=.strtab {}
│ @@ -1,8 +1,10 @@
│
│  Hex dump of section '.strtab':
│    0x00000000 0068656c 6c6f2e6f 00554152 545f4241 .hello.o.UART_BA
│    0x00000010 53450024 78727636 34693270 315f6d32 SE.$xrv64i2p1_m2
│    0x00000020 70305f61 3270315f 63327030 5f7a6d6d p0_a2p1_c2p0_zmm
│ -  0x00000030 756c3170 30006d65 73736167 65006c6f ul1p0.message.lo
│ -  0x00000040 6f700065 78697400 5f737461 727400   op.exit._start.
│ +  0x00000030 756c3170 305f7a61 616d6f31 70305f7a ul1p0_zaamo1p0_z
│ +  0x00000040 616c7273 63317030 006d6573 73616765 alrsc1p0.message
│ +  0x00000050 006c6f6f 70006578 6974005f 73746172 .loop.exit._star
│ +  0x00000060 7400                                t.
```
2025-02-22 22:37:34 +02:00
Artturin 9c0bc141f0 hello_world: Use nixpkgs target prefix
nixpkgs `riscv64-embedded` is `riscv64-none-elf`
2025-02-22 22:33:26 +02:00
Artturin eb77c50eb2 hello_world: Fix stat with coreutils(linux)
the development nix shell has coreutils
2025-02-22 22:33:26 +02:00
Artturin 459ed89ce2 Rename rv_formal.cabal to rvFormal
It appears that the convention is to use the package name as the
filename

```
error: path '/nix/store/3bljihq1ighvsr9ghaw5fvflcdapsrff-haskell-project-plan-to-nix-pkgs/.plan.nix/rvFormal.nix' does not exist
```
2025-02-22 22:33:26 +02:00
Artturin 5516da2619 Add flake
`haskell.nix` is quite different from normal nix infra but seems to be
working fine here.

Works with ghc 9.6.6
2025-02-22 22:33:26 +02:00
Artturin eed328e68a Fix shell.nix
```
[nix-shell:~/joyofhardware/RiscV-Formal]$ riscv64-unknown-linux-gnu-gcc
bash: /nix/store/xq4q2vv9ii7z2k2qp82jd180xdb0r4fv-gcc-riscv64-unknown-linux-gnu-14-20241116/bin/riscv64-unknown-linux-gnu-gcc: cannot execute binary file: Exec format error
```

`pkgs.pkgsCross.riscv64` is for running on riscv64
`pkgs.pkgsCross.riscv64.buildPackages` is for running on the build
system and compiling code for riscv64

`nativeBuildInputs` is for packages which run on the build system and
compile code for riscv64

with `__splicedPackages` we can avoid having to specify `buildPackages`
and have the dependency attributes (`nativeBuildInputs`) pick the
`buildHost` version of the package
2025-02-21 17:04:56 +02:00
29 changed files with 518 additions and 1247 deletions

1
.gitignore vendored
View file

@ -10,7 +10,6 @@ dist-newstyle/
cabal-dev cabal-dev
/cabal.project.local /cabal.project.local
.ghc.environment.* .ghc.environment.*
*.elf
*.o *.o
*.o-boot *.o-boot
*.hi *.hi

View file

@ -1,4 +0,0 @@
# Notes
In OOO design(or maybe even pipelined 5 stage design), the regfile
should have a variant of `Borrowed`.

View file

@ -11,9 +11,6 @@ Note that this repository is currently very much W.I.P. That being said,
this is how you would currently run a simulation: this is how you would currently run a simulation:
```bash ```bash
pushd rv_tests/hello_world/
make
popd
cabal run main --ghc-options="-D_RAM_DEPTH=2048" -- --firmware=./rv_tests/hello_world/hello.bin cabal run main --ghc-options="-D_RAM_DEPTH=2048" -- --firmware=./rv_tests/hello_world/hello.bin
``` ```
@ -25,14 +22,20 @@ essence forms the context of our micro-op machinery.
Change instructions to support Nix Change instructions to support Nix
## Disassembling
```
riscv64-unknown-elf-objdump -D -b binary -m riscv:rv64 ./rv_tests/hello_world/hello.bin > hello.asm
```
# TODO # TODO
- [ ] fetch should invoke mem read function - [ ] fetch should invoke mem read function
# Organization Thoughts
- Potential functions
1. BitPat -> Opcode
2. Opcode -> Fields
3. Fields -> Field Vals
4. Field Vals -> Reg Vals
# Thoroughness
- [ ] Check that all forms get used!! Remove unused forms!!
# Grant Notes # Grant Notes
- [ ] Some forms may be redundant(may need to remove some) - [ ] Some forms may be redundant(may need to remove some)

View file

@ -12,7 +12,7 @@ import Data.Maybe (listToMaybe)
import Data.List (isPrefixOf) import Data.List (isPrefixOf)
import Text.Show.Pretty (ppShow) import Text.Show.Pretty (ppShow)
import Simulation (simulation, Args(..), Simulation(..), RISCVCPU(..), Machine(..)) import Simulation (simulation, Args(..), Simulation(..))
main :: IO () main :: IO ()
main = do main = do
@ -23,7 +23,7 @@ main = do
case simResult of case simResult of
Success states -> do Success states -> do
-- mapM_ (putStrLn . ppShow) states -- Uncomment to print each state, if needed. -- mapM_ (putStrLn . ppShow) states -- Uncomment to print each state, if needed.
putStrLn $ "GPR last state: " ++ (show $ gpr $ cpu $ last states) putStrLn $ "Last state: " ++ show (last states)
putStrLn $ "Executed for " ++ show (length states) ++ " cycles" putStrLn $ "Executed for " ++ show (length states) ++ " cycles"
putStrLn "Simulation complete" putStrLn "Simulation complete"
Failure err -> do Failure err -> do

View file

@ -6,9 +6,6 @@
#include <stdbool.h> #include <stdbool.h>
static volatile bool ctrl_c_received = false; static volatile bool ctrl_c_received = false;
static char last_char = '\0';
int is_char_available();
void sigint_handler(int sig_num) { void sigint_handler(int sig_num) {
ctrl_c_received = true; ctrl_c_received = true;
@ -40,10 +37,8 @@ void restore_terminal() {
} }
char get_char_from_terminal() { char get_char_from_terminal() {
if (is_char_available()) { char c = getchar();
last_char = getchar(); // Update last_char if new character is available return c;
}
return last_char; // Return the last available character (or '\0' initially)
} }
void write_char_to_terminal(char chr) { void write_char_to_terminal(char chr) {

View file

@ -32,24 +32,6 @@
shell = shell =
let let
riscv64-linux = prev.pkgsCross.riscv64-embedded.__splicedPackages; riscv64-linux = prev.pkgsCross.riscv64-embedded.__splicedPackages;
# Everything here builds and runs without needing the below crossSystem
#riscv64-linux = (import prev.pkgs.path {
# localSystem = system;
# crossSystem = {
# config = "riscv64-none-elf";
# libc = "newlib";
# gcc = {
# # Both sets work to build and run hello_world
# # This matches what is in the makefile
# #arch = "rv64ima";
# #abi = "lp64";
# # This matches what you asked for on matrix
# #arch = "rv64g";
# #abi = "lp64d";
# };
# };
#}).__splicedPackages;
in in
{ {
tools = { tools = {
@ -62,9 +44,6 @@
riscv64-linux.binutils riscv64-linux.binutils
riscv64-linux.glibc riscv64-linux.glibc
]; ];
shellHook = ''
export CROSS_PREFIX="riscv64-none-elf"
'';
}; };
} }
) { }; ) { };

View file

@ -1,95 +0,0 @@
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
module Bus(
Peripherals(..),
ReadResponse,
WriteResponse,
Bus.read,
Bus.write,
) where
import Clash.Prelude
import Peripherals.Ram(Ram, RamLine, read, RamAddr)
import Peripherals.Uart(UartAddr, read, write)
import BusTypes(
BusError(..),
TransactionSize(..),
WriteRequest(..),
ReadRequest(..),
BusVal(..),
)
import Types(Addr)
import Peripherals.Ram(write, bytesInRam)
import Util((|>))
data Peripherals = Peripherals
{
ram :: Ram
}
deriving (Generic, Show, Eq, NFDataX)
type ReadResponse = Either BusError BusVal
type WriteResponse = Either BusError Peripherals
busValToTransactionSize :: BusVal -> TransactionSize
busValToTransactionSize (BusByte _) = SizeByte
busValToTransactionSize (BusHalfWord _) = SizeHalfWord
busValToTransactionSize (BusFullWord _) = SizeFullWord
busValToTransactionSize (BusDoubleWord _) = SizeDoubleWord
busValToTransactionSize (BusQuadWord _) = SizeQuadWord
alignCheck :: Addr -> TransactionSize -> Bool
alignCheck _ SizeByte = True
alignCheck addr SizeHalfWord = addr `mod` 2 == 0
alignCheck addr SizeFullWord = addr `mod` 4 == 0
alignCheck addr SizeDoubleWord = addr `mod` 8 == 0
alignCheck addr SizeQuadWord = addr `mod` 16 == 0
-- address space follows QEMU behavior for now
(ramStart, ramEnd) = (0x80000000 :: Addr, ramStart + (bytesInRam - 1))
(uartStart, uartEnd) = (0x10000000 :: Addr, uartStart + 7)
-- reading/writing from/to UART is implemented as reading/writing
-- from/to stdin/stdout, so we need IO.
read :: ReadRequest -> Peripherals -> IO ReadResponse
read (ReadRequest addr size) peripherals
| not (alignCheck addr size) = return |> Left UnAligned
| (addr >= ramStart) && (addr <= ramEnd) =
return |> Right |> Peripherals.Ram.read size ramWordAddr (ram peripherals)
| (addr >= uartStart) && (addr <= uartEnd) =
fmap Right (Peripherals.Uart.read size uartAddr)
| otherwise = return |> Left UnMapped
where
ramAddrNoOffset = addr - ramStart
ramAddr :: RamAddr
ramAddr = resize ramAddrNoOffset
ramWordAddr :: RamAddr
ramWordAddr = resize |> ramAddrNoOffset `shiftR` 2
uartAddrNoOffset = addr - uartStart
uartAddr :: UartAddr
uartAddr = resize uartAddrNoOffset
write :: WriteRequest -> Peripherals -> IO WriteResponse
write (WriteRequest addr val) peripherals
| not (alignCheck addr |> busValToTransactionSize val) = return |> Left UnAligned
| (addr >= uartStart) && (addr <= uartEnd) =
do
Peripherals.Uart.write val uartAddr
return |> Right peripherals
| (addr >= ramStart) && (addr <= ramEnd) =
return |> Right |>
peripherals {
ram = Peripherals.Ram.write val ramAddr (ram peripherals)
}
| otherwise = return |> Left UnMapped
where
ramAddrNoOffset = addr - ramStart
ramAddr :: RamAddr
ramAddr = resize ramAddrNoOffset
uartAddrNoOffset = addr - uartStart
uartAddr :: UartAddr
uartAddr = resize uartAddrNoOffset

View file

@ -1,41 +0,0 @@
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
module BusTypes(
BusError(..),
TransactionSize(..),
ReadRequest(..),
WriteRequest(..),
BusVal(..),
) where
import Clash.Prelude
import Types(Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord)
import Util((|>))
data BusError
= UnMapped
| UnAligned
deriving (Generic, Show, Eq, NFDataX)
data TransactionSize
= SizeByte
| SizeHalfWord
| SizeFullWord
| SizeDoubleWord
| SizeQuadWord
deriving (Generic, Show, Eq, NFDataX)
data ReadRequest = ReadRequest Addr TransactionSize
deriving (Generic, Show, Eq, NFDataX)
data WriteRequest = WriteRequest Addr BusVal
deriving (Generic, Show, Eq, NFDataX)
-- data WriteRequest
data BusVal
= BusByte Byte
| BusHalfWord HalfWord
| BusFullWord FullWord
| BusDoubleWord DoubleWord
| BusQuadWord QuadWord
deriving (Generic, Show, Eq, NFDataX)

View file

@ -1,39 +0,0 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Cpu(
RISCVCPU(..),
Endian(..),
riscvCPUInit) where
import Clash.Prelude
import Types(Pc)
import RegFiles(GPR, FPR, CSR, gprInit, fprInit, csrInit)
data Endian = Big | Little
deriving (Generic, Show, Eq, NFDataX)
data PrivilegeLevel
= MachineMode
| SuperVisorMode
| UserMode
deriving (Generic, Show, Eq, NFDataX)
data RISCVCPU = RISCVCPU
{ pc :: Pc,
gpr :: GPR,
fpr :: FPR,
csr :: CSR,
privilegeLevel :: PrivilegeLevel
}
deriving (Generic, Show, Eq, NFDataX)
riscvCPUInit :: RISCVCPU
riscvCPUInit =
RISCVCPU
{ pc = 0x8000_0000
, gpr = gprInit
, fpr = fprInit
, csr = csrInit
, privilegeLevel = MachineMode
}

View file

@ -1,218 +0,0 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Decode(decode, DecodeResult(..)) where
import DecodeTypes(
RTypeFields(..), ITypeFields(..), STypeFields(..),
BTypeFields(..), UTypeFields(..), JTypeFields(..),
Opcode(..)
)
import Clash.Prelude
import Fetch(FetchResult (Instruction, InstructionException))
import Exceptions(Exception(..))
import Types(Insn, Addr)
import RegFiles(RegVal(..))
import Util((|>))
data DecodeResult = Opcode {opcode :: Opcode, insnAddr :: Addr}
| DecodeException {exception :: Exception, insnAddr :: Addr}
| InstructionException {exception :: Exception, insnAddr :: Addr}
deriving (Generic, Show, Eq, NFDataX)
decode :: FetchResult -> DecodeResult
decode (Instruction insn addr) =
case insnToOpcode insn of
Just opcode -> Opcode opcode addr
Nothing -> DecodeException (IllegalInstruction insn) addr
decode (Fetch.InstructionException exception addr) =
Decode.InstructionException exception addr
insnToOpcode :: Insn -> Maybe Opcode
insnToOpcode insn =
decodeRType insn `chainAndTry`
decodeIType insn `chainAndTry`
decodeSType insn `chainAndTry`
decodeBType insn `chainAndTry`
decodeUType insn `chainAndTry`
decodeJType insn
where
chainAndTry :: Maybe Opcode -> Maybe Opcode -> Maybe Opcode
chainAndTry (Just left) _ = Just left
chainAndTry Nothing (Just right) = Just right
chainAndTry _ _ = Nothing
decodeRType :: Insn -> Maybe Opcode
decodeRType insn =
case opcode of
0b0110011 ->
case funct3 of
0x00 -> case funct7 of
0x00 -> Just |> ADD (RTypeFields rd funct3 rs1 rs2 funct7)
0x20 -> Just |> SUB (RTypeFields rd funct3 rs1 rs2 funct7)
_ -> Nothing
0x04 -> Just |> XOR (RTypeFields rd funct3 rs1 rs2 funct7)
0x06 -> Just |> OR (RTypeFields rd funct3 rs1 rs2 funct7)
0x07 -> Just |> AND (RTypeFields rd funct3 rs1 rs2 funct7)
0x01 -> Just |> SLL (RTypeFields rd funct3 rs1 rs2 funct7)
0x05 -> case funct7 of
0x00 -> Just |> SRL (RTypeFields rd funct3 rs1 rs2 funct7)
0x20 -> Just |> SRA (RTypeFields rd funct3 rs1 rs2 funct7)
_ -> Nothing
0x02 -> Just |> SLT (RTypeFields rd funct3 rs1 rs2 funct7)
0x03 -> Just |> SLTU (RTypeFields rd funct3 rs1 rs2 funct7)
_ -> Nothing
_ -> Nothing
where
opcode = getOpcode insn
rd = getRd insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
funct7 = getFunct7 insn
decodeIType :: Insn -> Maybe Opcode
decodeIType insn = case opcode of
0b0010011 -> case funct3 of
0x0 -> Just |> ADDI (ITypeFields rd funct3 rs1 imm)
0x4 -> Just |> XORI (ITypeFields rd funct3 rs1 imm)
0x6 -> Just |> ORI (ITypeFields rd funct3 rs1 imm)
0x7 -> Just |> ANDI (ITypeFields rd funct3 rs1 imm)
0x1 -> if slice d31 d25 (pack insn) == 0
then Just |> SLLI (ITypeFields rd funct3 rs1 imm)
else Nothing
0x5 -> case slice d31 d25 (pack insn) of -- Distinguish SRLI and SRAI
0x00 -> Just |> SRLI (ITypeFields rd funct3 rs1 imm)
0x20 -> Just |> SRAI (ITypeFields rd funct3 rs1 imm)
_ -> Nothing
0x2 -> Just |> SLTI (ITypeFields rd funct3 rs1 imm)
0x3 -> Just |> SLTIU (ITypeFields rd funct3 rs1 imm)
_ -> Nothing
0b0000011 -> case funct3 of
0x0 -> Just |> LB (ITypeFields rd funct3 rs1 imm)
0x1 -> Just |> LH (ITypeFields rd funct3 rs1 imm)
0x2 -> Just |> LW (ITypeFields rd funct3 rs1 imm)
0x4 -> Just |> LBU (ITypeFields rd funct3 rs1 imm)
0x5 -> Just |> LHU (ITypeFields rd funct3 rs1 imm)
_ -> Nothing
0b1100111 -> case funct3 of
0x0 -> Just |> JALR (ITypeFields rd funct3 rs1 imm)
_ -> Nothing
0b1110011 -> case imm of
0x000 -> Just |> ECALL (ITypeFields rd funct3 rs1 imm)
0x001 -> Just |> EBREAK (ITypeFields rd funct3 rs1 imm)
_ -> Nothing
_ -> Nothing
where
opcode = getOpcode insn
rd = getRd insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
imm = getImm12 insn
decodeSType :: Insn -> Maybe Opcode
decodeSType insn =
case opcode of
0b0100011 -> case funct3 of
0x0 -> Just |> SB (STypeFields funct3 rs1 rs2 imm12) -- Store Byte
0x1 -> Just |> SH (STypeFields funct3 rs1 rs2 imm12) -- Store Halfword
0x2 -> Just |> SW (STypeFields funct3 rs1 rs2 imm12) -- Store Word
_ -> Nothing
_ -> Nothing
where
opcode = getOpcode insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
imm12 = getImm12SType insn
decodeBType :: Insn -> Maybe Opcode
decodeBType insn =
case opcode of
0b1100011 -> case funct3 of
0x0 -> Just |> BEQ (BTypeFields funct3 rs1 rs2 imm13) -- Branch if equal
0x1 -> Just |> BNE (BTypeFields funct3 rs1 rs2 imm13) -- Branch if not equal
0x4 -> Just |> BLT (BTypeFields funct3 rs1 rs2 imm13) -- Branch if less than
0x5 -> Just |> BGE (BTypeFields funct3 rs1 rs2 imm13) -- Branch if greater or equal
0x6 -> Just |> BLTU (BTypeFields funct3 rs1 rs2 imm13) -- Branch if less than (unsigned)
0x7 -> Just |> BGEU (BTypeFields funct3 rs1 rs2 imm13) -- Branch if greater or equal (unsigned)
_ -> Nothing
_ -> Nothing
where
opcode = getOpcode insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
imm13 = getImm13BType insn
decodeUType :: Insn -> Maybe Opcode
decodeUType insn = case opcode of
0b0110111 -> Just |> LUI (UTypeFields rd imm20) -- LUI
0b0010111 -> Just |> AUIPC (UTypeFields rd imm20) -- AUIPC
_ -> Nothing
where
opcode = getOpcode insn
rd = getRd insn
imm20 = getImm20UType insn
decodeJType :: Insn -> Maybe Opcode
decodeJType insn =
case opcode of
0b1101111 -> Just |> JAL (JTypeFields rd imm21) -- JAL
_ -> Nothing
where
opcode = getOpcode insn
rd = getRd insn
imm21 = getImm21JType insn
getImm21JType :: Insn -> Unsigned 21
getImm21JType instr = bitCoerce |> imm20 ++# imm10_1 ++# imm11 ++# imm19_12 ++# zero
where
imm20 = slice d31 d31 (pack instr) -- imm[20]
imm10_1 = slice d30 d21 (pack instr) -- imm[10:1]
imm11 = slice d20 d20 (pack instr) -- imm[11]
imm19_12 = slice d19 d12 (pack instr) -- imm[19:12]
zero = 0 :: BitVector 1 -- LSB always zero for J-type
getOpcode :: Insn -> Unsigned 7
getOpcode instr = bitCoerce |> slice d6 d0 (pack instr)
getImm12 :: Insn -> Unsigned 12
getImm12 instr = bitCoerce |> slice d31 d20 (pack instr)
getImm12SType :: Insn -> Unsigned 12
getImm12SType instr = bitCoerce |> immediateUpper ++# immediateLower
where
immediateUpper = (slice d31 d25 (pack instr))
immediateLower = (slice d11 d7 (pack instr))
getImm20UType :: Insn -> Unsigned 20
getImm20UType instr = bitCoerce |> slice d31 d12 (pack instr)
getImm13BType :: Insn -> Unsigned 13
getImm13BType instr = bitCoerce |> imm12 ++# imm10_5 ++# imm4_1 ++# imm11 ++# zero
where
imm12 = slice d31 d31 (pack instr) -- imm[12]
imm10_5 = slice d30 d25 (pack instr) -- imm[10:5]
imm4_1 = slice d11 d8 (pack instr) -- imm[4:1]
imm11 = slice d7 d7 (pack instr) -- imm[11]
zero = 0 :: BitVector 1 -- LSB always zero for B-type
getFunct3 :: Insn -> Unsigned 3
getFunct3 instr = bitCoerce |> slice d14 d12 (pack instr)
getFunct7 :: Insn -> Unsigned 7
getFunct7 instr = bitCoerce |> slice d31 d25 (pack instr)
getRd :: Insn -> Unsigned 5
getRd instr = bitCoerce |> slice d11 d7 (pack instr)
getRs2 :: Insn -> RegVal
getRs2 instr = Unpopulated |> bitCoerce |> slice d24 d20 (pack instr)
getRs1 :: Insn -> RegVal
getRs1 instr = Unpopulated |> bitCoerce |> slice d19 d15 (pack instr)

View file

@ -1,90 +0,0 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Exceptions(
Exception(..),
exceptionCode,
isSynchronousException
) where
import Clash.Prelude
import Types(Addr, Insn)
data Exception =
SupervisorSoftwareInterrupt
| MachineSoftwareInterrupt
| SupervisorTimerInterrupt
| MachineTimerInterrupt
| SupervisorExternalInterrupt
| MachineExternalInterrupt
| CounterOverflowInterrupt
| InstructionAddressMisaligned
| InstructionAccessFault
| IllegalInstruction {insn :: Insn}
| Breakpoint
| LoadAddressMisaligned
| LoadAccessFault
| StoreAMOAddressMisaligned
| StoreAMOAccessFault
| EnvironmentCallFromUMode
| EnvironmentCallFromSMode
| EnvironmentCallFromMMode
| InstructionPageFault
| LoadPageFault
| StoreAMOPageFault
| DoubleTrap
| SoftwareCheck
| HardwareError
deriving (Generic, Show, Eq, NFDataX)
exceptionCode :: Exception -> Unsigned 6
exceptionCode SupervisorSoftwareInterrupt = 1
exceptionCode MachineSoftwareInterrupt = 3
exceptionCode SupervisorTimerInterrupt = 5
exceptionCode MachineTimerInterrupt = 7
exceptionCode SupervisorExternalInterrupt = 9
exceptionCode MachineExternalInterrupt = 11
exceptionCode CounterOverflowInterrupt = 13
exceptionCode InstructionAddressMisaligned = 0
exceptionCode InstructionAccessFault = 1
exceptionCode (IllegalInstruction _) = 2
exceptionCode Breakpoint = 3
exceptionCode LoadAddressMisaligned = 4
exceptionCode LoadAccessFault = 5
exceptionCode StoreAMOAddressMisaligned = 6
exceptionCode StoreAMOAccessFault = 7
exceptionCode EnvironmentCallFromUMode = 8
exceptionCode EnvironmentCallFromSMode = 9
exceptionCode EnvironmentCallFromMMode = 11
exceptionCode InstructionPageFault = 12
exceptionCode LoadPageFault = 13
exceptionCode StoreAMOPageFault = 15
exceptionCode DoubleTrap = 16
exceptionCode SoftwareCheck = 18
exceptionCode HardwareError = 19
isSynchronousException :: Exception -> Bool
isSynchronousException SupervisorSoftwareInterrupt = False
isSynchronousException MachineSoftwareInterrupt = False
isSynchronousException SupervisorTimerInterrupt = False
isSynchronousException MachineTimerInterrupt = False
isSynchronousException SupervisorExternalInterrupt = False
isSynchronousException MachineExternalInterrupt = False
isSynchronousException CounterOverflowInterrupt = False
isSynchronousException InstructionAddressMisaligned = True
isSynchronousException InstructionAccessFault = True
isSynchronousException (IllegalInstruction _) = True
isSynchronousException Breakpoint = True
isSynchronousException LoadAddressMisaligned = True
isSynchronousException LoadAccessFault = True
isSynchronousException StoreAMOAddressMisaligned = True
isSynchronousException StoreAMOAccessFault = True
isSynchronousException EnvironmentCallFromUMode = True
isSynchronousException EnvironmentCallFromSMode = True
isSynchronousException EnvironmentCallFromMMode = True
isSynchronousException InstructionPageFault = True
isSynchronousException LoadPageFault = True
isSynchronousException StoreAMOPageFault = True
isSynchronousException DoubleTrap = True
isSynchronousException SoftwareCheck = True
isSynchronousException HardwareError = True

View file

@ -1,215 +0,0 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Execute(execute) where
import Clash.Prelude
import Decode(DecodeResult(..))
import DecodeTypes(
Opcode(..),
RTypeFields(..), ITypeFields(..), STypeFields(..),
BTypeFields(..), UTypeFields(..), JTypeFields(..)
)
import Types(Addr, DoubleWord)
import Exceptions(Exception(..))
import BusTypes(
WriteRequest(..),
ReadRequest(..),
TransactionSize(..),
BusVal(..)
)
import RegFiles(RegFileIdx, RegVal(..))
import Util((|>))
data ExecuteResult = ReadRequest {readRequest :: ReadRequest, insnAddr :: Addr}
| WriteRequest {writeRequest :: WriteRequest, insnAddr :: Addr}
| WriteBackGPR {idx :: RegFileIdx, val :: DoubleWord}
| Jump { targetAddr :: Addr }
| DecodeException {exception :: Exception, insnAddr :: Addr}
| InstructionException {exception :: Exception, insnAddr :: Addr}
deriving (Generic, Show, Eq, NFDataX)
-- Helper functions to extract values from RegVal
extractRegVal :: RegVal -> DoubleWord
extractRegVal (Value _ val) = val
extractRegVal (Unpopulated _) = undefined
-- Execute function
execute :: DecodeResult -> ExecuteResult
execute (Opcode opcode addr) = case opcode of
-- R-Type Instructions
ADD (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (val1 + val2)
SUB (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (val1 - val2)
XOR (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (val1 `xor` val2)
OR (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (val1 .|. val2)
AND (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (val1 .&. val2)
SLL (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
shftAmt = fromIntegral |> slice d5 d0 val2
in WriteBackGPR rd (val1 `shiftL` shftAmt)
SRL (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
shftAmt = fromIntegral |> slice d5 d0 val2
in WriteBackGPR rd (val1 `shiftR` shftAmt)
SRA (RTypeFields rd _ rs1 rs2 _) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
val2 = extractRegVal rs2
shftAmt = fromIntegral |> slice d5 d0 val2
in WriteBackGPR rd (bitCoerce (val1 `shiftR` shftAmt))
SLT (RTypeFields rd _ rs1 rs2 _) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64
in WriteBackGPR rd (if val1 < val2 then 1 else 0)
SLTU (RTypeFields rd _ rs1 rs2 _) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
in WriteBackGPR rd (if val1 < val2 then 1 else 0)
-- I-Type Instructions
ADDI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
immVal = signExtend imm
in WriteBackGPR rd (val1 + immVal)
XORI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
immVal = signExtend imm
in WriteBackGPR rd (val1 `xor` immVal)
ORI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
immVal = signExtend imm
in WriteBackGPR rd (val1 .|. immVal)
ANDI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
immVal = signExtend imm
in WriteBackGPR rd (val1 .&. immVal)
SLLI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
shamt = imm .&. 0x3F
in WriteBackGPR rd (val1 `shiftL` fromIntegral shamt)
SRLI (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
shamt = imm .&. 0x3F
in WriteBackGPR rd (val1 `shiftR` fromIntegral shamt)
SRAI (ITypeFields rd _ rs1 imm) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
shamt = imm .&. 0x3F
in WriteBackGPR rd (bitCoerce (val1 `shiftR` fromIntegral shamt))
SLTI (ITypeFields rd _ rs1 imm) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
immVal = unpack (pack (signExtend imm) :: BitVector 64) :: Signed 64
in WriteBackGPR rd (if val1 < immVal then 1 else 0)
SLTIU (ITypeFields rd _ rs1 imm) ->
let val1 = extractRegVal rs1
immVal = signExtend imm
in WriteBackGPR rd (if val1 < immVal then 1 else 0)
LB (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeByte) addr
LH (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeHalfWord) addr
LW (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeFullWord) addr
LBU (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeByte) addr
LHU (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeHalfWord) addr
JALR (ITypeFields rd _ rs1 imm) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm
target = baseAddr + offset
in if rd /= 0 then WriteBackGPR rd (addr + 4) else Jump target
ECALL (ITypeFields _ _ _ _) ->
Execute.DecodeException EnvironmentCallFromMMode addr -- Assuming Machine mode for now
EBREAK (ITypeFields _ _ _ _) ->
Execute.DecodeException Breakpoint addr
-- S-Type Instructions
SB (STypeFields _ rs1 rs2 imm12) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm12
val = extractRegVal rs2
in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusByte (resize val))) addr
SH (STypeFields _ rs1 rs2 imm12) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm12
val = extractRegVal rs2
in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusHalfWord (resize val))) addr
SW (STypeFields _ rs1 rs2 imm12) ->
let baseAddr = extractRegVal rs1
offset = signExtend imm12
val = extractRegVal rs2
in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusFullWord (resize val))) addr
-- B-Type Instructions
BEQ (BTypeFields _ rs1 rs2 imm13) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
offset = signExtend imm13
in if val1 == val2 then Jump (addr + offset) else Jump (addr + 4)
BNE (BTypeFields _ rs1 rs2 imm13) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
offset = signExtend imm13
in if val1 /= val2 then Jump (addr + offset) else Jump (addr + 4)
BLT (BTypeFields _ rs1 rs2 imm13) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64
offset = signExtend imm13
in if val1 < val2 then Jump (addr + offset) else Jump (addr + 4)
BGE (BTypeFields _ rs1 rs2 imm13) ->
let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64
val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64
offset = signExtend imm13
in if val1 >= val2 then Jump (addr + offset) else Jump (addr + 4)
BLTU (BTypeFields _ rs1 rs2 imm13) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
offset = signExtend imm13
in if val1 < val2 then Jump (addr + offset) else Jump (addr + 4)
BGEU (BTypeFields _ rs1 rs2 imm13) ->
let val1 = extractRegVal rs1
val2 = extractRegVal rs2
offset = signExtend imm13
in if val1 >= val2 then Jump (addr + offset) else Jump (addr + 4)
-- U-Type Instructions
LUI (UTypeFields rd imm20) ->
let val = shiftL (resize imm20) 12
in WriteBackGPR rd val
AUIPC (UTypeFields rd imm20) ->
let val = addr + shiftL (resize imm20) 12
in WriteBackGPR rd val
-- J-Type Instructions
JAL (JTypeFields rd imm21) ->
let offset = signExtend imm21
in if rd /= 0 then WriteBackGPR rd (addr + 4) else Jump (addr + offset)
execute (Decode.DecodeException e addr) = Execute.DecodeException e addr
execute (Decode.InstructionException e addr) = Execute.InstructionException e addr

View file

@ -3,49 +3,24 @@
module Fetch( module Fetch(
fetchInstruction, fetchInstruction,
debugInsn, FetchResult(..)) where
FetchResult(..),
) where
import Clash.Prelude import Clash.Prelude
import qualified Prelude as P import Types(Mem, Addr, Insn)
import Types(Addr, Insn) import Util(endianSwapWord)
import Bus(read)
import Bus(Peripherals(..))
import BusTypes(
ReadRequest(..),
TransactionSize(..),
BusVal(..),
BusError(..))
import Exceptions(Exception(..))
import Util((|>))
data FetchResult = Instruction {insn :: Insn, insnAddr :: Addr} data FetchResult = Instruction Insn
| InstructionException {exception :: Exception, addr :: Addr} | Misaligned Addr
deriving (Generic, Show, Eq, NFDataX)
fetchInstruction :: KnownNat n => Mem n -> Addr -> FetchResult
fetchInstruction :: Peripherals -> Addr -> IO FetchResult fetchInstruction mem addr =
fetchInstruction peripherals addr = let
do isWordAligned = addr .&. 3 == 0
readReasponse <-Bus.read (BusTypes.ReadRequest addr BusTypes.SizeFullWord) peripherals addrWordAligned = addr `shiftR` 2
case readReasponse of insn = mem !! addrWordAligned
Right (BusFullWord insn) -> -- TODO : check if instruction is word aligned and create type
pure |> Instruction insn addr -- to capture if its not.
Left UnAligned -> in
pure |> InstructionException InstructionAddressMisaligned addr case isWordAligned of
Left UnMapped -> True -> Instruction insn
pure |> InstructionException InstructionAccessFault addr False -> Misaligned addr
Right _ ->
pure |> InstructionException InstructionAccessFault addr
debugInsn :: FetchResult -> String
debugInsn = show
-- case fetchResult of
-- Instruction insn ->
-- "Instruction raw binary | "
-- P.++ binaryInsn
-- P.++ " (" P.++ show insn P.++ ")"
-- where
-- binaryInsn = show (bitCoerce insn :: BitVector 32)
-- InstructionException e -> show e

206
hs/Isa/Decode.hs Normal file
View file

@ -0,0 +1,206 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Isa.Decode(decode) where
import Isa.Forms(
FUNCT7, RS2, RS1, FUNCT3, RD, OPCODE,
IMM12, IMM13, IMM20, IMM21,
RTypeFields(..), ITypeFields(..), STypeFields(..),
BTypeFields(..), UTypeFields(..), JTypeFields(..),
Opcode(..)
)
import Clash.Prelude
import Data.Functor.Contravariant (Op)
import Types(Mem, Addr, Insn)
import Distribution.Backpack.FullUnitId (FullDb)
getOpcode :: Insn -> Unsigned 7
getOpcode instr = bitCoerce $ slice d6 d0 (pack instr)
getImm12 :: Insn -> Unsigned 12
getImm12 instr = bitCoerce $ slice d31 d20 (pack instr)
getImm12SType :: Insn -> Unsigned 12
getImm12SType instr = bitCoerce $ immediateUpper ++# immediateLower
where
immediateUpper = (slice d31 d25 (pack instr))
immediateLower = (slice d11 d7 (pack instr))
getImm20UType :: Insn -> Unsigned 20
getImm20UType instr = bitCoerce $ slice d31 d12 (pack instr)
getImm13BType :: Insn -> Unsigned 13
getImm13BType instr = bitCoerce $ imm12 ++# imm10_5 ++# imm4_1 ++# imm11 ++# zero
where
imm12 = slice d31 d31 (pack instr) -- imm[12]
imm10_5 = slice d30 d25 (pack instr) -- imm[10:5]
imm4_1 = slice d11 d8 (pack instr) -- imm[4:1]
imm11 = slice d7 d7 (pack instr) -- imm[11]
zero = 0 :: BitVector 1 -- LSB always zero for B-type
getFunct3 :: Insn -> Unsigned 3
getFunct3 instr = bitCoerce $ slice d14 d12 (pack instr)
getFunct7 :: Insn -> Unsigned 7
getFunct7 instr = bitCoerce $ slice d31 d25 (pack instr)
getRd :: Insn -> Unsigned 5
getRd instr = bitCoerce $ slice d11 d7 (pack instr)
getRs2 :: Insn -> Unsigned 5
getRs2 instr = bitCoerce $ slice d24 d20 (pack instr)
getRs1 :: Insn -> Unsigned 5
getRs1 instr = bitCoerce $ slice d19 d15 (pack instr)
decodeRType :: Insn -> Opcode
decodeRType insn =
case opcode of
0b0110011 ->
case funct3 of
0x00 -> case funct7 of
0x00 -> ADD (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x20 -> SUB (RTypeFields opcode rd funct3 rs1 rs2 funct7)
_ -> Unimplemented
0x04 -> XOR (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x06 -> OR (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x07 -> AND (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x01 -> SLL (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x05 -> case funct7 of
0x00 -> SRL (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x20 -> SRA (RTypeFields opcode rd funct3 rs1 rs2 funct7)
_ -> Unimplemented
0x02 -> SLT (RTypeFields opcode rd funct3 rs1 rs2 funct7)
0x03 -> SLTU (RTypeFields opcode rd funct3 rs1 rs2 funct7)
_ -> Unimplemented
_ -> Unimplemented
where
opcode = getOpcode insn
rd = getRd insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
funct7 = getFunct7 insn
decodeIType :: Insn -> Opcode
decodeIType insn = case opcode of
0b0010011 -> case funct3 of
0x0 -> ADDI (ITypeFields opcode rd funct3 rs1 imm)
0x4 -> XORI (ITypeFields opcode rd funct3 rs1 imm)
0x6 -> ORI (ITypeFields opcode rd funct3 rs1 imm)
0x7 -> ANDI (ITypeFields opcode rd funct3 rs1 imm)
0x1 -> if slice d31 d25 (pack insn) == 0
then SLLI (ITypeFields opcode rd funct3 rs1 imm)
else Unimplemented
0x5 -> case slice d31 d25 (pack insn) of -- Distinguish SRLI and SRAI
0x00 -> SRLI (ITypeFields opcode rd funct3 rs1 imm)
0x20 -> SRAI (ITypeFields opcode rd funct3 rs1 imm)
_ -> Unimplemented
0x2 -> SLTI (ITypeFields opcode rd funct3 rs1 imm)
0x3 -> SLTIU (ITypeFields opcode rd funct3 rs1 imm)
_ -> Unimplemented
0b0000011 -> case funct3 of
0x0 -> LB (ITypeFields opcode rd funct3 rs1 imm)
0x1 -> LH (ITypeFields opcode rd funct3 rs1 imm)
0x2 -> LW (ITypeFields opcode rd funct3 rs1 imm)
0x4 -> LBU (ITypeFields opcode rd funct3 rs1 imm)
0x5 -> LHU (ITypeFields opcode rd funct3 rs1 imm)
_ -> Unimplemented
0b1100111 -> case funct3 of
0x0 -> JALR (ITypeFields opcode rd funct3 rs1 imm)
_ -> Unimplemented
0b1110011 -> case imm of
0x000 -> ECALL (ITypeFields opcode rd funct3 rs1 imm)
0x001 -> EBREAK (ITypeFields opcode rd funct3 rs1 imm)
_ -> Unimplemented
_ -> Unimplemented
where
opcode = getOpcode insn
rd = getRd insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
imm = getImm12 insn
decodeSType :: Insn -> Opcode
decodeSType insn =
case opcode of
0b0100011 -> case funct3 of
0x0 -> SB (STypeFields opcode funct3 rs1 rs2 imm12) -- Store Byte
0x1 -> SH (STypeFields opcode funct3 rs1 rs2 imm12) -- Store Halfword
0x2 -> SW (STypeFields opcode funct3 rs1 rs2 imm12) -- Store Word
_ -> Unimplemented
_ -> Unimplemented
where
opcode = getOpcode insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
imm12 = getImm12SType insn
decodeBType :: Insn -> Opcode
decodeBType insn =
case opcode of
0b1100011 -> case funct3 of
0x0 -> BEQ (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if equal
0x1 -> BNE (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if not equal
0x4 -> BLT (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if less than
0x5 -> BGE (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if greater or equal
0x6 -> BLTU (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if less than (unsigned)
0x7 -> BGEU (BTypeFields opcode funct3 rs1 rs2 imm13) -- Branch if greater or equal (unsigned)
_ -> Unimplemented
_ -> Unimplemented
where
opcode = getOpcode insn
funct3 = getFunct3 insn
rs1 = getRs1 insn
rs2 = getRs2 insn
imm13 = getImm13BType insn
decodeUType :: Insn -> Opcode
decodeUType insn = case opcode of
0b0110111 -> LUI (UTypeFields opcode rd imm20) -- LUI
0b0010111 -> AUIPC (UTypeFields opcode rd imm20) -- AUIPC
_ -> Unimplemented
where
opcode = getOpcode insn
rd = getRd insn
imm20 = getImm20UType insn
getImm21JType :: Insn -> Unsigned 21
getImm21JType instr = bitCoerce $ imm20 ++# imm10_1 ++# imm11 ++# imm19_12 ++# zero
where
imm20 = slice d31 d31 (pack instr) -- imm[20]
imm10_1 = slice d30 d21 (pack instr) -- imm[10:1]
imm11 = slice d20 d20 (pack instr) -- imm[11]
imm19_12 = slice d19 d12 (pack instr) -- imm[19:12]
zero = 0 :: BitVector 1 -- LSB always zero for J-type
decodeJType :: Insn -> Opcode
decodeJType insn =
case opcode of
0b1101111 -> JAL (JTypeFields opcode rd imm21) -- JAL
_ -> Unimplemented
where
opcode = getOpcode insn
rd = getRd insn
imm21 = getImm21JType insn
orElse :: Opcode -> Opcode -> Opcode
orElse Unimplemented y = y
orElse x _ = x
decode :: Insn -> Opcode
decode insn =
decodeRType insn `orElse`
decodeIType insn `orElse`
decodeSType insn `orElse`
decodeBType insn `orElse`
decodeUType insn `orElse`
decodeJType insn

View file

@ -1,7 +1,7 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE NumericUnderscores #-}
module DecodeTypes( module Isa.Forms(
FUNCT7, RS2, RS1, FUNCT3, RD, OPCODE, FUNCT7, RS2, RS1, FUNCT3, RD, OPCODE,
IMM12, IMM13, IMM20, IMM21, IMM12, IMM13, IMM20, IMM21,
@ -11,13 +11,13 @@ module DecodeTypes(
Opcode(..) Opcode(..)
) where ) where
import Clash.Prelude import Clash.Prelude
import RegFiles(RegFileIdx, RegVal) import Types(Mem, Addr, Insn)
type FUNCT7 = Unsigned 7 type FUNCT7 = Unsigned 7
type RS2 = RegVal type RS2 = Unsigned 5
type RS1 = RegVal type RS1 = Unsigned 5
type RD = RegFileIdx
type FUNCT3 = Unsigned 3 type FUNCT3 = Unsigned 3
type RD = Unsigned 5
type OPCODE = Unsigned 7 type OPCODE = Unsigned 7
type IMM12 = Unsigned 12 type IMM12 = Unsigned 12
@ -25,12 +25,12 @@ type IMM13 = Unsigned 13
type IMM20 = Unsigned 20 type IMM20 = Unsigned 20
type IMM21 = Unsigned 21 type IMM21 = Unsigned 21
data RTypeFields = RTypeFields RD FUNCT3 RS1 RS2 FUNCT7 deriving (Generic, Show, Eq, NFDataX) data RTypeFields = RTypeFields OPCODE RD FUNCT3 RS1 RS2 FUNCT7 deriving (Generic, Show, Eq, NFDataX)
data ITypeFields = ITypeFields RD FUNCT3 RS1 IMM12 deriving (Generic, Show, Eq, NFDataX) data ITypeFields = ITypeFields OPCODE RD FUNCT3 RS1 IMM12 deriving (Generic, Show, Eq, NFDataX)
data STypeFields = STypeFields FUNCT3 RS1 RS2 IMM12 deriving (Generic, Show, Eq, NFDataX) data STypeFields = STypeFields OPCODE FUNCT3 RS1 RS2 IMM12 deriving (Generic, Show, Eq, NFDataX)
data BTypeFields = BTypeFields FUNCT3 RS1 RS2 IMM13 deriving (Generic, Show, Eq, NFDataX) data BTypeFields = BTypeFields OPCODE FUNCT3 RS1 RS2 IMM13 deriving (Generic, Show, Eq, NFDataX)
data UTypeFields = UTypeFields RD IMM20 deriving (Generic, Show, Eq, NFDataX) data UTypeFields = UTypeFields OPCODE RD IMM20 deriving (Generic, Show, Eq, NFDataX)
data JTypeFields = JTypeFields RD IMM21 deriving (Generic, Show, Eq, NFDataX) data JTypeFields = JTypeFields OPCODE RD IMM21 deriving (Generic, Show, Eq, NFDataX)
data Opcode data Opcode
= =
@ -84,4 +84,6 @@ data Opcode
-- U-Type -- U-Type
| LUI UTypeFields | LUI UTypeFields
| AUIPC UTypeFields | AUIPC UTypeFields
| Unimplemented
deriving (Generic, Show, Eq, NFDataX) deriving (Generic, Show, Eq, NFDataX)

75
hs/Machine.hs Normal file
View file

@ -0,0 +1,75 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Machine(
Machine(..),
RISCVCPU(..),
Peripherals(..),
Endian(..),
machineInit) where
import Clash.Prelude
import Types(Pc, Mem)
import RegFiles(GPR, FPR, CSR, gprInit, fprInit, csrInit)
import Peripherals.Ram(Ram)
data Endian = Big | Little
deriving (Generic, Show, Eq, NFDataX)
data PrivilegeLevel
= MachineMode
| SuperVisorMode
| UserMode
deriving (Generic, Show, Eq, NFDataX)
data Peripherals = Peripherals
{
ram :: Ram
}
deriving (Generic, Show, Eq, NFDataX)
data RISCVCPU = RISCVCPU
{ pc :: Pc,
gpr :: GPR,
fpr :: FPR,
privilegeLevel :: PrivilegeLevel
}
deriving (Generic, Show, Eq, NFDataX)
data Machine = Machine
{ cpu :: RISCVCPU,
peripherals :: Peripherals
}
deriving (Generic, Show, Eq, NFDataX)
riscvCPUInit :: RISCVCPU
riscvCPUInit =
RISCVCPU
0
gprInit
fprInit
MachineMode
machineInit :: Peripherals -> Machine
machineInit peripherals =
Machine
riscvCPUInit
peripherals
memInit :: Vec 14 (Unsigned 32)
memInit =
0x0000A03C
:> 0x3000A5E8
:> 0x1A002038
:> 0x18002598
:> 0x10002588
:> 0x01002170
:> 0xF8FF8141
:> 0x08002588
:> 0x01002138
:> 0x00002598
:> 0xE8FFFF4B
:> 0x00000060
:> 0x002000C0
:> 0x00000000
:> Nil

View file

@ -3,28 +3,14 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
module Peripherals.Ram( module Peripherals.Ram(initRamFromFile, Ram) where
initRamFromFile,
RamAddr,
Ram,
RamLine,
bytesInRam,
read,
write,
) where
import Clash.Prelude hiding (empty, read) import Clash.Prelude
import qualified Prelude as P import qualified Prelude as P
import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy as BL
import Data.Binary.Get import Data.Binary.Get
import Data.Int (Int32) import Data.Int (Int32)
import qualified Clash.Sized.Vector as Vec import qualified Clash.Sized.Vector as Vec
import Types(Addr, FullWord, DoubleWord)
import BusTypes(
TransactionSize(..),
BusVal(..),
)
import Util((|>))
-- vector depth has to be known statically at compile time -- vector depth has to be known statically at compile time
#ifndef _RAM_DEPTH #ifndef _RAM_DEPTH
@ -33,101 +19,6 @@ import Util((|>))
-- TODO : replace Unsigned 32 with BusVal types later... -- TODO : replace Unsigned 32 with BusVal types later...
type Ram = Vec _RAM_DEPTH (Unsigned 32) type Ram = Vec _RAM_DEPTH (Unsigned 32)
type RamAddr = Unsigned (CLog 2 _RAM_DEPTH)
type RamLine = Unsigned 32
bytesInRam :: Addr
bytesInRam = _RAM_DEPTH * 4
read :: TransactionSize -> RamAddr -> Ram -> BusVal
read SizeByte addr ram = BusByte |> unpack byte
where
word = ram !! addr
byteOffset :: BitVector 2
byteOffset = slice d1 d0 addr
byte = case byteOffset of
0b00 -> slice d31 d24 word
0b01 -> slice d23 d16 word
0b10 -> slice d15 d8 word
0b11 -> slice d7 d0 word
read SizeHalfWord addr ram = BusHalfWord |> unpack halfWord
where
word = ram !! addr
halfWordOffset :: Unsigned 1
halfWordOffset = unpack |> slice d0 d0 addr
halfWord = case halfWordOffset of
0b0 -> slice d31 d16 word
0b1 -> slice d15 d0 word
read SizeFullWord addr ram = BusFullWord fullWord
where
fullWord = ram !! addr
read SizeDoubleWord addr ram = BusDoubleWord doubleWord
where
doubleWord = bitCoerce |> bitCoerce word0 ++# bitCoerce word1
word0 = readFullWordHelper ram addr
word1 = readFullWordHelper ram (addr + 1)
read SizeQuadWord addr ram = BusQuadWord quadWord
where
quadWord = bitCoerce |> bitCoerce dword0 ++# bitCoerce dword1
dword0 = readDoubleWordHelper ram addr
dword1 = readDoubleWordHelper ram (addr + 2)
readFullWordHelper :: Ram -> RamAddr -> FullWord
readFullWordHelper ram addr = ram !! addr
readDoubleWordHelper :: Ram -> RamAddr -> DoubleWord
readDoubleWordHelper ram addr = bitCoerce |> bitCoerce word0 ++# bitCoerce word1
where
word0 = readFullWordHelper ram addr
word1 = readFullWordHelper ram (addr + 1)
write :: BusVal -> RamAddr -> Ram -> Ram
write (BusByte byte) addr ram = replace addr updatedWord ram
where
word = ram !! addr
byteOffset :: BitVector 2
byteOffset = slice d1 d0 addr
updatedWord = case byteOffset of
0b00 -> setSlice d31 d24 (pack byte) word
0b01 -> setSlice d23 d16 (pack byte) word
0b10 -> setSlice d15 d8 (pack byte) word
0b11 -> setSlice d7 d0 (pack byte) word
write (BusHalfWord halfWord) addr ram = replace addr updatedWord ram
where
word = ram !! addr
halfWordOffset :: Unsigned 1
halfWordOffset = unpack |> slice d0 d0 addr
updatedWord = case halfWordOffset of
0b0 -> setSlice d31 d16 (pack halfWord) word
0b1 -> setSlice d15 d0 (pack halfWord) word
write (BusFullWord fullWord) addr ram = replace addr fullWord ram
write (BusDoubleWord doubleWord) addr ram = ram''
where
(word0, word1) = bitCoerce doubleWord
ram' = replace addr word0 ram
ram'' = replace (addr + 1) word1 ram'
write (BusQuadWord quadWord) addr ram = ram''''
where
(dword0 :: DoubleWord, dword1 :: DoubleWord) =
bitCoerce quadWord
(word0 :: FullWord, word1 :: FullWord) =
bitCoerce dword0
(word2 :: FullWord, word3 :: FullWord) =
bitCoerce dword1
ram' = replace addr word0 ram
ram'' = replace (addr + 1) word1 ram'
ram''' = replace (addr + 2) word2 ram''
ram'''' = replace (addr + 3) word3 ram'''
initRamFromFile :: FilePath -> IO (Maybe Ram) initRamFromFile :: FilePath -> IO (Maybe Ram)
initRamFromFile filePath = initRamFromFile filePath =
@ -137,7 +28,7 @@ initRamFromFile filePath =
do do
bs <- readFileIntoByteString filePath bs <- readFileIntoByteString filePath
let ints = getInts bs let ints = getInts bs
pure |> populateVectorFromInt32 ints initRam pure $ populateVectorFromInt32 ints initRam
readFileIntoByteString :: FilePath -> IO BL.ByteString readFileIntoByteString :: FilePath -> IO BL.ByteString
readFileIntoByteString filePath = BL.readFile filePath readFileIntoByteString filePath = BL.readFile filePath
@ -164,6 +55,39 @@ populateVectorFromInt32 ::
populateVectorFromInt32 ls v = Vec.fromList adjustedLs populateVectorFromInt32 ls v = Vec.fromList adjustedLs
where where
vecLen = length v vecLen = length v
adjustedLs = fmap fromIntegral (adjustLength vecLen ls) adjustedLs = fromIntegral <$> adjustLength vecLen ls
adjustLength :: Int -> [Int32] -> [Int32] adjustLength :: Int -> [Int32] -> [Int32]
adjustLength n xs = P.take n (xs P.++ P.repeat 0) adjustLength n xs = P.take n (xs P.++ P.repeat 0)
-- Function to increment each element of a Clash vector
-- prepareVector :: KnownNat n => [Int32] -> Vec n (Unsigned 32)
-- prepareVector xs = let
-- unsigneds = map (fromIntegral :: Int32 -> Unsigned 32) xs -- Step 1: Convert Int32 to Unsigned 32
-- len = length unsigneds
-- in case compare len (snatToNum (SNat @n)) of -- Step 2: Adjust the length of the list
-- LT -> takeI unsigneds ++ repeat 0 -- Pad with zeros if the list is shorter
-- GT -> takeI unsigneds -- Truncate if the list is longer
-- EQ -> takeI unsigneds -- No padding or truncation needed
-- Function to load firmware
-- loadFirmware :: KnownNat n => [Int32] -> Vec n (Unsigned 32)
-- loadFirmware (x:xs) = vecHead ++ vecTail
-- where
-- vecHead = singleton (fromIntegral x)
-- vecTail = loadFirmware xs
-- loadFirmware [] = takeI $ repeat 0
-- loadFirmware xs = v
-- where
-- mapped :: [Unsigned 32] = Clash.Prelude.fromIntegral <$> xs
-- c = takeI (mapped ++ repeat 0)
-- v = takeI $ (mapped ++ repeat 0)
-- -- Example usage
-- someList :: [Int32]
-- someList = [1, 2, 3, 4, 5]
-- mem :: Vec 16 (Unsigned 32)
-- mem = loadFirmware someList

View file

@ -7,7 +7,6 @@ import Peripherals.UartCFFI(initTerminal)
import Peripherals.Ram (initRamFromFile, Ram) import Peripherals.Ram (initRamFromFile, Ram)
import Control.Exception (try) import Control.Exception (try)
import System.IO.Error (ioeGetErrorString) import System.IO.Error (ioeGetErrorString)
import Util((|>))
type FirmwareFilePath = FilePath type FirmwareFilePath = FilePath
@ -21,10 +20,10 @@ setupPeripherals firmwareFilePath = do
initTerminal initTerminal
result <- try (initRamFromFile firmwareFilePath) result <- try (initRamFromFile firmwareFilePath)
return |> case result of return $ case result of
Right (Just ram) -> InitializedPeripherals ram Right (Just ram) -> InitializedPeripherals ram
Right Nothing -> InitializationError |> firmwareFilePath ++ failure ++ suggestion Right Nothing -> InitializationError $ firmwareFilePath ++ failure ++ suggestion
Left e -> InitializationError |> firmwareFilePath ++ failure ++ suggestion ++ " Error: " ++ ioeGetErrorString e Left e -> InitializationError $ firmwareFilePath ++ failure ++ suggestion ++ " Error: " ++ ioeGetErrorString e
where where
failure = ": Failed to initialize RAM from file!" failure = ": Failed to initialize RAM from file!"
suggestion = " Is the file 4-byte aligned?" suggestion = " Is the file 4-byte aligned?"

View file

@ -1,77 +0,0 @@
module Peripherals.Uart (read, write, UartAddr) where
import Clash.Prelude hiding (read)
import Types (Byte)
import Data.Char (ord, chr)
import Peripherals.UartCFFI (
getCharFromTerminal,
writeCharToTerminal,
isCharAvailable,
)
import BusTypes (
TransactionSize(..),
BusVal(..),
)
import Util((|>))
-- based on a 16550 UART which has an address space of 8 bytes
type UartAddr = Unsigned 3
-- Receiver Buffer Register address (commonly 0x0 for 16550 UART)
rbrAddr :: UartAddr
rbrAddr = 0x0
thrAddr :: UartAddr
thrAddr = 0x0
-- Line Status Register address
lsrAddr :: UartAddr
lsrAddr = 0x5
-- Helper function to convert Byte to BusVal based on TransactionSize
busValFromByte :: TransactionSize -> Byte -> BusVal
busValFromByte size val = case size of
SizeByte -> BusByte val
SizeHalfWord -> BusHalfWord (resize val)
SizeFullWord -> BusFullWord (resize val)
SizeDoubleWord -> BusDoubleWord (resize val)
SizeQuadWord -> BusQuadWord (resize val)
-- Reads a character from the terminal (RBR equivalent)
buildRBR :: IO Byte
buildRBR = do
c <- getCharFromTerminal
return |> fromIntegral (ord c) -- Convert Char to Byte
-- Reads the Line Status Register (LSR) to check character availability
buildLSR :: IO Byte
buildLSR = do
(char_available :: Byte) <- fmap fromIntegral isCharAvailable
-- highly unlikely that we overflow stdout buffer, so we set
-- transmit to always ready
let (transmit_ready :: Byte) = 0b0010_0000
return (char_available .|. transmit_ready)
-- Updated 'read' function to handle RBR and LSR reads
read :: TransactionSize -> UartAddr -> IO BusVal
read size addr
| addr == rbrAddr = fmap (busValFromByte size) buildRBR
| addr == lsrAddr = fmap (busValFromByte size) buildLSR
| otherwise = return |> busValFromByte size 0x00
extractLowestByte :: BusVal -> Byte
extractLowestByte (BusByte b) = b
extractLowestByte (BusHalfWord hw) = resize hw
extractLowestByte (BusFullWord fw) = resize fw
extractLowestByte (BusDoubleWord dw) = resize dw
extractLowestByte (BusQuadWord qw) = resize qw
byteToChar :: Byte -> Char
byteToChar = chr . fromIntegral
write :: BusVal -> UartAddr -> IO ()
write val addr
| addr == thrAddr = writeCharToTerminal |> byteToChar |> extractLowestByte val
| otherwise = return ()

View file

@ -7,12 +7,13 @@ module Peripherals.UartCFFI (
writeCharToTerminal, writeCharToTerminal,
isCharAvailable, isCharAvailable,
setupSigintHandler, setupSigintHandler,
ctrlCReceived wasCtrlCReceived
) where ) where
import Prelude import Prelude
import Util((|>))
import Foreign.C.Types import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr
import Data.Char (chr, ord) import Data.Char (chr, ord)
-- Foreign imports directly corresponding to the C functions -- Foreign imports directly corresponding to the C functions
@ -35,7 +36,7 @@ getCharFromTerminal :: IO Char
getCharFromTerminal = fmap (chr . fromEnum) c_getCharFromTerminal getCharFromTerminal = fmap (chr . fromEnum) c_getCharFromTerminal
writeCharToTerminal :: Char -> IO () writeCharToTerminal :: Char -> IO ()
writeCharToTerminal char = c_writeCharToTerminal (toEnum |> ord char) writeCharToTerminal char = c_writeCharToTerminal (toEnum $ ord char)
isCharAvailable :: IO Int isCharAvailable :: IO Int
isCharAvailable = fmap fromEnum c_isCharAvailable isCharAvailable = fmap fromEnum c_isCharAvailable

View file

@ -1,109 +0,0 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-}
module Read(Read.read) where
import DecodeTypes(
Opcode(..),
RTypeFields(..), ITypeFields(..), STypeFields(..),
BTypeFields(..), UTypeFields(..), JTypeFields(..),
)
import Clash.Prelude
import Decode(DecodeResult(..))
import Cpu(RISCVCPU(..))
import RegFiles (RegVal(..), GPR)
read :: DecodeResult -> RISCVCPU -> DecodeResult
read (Opcode opcode addr) riscvCPU =
let
gprRegFile = gpr riscvCPU
opcode' = case opcode of
-- R-Type
ADD fields -> (ADD (readRTypeFields fields gprRegFile))
SUB fields -> (SUB (readRTypeFields fields gprRegFile))
XOR fields -> (XOR (readRTypeFields fields gprRegFile))
OR fields -> (OR (readRTypeFields fields gprRegFile))
AND fields -> (AND (readRTypeFields fields gprRegFile))
SLL fields -> (SLL (readRTypeFields fields gprRegFile))
SRL fields -> (SRL (readRTypeFields fields gprRegFile))
SRA fields -> (SRA (readRTypeFields fields gprRegFile))
SLT fields -> (SLT (readRTypeFields fields gprRegFile))
SLTU fields -> (SLTU (readRTypeFields fields gprRegFile))
-- I-Type
ADDI fields -> (ADDI (readITypeFields fields gprRegFile))
XORI fields -> (XORI (readITypeFields fields gprRegFile))
ORI fields -> (ORI (readITypeFields fields gprRegFile))
ANDI fields -> (ANDI (readITypeFields fields gprRegFile))
SLLI fields -> (SLLI (readITypeFields fields gprRegFile))
SRLI fields -> (SRLI (readITypeFields fields gprRegFile))
SRAI fields -> (SRAI (readITypeFields fields gprRegFile))
SLTI fields -> (SLTI (readITypeFields fields gprRegFile))
SLTIU fields -> (SLTIU (readITypeFields fields gprRegFile))
LB fields -> (LB (readITypeFields fields gprRegFile))
LH fields -> (LH (readITypeFields fields gprRegFile))
LW fields -> (LW (readITypeFields fields gprRegFile))
LBU fields -> (LBU (readITypeFields fields gprRegFile))
LHU fields -> (LHU (readITypeFields fields gprRegFile))
JALR fields -> (JALR (readITypeFields fields gprRegFile))
ECALL fields -> (ECALL (readITypeFields fields gprRegFile)) -- No regs needed, but consistent
EBREAK fields -> (EBREAK (readITypeFields fields gprRegFile)) -- Ditto
-- S-Type
SB fields -> (SB (readSTypeFields fields gprRegFile))
SH fields -> (SH (readSTypeFields fields gprRegFile))
SW fields -> (SW (readSTypeFields fields gprRegFile))
-- B-Type
BEQ fields -> (BEQ (readBTypeFields fields gprRegFile))
BNE fields -> (BNE (readBTypeFields fields gprRegFile))
BLT fields -> (BLT (readBTypeFields fields gprRegFile))
BGE fields -> (BGE (readBTypeFields fields gprRegFile))
BLTU fields -> (BLTU (readBTypeFields fields gprRegFile))
BGEU fields -> (BGEU (readBTypeFields fields gprRegFile))
-- U-Type
LUI fields -> (LUI (readUTypeFields fields gprRegFile))
AUIPC fields -> (AUIPC (readUTypeFields fields gprRegFile))
-- J-Type
JAL fields -> (JAL (readJTypeFields fields gprRegFile))
in
Opcode opcode' addr
read (DecodeException e addr) _ = DecodeException e addr
read (InstructionException e addr) _ = InstructionException e addr
readRTypeFields :: RTypeFields -> GPR -> RTypeFields
readRTypeFields (RTypeFields rd funct3 rs1 rs2 funct7) gprRegFile =
let rs1_val = fetchGPRRegVal rs1 gprRegFile
rs2_val = fetchGPRRegVal rs2 gprRegFile
in RTypeFields rd funct3 rs1_val rs2_val funct7
readITypeFields :: ITypeFields -> GPR -> ITypeFields
readITypeFields (ITypeFields rd funct3 rs1 imm) gprRegFile =
let rs1_val = fetchGPRRegVal rs1 gprRegFile
in ITypeFields rd funct3 rs1_val imm
readSTypeFields :: STypeFields -> GPR -> STypeFields
readSTypeFields (STypeFields funct3 rs1 rs2 imm12) gprRegFile =
let rs1_val = fetchGPRRegVal rs1 gprRegFile
rs2_val = fetchGPRRegVal rs2 gprRegFile
in STypeFields funct3 rs1_val rs2_val imm12
readBTypeFields :: BTypeFields -> GPR -> BTypeFields
readBTypeFields (BTypeFields funct3 rs1 rs2 imm13) gprRegFile =
let rs1_val = fetchGPRRegVal rs1 gprRegFile
rs2_val = fetchGPRRegVal rs2 gprRegFile
in BTypeFields funct3 rs1_val rs2_val imm13
readUTypeFields :: UTypeFields -> GPR -> UTypeFields
readUTypeFields fields@(UTypeFields rd imm20) _ = fields
readJTypeFields :: JTypeFields -> GPR -> JTypeFields
readJTypeFields fields@(JTypeFields rd imm21) _ = fields
fetchGPRRegVal :: RegVal -> GPR -> RegVal
fetchGPRRegVal (Unpopulated idx) gprVal = Value idx (gprVal !! idx)
fetchGPRRegVal val@(Value _ _) _ = val -- Already populated, no change

View file

@ -1,20 +1,7 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE NumericUnderscores #-}
-- | This module defines the register files used in a RISC-V core, including:
-- General Purpose Registers (GPR), Floating Point Registers (FPR), and Control & Status Registers (CSR).
--
-- In RISC-V, besides the GPR, FPR, and CSR, we may also encounter
-- the following which are not modeled in this codebase:
-- * VRF (Vector Registers File) for vector processing.
-- * Debug Registers (DBR) for hardware debugging.
-- * Shadow Registers for fast context switching (optional).
-- * MPU Registers for memory protection.
-- * Counter/Timer Registers for time/cycle counting.
-- * Hypervisor Registers (HPR) for guest virtualization.
module RegFiles( module RegFiles(
RegFileIdx,
RegVal(..),
GPR, GPR,
FPR, FPR,
CSR, CSR,
@ -24,20 +11,19 @@ module RegFiles(
) where ) where
import Clash.Prelude import Clash.Prelude
import Util((|>))
import Types(DoubleWord)
type RegFileIdx = Unsigned 5 -- In RISC-V, besides the GPR, FPR, and CSR, we may also encounter
data RegVal = Value { -- the following which are not modeled in this codebase.
regFileIdx :: RegFileIdx, -- * VRF(Vector Registers File) for vector processing.
regVal :: DoubleWord -- * Debug Registers (DBR) for hardware debugging.
} -- * Shadow Registers for fast context switching (optional).
| Unpopulated {regFileIdx :: RegFileIdx} -- * MPU Registers for memory protection.
deriving (Generic, Show, Eq, NFDataX) -- * Counter/Timer Registers for time/cycle counting.
-- * Hypervisor Registers (HPR) for guest virtualization.
type GPR = Vec 32 (Unsigned 64) -- General Purpose Registers type GPR = Vec 32 (Unsigned 64)
type FPR = Vec 32 (Unsigned 64) -- Floating Point Registers type FPR = Vec 32 (Unsigned 64)
type CSR = Vec 4096 (Unsigned 64) -- Control and Status Registers type CSR = Vec 4096 (Unsigned 64)
gprInit :: GPR gprInit :: GPR
gprInit = repeat 0 gprInit = repeat 0
@ -45,54 +31,26 @@ gprInit = repeat 0
fprInit :: FPR fprInit :: FPR
fprInit = repeat 0 fprInit = repeat 0
-- | The 'CSRName' data type enumerates a subset of RISC-V CSRs (Control and Status Registers) -- TODO: CSR can't actually be all 0 during initialization.
-- that are modeled in this codebase. Each variant represents a particular CSR. -- We need to revisit the following and properly initialize
data CSRName = -- various registers later.
STVEC -- ^ Supervisor Trap-Vector Base Address: Base address for supervisor mode exception handlers.
| SEPC -- ^ Supervisor Exception Program Counter: Holds the return address for supervisor mode exceptions.
| MSTATUS -- ^ Machine Status Register: Contains global machine status flags and control bits.
| MISA -- ^ Machine ISA Register: Indicates the supported ISA extensions and width.
| MTVEC -- ^ Machine Trap-Vector Base Address: Base address for machine mode exception handlers.
| MEPC -- ^ Machine Exception Program Counter: Holds the return address for machine mode exceptions.
| MVENDORID -- ^ Machine Vendor ID: Identifies the vendor of the processor.
| MARCHID -- ^ Machine Architecture ID: Identifies the architecture of the processor.
| MIMPID -- ^ Machine Implementation ID: Identifies the implementation of the processor.
deriving (Generic, Show, Eq, NFDataX)
-- | Map each 'CSRName' variant to its corresponding CSR address.
csrNameToAddr :: CSRName -> Integer
csrNameToAddr STVEC = 0x105 -- Address for Supervisor Trap-Vector
csrNameToAddr SEPC = 0x141 -- Address for Supervisor Exception PC
csrNameToAddr MSTATUS = 0x300
csrNameToAddr MISA = 0x301
csrNameToAddr MTVEC = 0x305
csrNameToAddr MEPC = 0x341 -- Address for Machine Exception PC
csrNameToAddr MVENDORID = 0xF11
csrNameToAddr MARCHID = 0xF12
csrNameToAddr MIMPID = 0xF13
-- | Initial CSR values.
-- Note: The CSR registers are not all zero during proper initialization; these values
-- are placeholders to be revisited for proper initialization later.
csrInit :: CSR csrInit :: CSR
csrInit = csrInit =
replace (csrNameToAddr STVEC) stvec_init |> replace (0x301 :: Integer) misa_init
replace (csrNameToAddr SEPC) sepc_init |> $ replace (0x300 :: Integer) mstatus_init
replace (csrNameToAddr MSTATUS) mstatus_init |> $ replace (0x305 :: Integer) mtvec_init
replace (csrNameToAddr MISA) misa_init |> $ replace (0xF11 :: Integer) mvendorid_init
replace (csrNameToAddr MTVEC) mtvec_init |> $ replace (0xF12 :: Integer) marchid_init
replace (csrNameToAddr MEPC) mepc_init |> $ replace (0xF13 :: Integer) mimpid_init
replace (csrNameToAddr MVENDORID) mvendorid_init |> $ replace (0x701 :: Integer) mtime_init
replace (csrNameToAddr MARCHID) marchid_init |> $ replace (0x321 :: Integer) mtimecmp_init
replace (csrNameToAddr MIMPID) mimpid_init |> $ repeat 0
repeat 0
where where
stvec_init = 0x0000000000002000 -- Supervisor mode trap vector base address. misa_init = 0x8000000000001104 -- `RV64IMAFD`
sepc_init = 0x0000000000000000 -- Supervisor Exception PC initial value. mstatus_init = 0x0000000000001800 -- Default `mstatus`
mstatus_init = 0x0000000000001800 -- Default machine status. mtvec_init = 0x0000000000001000 -- Trap vector base
misa_init = 0x8000000000001104 -- RV64IMAFD: Machine ISA with standard extensions. mvendorid_init = 0x00000000
mtvec_init = 0x0000000000001000 -- Machine mode trap vector base address. marchid_init = 0x00000000
mepc_init = 0x0000000000000000 -- Machine Exception PC initial value. mimpid_init = 0x00000000
mvendorid_init = 0x00000000 -- Vendor-specific ID. mtime_init = 0x0000000000000000
marchid_init = 0x00000000 -- Architecture-specific ID. mtimecmp_init = 0xFFFFFFFFFFFFFFFF
mimpid_init = 0x00000000 -- Implementation-specific ID.

View file

@ -3,26 +3,26 @@
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ConstraintKinds #-}
module Simulation( module Simulation(Args(..), simulation, Simulation(..)) where
Args(..),
simulation,
RISCVCPU(..),
Machine(..),
Simulation(..)
) where
import qualified Prelude as P
import Peripherals.Setup(setupPeripherals, InitializedPeripherals(..)) import Peripherals.Setup(setupPeripherals, InitializedPeripherals(..))
import Peripherals.Teardown(teardownPeripherals) import Peripherals.Teardown(teardownPeripherals)
import Text.Printf (printf)
import Clash.Prelude import Clash.Prelude
import Bus(Peripherals(..)) import Machine(
import Read(read) Machine(..),
import Cpu(
RISCVCPU(..), RISCVCPU(..),
riscvCPUInit) Peripherals(..),
import Fetch(fetchInstruction, debugInsn) machineInit, RISCVCPU (RISCVCPU))
import Decode(decode) import Fetch(fetchInstruction, FetchResult (Instruction, Misaligned))
import qualified Prelude as P import Isa.Decode(decode)
import Util((|>)) import Isa.Forms(Opcode(..))
import Peripherals.UartCFFI(writeCharToTerminal)
import Control.Concurrent (threadDelay)
import Debug.Trace
import Types (Mem, Addr)
data Args = Args { data Args = Args {
firmware :: FilePath firmware :: FilePath
@ -32,40 +32,53 @@ data Simulation
= Success [Machine] = Success [Machine]
| Failure String | Failure String
deriving (Show) deriving (Show)
data Machine = Machine
{ cpu :: RISCVCPU,
peripherals :: Peripherals
}
deriving (Generic, Show, Eq, NFDataX)
-- machine :: Machine
-- machine = machineInit
machine' :: Machine -> Machine
machine' machine =
let
machinePeripherals = peripherals machine
machineMem = ram $ machinePeripherals
machineCPU = cpu machine
machinePC = pc machineCPU
addr = 0 :: Integer
mem' = replace addr (3) machineMem
peripherals' = machinePeripherals { ram = mem' }
cpu' = machineCPU { pc = machinePC + 4 }
instruction =
case (fetchInstruction machineMem machinePC) of
Instruction i -> i
_ -> undefined
in
case (fetchInstruction machineMem machinePC) of
Instruction insn ->
let binaryInsn = show (bitCoerce insn :: BitVector 32)
in trace ("Decoded instruction: " P.++ show opcode
P.++ " | Binary: " P.++ binaryInsn
P.++ " (" P.++ show insn P.++ ")") $
machine { cpu = cpu', peripherals = peripherals' }
where
opcode = decode insn
Misaligned addr -> undefined
simulationLoop :: Int -> Machine -> IO [Machine] simulationLoop :: Int -> Machine -> IO [Machine]
simulationLoop 0 machine = return [machine] simulationLoop 0 state = return [state]
simulationLoop n machine = do simulationLoop n state = do
let machinePeripherals = peripherals machine let newState = machine' state
currPc = pc |> cpu machine rest <- simulationLoop (n - 1) newState
fetchResult <- fetchInstruction machinePeripherals currPc return (state : rest)
let decodeResult = Read.read (decode fetchResult) (cpu machine)
putStrLn |> show decodeResult -- P.++ debugInsn fetchResult
let pc' = currPc + 4
cpu' = (cpu machine) { pc = pc' }
machine' = machine { cpu = cpu' }
rest <- simulationLoop (n - 1) machine'
return (machine : rest)
simulation :: Args -> IO Simulation simulation :: Args -> IO Simulation
simulation args = do simulation args = do
initializedPeripherals <- setupPeripherals (firmware args) initializedPeripherals <- setupPeripherals (firmware args)
case initializedPeripherals of case initializedPeripherals of
InitializationError e -> return |> Failure e InitializationError e -> return $ Failure e
InitializedPeripherals ramDevice -> do InitializedPeripherals ram -> do
let initState = let initState = machineInit $ Machine.Peripherals ram
Machine {
cpu = riscvCPUInit,
peripherals = Bus.Peripherals ramDevice
}
sim <- simulationLoop 15 initState sim <- simulationLoop 15 initState
teardownPeripherals teardownPeripherals
return |> Success sim return $ Success sim

View file

@ -1,11 +1,7 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE NumericUnderscores #-}
module Types( module Types(Pc, BusVal(..), Mem, FullWord, Insn, Addr) where
Pc, Mem, Insn, Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord
)
where
import Clash.Prelude import Clash.Prelude
@ -16,6 +12,14 @@ type DoubleWord = Unsigned 64
type QuadWord = Unsigned 128 type QuadWord = Unsigned 128
type Insn = FullWord type Insn = FullWord
data BusVal
= BusByte Byte
| BusHalfWord HalfWord
| BusWord FullWord
| BusDoubleWord DoubleWord
| BusQuadWord QuadWord
deriving (Generic, Show, Eq, NFDataX)
type Pc = DoubleWord type Pc = DoubleWord
type Addr = DoubleWord type Addr = DoubleWord
type Mem n = Vec n FullWord type Mem n = Vec n FullWord

View file

@ -1,10 +1,44 @@
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
module Util( module Util(
(|>), powerIndex32,
) where powerIndex64,
endianSwapWord) where
(|>) :: (a -> b) -> a -> b import Clash.Prelude
f |> x = f x import Types(FullWord)
infixr 0 |>
data ValidIndex32 (n :: Nat) where
ValidIndex32 :: (0 <= n, n <= 31) => SNat n -> ValidIndex32 n
mkValidIndex32 :: forall n. (KnownNat n, 0 <= n, n <= 31) => ValidIndex32 n
mkValidIndex32 = ValidIndex32 $ SNat @n
powerIndex32 :: forall n. (KnownNat n, 0 <= n, n <= 31) => SNat (31 - n)
powerIndex32 = case mkValidIndex32 @n of
ValidIndex32 _ -> SNat @(31 - n)
data ValidIndex63 (n :: Nat) where
ValidIndex63 :: (0 <= n, n <= 63) => SNat n -> ValidIndex63 n
mkValidIndex64 :: forall n. (KnownNat n, 0 <= n, n <= 63) => ValidIndex63 n
mkValidIndex64 = ValidIndex63 $ SNat @n
powerIndex64 :: forall n. (KnownNat n, 0 <= n, n <= 63) => SNat (63 - n)
powerIndex64 = case mkValidIndex64 @n of
ValidIndex63 _ -> SNat @(63 - n)
endianSwapWord :: FullWord -> FullWord
endianSwapWord x =
(byte0 `shiftL` 24) .|.
(byte1 `shiftL` 16) .|.
(byte2 `shiftL` 8) .|.
byte3
where
byte0 = (x .&. 0x000000FF)
byte1 = (x .&. 0x0000FF00) `shiftR` 8
byte2 = (x .&. 0x00FF0000) `shiftR` 16
byte3 = (x .&. 0xFF000000) `shiftR` 24

View file

@ -1 +0,0 @@
* [RISC-V Card](https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/notebooks/RISCV/RISCV_CARD.pdf)

View file

@ -87,22 +87,16 @@ library
exposed-modules: exposed-modules:
Simulation Simulation
other-modules: other-modules:
Fetch, Isa.Decode,
Decode, Isa.Forms,
DecodeTypes,
Execute,
Read,
Peripherals.Ram, Peripherals.Ram,
Peripherals.Uart,
Peripherals.UartCFFI, Peripherals.UartCFFI,
Peripherals.Setup, Peripherals.Setup,
Peripherals.Teardown, Peripherals.Teardown,
Types, Types,
Bus, Machine,
BusTypes,
Cpu,
RegFiles, RegFiles,
Exceptions, Fetch,
Util Util
c-sources: c/uart_sim_device.c c-sources: c/uart_sim_device.c
include-dirs: c include-dirs: c

View file

@ -1,13 +1,12 @@
# RISC-V toolchain # RISC-V toolchain
CROSS_PREFIX ?= riscv64-unknown-elf CC = riscv64-none-elf-gcc
CC = $(CROSS_PREFIX)-gcc AS = riscv64-none-elf-as
AS = $(CROSS_PREFIX)-as LD = riscv64-none-elf-ld
LD = $(CROSS_PREFIX)-ld OBJCOPY = riscv64-none-elf-objcopy
OBJCOPY = $(CROSS_PREFIX)-objcopy
QEMU = qemu-system-riscv64 QEMU = qemu-system-riscv64
# Compilation flags # Compilation flags
ARCH_FLAGS = -march=rv64ima -mabi=lp64 ARCH_FLAGS = -march=rv64imac -mabi=lp64
LDSCRIPT = linker.ld LDSCRIPT = linker.ld
# Output files # Output files

BIN
rv_tests/hello_world/hello.elf Executable file

Binary file not shown.