{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Bus() where import Clash.Prelude import Peripherals.Ram(Ram, RamLine, read, RamAddr) import Machine(Peripherals(..)) import BusTypes( BusError(..), TransactionSize(..), Request(..), 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) read :: Request -> Peripherals -> IO ReadResponse read (Request addr size) peripherals | not (alignCheck addr size) = return $ ReadResponse $ Error UnAligned | (addr > ramStart) && (addr < ramEnd) = return $ ReadResponse $ Result $ Peripherals.Ram.read size ramAddr (ram peripherals) | otherwise = return $ ReadResponse $ Error UnMapped where ramAddrNoOffset = addr - ramStart ramAddr :: RamAddr ramAddr = resize ramAddrNoOffset -- | (addr > ramStart) && (addr < ramEnd) = return $ ReadResponse $ Peripherals.Ram.read addr size (ram peripherals) -- | addr >= numBytesInRam = ReadError UnMapped -- case size of -- SizeByte -> BusByte $ fromIntegral $ extractByte (ramRead 0) -- SizeHalfWord -> BusHalfWord $ fromIntegral $ (ramRead 0 `shiftL` 8) .|. ramRead 1 -- SizeWord -> BusWord $ fromIntegral $ concatReads [0..3] -- SizeDoubleWord -> BusDoubleWord $ fromIntegral $ concatReads [0..7] -- SizeQuadWord -> BusQuadWord $ fromIntegral $ concatReads [0..15] -- where -- ramRead offset = Peripherals.Ram.read (ram peripherals) (fromIntegral (addr + offset)) -- concatReads offsets = foldl (\acc o -> (acc `shiftL` 8) .|. ramRead o) 0 offsets