diff --git a/clash-vexriscv/clash-vexriscv.cabal b/clash-vexriscv/clash-vexriscv.cabal index 7ae96cb..9ea44e0 100644 --- a/clash-vexriscv/clash-vexriscv.cabal +++ b/clash-vexriscv/clash-vexriscv.cabal @@ -126,6 +126,7 @@ library Glob, network, process >= 1.6 && < 1.8, + random, string-interpolate, tagged, template-haskell, diff --git a/clash-vexriscv/src/VexRiscv.hs b/clash-vexriscv/src/VexRiscv.hs index 098aba3..0a6ac14 100644 --- a/clash-vexriscv/src/VexRiscv.hs +++ b/clash-vexriscv/src/VexRiscv.hs @@ -41,13 +41,13 @@ data JtagIn = JtagIn , testModeSelect :: "TMS" ::: Bit , testDataIn :: "TDI" ::: Bit } - deriving (Generic, Eq, NFDataX, ShowX, BitPack) + deriving (Generic, Eq, NFDataX, ShowX, BitPack, Show) data JtagOut = JtagOut { testDataOut :: "TDO" ::: Bit , debugReset :: "RST" ::: Bit } - deriving (Generic, NFDataX, ShowX, Eq, BitPack) + deriving (Generic, NFDataX, ShowX, Eq, BitPack, Show) data CpuIn = CpuIn { timerInterrupt :: "TIMER_INTERRUPT" ::: Bit @@ -56,13 +56,13 @@ data CpuIn = CpuIn , iBusWbS2M :: "IBUS_IN_" ::: WishboneS2M (BitVector 32) , dBusWbS2M :: "DBUS_IN_" ::: WishboneS2M (BitVector 32) } - deriving (Generic, NFDataX, ShowX, Eq, BitPack) + deriving (Generic, NFDataX, ShowX, Eq, BitPack, Show) data CpuOut = CpuOut { iBusWbM2S :: "IBUS_OUT_" ::: WishboneM2S 30 4 (BitVector 32) , dBusWbM2S :: "DBUS_OUT_" ::: WishboneM2S 30 4 (BitVector 32) } - deriving (Generic, NFDataX, ShowX, Eq, BitPack) + deriving (Generic, NFDataX, ShowX, Eq, BitPack, Show) data Jtag (dom :: Domain) diff --git a/clash-vexriscv/src/VexRiscv/FFI.hsc b/clash-vexriscv/src/VexRiscv/FFI.hsc index 572cad8..13c3456 100644 --- a/clash-vexriscv/src/VexRiscv/FFI.hsc +++ b/clash-vexriscv/src/VexRiscv/FFI.hsc @@ -8,11 +8,15 @@ module VexRiscv.FFI where -import Foreign.Storable -import Foreign.Ptr -import Prelude import Clash.Prelude +import Prelude + +import Clash.Sized.Internal.BitVector(Bit(..)) import Data.Word +import Foreign.Ptr +import Foreign.Storable +import System.Random +import System.Random.Stateful #include "ffi/interface.h" @@ -32,13 +36,30 @@ foreign import ccall unsafe "vexr_jtag_bridge_init" vexrJtagBridgeInit :: Word16 foreign import ccall unsafe "vexr_jtag_bridge_step" vexrJtagBridgeStep :: Ptr VexRiscvJtagBridge -> Ptr JTAG_OUTPUT -> Ptr JTAG_INPUT -> IO () foreign import ccall unsafe "vexr_jtag_bridge_shutdown" vexrJtagBridgeShutdown :: Ptr VexRiscvJtagBridge -> IO () +-- TODO: Move to clash-prelude? +deriving instance Uniform Bit +instance UniformRange Bit where + uniformRM (Bit lMask lDat, Bit hMask hDat) g = do + + mask <- uniformRM (lMask, hMask) g + dat <- uniformRM (lDat, hDat) g + pure $ Bit mask dat + +instance Random Bit where + random g = (Bit 0 a, g') + where + (a, g') = (randomR (0, 1) g) + +undefinedToRandom :: (Random a, NFDataX a) => a -> IO a +undefinedToRandom inp = if hasUndefined inp then randomIO else pure inp + -- | CPU input that cannot combinatorially depend on the CPU output data NON_COMB_INPUT = NON_COMB_INPUT { reset :: Bit , timerInterrupt :: Bit , externalInterrupt :: Bit , softwareInterrupt :: Bit - } + } deriving (Generic, NFDataX, Show, Uniform, UniformRange, Random) -- | CPU input that can combinatorially depend on the CPU output data COMB_INPUT = COMB_INPUT @@ -54,7 +75,7 @@ data COMB_INPUT = COMB_INPUT , jtag_TMS :: Bit , jtag_TDI :: Bit } - deriving (Show) + deriving (Generic, NFDataX, Show, Uniform, UniformRange, Random) data OUTPUT = OUTPUT { iBusWishbone_CYC :: Bit @@ -78,20 +99,20 @@ data OUTPUT = OUTPUT , jtag_debug_resetOut :: Bit , jtag_TDO :: Bit } - deriving (Show) + deriving (Generic, NFDataX, Show, Uniform, UniformRange, Random) data JTAG_INPUT = JTAG_INPUT { tck :: Bit , tms :: Bit , tdi :: Bit } - deriving (Show) + deriving (Generic, NFDataX, Show, Uniform, UniformRange, Random) data JTAG_OUTPUT = JTAG_OUTPUT { debug_resetOut :: Bit , tdo :: Bit } - deriving (Show) + deriving (Generic, NFDataX, Show, Uniform, UniformRange, Random) instance Storable Bit where alignment = alignment . bitToBool @@ -110,11 +131,12 @@ instance Storable NON_COMB_INPUT where <*> (#peek NON_COMB_INPUT, softwareInterrupt) ptr {-# INLINE poke #-} - poke ptr this = do - (#poke NON_COMB_INPUT, reset) ptr (reset this) - (#poke NON_COMB_INPUT, timerInterrupt) ptr (timerInterrupt this) - (#poke NON_COMB_INPUT, externalInterrupt) ptr (externalInterrupt this) - (#poke NON_COMB_INPUT, softwareInterrupt) ptr (softwareInterrupt this) + poke ptr this0 = do + this1 <- undefinedToRandom this0 + (#poke NON_COMB_INPUT, reset) ptr (reset this1) + (#poke NON_COMB_INPUT, timerInterrupt) ptr (timerInterrupt this1) + (#poke NON_COMB_INPUT, externalInterrupt) ptr (externalInterrupt this1) + (#poke NON_COMB_INPUT, softwareInterrupt) ptr (softwareInterrupt this1) return () instance Storable COMB_INPUT where @@ -133,18 +155,19 @@ instance Storable COMB_INPUT where <*> (#peek COMB_INPUT, jtag_TDI) ptr {-# INLINE poke #-} - poke ptr this = do - (#poke COMB_INPUT, iBusWishbone_ACK) ptr (iBusWishbone_ACK this) - (#poke COMB_INPUT, iBusWishbone_DAT_MISO) ptr (iBusWishbone_DAT_MISO this) - (#poke COMB_INPUT, iBusWishbone_ERR) ptr (iBusWishbone_ERR this) - - (#poke COMB_INPUT, dBusWishbone_ACK) ptr (dBusWishbone_ACK this) - (#poke COMB_INPUT, dBusWishbone_DAT_MISO) ptr (dBusWishbone_DAT_MISO this) - (#poke COMB_INPUT, dBusWishbone_ERR) ptr (dBusWishbone_ERR this) - - (#poke COMB_INPUT, jtag_TCK) ptr (jtag_TCK this) - (#poke COMB_INPUT, jtag_TMS) ptr (jtag_TMS this) - (#poke COMB_INPUT, jtag_TDI) ptr (jtag_TDI this) + poke ptr this0 = do + this1 <- undefinedToRandom this0 + (#poke COMB_INPUT, iBusWishbone_ACK) ptr (iBusWishbone_ACK this1) + (#poke COMB_INPUT, iBusWishbone_DAT_MISO) ptr (iBusWishbone_DAT_MISO this1) + (#poke COMB_INPUT, iBusWishbone_ERR) ptr (iBusWishbone_ERR this1) + + (#poke COMB_INPUT, dBusWishbone_ACK) ptr (dBusWishbone_ACK this1) + (#poke COMB_INPUT, dBusWishbone_DAT_MISO) ptr (dBusWishbone_DAT_MISO this1) + (#poke COMB_INPUT, dBusWishbone_ERR) ptr (dBusWishbone_ERR this1) + + (#poke COMB_INPUT, jtag_TCK) ptr (jtag_TCK this1) + (#poke COMB_INPUT, jtag_TMS) ptr (jtag_TMS this1) + (#poke COMB_INPUT, jtag_TDI) ptr (jtag_TDI this1) return () instance Storable OUTPUT where @@ -174,27 +197,28 @@ instance Storable OUTPUT where <*> (#peek OUTPUT, jtag_TDO) ptr {-# INLINE poke #-} - poke ptr this = do - (#poke OUTPUT, iBusWishbone_CYC) ptr (iBusWishbone_CYC this) - (#poke OUTPUT, iBusWishbone_STB) ptr (iBusWishbone_STB this) - (#poke OUTPUT, iBusWishbone_WE) ptr (iBusWishbone_WE this) - (#poke OUTPUT, iBusWishbone_ADR) ptr (iBusWishbone_ADR this) - (#poke OUTPUT, iBusWishbone_DAT_MOSI) ptr (iBusWishbone_DAT_MOSI this) - (#poke OUTPUT, iBusWishbone_SEL) ptr (iBusWishbone_SEL this) - (#poke OUTPUT, iBusWishbone_CTI) ptr (iBusWishbone_CTI this) - (#poke OUTPUT, iBusWishbone_BTE) ptr (iBusWishbone_BTE this) - - (#poke OUTPUT, dBusWishbone_CYC) ptr (dBusWishbone_CYC this) - (#poke OUTPUT, dBusWishbone_STB) ptr (dBusWishbone_STB this) - (#poke OUTPUT, dBusWishbone_WE) ptr (dBusWishbone_WE this) - (#poke OUTPUT, dBusWishbone_ADR) ptr (dBusWishbone_ADR this) - (#poke OUTPUT, dBusWishbone_DAT_MOSI) ptr (dBusWishbone_DAT_MOSI this) - (#poke OUTPUT, dBusWishbone_SEL) ptr (dBusWishbone_SEL this) - (#poke OUTPUT, dBusWishbone_CTI) ptr (dBusWishbone_CTI this) - (#poke OUTPUT, dBusWishbone_BTE) ptr (dBusWishbone_BTE this) - - (#poke OUTPUT, jtag_debug_resetOut) ptr (jtag_debug_resetOut this) - (#poke OUTPUT, jtag_TDO) ptr (jtag_TDO this) + poke ptr this0 = do + this1 <- undefinedToRandom this0 + (#poke OUTPUT, iBusWishbone_CYC) ptr (iBusWishbone_CYC this1) + (#poke OUTPUT, iBusWishbone_STB) ptr (iBusWishbone_STB this1) + (#poke OUTPUT, iBusWishbone_WE) ptr (iBusWishbone_WE this1) + (#poke OUTPUT, iBusWishbone_ADR) ptr (iBusWishbone_ADR this1) + (#poke OUTPUT, iBusWishbone_DAT_MOSI) ptr (iBusWishbone_DAT_MOSI this1) + (#poke OUTPUT, iBusWishbone_SEL) ptr (iBusWishbone_SEL this1) + (#poke OUTPUT, iBusWishbone_CTI) ptr (iBusWishbone_CTI this1) + (#poke OUTPUT, iBusWishbone_BTE) ptr (iBusWishbone_BTE this1) + + (#poke OUTPUT, dBusWishbone_CYC) ptr (dBusWishbone_CYC this1) + (#poke OUTPUT, dBusWishbone_STB) ptr (dBusWishbone_STB this1) + (#poke OUTPUT, dBusWishbone_WE) ptr (dBusWishbone_WE this1) + (#poke OUTPUT, dBusWishbone_ADR) ptr (dBusWishbone_ADR this1) + (#poke OUTPUT, dBusWishbone_DAT_MOSI) ptr (dBusWishbone_DAT_MOSI this1) + (#poke OUTPUT, dBusWishbone_SEL) ptr (dBusWishbone_SEL this1) + (#poke OUTPUT, dBusWishbone_CTI) ptr (dBusWishbone_CTI this1) + (#poke OUTPUT, dBusWishbone_BTE) ptr (dBusWishbone_BTE this1) + + (#poke OUTPUT, jtag_debug_resetOut) ptr (jtag_debug_resetOut this1) + (#poke OUTPUT, jtag_TDO) ptr (jtag_TDO this1) return () instance Storable JTAG_OUTPUT where @@ -206,9 +230,10 @@ instance Storable JTAG_OUTPUT where <*> (#peek JTAG_OUTPUT, tdo) ptr {-# INLINE poke #-} - poke ptr this = do - (#poke JTAG_OUTPUT, debug_resetOut) ptr (debug_resetOut this) - (#poke JTAG_OUTPUT, tdo) ptr (tdo this) + poke ptr this0 = do + this1 <- undefinedToRandom this0 + (#poke JTAG_OUTPUT, debug_resetOut) ptr (debug_resetOut this1) + (#poke JTAG_OUTPUT, tdo) ptr (tdo this1) instance Storable JTAG_INPUT where alignment _ = #alignment JTAG_INPUT @@ -220,8 +245,9 @@ instance Storable JTAG_INPUT where <*> (#peek JTAG_INPUT, tdi) ptr {-# INLINE poke #-} - poke ptr this = do - (#poke JTAG_INPUT, tck) ptr (tck this) - (#poke JTAG_INPUT, tms) ptr (tms this) - (#poke JTAG_INPUT, tdi) ptr (tdi this) + poke ptr this0 = do + this1 <- undefinedToRandom this0 + (#poke JTAG_INPUT, tck) ptr (tck this1) + (#poke JTAG_INPUT, tms) ptr (tms this1) + (#poke JTAG_INPUT, tdi) ptr (tdi this1) return ()