Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions openroad/scripts/01_floorplan.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ utl::report "Read netlist: ${netlist}"
read_verilog $netlist
link_design $top_design

utl::report "Read DFT configuration"
source src/dft_config.tcl

utl::report "Insert scan flip-flops"
scan_replace

utl::report "Read constraints"
read_sdc src/constraints.sdc

Expand Down
19 changes: 19 additions & 0 deletions openroad/scripts/02_placement.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ utl::report "###################################################################
set clock_nets [get_nets -of_objects [get_pins -of_objects "*_reg" -filter "name == CLK"]]
set_dont_touch $clock_nets

# Prevent scan input buffers from being optimized away
set scan_in_buf_cells [get_cells *i_scan_in_buf_*]
puts "Scan input buffers: $scan_in_buf_cells"
set_dont_touch $scan_in_buf_cells

utl::report "Repair tie fanout"
repair_tie_fanout $tieHiPin
repair_tie_fanout $tieLoPin
Expand Down Expand Up @@ -112,6 +117,20 @@ detailed_placement
utl::report "Optimize mirroring"
optimize_mirroring

utl::report "Read DFT configuration"
source src/dft_config.tcl

utl::report "Stitch Scan Chain"
execute_dft_plan
unset_dont_touch $scan_in_buf_cells

utl::report "Repair scan enable fanout..."
set other_nets [get_nets -filter "name != soc_scan_en_i"]
set_dont_touch $other_nets
repair_design -verbose
unset_dont_touch $other_nets
detailed_placement

utl::report "Estimate parasitics"
estimate_parasitics -placement

Expand Down
18 changes: 9 additions & 9 deletions openroad/src/constraints.sdc
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,16 @@ set_max_delay 3.0 -from $JTAG_ASYNC_RSP_START -to $JTAG_ASYNC_RSP_END -ignore_cl
puts "Input/Outputs..."

# Reset should propagate to system domain within a clock cycle.
set_input_delay -max [ expr $TCK_JTG * 0.10 ] [get_ports {rst_ni testmode_i}]
set_false_path -hold -from [get_ports {rst_ni testmode_i}]
set_max_delay $TCK_SYS -from [get_ports {rst_ni testmode_i}]
set_input_delay -max [ expr $TCK_JTG * 0.10 ] [get_ports {rst_ni testmode_i bootmode_scan_en_i}]
set_false_path -hold -from [get_ports {rst_ni testmode_i bootmode_scan_en_i}]
set_max_delay $TCK_SYS -from [get_ports {rst_ni}]

# Give testmode a bit more time (for scan chain)
set_max_delay $TCK_JTG -from [get_ports {testmode_i}]

set_max_delay $TCK_SYS -from [get_ports bootmode_scan_en_i] -to [get_pins */SCE]
set_max_delay $TCK_SYS -from [get_ports bootmode_scan_en_i] -to [get_ports uart_tx_o]
set_max_delay $TCK_JTG -from [get_ports bootmode_scan_en_i] -to [get_ports jtag_tdo_o]

##########
## JTAG ##
Expand All @@ -98,12 +104,6 @@ set_input_delay -max -add_delay -clock clk_jtg [ expr $TCK_JTG * 0.30 ] [get_po
set_output_delay -min -add_delay -clock clk_jtg [ expr $TCK_JTG * 0.10 ] [get_ports jtag_tdo_o]
set_output_delay -max -add_delay -clock clk_jtg [ expr $TCK_JTG * 0.20 ] [get_ports jtag_tdo_o]

# Reset should propagate to system domain within a clock cycle.
set_input_delay -max [ expr $TCK_JTG * 0.10 ] [get_ports jtag_trst_ni]
set_false_path -hold -from [get_ports jtag_trst_ni]
set_max_delay $TCK_JTG -from [get_ports jtag_trst_ni]


##########
## GPIO ##
##########
Expand Down
22 changes: 22 additions & 0 deletions openroad/src/dft_config.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2026 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Authors:
# - Tobias Senti <tsenti@ethz.ch>

## Scan chain configuration

# max_chains: 1 scan chain per clock domain (clk_i and jtag_tck_i)
# scan_enable_name_pattern: Connecto to p2c pin of pad_scan_en_i
# scan_in_name_pattern: Connect to X pin of i_scan_in_buf_{} (0 and 1)
# scan_out_name_pattern: Connect to A1 pin of i_scan_out_mux_{} (0 and 1)

set_dft_config \
-max_chains 1 \
-scan_enable_name_pattern i_scan_en_gate/X \
-scan_in_name_pattern i_scan_in_buf_{}/X \
-scan_out_name_pattern i_scan_out_mux_{}/A1

# Report config
report_dft_config
32 changes: 16 additions & 16 deletions openroad/src/padring.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,22 @@ set westSpan [expr {$chipH - 2*$cornerToPad - $padW}]; # -padW because we place
set westPitch [expr {floor($westSpan / double($numPadsPerEdge - 1))}]
set westStart [expr {$chipH - $cornerToPad - $padW}]

place_pad -row IO_WEST -location [expr {$westStart - 0*$westPitch}] "pad_vssio0" ; # pin no: 1
place_pad -row IO_WEST -location [expr {$westStart - 1*$westPitch}] "pad_vddio0" ; # pin no: 2
place_pad -row IO_WEST -location [expr {$westStart - 2*$westPitch}] "pad_uart_rx_i" ; # pin no: 3
place_pad -row IO_WEST -location [expr {$westStart - 3*$westPitch}] "pad_uart_tx_o" ; # pin no: 4
place_pad -row IO_WEST -location [expr {$westStart - 4*$westPitch}] "pad_testmode_i" ; # pin no: 5
place_pad -row IO_WEST -location [expr {$westStart - 5*$westPitch}] "pad_status_o" ; # pin no: 6
place_pad -row IO_WEST -location [expr {$westStart - 6*$westPitch}] "pad_clk_i" ; # pin no: 7
place_pad -row IO_WEST -location [expr {$westStart - 7*$westPitch}] "pad_ref_clk_i" ; # pin no: 8
place_pad -row IO_WEST -location [expr {$westStart - 8*$westPitch}] "pad_rst_ni" ; # pin no: 9
place_pad -row IO_WEST -location [expr {$westStart - 9*$westPitch}] "pad_jtag_tck_i" ; # pin no: 10
place_pad -row IO_WEST -location [expr {$westStart - 10*$westPitch}] "pad_jtag_trst_ni" ; # pin no: 11
place_pad -row IO_WEST -location [expr {$westStart - 11*$westPitch}] "pad_jtag_tms_i" ; # pin no: 12
place_pad -row IO_WEST -location [expr {$westStart - 12*$westPitch}] "pad_jtag_tdi_i" ; # pin no: 13
place_pad -row IO_WEST -location [expr {$westStart - 13*$westPitch}] "pad_jtag_tdo_o" ; # pin no: 14
place_pad -row IO_WEST -location [expr {$westStart - 14*$westPitch}] "pad_vss0" ; # pin no: 15
place_pad -row IO_WEST -location [expr {$westStart - 15*$westPitch}] "pad_vdd0" ; # pin no: 16
place_pad -row IO_WEST -location [expr {$westStart - 0*$westPitch}] "pad_vssio0" ; # pin no: 1
place_pad -row IO_WEST -location [expr {$westStart - 1*$westPitch}] "pad_vddio0" ; # pin no: 2
place_pad -row IO_WEST -location [expr {$westStart - 2*$westPitch}] "pad_uart_rx_i" ; # pin no: 3
place_pad -row IO_WEST -location [expr {$westStart - 3*$westPitch}] "pad_uart_tx_o" ; # pin no: 4
place_pad -row IO_WEST -location [expr {$westStart - 4*$westPitch}] "pad_testmode_i" ; # pin no: 5
place_pad -row IO_WEST -location [expr {$westStart - 5*$westPitch}] "pad_status_o" ; # pin no: 6
place_pad -row IO_WEST -location [expr {$westStart - 6*$westPitch}] "pad_clk_i" ; # pin no: 7
place_pad -row IO_WEST -location [expr {$westStart - 7*$westPitch}] "pad_ref_clk_i" ; # pin no: 8
place_pad -row IO_WEST -location [expr {$westStart - 8*$westPitch}] "pad_rst_ni" ; # pin no: 9
place_pad -row IO_WEST -location [expr {$westStart - 9*$westPitch}] "pad_jtag_tck_i" ; # pin no: 10
place_pad -row IO_WEST -location [expr {$westStart - 10*$westPitch}] "pad_bootmode_scan_en_i" ; # pin no: 11 TODO: Adjust this
place_pad -row IO_WEST -location [expr {$westStart - 11*$westPitch}] "pad_jtag_tms_i" ; # pin no: 12
place_pad -row IO_WEST -location [expr {$westStart - 12*$westPitch}] "pad_jtag_tdi_i" ; # pin no: 13
place_pad -row IO_WEST -location [expr {$westStart - 13*$westPitch}] "pad_jtag_tdo_o" ; # pin no: 14
place_pad -row IO_WEST -location [expr {$westStart - 14*$westPitch}] "pad_vss0" ; # pin no: 15
place_pad -row IO_WEST -location [expr {$westStart - 15*$westPitch}] "pad_vdd0" ; # pin no: 16

##########################################################################
# Edge: BOTTOM (left to right) #
Expand Down
39 changes: 31 additions & 8 deletions rtl/croc_chip.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ module croc_chip import croc_pkg::*; #() (
input wire ref_clk_i,

input wire jtag_tck_i,
input wire jtag_trst_ni,
input wire jtag_tms_i,
input wire jtag_tdi_i,
output wire jtag_tdo_o,

input wire uart_rx_i,
output wire uart_tx_o,

input wire bootmode_scan_en_i,
input wire testmode_i,
output wire status_o,

Expand Down Expand Up @@ -68,6 +68,8 @@ module croc_chip import croc_pkg::*; #() (
logic soc_rst_ni;
logic soc_ref_clk_i;
logic soc_testmode_i;
// logic soc_bootmode_i; // Currently unused
logic soc_bootmode_scan_en_i;

logic soc_jtag_tck_i;
logic soc_jtag_trst_ni;
Expand All @@ -77,6 +79,12 @@ module croc_chip import croc_pkg::*; #() (

logic soc_status_o;

logic soc_scan_en_i;
logic scan_in_0;
logic scan_in_1;
logic soc_uart_tx_scan_out_0;
logic soc_jtag_tdo_scan_out_1;

localparam int unsigned GpioCount = 32;

logic [GpioCount-1:0] soc_gpio_i;
Expand All @@ -87,16 +95,16 @@ module croc_chip import croc_pkg::*; #() (
sg13g2_IOPadIn pad_rst_ni (.pad(rst_ni), .p2c(soc_rst_ni));
sg13g2_IOPadIn pad_ref_clk_i (.pad(ref_clk_i), .p2c(soc_ref_clk_i));
sg13g2_IOPadIn pad_jtag_tck_i (.pad(jtag_tck_i), .p2c(soc_jtag_tck_i));
sg13g2_IOPadIn pad_jtag_trst_ni (.pad(jtag_trst_ni), .p2c(soc_jtag_trst_ni));
sg13g2_IOPadIn pad_jtag_tms_i (.pad(jtag_tms_i), .p2c(soc_jtag_tms_i));
sg13g2_IOPadIn pad_jtag_tdi_i (.pad(jtag_tdi_i), .p2c(soc_jtag_tdi_i));
sg13g2_IOPadOut16mA pad_jtag_tdo_o (.pad(jtag_tdo_o), .c2p(soc_jtag_tdo_o));
sg13g2_IOPadIn pad_jtag_tdi_i (.pad(jtag_tdi_i), .p2c(soc_jtag_tdi_i)); // jtag_tck_i Scan chain 1 input
sg13g2_IOPadOut16mA pad_jtag_tdo_o (.pad(jtag_tdo_o), .c2p(soc_jtag_tdo_scan_out_1)); // jtag_tck_i Scan chain 1 output

sg13g2_IOPadIn pad_uart_rx_i (.pad(uart_rx_i), .p2c(soc_uart_rx_i));
sg13g2_IOPadOut16mA pad_uart_tx_o (.pad(uart_tx_o), .c2p(soc_uart_tx_o));
sg13g2_IOPadIn pad_uart_rx_i (.pad(uart_rx_i), .p2c(soc_uart_rx_i)); // clk_i Scan chain 0 input
sg13g2_IOPadOut16mA pad_uart_tx_o (.pad(uart_tx_o), .c2p(soc_uart_tx_scan_out_0)); // clk_i Scan chain 0 output

sg13g2_IOPadIn pad_testmode_i (.pad(testmode_i), .p2c(soc_testmode_i));
sg13g2_IOPadOut16mA pad_status_o (.pad(status_o), .c2p(soc_status_o));
sg13g2_IOPadIn pad_testmode_i (.pad(testmode_i), .p2c(soc_testmode_i));
sg13g2_IOPadIn pad_bootmode_scan_en_i (.pad(bootmode_scan_en_i), .p2c(soc_bootmode_scan_en_i));
sg13g2_IOPadOut16mA pad_status_o (.pad(status_o), .c2p(soc_status_o));

sg13g2_IOPadInOut30mA pad_gpio0_io (.pad(gpio0_io), .c2p(soc_gpio_o[0]), .p2c(soc_gpio_i[0]), .c2p_en(soc_gpio_out_en_o[0]));
sg13g2_IOPadInOut30mA pad_gpio1_io (.pad(gpio1_io), .c2p(soc_gpio_o[1]), .p2c(soc_gpio_i[1]), .c2p_en(soc_gpio_out_en_o[1]));
Expand Down Expand Up @@ -135,6 +143,21 @@ module croc_chip import croc_pkg::*; #() (
sg13g2_IOPadOut16mA pad_unused2_o (.pad(unused2_o), .c2p(soc_status_o));
sg13g2_IOPadOut16mA pad_unused3_o (.pad(unused3_o), .c2p(soc_status_o));

// During normal operation connect jtag reset with system reset, inactivate in testmode
assign soc_jtag_trst_ni = soc_testmode_i ? 1'b1 : soc_rst_ni;
// assign soc_bootmode_i = soc_testmode_i ? 1'b0 : soc_bootmode_scan_en_i; // Currently unused

// Scan enable only active in testmode
(* dont_touch = "true" *)sg13g2_and2_1 i_scan_en_gate (.A(soc_testmode_i), .B(soc_bootmode_scan_en_i), .X(soc_scan_en_i));

(* dont_touch = "true" *)sg13g2_buf_1 i_scan_in_buf_0 (.A(soc_uart_rx_i), .X(scan_in_0)); // clk_i Scan chain 0 input buffer
(* dont_touch = "true" *)sg13g2_buf_1 i_scan_in_buf_1 (.A(soc_jtag_tdi_i), .X(scan_in_1)); // jtag_tck_i Scan chain 1 input buffer

(* dont_touch = "true" *)sg13g2_mux2_1 i_scan_out_mux_0 (.A0(soc_uart_tx_o), .A1(soc_uart_tx_o),
.S(soc_scan_en_i), .X(soc_uart_tx_scan_out_0));
(* dont_touch = "true" *)sg13g2_mux2_1 i_scan_out_mux_1 (.A0(soc_jtag_tdo_o), .A1(soc_jtag_tdo_o),
.S(soc_scan_en_i), .X(soc_jtag_tdo_scan_out_1));

Comment thread
TheMightyDuckOfDoom marked this conversation as resolved.
(* dont_touch = "true" *)sg13g2_IOPadVdd pad_vdd0();
(* dont_touch = "true" *)sg13g2_IOPadVdd pad_vdd1();
(* dont_touch = "true" *)sg13g2_IOPadVdd pad_vdd2();
Expand Down
Loading