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 Clash.Prelude
import Peripherals.Ram(Ram, RamLine) import Peripherals.Ram(Ram, RamLine, read, RamAddr)
import Machine(Peripherals(..)) import Machine(Peripherals(..))
import BusTypes( import BusTypes(
BusError(..), BusError(..),
@ -16,24 +16,33 @@ import BusTypes(
) )
import Types(Addr, import Types(Addr,
Byte, HalfWord, FullWord, DoubleWord, QuadWord) Byte, HalfWord, FullWord, DoubleWord, QuadWord)
import Peripherals.Ram(read, bytesInRam)
import Distribution.Types.UnitId (DefUnitId(unDefUnitId))
alignCheck :: Addr -> TransactionSize -> Bool alignCheck :: Addr -> TransactionSize -> Bool
alignCheck addr SizeByte = True alignCheck addr SizeByte = True
alignCheck addr SizeHalfWord = addr `mod` 2 == 0 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 SizeDoubleWord = addr `mod` 8 == 0
alignCheck addr SizeQuadWord = addr `mod` 16 == 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 read :: Request -> Peripherals -> IO ReadResponse
-- concatWords readers ram baseAddr = foldl (\acc f -> (acc `shiftL` 32) .|. f ram baseAddr) 0 readers 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 -- | (addr > ramStart) && (addr < ramEnd) = return $ ReadResponse $ Peripherals.Ram.read addr size (ram peripherals)
-- read (Request addr size) peripherals
-- | not (alignCheck addr size) = ReadError UnAligned
-- | addr >= numBytesInRam = ReadError UnMapped -- | addr >= numBytesInRam = ReadError UnMapped
-- | otherwise =
-- case size of -- case size of
-- SizeByte -> BusByte $ fromIntegral $ extractByte (ramRead 0) -- SizeByte -> BusByte $ fromIntegral $ extractByte (ramRead 0)
-- SizeHalfWord -> BusHalfWord $ fromIntegral $ (ramRead 0 `shiftL` 8) .|. ramRead 1 -- SizeHalfWord -> BusHalfWord $ fromIntegral $ (ramRead 0 `shiftL` 8) .|. ramRead 1

View file

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

View file

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

View file

@ -34,7 +34,7 @@ $(BIN): $(ELF)
# Run in QEMU # Run in QEMU
run: $(BIN) run: $(BIN)
echo "Press CTRL+A then X to exit QEMU" 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 up generated files
clean: clean: