libriscv-0.1.0.0: test/ArchStateTest.hs
module ArchStateTest where
import Data.Array.IO (IOUArray)
import qualified Data.ByteString.Lazy as BSL
import Data.Word
import LibRISCV (RegIdx (..))
import LibRISCV.Effects.Operations.Default.Machine.Memory
import LibRISCV.Effects.Operations.Default.Machine.Register
import Test.Tasty
import Test.Tasty.HUnit
mkReg :: IO (RegisterFile IOUArray Word32)
mkReg = mkRegFile 0
registerTests :: TestTree
registerTests =
testGroup
"RegisterFile Tests"
[ testCase "Read and write general-puropose register" $ do
r <- mkReg
writeRegister r A1 23
regVal <- readRegister r A1
assertEqual "" 23 regVal
, testCase "Write zero register" $ do
r <- mkReg
writeRegister r Zero 42
regVal <- readRegister r Zero
assertEqual "" 0 regVal
, testCase "Read and write program counter" $ do
r <- mkReg
initVal <- readPC r
assertEqual "PC is zero initially" 0 initVal
writePC r 1337
regVal <- readPC r
assertEqual "PC can be written" 1337 regVal
writePC r 0
regVal <- readPC r
assertEqual "Zero can be written to PC" 0 regVal
]
memoryTests :: TestTree
memoryTests =
testGroup
"Memory Tests"
[ testCase "Create memory and extract its size" $ do
m <- mkMemory 0x0 512 :: IO (Memory IOUArray Word8)
memSize m >>= assertEqual "" 512
, testCase "Store and load byte" $ do
m <- mkMemory 0x0 512 :: IO (Memory IOUArray Word8)
storeByte m 0x4 0xab
loadByte m 0x04 >>= assertEqual "" 0xab
, testCase "Read uninitialized memory" $ do
m <- mkMemory 0x0 256 :: IO (Memory IOUArray Word8)
-- We don't really care what this evaluates to. This returns
-- undefined values which is fine as long as the memory doesn't
-- error on an uninitialized memory accesses.
(loadWord m 128 :: IO Word32) >> pure ()
, testCase "StoreWord in between" $ do
m <- mkMemory 0x0 12 :: IO (Memory IOUArray Word8)
storeWord m 0 (0xffffffff :: Word32)
storeWord m 4 (0xffffffff :: Word32)
storeWord m 8 (0xffffffff :: Word32)
storeWord m 0x2 (0x12345678 :: Word32)
(loadWord m 0 :: IO Word32) >>= assertEqual "1st word" 0x5678ffff
(loadWord m 4 :: IO Word32) >>= assertEqual "2nd word" 0xffff1234
(loadWord m 8 :: IO Word32) >>= assertEqual "3rd word" 0xffffffff
, testCase "Store and load word" $ do
m <- mkMemory 0x0 256 :: IO (Memory IOUArray Word8)
storeWord m 8 (0xdeadbeef :: Word32)
(loadWord m 8 :: IO Word32) >>= assertEqual "Load entire word" 0xdeadbeef
loadByte m 8 >>= assertEqual "Load 1st byte" 0xef
loadByte m 9 >>= assertEqual "Load 2nd byte" 0xbe
loadByte m 11 >>= assertEqual "Load 4th byte" 0xde
, testCase "Write ByteString in little endian byteorder" $ do
m <- mkMemory 0x0 32 :: IO (Memory IOUArray Word8)
let bs = BSL.pack [0xde, 0xad, 0xbe, 0xef]
storeByteString fromIntegral m 0x0 bs
(loadWord m 0x0 :: IO Word32) >>= assertEqual "" 0xefbeadde
, testCase "Write ByteString with multiple bytes" $ do
m <- mkMemory 0x0 8 :: IO (Memory IOUArray Word8)
let bs = BSL.pack [0xde, 0xad, 0xbe, 0xef, 0x12, 0x23, 0x34, 0xff]
storeByteString fromIntegral m 0x0 bs
(loadWord m 0x0 :: IO Word32) >>= assertEqual "" 0xefbeadde
(loadWord m 0x4 :: IO Word32) >>= assertEqual "" 0xff342312
]