RiscV-Formal/hs/Bus.hs

65 lines
2.2 KiB
Haskell

{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
module Bus() where
import Clash.Prelude
import Peripherals.Ram(Ram, RamLine, read, RamAddr)
import Peripherals.Uart(UartAddr, read, write)
import Machine(Peripherals(..))
import BusTypes(
BusError(..),
TransactionSize(..),
ReadRequest(..),
BusResponse(..),
BusVal(..),
ReadResponse(..),
WriteResponse(..)
)
import Types(Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord)
import Peripherals.Ram(read, bytesInRam)
import Distribution.Types.UnitId (DefUnitId(unDefUnitId))
alignCheck :: Addr -> TransactionSize -> Bool
alignCheck addr 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 (Request addr size) peripherals
| not (alignCheck addr size) = return $ Left UnAligned
| (addr >= ramStart) && (addr <= ramEnd) =
return $ Right $ Peripherals.Ram.read size ramAddr (ram peripherals)
| (addr >= uartStart) && (addr <= uartEnd) =
Right <$> Peripherals.Uart.read size uartAddr
| otherwise = return $ Left UnMapped
where
ramAddrNoOffset = addr - ramStart
ramAddr :: RamAddr
ramAddr = resize ramAddrNoOffset
uartAddrNoOffset = addr - uartStart
uartAddr :: UartAddr
uartAddr = resize uartAddrNoOffset
-- write :: BusVal -> Addr -> Peripherals -> IO WriteResponse
-- write val addr peripherals
-- | (addr >= uartStart) && (addr <= uartEnd) =
-- WriteResponse . Result <$> Peripherals.Uart.write val uartAddr
-- where
-- ramAddrNoOffset = addr - ramStart
-- ramAddr :: RamAddr
-- ramAddr = resize ramAddrNoOffset
-- uartAddrNoOffset = addr - uartStart
-- uartAddr :: UartAddr
-- uartAddr = resize uartAddrNoOffset