need to start re-thinking structure of uart etc

This commit is contained in:
Yehowshua Immanuel 2025-04-18 19:42:03 -04:00
parent d03cceb283
commit 44324eb803
5 changed files with 4 additions and 4 deletions

46
bs/Uart/ClkDivider.bs Normal file
View file

@ -0,0 +1,46 @@
package ClkDivider(
mkClkDivider,
MkClkDivType,
ClkDivider(..)
) where
interface (ClkDivider :: # -> *) hi =
{
reset :: Action
;isAdvancing :: Bool
;isHalfCycle :: Bool
}
type MkClkDivType maxCycles = (UInt (TLog (TAdd 1 maxCycles)))
mkClkDivider :: Handle -> Module (ClkDivider hi)
mkClkDivider fileHandle = do
counter <- mkReg(0 :: MkClkDivType hi)
let hi_value :: (MkClkDivType hi) = (fromInteger $ valueOf hi)
let half_hi_value :: (MkClkDivType hi) = (fromInteger $ valueOf (TDiv hi 2))
let val :: Real = (fromInteger $ valueOf hi)
let msg = "Clock Div Period : " + (realToString val) + "\n"
hPutStr fileHandle msg
hPutStr fileHandle genModuleName
addRules $
rules
{-# ASSERT fire when enabled #-}
{-# ASSERT no implicit conditions #-}
"tick" : when True ==> action
$display (counter)
counter := if (counter == hi_value)
then 0
else counter + 1
return $
interface ClkDivider
reset :: Action
reset = do
counter := 0
isAdvancing :: Bool
isAdvancing = (counter == hi_value)
isHalfCycle = (counter == half_hi_value)

53
bs/Uart/Deserializer.bs Normal file
View file

@ -0,0 +1,53 @@
package Deserializer(
mkDeserialize,
IDeserializer(..),
State(..))
where
import ClkDivider
import State
interface (IDeserializer :: # -> # -> *) clkFreq baudRate =
get :: Bit 8
putBitIn :: (Bit 1) -> Action {-# always_enabled, always_ready #-}
mkDeserialize :: Handle -> Module (IDeserializer clkFreq baudRate)
mkDeserialize fileHandle = do
ftdiRxIn :: Wire(Bit 1) <- mkBypassWire
shiftReg :: Reg(Bit 8) <- mkReg(0)
ftdiState <- mkReg(IDLE)
clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle
addRules $
rules
{-# ASSERT fire when enabled #-}
"IDLE" : when (ftdiState == IDLE), (ftdiRxIn == 0) ==>
do
clkDivider.reset
ftdiState := ftdiState' ftdiState
{-# ASSERT fire when enabled #-}
"NOT IDLE" : when (ftdiState /= IDLE), (clkDivider.isAdvancing) ==>
do
ftdiState := ftdiState' ftdiState
{-# ASSERT fire when enabled #-}
"SAMPLING" : when
DATA(n) <- ftdiState,
n >= 0,
n <= 7,
let sampleTrigger = clkDivider.isHalfCycle
in sampleTrigger
==>
do
shiftReg := ftdiRxIn ++ shiftReg[7:1]
return $
interface IDeserializer
{get = shiftReg when (ftdiState == STOP), (clkDivider.isAdvancing)
;putBitIn bit =
ftdiRxIn := bit
}

51
bs/Uart/Serializer.bs Normal file
View file

@ -0,0 +1,51 @@
package Serializer(
mkSerialize,
ISerializer(..),
State(..))
where
import ClkDivider
import State
serialize :: State -> Bit 8 -> Bit 1
serialize ftdiState dataReg =
case ftdiState of
START -> 1'b0
(DATA n) -> dataReg[n:n]
_ -> 1'b1
interface (ISerializer :: # -> # -> *) clkFreq baudRate =
putBit8 :: (Bit 8) -> Action
bitLineOut :: Bit 1
mkSerialize :: Handle -> Module (ISerializer clkFreq baudRate)
mkSerialize fileHandle = do
ftdiTxOut :: Wire(Bit 1) <- mkBypassWire
dataReg :: Reg(Bit 8) <- mkReg(0)
ftdiState <- mkReg(IDLE)
clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle
addRules $
rules
{-# ASSERT fire when enabled #-}
"ADVANCE UART STATE WHEN NOT IDLE" : when
(ftdiState /= IDLE),
(clkDivider.isAdvancing) ==>
do
ftdiState := ftdiState' ftdiState
{-# ASSERT fire when enabled #-}
"BIT LINE" : when True ==>
do
ftdiTxOut := serialize ftdiState dataReg
return $
interface ISerializer
putBit8 bit8Val =
do
clkDivider.reset
dataReg := bit8Val
ftdiState := ftdiState' ftdiState
when (ftdiState == IDLE)
bitLineOut = ftdiTxOut

20
bs/Uart/State.bs Normal file
View file

@ -0,0 +1,20 @@
package State(
State(..),
ftdiState') where
data State = IDLE
| START
| DATA (UInt (TLog 8))
| PARITY
| STOP
deriving (Bits, Eq, FShow)
ftdiState' :: State -> State
ftdiState' state =
case state of
IDLE -> START
START -> DATA(0)
DATA(7) -> PARITY
DATA(n) -> DATA(n+1)
PARITY -> STOP
STOP -> IDLE