Updates to Freedom SoCs
[freedom-sifive.git] / src / main / scala / everywhere / e300artydevkit / FPGAChip.scala
1 // See LICENSE for license details.
2 package sifive.freedom.everywhere.e300artydevkit
3
4 import Chisel._
5 import chisel3.core.{attach}
6 import chisel3.experimental.{withClockAndReset}
7
8 import freechips.rocketchip.config._
9 import freechips.rocketchip.diplomacy.{LazyModule}
10
11 import sifive.blocks.devices.gpio._
12 import sifive.blocks.devices.spi._
13
14 import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell}
15 import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
16
17 //-------------------------------------------------------------------------
18 // E300ArtyDevKitFPGAChip
19 //-------------------------------------------------------------------------
20
21 class E300ArtyDevKitFPGAChip(implicit override val p: Parameters) extends ArtyShell {
22
23 //-----------------------------------------------------------------------
24 // Clock divider
25 //-----------------------------------------------------------------------
26 val slow_clock = Wire(Bool())
27
28 // Divide clock by 256, used to generate 32.768 kHz clock for AON block
29 withClockAndReset(clock_8MHz, ~mmcm_locked) {
30 val clockToggleReg = RegInit(false.B)
31 val (_, slowTick) = Counter(true.B, 256)
32 when (slowTick) {clockToggleReg := ~clockToggleReg}
33 slow_clock := clockToggleReg
34 }
35
36 //-----------------------------------------------------------------------
37 // DUT
38 //-----------------------------------------------------------------------
39
40 withClockAndReset(clock_32MHz, ck_rst) {
41 val dut = Module(new E300ArtyDevKitPlatform)
42
43 //---------------------------------------------------------------------
44 // SPI flash IOBUFs
45 //---------------------------------------------------------------------
46
47 IOBUF(qspi_sck, dut.io.pins.qspi.sck)
48 IOBUF(qspi_cs, dut.io.pins.qspi.cs(0))
49
50 IOBUF(qspi_dq(0), dut.io.pins.qspi.dq(0))
51 IOBUF(qspi_dq(1), dut.io.pins.qspi.dq(1))
52 IOBUF(qspi_dq(2), dut.io.pins.qspi.dq(2))
53 IOBUF(qspi_dq(3), dut.io.pins.qspi.dq(3))
54
55 //---------------------------------------------------------------------
56 // JTAG IOBUFs
57 //---------------------------------------------------------------------
58
59 dut.io.pins.jtag.TCK.i.ival := IBUFG(IOBUF(jd_2).asClock).asUInt
60
61 IOBUF(jd_5, dut.io.pins.jtag.TMS)
62 PULLUP(jd_5)
63
64 IOBUF(jd_4, dut.io.pins.jtag.TDI)
65 PULLUP(jd_4)
66
67 IOBUF(jd_0, dut.io.pins.jtag.TDO)
68
69 // mimic putting a pullup on this line (part of reset vote)
70 SRST_n := IOBUF(jd_6)
71 PULLUP(jd_6)
72
73 // jtag reset
74 val jtag_power_on_reset = PowerOnResetFPGAOnly(clock_32MHz)
75 dut.io.jtag_reset := jtag_power_on_reset
76
77 // debug reset
78 dut_ndreset := dut.io.ndreset
79
80 //---------------------------------------------------------------------
81 // Assignment to package pins
82 //---------------------------------------------------------------------
83 // Pins IO0-IO13
84 //
85 // FTDI UART TX/RX are not connected to ck_io[0,1]
86 // the way they are on Arduino boards. We copy outgoing
87 // data to both places, switch 3 (sw[3]) determines whether
88 // input to UART comes from FTDI chip or gpio_16 (shield pin PD0)
89
90 val iobuf_ck0 = Module(new IOBUF())
91 iobuf_ck0.io.I := dut.io.pins.gpio.pins(16).o.oval
92 iobuf_ck0.io.T := ~dut.io.pins.gpio.pins(16).o.oe
93 attach(iobuf_ck0.io.IO, ck_io(0)) // UART0 RX
94
95 val iobuf_uart_txd = Module(new IOBUF())
96 iobuf_uart_txd.io.I := dut.io.pins.gpio.pins(16).o.oval
97 iobuf_uart_txd.io.T := ~dut.io.pins.gpio.pins(16).o.oe
98 attach(iobuf_uart_txd.io.IO, uart_txd_in)
99
100 // gpio(16) input is shared between FTDI TX pin and the Arduino shield pin using SW[3]
101 val sw_3_in = IOBUF(sw_3)
102 dut.io.pins.gpio.pins(16).i.ival := Mux(sw_3_in,
103 iobuf_ck0.io.O & dut.io.pins.gpio.pins(16).o.ie,
104 iobuf_uart_txd.io.O & dut.io.pins.gpio.pins(16).o.ie)
105
106 IOBUF(uart_rxd_out, dut.io.pins.gpio.pins(17))
107
108 // Shield header row 0: PD2-PD7
109 IOBUF(ck_io(2), dut.io.pins.gpio.pins(18))
110 IOBUF(ck_io(3), dut.io.pins.gpio.pins(19)) // PWM1(1)
111 IOBUF(ck_io(4), dut.io.pins.gpio.pins(20)) // PWM1(0)
112 IOBUF(ck_io(5), dut.io.pins.gpio.pins(21)) // PWM1(2)
113 IOBUF(ck_io(6), dut.io.pins.gpio.pins(22)) // PWM1(3)
114 IOBUF(ck_io(7), dut.io.pins.gpio.pins(23))
115
116 // Header row 1: PB0-PB5
117 IOBUF(ck_io(8), dut.io.pins.gpio.pins(0)) // PWM0(0)
118 IOBUF(ck_io(9), dut.io.pins.gpio.pins(1)) // PWM0(1)
119 IOBUF(ck_io(10), dut.io.pins.gpio.pins(2)) // SPI CS(0) / PWM0(2)
120 IOBUF(ck_io(11), dut.io.pins.gpio.pins(3)) // SPI MOSI / PWM0(3)
121 IOBUF(ck_io(12), dut.io.pins.gpio.pins(4)) // SPI MISO
122 IOBUF(ck_io(13), dut.io.pins.gpio.pins(5)) // SPI SCK
123
124 dut.io.pins.gpio.pins(6).i.ival := 0.U
125 dut.io.pins.gpio.pins(7).i.ival := 0.U
126 dut.io.pins.gpio.pins(8).i.ival := 0.U
127
128 // Header row 3: A0-A5 (we don't support using them as analog inputs)
129 // just treat them as regular digital GPIOs
130 IOBUF(ck_io(15), dut.io.pins.gpio.pins(9)) // A1 = CS(2)
131 IOBUF(ck_io(16), dut.io.pins.gpio.pins(10)) // A2 = CS(3) / PWM2(0)
132 IOBUF(ck_io(17), dut.io.pins.gpio.pins(11)) // A3 = PWM2(1)
133 IOBUF(ck_io(18), dut.io.pins.gpio.pins(12)) // A4 = PWM2(2) / SDA
134 IOBUF(ck_io(19), dut.io.pins.gpio.pins(13)) // A5 = PWM2(3) / SCL
135
136 // Mirror outputs of GPIOs with PWM peripherals to RGB LEDs on Arty
137 // assign RGB LED0 R,G,B inputs = PWM0(1,2,3) when iof_1 is active
138 IOBUF(led0_r, dut.io.pins.gpio.pins(1))
139 IOBUF(led0_g, dut.io.pins.gpio.pins(2))
140 IOBUF(led0_b, dut.io.pins.gpio.pins(3))
141
142 // Note that this is the one which is actually connected on the HiFive/Crazy88
143 // Board. Same with RGB LED1 R,G,B inputs = PWM1(1,2,3) when iof_1 is active
144 IOBUF(led1_r, dut.io.pins.gpio.pins(19))
145 IOBUF(led1_g, dut.io.pins.gpio.pins(21))
146 IOBUF(led1_b, dut.io.pins.gpio.pins(22))
147
148 // and RGB LED2 R,G,B inputs = PWM2(1,2,3) when iof_1 is active
149 IOBUF(led2_r, dut.io.pins.gpio.pins(11))
150 IOBUF(led2_g, dut.io.pins.gpio.pins(12))
151 IOBUF(led2_b, dut.io.pins.gpio.pins(13))
152
153 // Only 19 out of 20 shield pins connected to GPIO pins
154 // Shield pin A5 (pin 14) left unconnected
155 // The buttons are connected to some extra GPIO pins not connected on the
156 // HiFive1 board
157 IOBUF(btn_0, dut.io.pins.gpio.pins(15))
158 IOBUF(btn_1, dut.io.pins.gpio.pins(30))
159 IOBUF(btn_2, dut.io.pins.gpio.pins(31))
160
161 val iobuf_btn_3 = Module(new IOBUF())
162 iobuf_btn_3.io.I := ~dut.io.pins.aon.pmu.dwakeup_n.o.oval
163 iobuf_btn_3.io.T := ~dut.io.pins.aon.pmu.dwakeup_n.o.oe
164 attach(btn_3, iobuf_btn_3.io.IO)
165 dut.io.pins.aon.pmu.dwakeup_n.i.ival := ~iobuf_btn_3.io.O & dut.io.pins.aon.pmu.dwakeup_n.o.ie
166
167 // UART1 RX/TX pins are assigned to PMOD_D connector pins 0/1
168 IOBUF(ja_0, dut.io.pins.gpio.pins(25)) // UART1 TX
169 IOBUF(ja_1, dut.io.pins.gpio.pins(24)) // UART1 RX
170
171 // SPI2 pins mapped to 6 pin ICSP connector (standard on later
172 // arduinos) These are connected to some extra GPIO pins not connected
173 // on the HiFive1 board
174 IOBUF(ck_ss, dut.io.pins.gpio.pins(26))
175 IOBUF(ck_mosi, dut.io.pins.gpio.pins(27))
176 IOBUF(ck_miso, dut.io.pins.gpio.pins(28))
177 IOBUF(ck_sck, dut.io.pins.gpio.pins(29))
178
179 // Use the LEDs for some more useful debugging things
180 IOBUF(led_0, ck_rst)
181 IOBUF(led_1, SRST_n)
182 IOBUF(led_2, dut.io.pins.aon.pmu.dwakeup_n.i.ival)
183 IOBUF(led_3, dut.io.pins.gpio.pins(14))
184
185 //---------------------------------------------------------------------
186 // Unconnected inputs
187 //---------------------------------------------------------------------
188
189 dut.io.pins.aon.erst_n.i.ival := ~reset_periph
190 dut.io.pins.aon.lfextclk.i.ival := slow_clock
191 dut.io.pins.aon.pmu.vddpaden.i.ival := 1.U
192 }
193 }