{-# 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