diff options
Diffstat (limited to 'fpga/src/Top.bs')
-rw-r--r-- | fpga/src/Top.bs | 225 |
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 } #-} |