diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-05-05 22:30:50 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-05-05 22:30:50 -0500 |
commit | f9b73dc7b93bbf60f5b2281a5056c4339e049388 (patch) | |
tree | 5325a2e6ee78bb36179c5b2b4c56da806214e426 /src | |
parent | 0874c7f1852145c3ae62f1e28dc10c0c89d78b45 (diff) |
triyng a uart from scratch... not yet working...
Diffstat (limited to 'src')
-rw-r--r-- | src/Top.bs | 54 | ||||
-rw-r--r-- | src/UART.bs | 101 | ||||
-rw-r--r-- | src/Util.bs | 7 |
3 files changed, 125 insertions, 37 deletions
@@ -1,7 +1,6 @@ package Top where -import GetPut -import RS232 +import UART interface Top = -- RS232 @@ -30,49 +29,30 @@ clockFreqHz = 12_000_000 mkTop :: Module Top mkTop = module - let uartBaud :: Integer - uartBaud = 115200 - uartDivider :: Integer - uartDivider = clockFreqHz / uartBaud - uart :: UART 8 <- mkUART 8 NONE STOP_1 (fromInteger uartDivider) - - clkState :: Reg (Bit 32) <- mkReg 0 - btn1State :: Reg (Bit 1) <- mkReg 0 - btn2State :: Reg (Bit 1) <- mkReg 0 - btn3State :: Reg (Bit 1) <- mkReg 0 - led4State :: Reg (Bit 1) <- mkReg 0 - led5State :: Reg (Bit 1) <- mkReg 0 - - rules - "echo": when (clkState == 0) ==> do - led4State := led4State + 1 - uart.rx.put 0x7e - "increment_clock": when True ==> do - if clkState == fromInteger (clockFreqHz / 10) then do - clkState := 0 - led5State := led5State + 1 - else - clkState := clkState + 1 + bitState :: Reg (Bit 1) <- mkReg 0 + uart <- mkUART (clockFreqHz / 9600) interface Top -- RS232 - rx = uart.rs232.sin - tx = uart.rs232.sout + rx bit = do + bitState := bit + uart.rxPin bit + tx = uart.txPin -- Onboard LEDs - ledR_N = 1 - ledG_N = 1 + ledR_N = uart.txPin + ledG_N = bitState -- RGB LED driver ledRed_N = 1 ledGrn_N = 1 ledBlu_N = 1 -- LEDs and buttons (PMOD 2) - led1 = btn1State - led2 = btn2State - led3 = btn3State - led4 = led4State - led5 = led5State - btn1 x = btn1State := x - btn2 x = btn2State := x - btn3 x = btn3State := x + led1 = 0 + led2 = 0 + led3 = 0 + led4 = 0 + led5 = 0 + btn1 _ = return () + btn2 _ = return () + btn3 _ = return () {-# verilog mkTop #-} {-# properties mkTop = { RSTN = BTN_N } #-} diff --git a/src/UART.bs b/src/UART.bs new file mode 100644 index 0000000..f837949 --- /dev/null +++ b/src/UART.bs @@ -0,0 +1,101 @@ +package UART where + +import GetPut +import Util + +interface Clock = + clk :: Bool + +defaultClock :: Clock +defaultClock = + interface Clock + clk = True + +mkDivider :: Integer -> Clock -> Module Clock +mkDivider divisor clockIn = + module + count <- mkReg 0 + + rules + "increment_divider": when clockIn.clk ==> do + if count == fromInteger divisor then do + count := 0 + else + count := count + 1 + + interface Clock + clk = count == 0 + +interface ShiftRegister = + get :: Get (Bit 1) + put :: Put (Bit 1) + +mkShiftRegister :: Module ShiftRegister +mkShiftRegister = + module + reg :: Reg (Bit 8) <- mkReg 0 + + interface ShiftRegister + get = interface Get + get = return 0 + put = interface Put + put bit = do + return () + +-- An 8n1 UART. +interface UART = + -- The RX pin. + rxPin :: Bit 1 -> Action + -- The TX pin. + txPin :: Bit 1 + + -- Reads a byte from the UART. + rxByte :: Get (Bit 8) + -- Writes a byte to the UART. + txByte :: Put (Bit 8) + +mkUART :: Integer -> Module UART +mkUART baudDivisor = + module + baud <- mkDivider baudDivisor defaultClock + + count :: Reg (Bit 4) <- mkReg 0 + rules + "increment_count": when baud.clk ==> do + count := count + 1 + + let start = 0 + d0 = 1 + d1 = 0 + d2 = 0 + d3 = 0 + d4 = 1 + d5 = 0 + d6 = 0 + d7 = 0 + stop = 1 + + interface UART + rxPin _bit = when_ baud.clk $ do + return () -- TODO + txPin = case count of + 0 -> start + 1 -> d0 + 2 -> d1 + 3 -> d2 + 4 -> d3 + 5 -> d4 + 6 -> d5 + 7 -> d6 + 8 -> d7 + 9 -> stop + _ -> 1 + + rxByte = interface Get + get = return 0 when False + txByte = interface Put + put _ = do + -- TODO + return () + +-- vim: set ft=haskell : diff --git a/src/Util.bs b/src/Util.bs new file mode 100644 index 0000000..ab3074c --- /dev/null +++ b/src/Util.bs @@ -0,0 +1,7 @@ +package Util where + +when_ :: (Monad m) => Bool -> m () -> m () +when_ True x = x +when_ False _ = return () + +-- vim: set ft=haskell : |