packages feed

lion 0.2.0.0 → 0.3.0.0

raw patch · 5 files changed

+135/−50 lines, 5 filesdep −Cabaldep ~basePVP ok

version bump matches the API change (PVP)

Dependencies removed: Cabal

Dependency ranges changed: base

API changes (from Hackage documentation)

- Lion.Core: [startPC] :: PipeConfig -> BitVector 32
- Lion.Core: instance GHC.Classes.Eq (Lion.Core.CoreConfig a)
- Lion.Core: instance GHC.Generics.Generic (Lion.Core.CoreConfig a)
- Lion.Core: instance GHC.Show.Show (Lion.Core.CoreConfig a)
- Lion.Core: newtype PipeConfig
+ Lion.Core: data PipeConfig (startPC :: Nat)
+ Lion.Core: instance GHC.Classes.Eq (Lion.Core.CoreConfig startPC a)
+ Lion.Core: instance GHC.Generics.Generic (Lion.Core.CoreConfig startPC a)
+ Lion.Core: instance GHC.Show.Show (Lion.Core.CoreConfig startPC a)
- Lion.Core: CoreConfig :: PipeConfig -> CoreConfig (a :: AluConfig)
+ Lion.Core: CoreConfig :: PipeConfig (startPC :: Nat) -> CoreConfig (startPC :: Nat) (a :: AluConfig)
- Lion.Core: PipeConfig :: BitVector 32 -> PipeConfig
+ Lion.Core: PipeConfig :: PipeConfig (startPC :: Nat)
- Lion.Core: [pipeConfig] :: CoreConfig (a :: AluConfig) -> PipeConfig
+ Lion.Core: [pipeConfig] :: CoreConfig (startPC :: Nat) (a :: AluConfig) -> PipeConfig (startPC :: Nat)
- Lion.Core: core :: forall a dom. HiddenClockResetEnable dom => Alu a => CoreConfig (a :: AluConfig) -> Signal dom (BitVector 32) -> FromCore dom
+ Lion.Core: core :: forall a startPC dom. HiddenClockResetEnable dom => Alu a => (KnownNat startPC, startPC <= 4294967295) => CoreConfig (startPC :: Nat) (a :: AluConfig) -> Signal dom (BitVector 32) -> FromCore dom
- Lion.Core: defaultCoreConfig :: CoreConfig 'Soft
+ Lion.Core: defaultCoreConfig :: CoreConfig 0 'Soft
- Lion.Core: defaultPipeConfig :: PipeConfig
+ Lion.Core: defaultPipeConfig :: PipeConfig 0
- Lion.Core: newtype CoreConfig (a :: AluConfig)
+ Lion.Core: newtype CoreConfig (startPC :: Nat) (a :: AluConfig)
- Lion.Rvfi: rdataCsr :: forall n_aKUp. Lens' (RvfiCsr n_aKUp) ((:::) "rdata" (BitVector n_aKUp))
+ Lion.Rvfi: rdataCsr :: forall n_aAfo. Lens' (RvfiCsr n_aAfo) ((:::) "rdata" (BitVector n_aAfo))
- Lion.Rvfi: rmaskCsr :: forall n_aKUp. Lens' (RvfiCsr n_aKUp) ((:::) "rmask" (BitVector n_aKUp))
+ Lion.Rvfi: rmaskCsr :: forall n_aAfo. Lens' (RvfiCsr n_aAfo) ((:::) "rmask" (BitVector n_aAfo))
- Lion.Rvfi: wdataCsr :: forall n_aKUp. Lens' (RvfiCsr n_aKUp) ((:::) "wdata" (BitVector n_aKUp))
+ Lion.Rvfi: wdataCsr :: forall n_aAfo. Lens' (RvfiCsr n_aAfo) ((:::) "wdata" (BitVector n_aAfo))
- Lion.Rvfi: wmaskCsr :: forall n_aKUp. Lens' (RvfiCsr n_aKUp) ((:::) "wmask" (BitVector n_aKUp))
+ Lion.Rvfi: wmaskCsr :: forall n_aAfo. Lens' (RvfiCsr n_aAfo) ((:::) "wmask" (BitVector n_aAfo))

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for lion +## 0.3.0.0++* Update base dependency version bounds+* Minor internal pipeline updates+* Remove Cabal dependency+* Move start PC configuration variable to type-level+* Update documentation+ ## 0.2.0.0 -- 2021-03-27  * Update core/memory/peripheral interface
lion.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               lion-version:            0.2.0.0+version:            0.3.0.0 synopsis:           RISC-V Core description:        Lion is a formally verified, 5-stage pipeline [RISC-V](https://riscv.org) core. Lion targets the [VELDT FPGA development board](https://standardsemiconductor.com) and is written in Haskell using [Clash](https://clash-lang.org). bug-reports:        https://github.com/standardsemiconductor/lion/issues@@ -16,7 +16,7 @@  source-repository head   type: git-  location: git://github.com/standardsemiconductor/lion.git+  location: https://github.com/standardsemiconductor/lion  library   exposed-modules: Lion.Core@@ -27,8 +27,7 @@   hs-source-dirs: src   default-language: Haskell2010   build-depends: -    base           >= 4.13  && < 4.15,-    Cabal,+    base           >= 4.13  && < 4.16,     generic-monoid >= 0.1   && < 0.2,     mtl            >= 2.2   && < 2.3,     lens           >= 4.19  && < 5.1,@@ -67,6 +66,7 @@     ScopedTypeVariables     TemplateHaskell     TupleSections+    TypeApplications     TypeFamilies     TypeOperators     ViewPatterns
src/Lion/Core.hs view
@@ -33,8 +33,8 @@ -- | Core configuration -- -- ALU configuration default: `Soft`-newtype CoreConfig (a :: AluConfig) = CoreConfig-  { pipeConfig :: P.PipeConfig -- ^ pipeline configuration+newtype CoreConfig (startPC :: Nat) (a :: AluConfig) = CoreConfig+  { pipeConfig :: P.PipeConfig (startPC :: Nat) -- ^ pipeline configuration   }   deriving stock (Generic, Show, Eq) @@ -43,7 +43,7 @@ -- ALU configuration = `Soft` -- -- `pipeConfig` = `defaultPipeConfig`-defaultCoreConfig :: CoreConfig 'Soft+defaultCoreConfig :: CoreConfig 0 'Soft defaultCoreConfig = CoreConfig   { pipeConfig = P.defaultPipeConfig   }@@ -56,10 +56,11 @@  -- | RISC-V Core: RV32I core-  :: forall a dom+  :: forall a startPC dom    . HiddenClockResetEnable dom   => Alu a-  => CoreConfig (a :: AluConfig) -- ^ core configuration+  => (KnownNat startPC, startPC <= 0xFFFFFFFF)+  => CoreConfig (startPC :: Nat) (a :: AluConfig) -- ^ core configuration   -> Signal dom (BitVector 32)   -- ^ core input, from memory/peripherals   -> FromCore dom                -- ^ core output core config toCore = FromCore
src/Lion/Pipe.hs view
@@ -17,16 +17,14 @@ import Lion.Rvfi  -- | Pipeline configuration-newtype PipeConfig = PipeConfig-  { startPC :: BitVector 32 -- ^ initial Program Counter address, default = 0-  }+data PipeConfig (startPC :: Nat) = PipeConfig   deriving stock (Generic, Show, Eq)  -- | Default pipeline configuration --  -- `startPC` = 0-defaultPipeConfig :: PipeConfig-defaultPipeConfig = PipeConfig 0+defaultPipeConfig :: PipeConfig 0+defaultPipeConfig = PipeConfig  -- | Pipeline inputs data ToPipe = ToPipe@@ -153,9 +151,13 @@   deriving anyclass NFDataX makeLenses ''Pipe -mkPipe :: PipeConfig -> Pipe-mkPipe config = Pipe-  { _fetchPC = startPC config+mkPipe +  :: forall startPC+   . (KnownNat startPC, startPC <= 0xFFFFFFFF)+  => PipeConfig (startPC :: Nat) +  -> Pipe+mkPipe _ = Pipe+  { _fetchPC = natToNum @startPC    -- decode stage    , _dePC    = 0@@ -183,7 +185,8 @@ -- | 5-Stage RISC-V pipeline pipe    :: HiddenClockResetEnable dom-  => PipeConfig+  => (KnownNat startPC, startPC <= 0xFFFFFFFF)+  => PipeConfig (startPC :: Nat)   -> Signal dom ToPipe   -> Signal dom FromPipe pipe config = mealy pipeMealy (mkPipe config)@@ -215,12 +218,14 @@       control.wbMemory .= True       wbRvfi.rvfiRdAddr .= rdAddr       mem <- wbRvfi.rvfiMemRData <<~ view fromMem-      let wr = case op of-            Lb  -> signExtend $ sliceByte mask mem-            Lh  -> signExtend $ sliceHalf mask mem+      let byte = sliceByte mask mem+          half = sliceHalf mask mem+          wr = case op of+            Lb  -> signExtend byte+            Lh  -> signExtend half             Lw  -> mem-            Lbu -> zeroExtend $ sliceByte mask mem-            Lhu -> zeroExtend $ sliceHalf mask mem+            Lbu -> zeroExtend byte+            Lhu -> zeroExtend half       rdData <- wbRvfi.rvfiRdWData <.= guardZero rdAddr wr       scribe toRd . First =<< control.wbRegFwd <.= Just (rdAddr, rdData)     WbStore -> control.wbMemory .= True@@ -272,23 +277,17 @@   rs1Data <- meRvfi.rvfiRs1Data <<~ regFwd exRs1 fromRs1 (control.meRegFwd) (control.wbRegFwd)   rs2Data <- meRvfi.rvfiRs2Data <<~ regFwd exRs2 fromRs2 (control.meRegFwd) (control.wbRegFwd)   withInstr exIR $ \case-    Ex op rd imm -> case op of-      Lui -> do -        scribeAlu Add 0 imm-        meIR ?= MeRegWr rd-      Auipc -> do-        scribeAlu Add pc imm-        meIR ?= MeRegWr rd+    Ex op rd imm -> do+      scribeAlu Add imm $ case op of+        Lui   -> 0+        Auipc -> pc+      meIR ?= MeRegWr rd     ExJump jump rd imm -> do-      case jump of-        Jal -> do-          npc <- meRvfi.rvfiPcWData <<~ control.exBranching <?= pc + imm-          meRvfi.rvfiTrap ||= isMisaligned npc-          meIR ?= MeJump rd pc4-        Jalr -> do-          npc <- meRvfi.rvfiPcWData <<~ control.exBranching <?= clearBit (rs1Data + imm) 0-          meRvfi.rvfiTrap ||= isMisaligned npc-          meIR ?= MeJump rd pc4+      npc <- meRvfi.rvfiPcWData <<~ control.exBranching <?= case jump of+        Jal  -> pc + imm+        Jalr -> clearBit (rs1Data + imm) 0+      meRvfi.rvfiTrap ||= isMisaligned npc+      meIR ?= MeJump rd pc4     ExBranch op imm ->       if branch op rs1Data rs2Data         then do@@ -334,16 +333,6 @@       scribe toAluInput1 $ First $ Just in1       scribe toAluInput2 $ First $ Just in2 -    guardZero  -- register x0 always has value 0.-      :: MonadState s m -      => Lens' s (Unsigned 5) -      -> BitVector 32 -      -> m (BitVector 32)-    guardZero rsAddr rsValue = do-      isZero <- uses rsAddr (== 0)-      return $ if isZero-        then 0-        else rsValue     regFwd        :: MonadState s m        => MonadReader r m@@ -354,6 +343,17 @@       -> m (BitVector 32)     regFwd rsAddr rsData meFwd wbFwd =        guardZero rsAddr =<< fwd <$> use rsAddr <*> view rsData <*> use meFwd <*> use wbFwd+      where+        guardZero  -- register x0 always has value 0.+          :: MonadState s m +          => Lens' s (Unsigned 5) +          -> BitVector 32 +          -> m (BitVector 32)+        guardZero addr value = do+          isZero <- uses addr (== 0)+          return $ if isZero+             then 0+             else value  -- | Decode stage decode :: RWS ToPipe FromPipe Pipe ()
src/Lion/Rvfi.hs view
@@ -28,27 +28,103 @@  -- | RISC-V Formal Interface data Rvfi = Rvfi-  { _rvfiValid       :: "valid"        ::: Bool+  { -- | When the core retires an instruction, it asserts the `rvfiValid` signal+    -- and uses the signals described in Rvfi to output the details of the+    -- retired instruction. The signals below are only valid during such a+    -- cycle and can be driven to arbitrary values in a cycle in which `_rvfiValid+    -- is not asserted.+    _rvfiValid       :: "valid"        ::: Bool++    -- | The `rvfiOrder` field must be set to the instruction index. No indices+    -- must be used twice and there must be no gaps. Instructions may be retired+    -- in a reordered fashion, as long as causality is preserved+    -- (register nad memory write operations must be retired before the read+    -- operations that depend on them).   , _rvfiOrder       :: "order"        ::: BitVector 64++    -- | `rvfiInsn` is the instruction word for the retired instruction.+    -- In case of an instruction with fewer than ILEN bits, the upper bits+    -- of this output must all be zero. For compressed instructions the+    -- compressed instruction word must be output on this port.+    -- For fused instructions the complete fused instruciton sequence must+    -- be output   , _rvfiInsn        :: "insn"         ::: BitVector 32++    -- | `rvfiTrap` must be set for an instruction that cannot be decoded+    -- as a legal instruction, such as 0x00000000.   , _rvfiTrap        :: "trap"         ::: Bool++    -- | The signal `rvfiHalt` must be set when the instruction is+    -- the last instruction that the core retires before halting execution.+    -- It should not be set for an instruction that triggers a trap condition+    -- if the CPU reacts to the trap by executing a trap handler. This signal+    -- enable verification of liveness properties.   , _rvfiHalt        :: "halt"         ::: Bool++    -- | `rvfiIntr` must be set for the first instruction that is part of a+    -- trap handler, i.e. an instruction that has a `rvfiPcRData` that+    -- does not match the `rvfiPcWData` of the previous instruction.   , _rvfiIntr        :: "intr"         ::: Bool++    -- | `rvfiMode` must be set to the current privilege level, using the+    -- following encoding: 0=U-Mode, 1=S-Mode, 2=Reserved, 3=M-Mode   , _rvfiMode        :: "mode"         ::: BitVector 2++    -- | `rvfiIxl` must be set to the value of MXL/SXL/UXL in the current+    -- privilege level, using the following encoding: 1=32, 2=64   , _rvfiIxl         :: "ixl"          ::: BitVector 2++    -- | `rvfiRs1Addr` and `rvfiRs2Addr` are the decoded rs1 and rs2+    -- register addresses for the retired instruction. For an instruction+    -- that reads no rs1/rs2 register, this output can have an arbitrary value.+    -- However if this output is nonzero then `rvfiRs1Data` or `rvfiRs2Data` must+    -- carry the value stored in that register in the pre-state.   , _rvfiRs1Addr     :: "rs1_addr"     ::: Unsigned 5   , _rvfiRs2Addr     :: "rs2_addr"     ::: Unsigned 5++    -- | `rvfiRs1Data` and `rvfiRs2Data` are the values of the register+    -- addressed by rs1 and rs2 before execute of this instruction.+    -- This output must be zero when rs1/rs2 is zero.   , _rvfiRs1Data     :: "rs1_rdata"    ::: BitVector 32   , _rvfiRs2Data     :: "rs2_rdata"    ::: BitVector 32++    -- | `rvfiRdAddr` is the decoded rd register address for the retired+    -- instruction. For an instruction that writes no rd register, this output+    -- must always be zero.   , _rvfiRdAddr      :: "rd_addr"      ::: Unsigned 5++    -- | `rvfiRdWData` is the value of the register addressed by rd after+    -- execution of this instruction. This output must be zero when rd+    -- is zero.   , _rvfiRdWData     :: "rd_wdata"     ::: BitVector 32++    -- | This is the program counter (pc) before (`rvfiPcRData`) and after+    -- (`rvfiPcWData`) execution of this instruciton. I.e. this is the+    -- address of the retired instruction and the address of the next+    -- instruction.   , _rvfiPcRData     :: "pc_rdata"     ::: BitVector 32   , _rvfiPcWData     :: "pc_wdata"     ::: BitVector 32++    -- | For memory operations (`rvfiMemRMask` and/or `rvfiMemWMask` are non-zero),+    -- `rvfiMemAddr` holds the accessed memory location.   , _rvfiMemAddr     :: "mem_addr"     ::: BitVector 32++    -- | `rvfiMemRMask` is a bitmask that specifies which bytes in `rvfiMemRData`+    -- contain valid read data from `rvfiMemAddr`.   , _rvfiMemRMask    :: "mem_rmask"    ::: BitVector 4++    -- | `rvfiMemWMask` is a bitmask that specifies which bytes in `rvfiMemWData` +    -- contain valid data this is written to `rvfiMemAddr`.   , _rvfiMemWMask    :: "mem_wmask"    ::: BitVector 4++    -- | `rvfiMemRData` is the pre-state data read from `rvfiMemAddr`.+    -- `rvfiMemRMask` specifies which bytes are valid.   , _rvfiMemRData    :: "mem_rdata"    ::: BitVector 32++    -- | `rvfiMemWData` is the post-state data written to `rvfiMemAddr`.+    -- `rvfiMemWMask` specifies which bytes are valid.   , _rvfiMemWData    :: "mem_wdata"    ::: BitVector 32+   , _rvfiCsrMinstret :: "csr_minstret" ::: RvfiCsr 64   , _rvfiCsrMcycle   :: "csr_mcycle"   ::: RvfiCsr 64   , _rvfiCsrMscratch :: "csr_mscratch" ::: RvfiCsr 32