Skip to content
Open
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.bender
tmp
tmp
xilinx/scripts/add_sources.artyz720.tcl
xilinx/scripts/add_sources.genesys2.tcl
xilinx/scripts/add_sources.zyboz720.tcl
8 changes: 8 additions & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ sources:
- xilinx/hw/croc_xilinx.sv
- xilinx/hw/fan_ctrl.sv

- target: artyz720
files:
- xilinx/hw/croc_xilinx.sv

- target: zyboz720
files:
- xilinx/hw/croc_xilinx.sv

vendor_package:
#################################
# commonly used building blocks #
Expand Down
15 changes: 9 additions & 6 deletions rtl/common_cells/fifo_v3.sv
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ module fifo_v3 #(
end

`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
`ASSERT_INIT(depth_0, DEPTH > 0, "DEPTH must be greater than 0.")

`ASSERT(full_write, full_o |-> ~push_i, clk_i, !rst_ni,
"Trying to push new data although the FIFO is full.")

`ASSERT(empty_read, empty_o |-> ~pop_i, clk_i, !rst_ni,
"Trying to pop data although the FIFO is empty.")
`ASSERT(full_write, full_o |-> ~push_i, clk_i, !rst_ni, "Trying to push new data although the FIFO is full.")
`ASSERT(empty_read, empty_o |-> ~pop_i, clk_i, !rst_ni, "Trying to pop data although the FIFO is empty.")
`else
`ASSERT_INIT(depth_0, DEPTH > 0)
`ASSERT(full_write, full_o |-> ~push_i, clk_i, !rst_ni)
`ASSERT(empty_read, empty_o |-> ~pop_i, clk_i, !rst_ni)
`endif
`endif


endmodule // fifo_v3
18 changes: 16 additions & 2 deletions rtl/common_cells/lzc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,18 @@ module lzc #(

localparam int unsigned NumLevels = $clog2(WIDTH);



`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT_INIT(width_0, WIDTH > 0, "input must be at least one bit wide")
`ifndef SYNTHESIS
`ASSERT_INIT(width_0, WIDTH > 0, "input must be at least one bit wide")
`else
`ASSERT_INIT(width_0, WIDTH > 0)
`endif
`endif



logic [WIDTH-1:0][NumLevels-1:0] index_lut;
logic [2**NumLevels-1:0] sel_nodes;
logic [2**NumLevels-1:0][NumLevels-1:0] index_nodes;
Expand Down Expand Up @@ -99,8 +107,14 @@ module lzc #(

end : gen_lzc


`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT_INIT(width_0, WIDTH >= 1, "The WIDTH must at least be one bit wide!")
`ifndef SYNTHESIS
`ASSERT_INIT(width_0, WIDTH >= 1, "The WIDTH must at least be one bit wide!")
`else
`ASSERT_INIT(width_0, WIDTH >= 1)
`endif
`endif


endmodule : lzc
83 changes: 61 additions & 22 deletions rtl/common_cells/rr_arb_tree.sv
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,36 @@ module rr_arb_tree #(
end
end
end

`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT(lock, req_o && (!gnt_i && !flush_i) |=> idx_o == $past(idx_o),
clk_i, !rst_ni || flush_i,
"Lock implies same arbiter decision in next cycle if output is not ready.")

logic [NumIn-1:0] req_tmp;
assign req_tmp = req_q & req_i;
`ASSUME(lock_req, lock_d |=> req_tmp == req_q, clk_i, !rst_ni || flush_i,
"It is disallowed to deassert unserved request signals when LockIn is enabled.")
`ifndef SYNTHESIS
`ASSERT(lock,
req_o && (!gnt_i && !flush_i) |=> idx_o == $past(idx_o),
clk_i, !rst_ni || flush_i,
"Lock implies same arbiter decision in next cycle if output is not ready.")

logic [NumIn-1:0] req_tmp;
assign req_tmp = req_q & req_i;

`ASSUME(lock_req,
lock_d |=> req_tmp == req_q,
clk_i, !rst_ni || flush_i,
"It is disallowed to deassert unserved request signals when LockIn is enabled.")
`else
`ASSERT(lock,
req_o && (!gnt_i && !flush_i) |=> idx_o == $past(idx_o),
clk_i, !rst_ni || flush_i)

logic [NumIn-1:0] req_tmp;
assign req_tmp = req_q & req_i;

`ASSUME(lock_req,
lock_d |=> req_tmp == req_q,
clk_i, !rst_ni || flush_i)
`endif
`endif


always_ff @(posedge clk_i or negedge rst_ni) begin : p_req_regs
if (!rst_ni) begin
req_q <= '0;
Expand Down Expand Up @@ -293,27 +311,48 @@ module rr_arb_tree #(
//////////////////////////////////////////////////////////////
end
end

`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT_INIT(numin_0, NumIn, "Input must be at least one element wide.")
`ASSERT_INIT(lockin_and_extprio, !(LockIn && ExtPrio),
"Cannot use LockIn feature together with external ExtPrio.")
`ifndef SYNTHESIS
`ASSERT_INIT(numin_0, NumIn, "Input must be at least one element wide.")
`ASSERT_INIT(lockin_and_extprio, !(LockIn && ExtPrio),
"Cannot use LockIn feature together with external ExtPrio.")

`ASSERT(hot_one, $onehot0(gnt_o), clk_i, !rst_ni || flush_i,
"Grant signal must be hot1 or zero.")

`ASSERT(gnt0, |gnt_o |-> gnt_i, clk_i, !rst_ni || flush_i,
"Grant out implies grant in.")

`ASSERT(hot_one, $onehot0(gnt_o), clk_i, !rst_ni || flush_i,
"Grant signal must be hot1 or zero.")
`ASSERT(gnt1, req_o |-> gnt_i |-> |gnt_o, clk_i, !rst_ni || flush_i,
"Req out and grant in implies grant out.")

`ASSERT(gnt0, |gnt_o |-> gnt_i, clk_i, !rst_ni || flush_i, "Grant out implies grant in.")
`ASSERT(gnt_idx, req_o |-> gnt_i |-> gnt_o[idx_o], clk_i, !rst_ni || flush_i,
"Idx_o / gnt_o do not match.")

`ASSERT(gnt1, req_o |-> gnt_i |-> |gnt_o, clk_i, !rst_ni || flush_i,
"Req out and grant in implies grant out.")
`ASSERT(req0, |req_i |-> req_o, clk_i, !rst_ni || flush_i,
"Req in implies req out.")

`ASSERT(gnt_idx, req_o |-> gnt_i |-> gnt_o[idx_o], clk_i, !rst_ni || flush_i,
"Idx_o / gnt_o do not match.")
`ASSERT(req1, req_o |-> |req_i, clk_i, !rst_ni || flush_i,
"Req out implies req in.")
`else
`ASSERT_INIT(numin_0, NumIn)
`ASSERT_INIT(lockin_and_extprio, !(LockIn && ExtPrio))

`ASSERT(req0, |req_i |-> req_o, clk_i, !rst_ni || flush_i, "Req in implies req out.")
`ASSERT(hot_one, $onehot0(gnt_o), clk_i, !rst_ni || flush_i)

`ASSERT(req1, req_o |-> |req_i, clk_i, !rst_ni || flush_i, "Req out implies req in.")
`ASSERT(gnt0, |gnt_o |-> gnt_i, clk_i, !rst_ni || flush_i)

`ASSERT(gnt1, req_o |-> gnt_i |-> |gnt_o, clk_i, !rst_ni || flush_i)

`ASSERT(gnt_idx, req_o |-> gnt_i |-> gnt_o[idx_o], clk_i, !rst_ni || flush_i)

`ASSERT(req0, |req_i |-> req_o, clk_i, !rst_ni || flush_i)

`ASSERT(req1, req_o |-> |req_i, clk_i, !rst_ni || flush_i)
`endif
`endif

end

endmodule : rr_arb_tree
10 changes: 7 additions & 3 deletions rtl/common_cells/spill_register_flushable.sv
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@ module spill_register_flushable #(
// We empty the spill register before the slice register.
assign data_o = b_full_q ? b_data_q : a_data_q;

`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT(flush_valid, flush_i |-> ~valid_i, clk_i, !rst_ni,
`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
`ASSERT(flush_valid, flush_i |-> ~valid_i, clk_i, !rst_ni,
"Trying to flush and feed the spill register simultaneously. You will lose data!")
`endif
`else
`ASSERT(flush_valid, flush_i |-> ~valid_i, clk_i, !rst_ni)
`endif
`endif
end
endmodule
36 changes: 35 additions & 1 deletion xilinx/hw/croc_xilinx.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// Yann Picod <ypicod@ethz.ch>
// Paul Scheffler <paulsc@iis.ee.ethz.ch>
// Philippe Sauter <phsauter@iis.ee.ethz.ch>
// Felix Niederer <fniederer@student.ethz.ch>

`ifdef TARGET_GENESYS2
`define USE_RESETN
Expand All @@ -17,8 +18,27 @@
`define USE_LEDS
`define USE_FAN
`define USE_VIO
`define USE_DIFF_CLK

`endif

`ifdef TARGET_ARTYZ720
`define USE_RESET
`define USE_STATUS
`define USE_SWITCHES
`define USE_LEDS
`define USE_VIO
`endif

`ifdef TARGET_ZYBOZ720
`define USE_RESET
`define USE_STATUS
`define USE_SWITCHES
`define USE_LEDS
`define USE_VIO
`endif


`define ila(__name, __signal) \
(* dont_touch = "yes" *) (* mark_debug = "true" *) logic [$bits(__signal)-1:0] __name; \
assign __name = __signal;
Expand All @@ -27,8 +47,11 @@ module croc_xilinx import croc_pkg::*; #(
localparam int unsigned GpioCount = 4
) (
input logic sys_clk_p,
input logic sys_clk_n,

`ifdef USE_DIFF_CLK
input logic sys_clk_n,
`endif

`ifdef USE_RESET
input logic sys_reset,
`endif
Expand Down Expand Up @@ -77,13 +100,24 @@ module croc_xilinx import croc_pkg::*; #(
wire sys_clk;
wire soc_clk;


`ifdef USE_DIFF_CLK
IBUFDS #(
.IBUF_LOW_PWR ("FALSE")
) i_bufds_sys_clk (
.I ( sys_clk_p ),
.IB ( sys_clk_n ),
.O ( sys_clk )
);
`endif

`ifndef USE_DIFF_CLK
IBUF i_buf_sys_clk (
.I ( sys_clk_p ),
.O ( sys_clk )
);
`endif


clkwiz i_clkwiz (
.clk_in1 ( sys_clk ),
Expand Down
63 changes: 48 additions & 15 deletions xilinx/implement.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,20 +1,53 @@
bender script vivado -t fpga -t rtl -t genesys2 > scripts/add_sources.genesys2.tcl
mkdir -p build/genesys2.clkwiz
cd build/genesys2.clkwiz && \
vitis-2022.1 vivado -mode batch -log ../genesys2.clkwiz.log -jou ../genesys2.clkwiz.jou \
#!/bin/bash

# Default board is genesys2
BOARD="genesys2"

# Parse command line arguments
while getopts "b:" opt; do
case ${opt} in
b )
BOARD=$OPTARG
;;
\? )
echo "Usage: $0 [-b board_type]"
echo "Supported boards: genesys2, artyz720, zyboz720"
exit 1
;;
esac
done

# Validate board selection
if [[ "$BOARD" != "genesys2" && "$BOARD" != "artyz720" && "$BOARD" != "zyboz720" ]]; then
echo "Error: Unsupported board type '$BOARD'"
echo "Supported boards: genesys2, artyz720, zyboz720"
exit 1
fi

# Generate the TCL script
bender script vivado -t fpga -t rtl -t $BOARD > scripts/add_sources.$BOARD.tcl

# Build Clkwiz
mkdir -p build/$BOARD.clkwiz
cd build/$BOARD.clkwiz && \
vitis-2022.1 vivado -mode batch -log ../$BOARD.clkwiz.log -jou ../$BOARD.clkwiz.jou \
-source ../../scripts/impl_ip.tcl \
-tclargs genesys2 clkwiz \
-tclargs $BOARD clkwiz \
&& cd ../..
mkdir -p build/genesys2.vio
cd build/genesys2.vio &&
vitis-2022.1 vivado -mode batch -log ../genesys2.vio.log -jou ../genesys2.vio.jou \

# Build VIO
mkdir -p build/$BOARD.vio
cd build/$BOARD.vio && \
vitis-2022.1 vivado -mode batch -log ../$BOARD.vio.log -jou ../$BOARD.vio.jou \
-source ../../scripts/impl_ip.tcl \
-tclargs genesys2 vio\
-tclargs $BOARD vio \
&& cd ../..
mkdir -p build/genesys2.croc
cd build/genesys2.croc && \
vitis-2022.1 vivado -mode batch -log ../croc.genesys2.log -jou ../croc.genesys2.jou \

# Build top croc module
mkdir -p build/$BOARD.croc
cd build/$BOARD.croc && \
vitis-2022.1 vivado -mode batch -log ../croc.$BOARD.log -jou ../croc.$BOARD.jou \
-source ../../scripts/impl_sys.tcl \
-tclargs genesys2 croc \
../genesys2.clkwiz/out.xci \
../genesys2.vio/out.xci
-tclargs $BOARD croc \
../$BOARD.clkwiz/out.xci \
../$BOARD.vio/out.xci
24 changes: 24 additions & 0 deletions xilinx/scripts/clkwiz/clkwiz_artyz720.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2024 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51
#
# Florian Zaruba <zarubaf@iis.ee.ethz.ch>
# Cyril Koenig <cykoenig@iis.ee.ethz.ch>
# Paul Scheffler <paulsc@iis.ee.ethz.ch>
# Felix Niederer <fniederer@student.ethz.ch>

create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name $proj
set_property -dict [list \
CONFIG.PRIM_SOURCE {No_buffer} \
CONFIG.PRIM_IN_FREQ {125.000} \
CONFIG.CLKOUT1_USED {true} \
CONFIG.CLK_OUT1_PORT {clk_20} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {20.000} \
CONFIG.CLKIN1_JITTER_PS {50.0} \
CONFIG.MMCM_CLKFBOUT_MULT_F {8.000} \
CONFIG.MMCM_CLKIN1_PERIOD {8.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {50} \
CONFIG.NUM_OUT_CLKS {1} \
CONFIG.CLKOUT1_JITTER {155.330} \
CONFIG.CLKOUT1_PHASE_ERROR {89.971} \
] [get_ips $proj]
23 changes: 23 additions & 0 deletions xilinx/scripts/clkwiz/clkwiz_genesys2.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2024 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51
#
# Florian Zaruba <zarubaf@iis.ee.ethz.ch>
# Cyril Koenig <cykoenig@iis.ee.ethz.ch>
# Paul Scheffler <paulsc@iis.ee.ethz.ch>

create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name $proj
set_property -dict [list \
CONFIG.PRIM_SOURCE {No_buffer} \
CONFIG.PRIM_IN_FREQ {200.000} \
CONFIG.CLKOUT1_USED {true} \
CONFIG.CLK_OUT1_PORT {clk_20} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {20.000} \
CONFIG.CLKIN1_JITTER_PS {50.0} \
CONFIG.MMCM_CLKFBOUT_MULT_F {6.000} \
CONFIG.MMCM_CLKIN1_PERIOD {5.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {60} \
CONFIG.NUM_OUT_CLKS {1} \
CONFIG.CLKOUT1_JITTER {155.330} \
CONFIG.CLKOUT1_PHASE_ERROR {89.971} \
] [get_ips $proj]
Loading