aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-05-06 11:00:22 -0500
committerNathan Ringo <nathan@remexre.com>2024-05-06 11:00:22 -0500
commit11bce65ecc903e6f11bbbe6cbe05ffd2e259126e (patch)
treebe32cb2e0385d4ff7ab7810bfa7c4e573fc37b6e
parentd8db4d5cfa3977001181714e632d5addd7c0e4ba (diff)
Attempt at RX, but it doesn't yet work...
-rw-r--r--Makefile2
-rw-r--r--src/Top.bs14
-rw-r--r--src/Uart.bs100
3 files changed, 76 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 269cf32..bfb3088 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
BSC_COMP_FLAGS = -aggressive-conditions -bdir tmp -check-assert -keep-fires \
-p src:+ -vdir tmp
BSC_LINK_FLAGS = -keep-fires
-BSC_SOURCES = FIFO1.v
+BSC_SOURCES = FIFO1.v FIFO10.v SizedFIFO.v
TOPFILE = Top
TOPMODULE = mkTop
SRCS = $(shell find src -name '*.bs')
diff --git a/src/Top.bs b/src/Top.bs
index d5cb7e3..9fb3b21 100644
--- a/src/Top.bs
+++ b/src/Top.bs
@@ -1,5 +1,6 @@
package Top where
+import FIFOF
import GetPut
import Uart
@@ -33,12 +34,21 @@ mkTop =
bitState :: Reg (Bit 1) <- mkReg 0
uart <- mkUart (clockFreqHz / 9600)
- lastByte :: Reg (Bit 8) <- mkReg 0x21
+ {-
+ lastByte :: Reg (Bit 8) <- mkReg 0x21
tick <- mkDivider (clockFreqHz)
rules
"tick": when tick.clk ==> do
uart.send.put lastByte
+ "recv": when tick.clk ==> do
+ byte <- uart.recv.get
+ lastByte := byte
+ -}
+ rules
+ "echo": when True ==> do
+ byte <- uart.recv.get
+ uart.send.put byte
interface Top
-- RS232
@@ -48,7 +58,7 @@ mkTop =
tx = uart.txPin
-- Onboard LEDs
ledR_N = bitState
- ledG_N = uart.txPin
+ ledG_N = uart.bit
-- RGB LED driver
ledRed_N = 1
ledGrn_N = 1
diff --git a/src/Uart.bs b/src/Uart.bs
index 0a3e82b..d6918f9 100644
--- a/src/Uart.bs
+++ b/src/Uart.bs
@@ -22,29 +22,6 @@ mkDivider divisor =
interface Clock
clk = count == 0
--- | A shift register.
-interface ShiftRegister item numItems =
- -- | Shifts an item into the shift register.
- put :: Put item
- -- | Shifts an item out of the shift register.
- get :: Get item
- -- | The number of items currently in the shift register.
- size :: Bit (TLog numItems)
-
--- | Creates a shift register.
-mkShiftRegister :: (Bits item itemSize) => Module (ShiftRegister item numItems)
-mkShiftRegister =
- module
- size :: Reg (Bit (TLog numItems)) <- mkReg 0
- buffer :: Reg (Bit (TMul itemSize numItems)) <- mkReg 0
-
- interface ShiftRegister
- put = interface Put
- put _ = return ()
- get = interface Get
- get = return (unpack 0) when False
- size = size
-
-- | The state of the TX side of the UART.
data TxState
= -- | The UART is not currently sending anything. May transition to
@@ -65,16 +42,16 @@ data TxState
interface TxUart =
-- | The TX pin.
pin :: Bit 1
- -- Writes a byte to the UART.
+ -- | Writes a byte to the UART's transmit buffer.
send :: Put (Bit 8)
mkTxUart :: Clock -> Integer -> Module TxUart
mkTxUart baudClock bufferSize =
module
fifo :: FIFOF (Bit 8) <- mkSizedFIFOF bufferSize
- state <- mkReg Idle
+ state :: Reg TxState <- mkReg Idle
rules
- "uart_tx_send": when baudClock.clk ==> do
+ "uart_tx_update_state": when baudClock.clk ==> do
case state of
Idle -> do
b <- (toGet fifo).get
@@ -95,31 +72,80 @@ mkTxUart baudClock bufferSize =
Stop -> 1
send = toPut fifo
--- An 8n1 UART.
+-- | The state of the RX side of the UART.
+data RxState
+ = -- | The UART is not currently receiving anything. May transition to
+ -- 'Data 0 0' when the start bit is received.
+ Idle
+ | -- | In the 'Data _ n' state, the UART has received the start bit and 'n'
+ -- data bits, and is about to receive more data bits. 'Data _ n'
+ -- transitions to 'Data _ (n + 1)' by receiving a data bit. 'Data b 7'
+ -- transitions to 'Idle' by receving the last data bit.
+ Data (Bit 8) (Bit 3)
+ deriving (Bits)
+
+-- | The RX side of the UART.
+interface RxUart =
+ -- | The RX pin.
+ pin :: Bit 1 -> Action
+ -- | Reads a byte from the UART's receive buffer.
+ recv :: Get (Bit 8)
+
+ bit :: Bit 1
+
+mkRxUart :: Clock -> Integer -> Module RxUart
+mkRxUart baudClock bufferSize =
+ module
+ fifo :: FIFOF (Bit 8) <- mkSizedFIFOF bufferSize
+ state :: Reg RxState <- mkReg Idle
+ debug :: Reg (Bit 1) <- mkReg 1
+ interface RxUart
+ pin bit = when_ baudClock.clk $ do
+ nextState :: RxState <- case state of
+ Idle -> do
+ debug := bit
+ if bit == 0 then
+ return (Data 0 0)
+ else
+ return Idle
+ Data hi n -> do
+ debug := bit
+ let b = hi[7:1] ++ bit -- <-- weird if i flip
+ if n == 7 then do
+ when_ fifo.notFull $ do
+ fifo.enq b
+ return Idle
+ else
+ return (Data b (n + 1))
+ state := nextState
+ recv = toGet fifo
+ bit = debug
+
+-- | An 8n1 UART.
interface Uart =
- -- The RX pin.
+ -- | The RX pin.
rxPin :: Bit 1 -> Action
- -- The TX pin.
+ -- | The TX pin.
txPin :: Bit 1
- -- Reads a byte from the UART.
+ -- | Reads a byte from the UART's receive buffer.
recv :: Get (Bit 8)
- -- Writes a byte to the UART.
+ -- | Writes a byte to the UART's transmit buffer.
send :: Put (Bit 8)
+ bit :: Bit 1
mkUart :: Integer -> Module Uart
mkUart baudDivisor =
module
baudClock <- mkDivider baudDivisor
- tx <- mkTxUart baudClock 1
+ rx <- mkRxUart baudClock 8
+ tx <- mkTxUart baudClock 8
interface Uart
- rxPin _bit = when_ baudClock.clk $ do
- return () -- TODO
+ rxPin = rx.pin
txPin = tx.pin
-
- recv = interface Get
- get = return 0 when False
+ recv = rx.recv
send = tx.send
+ bit = rx.bit
-- vim: set ft=haskell :