aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-05-05 17:20:00 -0500
committerNathan Ringo <nathan@remexre.com>2024-05-05 17:20:00 -0500
commit0874c7f1852145c3ae62f1e28dc10c0c89d78b45 (patch)
tree0717d0293a78510ac62ea7f463da4ef6d54229cb
parent2ec6d7d09e2cd6c08686aae9427b46a217972675 (diff)
Not yet working UART...
-rw-r--r--Makefile39
-rwxr-xr-xclean.sh13
-rw-r--r--flake.lock11
-rw-r--r--flake.nix18
-rw-r--r--src/Top.bs111
-rw-r--r--src/icebreaker.pcf54
6 files changed, 172 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 80b04e5..574b9b7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,19 +1,36 @@
-BSC_COMP_FLAGS = -aggressive-conditions -check-assert -keep-fires
+BSC_COMP_FLAGS = -aggressive-conditions -bdir tmp -check-assert -keep-fires \
+ -p src:$(BSC_CONTRIB)/Libraries/FPGA/Misc:+ -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).exe tmp/$(TOPMODULE).v
+all: tmp/$(TOPMODULE).bin
clean: clean.sh
- @./clean.sh
-.PHONY: all 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; }' \
+ | xargs -0 rm -r
+flash: tmp/$(TOPMODULE).bin
+ sudo iceprog $<
+.PHONY: all clean flash
-tmp/$(TOPMODULE).exe: tmp/$(TOPMODULE).ba
+tmp/%.bin: tmp/%.asc
+ # 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))
+ 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
+tmp/%.bo:
@mkdir -p $(dir $@)
- bsc -e $(TOPMODULE) -o $@ -p $(dir $<) -sim -simdir tmp -u $(BSC_LINK_FLAGS)
-tmp/$(TOPMODULE).ba: src/$(TOPFILE).bs
- @mkdir -p $(dir $@)
- bsc -bdir $(dir $@) -g $(TOPMODULE) -sim -u $(BSC_COMP_FLAGS) $<
-tmp/$(TOPMODULE).v: src/$(TOPFILE).bs
+ bsc -verilog $(BSC_COMP_FLAGS) $<
+
+tmp/depends.mk:
@mkdir -p $(dir $@)
- bsc -bdir tmp -g $(TOPMODULE) -u -verilog -vdir tmp $(BSC_COMP_FLAGS) $<
+ bluetcl -exec makedepend $(BSC_COMP_FLAGS) src/$(TOPFILE).bs > $@
+include tmp/depends.mk
diff --git a/clean.sh b/clean.sh
deleted file mode 100755
index 68769e6..0000000
--- a/clean.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-set -eu
-
-cd "$(git rev-parse --show-toplevel)"
-
-if [ "$(git status --porcelain=v1 --ignored -z | grep -z '^!!' | wc -c)" = 0 ]; then
- exit
-fi
-
-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; }' \
-| xargs -0 rm -r
diff --git a/flake.lock b/flake.lock
index df65460..2ea934c 100644
--- a/flake.lock
+++ b/flake.lock
@@ -19,16 +19,17 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1708702655,
- "narHash": "sha256-qxT5jSLhelfLhQ07+AUxSTm1VnVH+hQxDkQSZ/m/Smo=",
+ "lastModified": 1714933973,
+ "narHash": "sha256-a3cOXb2Hhj/z6N+oCfJJTdpWUx0V8rTqmY96i8N9B0A=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "c5101e457206dd437330d283d6626944e28794b3",
+ "rev": "135fbd12c398100f8071584d2b8c9c7aa2bc5e99",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "type": "indirect"
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "type": "github"
}
},
"root": {
diff --git a/flake.nix b/flake.nix
index e49859b..0dd1743 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,7 +1,16 @@
{
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs";
outputs = { self, flake-utils, nixpkgs }:
flake-utils.lib.eachDefaultSystem (system:
- let pkgs = nixpkgs.legacyPackages.${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=";
+ };
in rec {
devShells.default = pkgs.mkShell {
inputsFrom = builtins.attrValues packages;
@@ -9,9 +18,14 @@
pkgs.bluespec
pkgs.gtkwave
pkgs.icestorm
- pkgs.verilator
+ pkgs.nextpnr
+ pkgs.picocom
pkgs.yosys
];
+ env = {
+ BSC = pkgs.bluespec;
+ BSC_CONTRIB = bsc-contrib;
+ };
};
packages = { };
diff --git a/src/Top.bs b/src/Top.bs
index 6dee830..61bdc86 100644
--- a/src/Top.bs
+++ b/src/Top.bs
@@ -1,53 +1,78 @@
package Top where
-mkTop :: Module Empty
-mkTop =
- module
- deepThought :: DeepThought_IFC <- mkDeepThought
-
- rules
- "rl_ask": when True ==> do
- $display "Asking the Ultimate Question of Life, The Universe and Everything"
- deepThought.whatIsTheAnswer
+import GetPut
+import RS232
- "rl_print_answer": when True ==> do
- x <- deepThought.getAnswer
- $display "Deep Thought says: Hello, World! The answer is %0d." x
- $finish
+interface Top =
+ -- RS232
+ rx :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [RX] #-}
+ tx :: Bit 1 {-# always_ready, result = TX #-}
+ -- Onboard LEDs
+ ledR_N :: Bit 1 {-# always_ready, result = LEDR_N #-}
+ ledG_N :: Bit 1 {-# always_ready, result = LEDG_N #-}
+ -- RGB LED driver
+ ledRed_N :: Bit 1 {-# always_ready, result = LED_RED_N #-}
+ ledGrn_N :: Bit 1 {-# always_ready, result = LED_GRN_N #-}
+ ledBlu_N :: Bit 1 {-# always_ready, result = LED_BLU_N #-}
+ -- LEDs and buttons (PMOD 2)
+ led1 :: Bit 1 {-# always_ready, result = LED1 #-}
+ led2 :: Bit 1 {-# always_ready, result = LED2 #-}
+ led3 :: Bit 1 {-# always_ready, result = LED3 #-}
+ led4 :: Bit 1 {-# always_ready, result = LED4 #-}
+ led5 :: Bit 1 {-# always_ready, result = LED5 #-}
+ btn1 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [BTN1] #-}
+ btn2 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [BTN2] #-}
+ btn3 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [BTN3] #-}
-interface DeepThought_IFC =
- whatIsTheAnswer :: Action
- getAnswer :: ActionValue (Int 32)
+clockFreqHz :: Integer
+clockFreqHz = 12_000_000
-data State_DT = IDLE | THINKING | ANSWER_READY
- deriving (Eq, Bits, FShow)
-
-mkDeepThought :: Module DeepThought_IFC
-mkDeepThought =
+mkTop :: Module Top
+mkTop =
module
- rg_state_dt :: Reg State_DT <- mkReg IDLE
- rg_half_millenia :: Reg (Bit 4) <- mkReg 0
+ let uartBaud :: Integer
+ uartBaud = 115200
+ uartDivider :: Integer
+ uartDivider = clockFreqHz / uartBaud
+ uart :: UART 8 <- mkUART 8 NONE STOP_1 (fromInteger uartDivider)
- let millenia = rg_half_millenia [3:1]
- let half_millenium = rg_half_millenia [0:0]
+ 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
- "rl_think": when (rg_state_dt == THINKING) ==> do
- $write " DeepThought: ... thinking ... (%0d" millenia
- if (half_millenium == 1) then $write ".5" else noAction
- $display " million years)"
-
- if (rg_half_millenia == 15) then
- rg_state_dt := ANSWER_READY
- else
- rg_half_millenia := rg_half_millenia + 1
-
- interface
- whatIsTheAnswer = rg_state_dt := THINKING
- when (rg_state_dt == IDLE)
+ "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
- getAnswer = do
- rg_state_dt := IDLE
- rg_half_millenia := 0
- return 42
- when (rg_state_dt == ANSWER_READY)
+ interface Top
+ -- RS232
+ rx = uart.rs232.sin
+ tx = uart.rs232.sout
+ -- Onboard LEDs
+ ledR_N = 1
+ ledG_N = 1
+ -- 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
+{-# verilog mkTop #-}
+{-# properties mkTop = { RSTN = BTN_N } #-}
diff --git a/src/icebreaker.pcf b/src/icebreaker.pcf
new file mode 100644
index 0000000..1164c98
--- /dev/null
+++ b/src/icebreaker.pcf
@@ -0,0 +1,54 @@
+# 12 MHz clock
+set_io -nowarn CLK 35
+
+# RS232
+set_io -nowarn RX 6
+set_io -nowarn TX 9
+
+# LEDs and Button
+set_io -nowarn BTN_N 10
+set_io -nowarn LEDR_N 11
+set_io -nowarn LEDG_N 37
+
+# RGB LED Driver
+set_io -nowarn LED_RED_N 39
+set_io -nowarn LED_GRN_N 40
+set_io -nowarn LED_BLU_N 41
+
+# SPI Flash
+set_io -nowarn FLASH_SCK 15
+set_io -nowarn FLASH_SSB 16
+set_io -nowarn FLASH_IO0 14
+set_io -nowarn FLASH_IO1 17
+set_io -nowarn FLASH_IO2 12
+set_io -nowarn FLASH_IO3 13
+
+# PMOD 1A
+set_io -nowarn P1A1 4
+set_io -nowarn P1A2 2
+set_io -nowarn P1A3 47
+set_io -nowarn P1A4 45
+set_io -nowarn P1A7 3
+set_io -nowarn P1A8 48
+set_io -nowarn P1A9 46
+set_io -nowarn P1A10 44
+
+# PMOD 1B
+set_io -nowarn P1B1 43
+set_io -nowarn P1B2 38
+set_io -nowarn P1B3 34
+set_io -nowarn P1B4 31
+set_io -nowarn P1B7 42
+set_io -nowarn P1B8 36
+set_io -nowarn P1B9 32
+set_io -nowarn P1B10 28
+
+# LEDs and Buttons (PMOD 2)
+set_io -nowarn LED1 26
+set_io -nowarn LED2 27
+set_io -nowarn LED3 25
+set_io -nowarn LED4 23
+set_io -nowarn LED5 21
+set_io -nowarn BTN1 20
+set_io -nowarn BTN2 19
+set_io -nowarn BTN3 18