diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | flake.nix | 14 | ||||
-rw-r--r-- | src/Top.bs | 54 | ||||
-rw-r--r-- | src/UART.bs | 101 | ||||
-rw-r--r-- | src/Util.bs | 7 |
5 files changed, 130 insertions, 55 deletions
@@ -1,13 +1,12 @@ BSC_COMP_FLAGS = -aggressive-conditions -bdir tmp -check-assert -keep-fires \ - -p src:$(BSC_CONTRIB)/Libraries/FPGA/Misc:+ -vdir tmp + -p src:+ -vdir tmp BSC_LINK_FLAGS = -keep-fires -BSC_SOURCES = Counter.v SizedFIFO.v TOPFILE = Top TOPMODULE = mkTop SRCS = $(shell find src -name '*.bs') all: tmp/$(TOPMODULE).bin -clean: clean.sh +clean: @git status --porcelain=v1 --ignored -z \ | grep -z '^!!' \ | xargs -0 awk 'BEGIN { for(i = 1; i < ARGC; i++) printf "%s%c", substr(ARGV[i], 4), 0; }' \ @@ -17,12 +16,12 @@ flash: tmp/$(TOPMODULE).bin .PHONY: all clean flash tmp/%.bin: tmp/%.asc - # icetime -d up5k -c 12 $< + icetime -d up5k -c 12 $< icepack $< $@ tmp/%.asc: tmp/%.json src/icebreaker.pcf nextpnr-ice40 -ql tmp/$*.nplog --up5k --package sg48 --freq 12 \ --asc $@ --pcf src/icebreaker.pcf --json $< -tmp/$(TOPMODULE).json: tmp/$(TOPMODULE).v $(addprefix $(BSC)/lib/Verilog/,$(BSC_SOURCES)) +tmp/$(TOPMODULE).json: tmp/$(TOPMODULE).v yosys -ql tmp/$(TOPMODULE).yslog -p 'synth_ice40 -top mkTop -json $@' $^ tmp/$(TOPMODULE).v: tmp/$(TOPFILE).bo bsc -g $(TOPMODULE) -verilog $(BSC_COMP_FLAGS) src/$(TOPFILE).bs @@ -2,15 +2,7 @@ inputs.nixpkgs.url = "github:NixOS/nixpkgs"; outputs = { self, flake-utils, nixpkgs }: flake-utils.lib.eachDefaultSystem (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - bsc-contrib = pkgs.fetchFromGitHub { - name = "bsc-contrib-src"; - owner = "B-Lang-org"; - repo = "bsc-contrib"; - rev = "fc26b91c8add9660204c4311dcc60d223ed23ea5"; - hash = "sha256-7H+R7QwcyskrXGO51zZuuyIwZZROc25gJy9nqg/I6lM="; - }; + let pkgs = nixpkgs.legacyPackages.${system}; in rec { devShells.default = pkgs.mkShell { inputsFrom = builtins.attrValues packages; @@ -22,10 +14,6 @@ pkgs.picocom pkgs.yosys ]; - env = { - BSC = pkgs.bluespec; - BSC_CONTRIB = bsc-contrib; - }; }; packages = { }; @@ -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 : |