forked from Yehowshua/RiscV-Formal
read getting closer to being done
This commit is contained in:
parent
1f9bd2f015
commit
7265728932
27
hs/Bus.hs
27
hs/Bus.hs
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue