aboutsummaryrefslogtreecommitdiff
path: root/fpga/src/Top.bs
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/src/Top.bs')
-rw-r--r--fpga/src/Top.bs225
1 files changed, 141 insertions, 84 deletions
diff --git a/fpga/src/Top.bs b/fpga/src/Top.bs
index 29558d4..df79387 100644
--- a/fpga/src/Top.bs
+++ b/fpga/src/Top.bs
@@ -4,108 +4,165 @@ package Top where
import Connectable
import CPU
import GetPut
+import Numini
import TriState
import Uart
-- | The interface to the iCEBreaker.
interface Top =
-- RS232
- rx :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [RX] #-}
- tx :: Bit 1 {-# always_ready, result = TX #-}
+ usb_uart_rx :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [RX] #-}
+ usb_uart_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 #-}
+ led_r_n :: Bit 1 {-# always_ready, result = LEDR_N #-}
+ led_g_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 #-}
+ rgb_r_n :: Bit 1 {-# always_ready, result = LED_RED_N #-}
+ rgb_g_n :: Bit 1 {-# always_ready, result = LED_GRN_N #-}
+ rgb_b_n :: Bit 1 {-# always_ready, result = LED_BLU_N #-}
-- HyperBus 1 (PMOD 1A)
- hyperBus_CS2_N :: Bit 1 {-# always_ready, result = P1A1 #-}
- hyperBus_CS0_N :: Bit 1 {-# always_ready, result = P1A2 #-}
- hyperBus_CK :: Bit 1 {-# always_ready, result = P1A3 #-}
- hyperBus_CK_N :: Bit 1 {-# always_ready, result = P1A4 #-}
- hyperBus_CS3_N :: Bit 1 {-# always_ready, result = P1A7 #-}
- hyperBus_CS1_N :: Bit 1 {-# always_ready, result = P1A8 #-}
- hyperBus_RESET_N :: Bit 1 {-# always_ready, result = P1A9 #-}
- hyperBus_RWDS :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P1A10] #-}
+ hyperbus_cs2_n :: Bit 1 {-# always_ready, result = P1A1 #-}
+ hyperbus_cs0_n :: Bit 1 {-# always_ready, result = P1A2 #-}
+ hyperbus_ck :: Bit 1 {-# always_ready, result = P1A3 #-}
+ hyperbus_ck_n :: Bit 1 {-# always_ready, result = P1A4 #-}
+ hyperbus_cs3_n :: Bit 1 {-# always_ready, result = P1A7 #-}
+ hyperbus_cs1_n :: Bit 1 {-# always_ready, result = P1A8 #-}
+ hyperbus_reset_n :: Bit 1 {-# always_ready, result = P1A9 #-}
+ hyperbus_rwds :: Inout (Bit 1) {-# prefix = "P1A10" #-}
-- HyperBus 2 (PMOD 1B)
- hyperBus_DQ0 :: Inout (Bit 1) {-# prefix = "P1B1" #-}
- hyperBus_DQ1 :: Inout (Bit 1) {-# prefix = "P1B2" #-}
- hyperBus_DQ2 :: Inout (Bit 1) {-# prefix = "P1B3" #-}
- hyperBus_DQ3 :: Inout (Bit 1) {-# prefix = "P1B4" #-}
- hyperBus_DQ7 :: Inout (Bit 1) {-# prefix = "P1B7" #-}
- hyperBus_DQ6 :: Inout (Bit 1) {-# prefix = "P1B8" #-}
- hyperBus_DQ5 :: Inout (Bit 1) {-# prefix = "P1B9" #-}
- hyperBus_DQ4 :: Inout (Bit 1) {-# prefix = "P1B10" #-}
- -- LEDs and buttons (PMOD 2)
- led1 :: Bit 1 {-# always_ready, result = P2_7 #-}
- led2 :: Bit 1 {-# always_ready, result = P2_1 #-}
- led3 :: Bit 1 {-# always_ready, result = P2_2 #-}
- led4 :: Bit 1 {-# always_ready, result = P2_8 #-}
- led5 :: Bit 1 {-# always_ready, result = P2_3 #-}
- btn1 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_9] #-}
- btn2 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_4] #-}
- btn3 :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_10] #-}
+ hyperbus_dq0 :: Inout (Bit 1) {-# prefix = "P1B1" #-}
+ hyperbus_dq1 :: Inout (Bit 1) {-# prefix = "P1B2" #-}
+ hyperbus_dq2 :: Inout (Bit 1) {-# prefix = "P1B3" #-}
+ hyperbus_dq3 :: Inout (Bit 1) {-# prefix = "P1B4" #-}
+ hyperbus_dq7 :: Inout (Bit 1) {-# prefix = "P1B7" #-}
+ hyperbus_dq6 :: Inout (Bit 1) {-# prefix = "P1B8" #-}
+ hyperbus_dq5 :: Inout (Bit 1) {-# prefix = "P1B9" #-}
+ hyperbus_dq4 :: Inout (Bit 1) {-# prefix = "P1B10" #-}
+ -- Serial buses (PMOD 2)
+ ch559_uart_rx :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_1] #-}
+ ch559_uart_tx :: Bit 1 {-# always_ready, result = P2_2 #-}
+ inkplate_uart_rx :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_3] #-}
+ inkplate_uart_tx :: Bit 1 {-# always_ready, result = P2_4 #-}
+ i2c_scl :: Bit 1 {-# always_ready, result = P2_7 #-}
+ i2c_sda :: Inout (Bit 1) {-# prefix = "P2_8" #-}
+ todo_btn :: Bit 1 -> Action {-# always_enabled, always_ready, prefix = "", arg_names = [P2_9] #-}
+ todo_led :: Bit 1 {-# always_ready, result = P2_10 #-}
clockFreqHz :: Integer
clockFreqHz = 12_000_000
mkTop :: Module Top
-mkTop =
- module
- cpu <- mkCPU
+mkTop = module
+ ch559_uart_rx <- mkWire
+ inkplate_uart_rx <- mkWire
+ usb_uart_rx <- mkWire
- uart <- mkUart (clockFreqHz / 9600)
- mkConnection cpu.uart_tx uart.send
- mkConnection cpu.uart_rx uart.recv
+ -- Make tristates for the HyperBus inouts.
+ hyperbus_rwds_enable :: Reg Bool <- mkReg False
+ hyperbus_rwds_out :: Reg (Bit 1) <- mkReg 0
+ hyperbus_dq_enable :: Reg Bool <- mkReg False
+ hyperbus_dq_out :: Reg (Bit 8) <- mkReg 0
+ hyperbus_rwds <- mkTriState hyperbus_rwds_enable hyperbus_rwds_out
+ hyperbus_dq0 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[0:0]
+ hyperbus_dq1 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[1:1]
+ hyperbus_dq2 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[2:2]
+ hyperbus_dq3 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[3:3]
+ hyperbus_dq4 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[4:4]
+ hyperbus_dq5 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[5:5]
+ hyperbus_dq6 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[6:6]
+ hyperbus_dq7 <- mkTriState hyperbus_dq_enable hyperbus_dq_out[7:7]
- hyperBus_data0 <- mkTriState True 1
- hyperBus_data1 <- mkTriState True 1
- hyperBus_data2 <- mkTriState True 1
- hyperBus_data3 <- mkTriState True 1
- hyperBus_data4 <- mkTriState True 1
- hyperBus_data5 <- mkTriState True 1
- hyperBus_data6 <- mkTriState True 1
- hyperBus_data7 <- mkTriState True 1
+ -- Make a tristate for the I2C inout.
+ i2c_sda_enable <- mkReg False
+ i2c_sda_out <- mkReg 0
+ i2c_sda <- mkTriState i2c_sda_enable i2c_sda_out
- interface Top
- -- RS232
- rx = uart.rxPin
- tx = uart.txPin
- -- Onboard LEDs
- ledR_N = uart.txPin
- ledG_N = 1
- -- RGB LED driver
- ledRed_N = 1
- ledGrn_N = 1
- ledBlu_N = 1
- -- HyperBus 1 (PMOD 1A)
- hyperBus_CS2_N = 1
- hyperBus_CS0_N = 1
- hyperBus_CK = 0
- hyperBus_CK_N = 1
- hyperBus_CS3_N = 1
- hyperBus_CS1_N = 1
- hyperBus_RESET_N = 1
- hyperBus_RWDS _ = noAction
- -- HyperBus 2 (PMOD 1B)
- hyperBus_DQ0 = hyperBus_data0.io
- hyperBus_DQ1 = hyperBus_data1.io
- hyperBus_DQ2 = hyperBus_data2.io
- hyperBus_DQ3 = hyperBus_data3.io
- hyperBus_DQ4 = hyperBus_data4.io
- hyperBus_DQ5 = hyperBus_data5.io
- hyperBus_DQ6 = hyperBus_data6.io
- hyperBus_DQ7 = hyperBus_data7.io
- -- LEDs and buttons (PMOD 2)
- led1 = 0
- led2 = 0
- led3 = 0
- led4 = 0
- led5 = 0
- btn1 _ = noAction
- btn2 _ = noAction
- btn3 _ = noAction
+ -- Make wires for all the inout inputs.
+ hyperbus_rwds_in :: Wire (Bit 1) <- mkWire
+ hyperbus_dq_in :: Wire (Bit 8) <- mkWire
+ i2c_sda_in :: Wire (Bit 1) <- mkWire
+
+ numini <- mkNumini ch559_uart_rx inkplate_uart_rx usb_uart_rx
+ hyperbus_rwds_in hyperbus_dq_in i2c_sda_in
+
+ -- Wire up the tristates.
+ rules
+ "update_hyperbus_rwds_out": when True ==> do
+ case numini.hyperbus_rwds_out of
+ Just bits -> do
+ hyperbus_rwds_enable := True
+ hyperbus_rwds_out := bits
+ Nothing -> do
+ hyperbus_rwds_enable := False
+ hyperbus_rwds_out := 0
+ "update_hyperbus_rwds_in": when True ==> do
+ hyperbus_rwds_in := hyperbus_rwds._read
+ "update_hyperbus_dq_out": when True ==> do
+ case numini.hyperbus_dq_out of
+ Just bits -> do
+ hyperbus_dq_enable := True
+ hyperbus_dq_out := bits
+ Nothing -> do
+ hyperbus_dq_enable := False
+ hyperbus_dq_out := 0
+ "update_hyperbus_dq_in": when True ==> do
+ hyperbus_dq_in := hyperbus_dq7._read
+ ++ hyperbus_dq6._read
+ ++ hyperbus_dq5._read
+ ++ hyperbus_dq4._read
+ ++ hyperbus_dq3._read
+ ++ hyperbus_dq2._read
+ ++ hyperbus_dq1._read
+ ++ hyperbus_dq0._read
+ "update_i2c_sda_out": when True ==> do
+ case numini.i2c_sda_out of
+ Just bits -> do
+ i2c_sda_enable := True
+ i2c_sda_out := bits
+ Nothing -> do
+ i2c_sda_enable := False
+ i2c_sda_out := 0
+ "update_i2c_sda_in": when True ==> do
+ i2c_sda_in := i2c_sda._read
+
+ interface Top
+ -- RS232
+ usb_uart_rx bit = usb_uart_rx := bit
+ usb_uart_tx = numini.usb_uart_tx
+ -- Onboard LEDs
+ led_r_n = numini.led_r_n
+ led_g_n = numini.led_g_n
+ -- RGB LED driver
+ rgb_r_n = numini.rgb_r_n
+ rgb_g_n = numini.rgb_g_n
+ rgb_b_n = numini.rgb_b_n
+ -- HyperBus 1 (PMOD 1A)
+ hyperbus_cs2_n = numini.hyperbus_cs2_n
+ hyperbus_cs0_n = numini.hyperbus_cs0_n
+ hyperbus_ck = numini.hyperbus_ck
+ hyperbus_ck_n = numini.hyperbus_ck_n
+ hyperbus_cs3_n = numini.hyperbus_cs3_n
+ hyperbus_cs1_n = numini.hyperbus_cs1_n
+ hyperbus_reset_n = numini.hyperbus_reset_n
+ hyperbus_rwds = hyperbus_rwds.io
+ -- HyperBus 2 (PMOD 1B)
+ hyperbus_dq0 = hyperbus_dq0.io
+ hyperbus_dq1 = hyperbus_dq1.io
+ hyperbus_dq2 = hyperbus_dq2.io
+ hyperbus_dq3 = hyperbus_dq3.io
+ hyperbus_dq4 = hyperbus_dq4.io
+ hyperbus_dq5 = hyperbus_dq5.io
+ hyperbus_dq6 = hyperbus_dq6.io
+ hyperbus_dq7 = hyperbus_dq7.io
+ -- LEDs and buttons (PMOD 2)
+ ch559_uart_rx bit = ch559_uart_rx := bit
+ ch559_uart_tx = numini.ch559_uart_tx
+ inkplate_uart_rx bit = inkplate_uart_rx := bit
+ inkplate_uart_tx = numini.inkplate_uart_tx
+ i2c_scl = numini.i2c_scl
+ i2c_sda = i2c_sda.io
+ todo_btn _ = noAction
+ todo_led = 0
{-# verilog mkTop #-}
{-# properties mkTop = { RSTN = BTN_N } #-}