diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-05-06 11:00:22 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-05-06 11:00:22 -0500 |
commit | 11bce65ecc903e6f11bbbe6cbe05ffd2e259126e (patch) | |
tree | be32cb2e0385d4ff7ab7810bfa7c4e573fc37b6e | |
parent | d8db4d5cfa3977001181714e632d5addd7c0e4ba (diff) |
Attempt at RX, but it doesn't yet work...
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/Top.bs | 14 | ||||
-rw-r--r-- | src/Uart.bs | 100 |
3 files changed, 76 insertions, 40 deletions
@@ -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') @@ -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 : |