Skip to content

Commit 8636d52

Browse files
thommythomasophsauter
authored andcommitted
Xilinx: Add simple FPGA flow for Genesys2
1 parent de4914c commit 8636d52

File tree

10 files changed

+768
-1
lines changed

10 files changed

+768
-1
lines changed

Bender.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ sources:
4646
- rtl/user_domain.sv
4747
# Level 3
4848
- rtl/croc_soc.sv
49-
# Level 4
49+
50+
- target: not(fpga)
51+
files:
52+
# Level 0
5053
- rtl/croc_chip.sv
5154

5255
# netlist for simulation
@@ -58,6 +61,11 @@ sources:
5861
files:
5962
- rtl/tb_croc_soc.sv
6063

64+
- target: genesys2
65+
files:
66+
- xilinx/hw/croc_xilinx.sv
67+
- xilinx/hw/fan_ctrl.sv
68+
6169
vendor_package:
6270
#################################
6371
# commonly used building blocks #

xilinx/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build
2+
out
3+
scripts/add_sources.genesys2.tcl
4+

xilinx/hw/croc_xilinx.sv

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
// Copyright 2024 ETH Zurich and University of Bologna.
2+
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
3+
// SPDX-License-Identifier: SHL-0.51
4+
//
5+
// Nicole Narr <narrn@student.ethz.ch>
6+
// Christopher Reinwardt <creinwar@student.ethz.ch>
7+
// Cyril Koenig <cykoenig@iis.ee.ethz.ch>
8+
// Yann Picod <ypicod@ethz.ch>
9+
// Paul Scheffler <paulsc@iis.ee.ethz.ch>
10+
// Philippe Sauter <phsauter@iis.ee.ethz.ch>
11+
12+
`ifdef TARGET_GENESYS2
13+
`define USE_RESETN
14+
`define USE_JTAG_TRSTN
15+
`define USE_STATUS
16+
`define USE_SWITCHES
17+
`define USE_LEDS
18+
`define USE_FAN
19+
`define USE_VIO
20+
`endif
21+
22+
`define ila(__name, __signal) \
23+
(* dont_touch = "yes" *) (* mark_debug = "true" *) logic [$bits(__signal)-1:0] __name; \
24+
assign __name = __signal;
25+
26+
module croc_xilinx import croc_pkg::*; #(
27+
localparam int unsigned GpioCount = 4
28+
) (
29+
input logic sys_clk_p,
30+
input logic sys_clk_n,
31+
32+
`ifdef USE_RESET
33+
input logic sys_reset,
34+
`endif
35+
`ifdef USE_RESETN
36+
input logic sys_resetn,
37+
`endif
38+
39+
`ifdef USE_SWITCHES
40+
input logic fetch_en_i, // switch 7
41+
input logic [GpioCount-1:0] gpio_i, // switch 0-3
42+
`endif
43+
44+
`ifdef USE_LEDS
45+
output logic [GpioCount-1:0] gpio_o,
46+
`endif
47+
48+
`ifdef USE_STATUS
49+
output logic status_o,
50+
`endif
51+
52+
input logic jtag_tck_i,
53+
input logic jtag_tms_i,
54+
input logic jtag_tdi_i,
55+
output logic jtag_tdo_o,
56+
`ifdef USE_JTAG_TRSTN
57+
input logic jtag_trst_ni,
58+
`endif
59+
`ifdef USE_JTAG_VDDGND
60+
output logic jtag_vdd_o,
61+
output logic jtag_gnd_o,
62+
`endif
63+
64+
`ifdef USE_FAN
65+
input logic [2:0] fan_sw, // switch 4-6
66+
output logic fan_pwm,
67+
`endif
68+
69+
output logic uart_tx_o,
70+
input logic uart_rx_i
71+
);
72+
73+
////////////////////////
74+
// Clock Generation //
75+
////////////////////////
76+
77+
wire sys_clk;
78+
wire soc_clk;
79+
80+
IBUFDS #(
81+
.IBUF_LOW_PWR ("FALSE")
82+
) i_bufds_sys_clk (
83+
.I ( sys_clk_p ),
84+
.IB ( sys_clk_n ),
85+
.O ( sys_clk )
86+
);
87+
88+
clkwiz i_clkwiz (
89+
.clk_in1 ( sys_clk ),
90+
.reset ( '0 ),
91+
.locked ( ),
92+
.clk_20 ( soc_clk )
93+
);
94+
95+
/////////////////////
96+
// System Inputs //
97+
/////////////////////
98+
99+
// Select SoC reset
100+
`ifdef USE_RESET
101+
logic sys_resetn;
102+
assign sys_resetn = ~sys_reset;
103+
`elsif USE_RESETN
104+
logic sys_reset;
105+
assign sys_reset = ~sys_resetn;
106+
`endif
107+
108+
// Tie off inputs of no switches
109+
`ifndef USE_SWITCHES
110+
logic fetch_en_i;
111+
logic [GpioCount-2:0] gpio_i;
112+
assign test_mode_i = '0;
113+
assign fetch_en_i = '0;
114+
assign gpio_i = '0;
115+
`endif
116+
117+
`ifndef USE_STATUS
118+
logic status_o;
119+
`endif
120+
121+
`ifndef USE_LEDS
122+
logic [GpioCount-1:0] gpio_o;
123+
`endif
124+
125+
////////////
126+
// VIOs //
127+
////////////
128+
logic vio_reset, vio_fetch_en, vio_gpio;
129+
130+
`ifdef USE_VIO
131+
vio i_vio (
132+
.clk ( soc_clk ),
133+
.probe_out0 ( vio_reset ),
134+
.probe_out1 ( vio_fetch_en ),
135+
.probe_out2 ( vio_gpio )
136+
);
137+
`else
138+
assign vio_reset = '0;
139+
assign vio_fetch_en = '0;
140+
assign vio_gpio = '0;
141+
`endif
142+
143+
144+
//////////////
145+
// SOC IO //
146+
//////////////
147+
148+
logic soc_fetch_en;
149+
logic soc_rst_n;
150+
151+
assign soc_fetch_en = fetch_en_i | vio_fetch_en;
152+
assign soc_rst = ~sys_resetn | vio_reset;
153+
154+
logic [GpioCount-1:0] soc_gpio_i;
155+
logic [GpioCount-1:0] soc_gpio_o;
156+
logic [GpioCount-1:0] soc_gpio_out_en_o;
157+
158+
for(genvar idx=0; idx<GpioCount; idx++) begin
159+
assign gpio_o[idx] = soc_gpio_out_en_o[idx] ? soc_gpio_o[idx] : '0;
160+
161+
if(idx == 0) begin
162+
assign soc_gpio_i[idx] = ~soc_gpio_out_en_o[idx] ? vio_gpio | gpio_i[0] : '0;
163+
end else begin
164+
assign soc_gpio_i[idx] = ~soc_gpio_out_en_o[idx] ? gpio_i[idx] : '0;
165+
end
166+
end
167+
168+
169+
//////////////////
170+
// Reset Sync //
171+
//////////////////
172+
173+
wire rst_n;
174+
175+
rstgen i_rstgen (
176+
.clk_i ( soc_clk ),
177+
.rst_ni ( ~soc_rst ),
178+
.test_mode_i ( '0 ),
179+
.rst_no ( rst_n ),
180+
.init_no ( )
181+
);
182+
183+
////////////
184+
// JTAG //
185+
////////////
186+
187+
`ifdef USE_JTAG_VDDGND
188+
assign jtag_vdd_o = 1'b1;
189+
assign jtag_gnd_o = 1'b0;
190+
`endif
191+
`ifndef USE_JTAG_TRSTN
192+
logic jtag_trst_ni;
193+
assign jtag_trst_ni = 1'b1;
194+
`endif
195+
196+
197+
/////////////////////////
198+
// "RTC" Clock Divider //
199+
/////////////////////////
200+
201+
logic rtc_clk_d, rtc_clk_q;
202+
logic [15:0] counter_d, counter_q;
203+
204+
// Divide soc_clk (20 MHz) by 610 => ~32.768kHz RTC Clock
205+
// TODO: does genesys 2 have a 32.768kHz reference clock?
206+
always_comb begin
207+
counter_d = counter_q + 1;
208+
rtc_clk_d = rtc_clk_q;
209+
210+
if(counter_q == 610) begin
211+
counter_d = '0;
212+
rtc_clk_d = ~rtc_clk_q;
213+
end
214+
end
215+
216+
always_ff @(posedge soc_clk, negedge rst_n) begin
217+
if(~rst_n) begin
218+
counter_q <= '0;
219+
rtc_clk_q <= 0;
220+
end else begin
221+
counter_q <= counter_d;
222+
rtc_clk_q <= rtc_clk_d;
223+
end
224+
end
225+
226+
/////////////////
227+
// Fan Control //
228+
/////////////////
229+
230+
`ifdef USE_FAN
231+
fan_ctrl i_fan_ctrl (
232+
.clk_i ( soc_clk ),
233+
.rst_ni ( rst_n ),
234+
.pwm_setting_i ( {'0, fan_sw} ),
235+
.fan_pwm_o ( fan_pwm )
236+
);
237+
`endif
238+
239+
240+
//////////////////
241+
// Cheshire SoC //
242+
//////////////////
243+
logic soc_testmode_i;
244+
assign soc_testmode_i = '0;
245+
246+
croc_soc #(
247+
.GpioCount( GpioCount )
248+
)
249+
i_croc_soc (
250+
.clk_i ( soc_clk ),
251+
.rst_ni ( rst_n ),
252+
.ref_clk_i ( rtc_clk_q ),
253+
.testmode_i ( soc_testmode_i ),
254+
.fetch_en_i ( soc_fetch_en ),
255+
.status_o ( status_o ),
256+
257+
.jtag_tck_i ( jtag_tck_i ),
258+
.jtag_tdi_i ( jtag_tdi_i ),
259+
.jtag_tdo_o ( jtag_tdo_o ),
260+
.jtag_tms_i ( jtag_tms_i ),
261+
.jtag_trst_ni ( jtag_trst_ni ),
262+
263+
.uart_rx_i ( uart_rx_i ),
264+
.uart_tx_o ( uart_tx_o ),
265+
266+
.gpio_i ( soc_gpio_i ),
267+
.gpio_o ( soc_gpio_o ),
268+
.gpio_out_en_o ( soc_gpio_out_en_o )
269+
);
270+
271+
endmodule

xilinx/hw/fan_ctrl.sv

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2018 ETH Zurich and University of Bologna.
2+
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
3+
// SPDX-License-Identifier: SHL-0.51
4+
//
5+
// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch
6+
// Description: PWM Fan Control for Genesys II board
7+
8+
module fan_ctrl (
9+
input logic clk_i,
10+
input logic rst_ni,
11+
input logic [3:0] pwm_setting_i,
12+
output logic fan_pwm_o
13+
);
14+
logic [3:0] ms_clock_d, ms_clock_q;
15+
logic [11:0] cycle_counter_d, cycle_counter_q;
16+
17+
// clock divider
18+
always_comb begin
19+
cycle_counter_d = cycle_counter_q + 1;
20+
ms_clock_d = ms_clock_q;
21+
22+
// divide clock by 49
23+
// At 50 MHz input clock this results in a 62.5 kHz
24+
// PWM Signal
25+
if (cycle_counter_q == 49) begin
26+
cycle_counter_d = 0;
27+
ms_clock_d = ms_clock_q + 1;
28+
end
29+
30+
if (ms_clock_q == 15) begin
31+
ms_clock_d = 0;
32+
end
33+
end
34+
35+
// duty cycle
36+
always_comb begin
37+
if (ms_clock_q < pwm_setting_i) begin
38+
fan_pwm_o = 1'b1;
39+
end else begin
40+
fan_pwm_o = 1'b0;
41+
end
42+
end
43+
44+
always_ff @(posedge clk_i or negedge rst_ni) begin
45+
if (~rst_ni) begin
46+
ms_clock_q <= '0;
47+
cycle_counter_q <= '0;
48+
end else begin
49+
ms_clock_q <= ms_clock_d;
50+
cycle_counter_q <= cycle_counter_d;
51+
end
52+
end
53+
endmodule

xilinx/implement.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
bender script vivado -t fpga -t rtl -t genesys2 > scripts/add_sources.genesys2.tcl
2+
mkdir -p build/genesys2.clkwiz
3+
cd build/genesys2.clkwiz && \
4+
vitis-2022.1 vivado -mode batch -log ../genesys2.clkwiz.log -jou ../genesys2.clkwiz.jou \
5+
-source ../../scripts/impl_ip.tcl \
6+
-tclargs genesys2 clkwiz \
7+
&& cd ../..
8+
mkdir -p build/genesys2.vio
9+
cd build/genesys2.vio &&
10+
vitis-2022.1 vivado -mode batch -log ../genesys2.vio.log -jou ../genesys2.vio.jou \
11+
-source ../../scripts/impl_ip.tcl \
12+
-tclargs genesys2 vio\
13+
&& cd ../..
14+
mkdir -p build/genesys2.croc
15+
cd build/genesys2.croc && \
16+
vitis-2022.1 vivado -mode batch -log ../croc.genesys2.log -jou ../croc.genesys2.jou \
17+
-source ../../scripts/impl_sys.tcl \
18+
-tclargs genesys2 croc \
19+
../genesys2.clkwiz/out.xci \
20+
../genesys2.vio/out.xci

0 commit comments

Comments
 (0)