read getting closer to being done

This commit is contained in:
Yehowshua Immanuel 2025-02-25 19:09:37 -05:00
parent 1f9bd2f015
commit 7265728932
4 changed files with 78 additions and 52 deletions

View file

@ -3,7 +3,7 @@ module Bus() where
import Clash.Prelude
import Peripherals.Ram(Ram, RamLine)
import Peripherals.Ram(Ram, RamLine, read, RamAddr)
import Machine(Peripherals(..))
import BusTypes(
BusError(..),
@ -16,24 +16,33 @@ import BusTypes(
)
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 SizeWord = addr `mod` 4 == 0
alignCheck addr SizeFullWord = addr `mod` 4 == 0
alignCheck addr SizeDoubleWord = addr `mod` 8 == 0
alignCheck addr SizeQuadWord = addr `mod` 16 == 0
-- ram shoudl start at 0x80000000
-- address space follows QEMU behavior for now
(ramStart, ramEnd) = (0x80000000 :: Addr, ramStart + (bytesInRam - 1))
(uartStart, uartEnd) = (0x10000000 :: Addr, uartStart + 7)
-- concatWords :: [Ram -> Addr -> RamLine] -> Ram -> Addr -> RamLine
-- concatWords readers ram baseAddr = foldl (\acc f -> (acc `shiftL` 32) .|. f ram baseAddr) 0 readers
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
-- read :: Request -> Peripherals -> ReadResponse
-- read (Request addr size) peripherals
-- | not (alignCheck addr size) = ReadError UnAligned
-- | (addr > ramStart) && (addr < ramEnd) = return $ ReadResponse $ Peripherals.Ram.read addr size (ram peripherals)
-- | addr >= numBytesInRam = ReadError UnMapped
-- | otherwise =
-- case size of
-- SizeByte -> BusByte $ fromIntegral $ extractByte (ramRead 0)
-- SizeHalfWord -> BusHalfWord $ fromIntegral $ (ramRead 0 `shiftL` 8) .|. ramRead 1

View file

@ -11,8 +11,6 @@ module BusTypes(
import Clash.Prelude
import Peripherals.Ram(Ram, RamLine)
import Machine(Peripherals(..))
import Types(Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord)
@ -24,7 +22,7 @@ data BusError
data TransactionSize
= SizeByte
| SizeHalfWord
| SizeWord
| SizeFullWord
| SizeDoubleWord
| SizeQuadWord
deriving (Generic, Show, Eq, NFDataX)
@ -40,7 +38,7 @@ data BusResponse a
data BusVal
= BusByte Byte
| BusHalfWord HalfWord
| BusWord FullWord
| BusFullWord FullWord
| BusDoubleWord DoubleWord
| BusQuadWord QuadWord
deriving (Generic, Show, Eq, NFDataX)

View file

@ -5,12 +5,14 @@
module Peripherals.Ram(
initRamFromFile,
RamAddr,
Ram,
RamLine,
-- Peripherals.Ram.read,
bytesInRam,
read,
write) where
import Clash.Prelude
import Clash.Prelude hiding (read)
import qualified Prelude as P
import qualified Data.ByteString.Lazy as BL
import Data.Binary.Get
@ -18,6 +20,15 @@ import Data.Int (Int32)
import qualified Clash.Sized.Vector as Vec
import Types(Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord)
import BusTypes(
BusError(..),
TransactionSize(..),
Request(..),
BusResponse(..),
BusVal(..),
ReadResponse(..),
WriteResponse(..)
)
-- vector depth has to be known statically at compile time
#ifndef _RAM_DEPTH
@ -28,46 +39,54 @@ import Types(Addr,
type Ram = Vec _RAM_DEPTH (Unsigned 32)
type RamAddr = Unsigned (CLog 2 _RAM_DEPTH)
type RamLine = Unsigned 32
bytesInRam = 1024 * 4
bytesInRam :: Addr
bytesInRam = _RAM_DEPTH * 4
readByte0 :: Ram -> RamAddr -> Byte
readByte0 ram addr = unpack $ slice d31 d24 word
where word = ram !! addr
readByte1 :: Ram -> RamAddr -> Byte
readByte1 ram addr = unpack $ slice d23 d16 word
where word = ram !! addr
readByte2 :: Ram -> RamAddr -> Byte
readByte2 ram addr = unpack $ slice d15 d8 word
where word = ram !! addr
readByte3 :: Ram -> RamAddr -> Byte
readByte3 ram addr = unpack $ slice d7 d0 word
where word = ram !! addr
readHalfWord0 :: Ram -> RamAddr -> HalfWord
readHalfWord0 ram addr = unpack $ slice d31 d16 word
where word = ram !! addr
readHalfWord1 :: Ram -> RamAddr -> HalfWord
readHalfWord1 ram addr = unpack $ slice d15 d0 word
where word = ram !! addr
readFullWord :: Ram -> RamAddr -> FullWord
readFullWord ram addr = ram !! addr
readDoubleWord :: Ram -> RamAddr -> DoubleWord
readDoubleWord ram addr = bitCoerce $ bitCoerce word0 ++# bitCoerce word1
read :: TransactionSize -> RamAddr -> Ram -> BusVal
read SizeByte addr ram = BusByte $ unpack byte
where
word0 = readFullWord ram addr
word1 = readFullWord ram (addr + 1)
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
readQuadWord :: Ram -> RamAddr -> QuadWord
readQuadWord ram addr = bitCoerce $ bitCoerce dword0 ++# bitCoerce dword1
read SizeHalfWord addr ram = BusHalfWord $ unpack halfWord
where
dword0 = readDoubleWord ram addr
dword1 = readDoubleWord ram (addr + 2)
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 :: Ram -> RamAddr -> RamLine -> Ram
write ram addr value = replace addr value ram

View file

@ -34,7 +34,7 @@ $(BIN): $(ELF)
# Run in QEMU
run: $(BIN)
echo "Press CTRL+A then X to exit QEMU"
$(QEMU) -machine virt -nographic -bios none -kernel $(BIN) -device loader,file=$(BIN),addr=0x80000000
$(QEMU) -machine virt -nographic -bios none -kernel $(BIN) -device loader,file=$(BIN),addr=0x80000000 -device sifive_uart
# Clean up generated files
clean: