From a0121db363737f32bde141a7c0a0e14b25f71954 Mon Sep 17 00:00:00 2001 From: dopamane Date: Sat, 20 Jul 2024 21:05:22 -0700 Subject: [PATCH] Add `memory` wrapper --- lib/Bayeux/Ice40/Spram.hs | 83 +++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/lib/Bayeux/Ice40/Spram.hs b/lib/Bayeux/Ice40/Spram.hs index a74f2d9..3c30c1c 100644 --- a/lib/Bayeux/Ice40/Spram.hs +++ b/lib/Bayeux/Ice40/Spram.hs @@ -1,13 +1,21 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} module Bayeux.Ice40.Spram ( spramC + , Addr14(..) + , Word4(..) , MonadSpram(..) + , memory ) where -import Bayeux.Rtl +import Bayeux.Cell +import Bayeux.Encode +import Bayeux.Rtl hiding (process) import Bayeux.Signal +import Bayeux.Width import Control.Monad.Writer import Data.Array import Data.Finite @@ -43,16 +51,22 @@ spramC name a din maskWrEn wren cs clk sb slp pwrOff dout = Cell ] CellEndStmt +newtype Addr14 = Addr14{ unAddr14 :: Array (Finite 14) Bool } + deriving (Encode, Eq, Read, Show, Width) + +newtype Word4 = Word4{ unWord4 :: Array (Finite 4) Bool } + deriving (Encode, Eq, Read, Show, Width) + class MonadSpram m where - spram :: Sig (Array (Finite 14) Bool) -- ^ address - -> Sig Word16 -- ^ data in - -> Sig (Array (Finite 4) Bool) -- ^ mask write enable - -> Sig Bool -- ^ write enable - -> Sig Bool -- ^ chip select - -> Sig Bool -- ^ stand by - -> Sig Bool -- ^ sleep - -> Sig Bool -- ^ poweroff - -> m (Sig Word16) -- ^ data out + spram :: Sig Addr14 -- ^ address + -> Sig Word16 -- ^ data in + -> Sig Word4 -- ^ mask write enable + -> Sig Bool -- ^ write enable + -> Sig Bool -- ^ chip select + -> Sig Bool -- ^ stand by + -> Sig Bool -- ^ sleep + -> Sig Bool -- ^ poweroff + -> m (Sig Word16) -- ^ data out instance MonadSpram Rtl where spram a din maskWrEn wren cs sb slp pwrOff = do @@ -71,3 +85,48 @@ instance MonadSpram Rtl where (spec pwrOff) dout] return $ Sig dout + +data Req = R Addr14 + | W Addr14 Word16 Word4 + deriving (Eq, Read, Show) + +instance Width Req where + width _ = 35 + +instance Encode Req where + encode = \case + R a -> [B0] <> encode a <> replicate 20 B0 + W a d m -> [B1] <> encode a <> encode d <> encode m + +sliceWrEn :: Sig Req -> Sig Bool +sliceWrEn = slice 34 34 + +sliceAddr :: Sig Req -> Sig Addr14 +sliceAddr = slice 33 20 + +sliceDataIn :: Sig Req -> Sig Word16 +sliceDataIn = slice 19 4 + +sliceMaskWrEn :: Sig Req -> Sig Word4 +sliceMaskWrEn = slice 3 0 + +memory + :: Monad m + => MonadSignal m + => MonadSpram m + => Sig (Maybe Req) + -> m (Sig (Maybe Word16)) +memory reqM = do + let req = sliceValue reqM + wrEn = sliceWrEn req + b16 <- spram + (sliceAddr req) + (sliceDataIn req) + (sliceMaskWrEn req) + wrEn + (sliceValid reqM) + (sig False) + (sig False) + (sig True) + isValid <- process $ const $ logicAnd (sliceValid reqM) =<< logicNot wrEn + return $ Sig $ spec isValid <> spec b16