feat: add OpenLane hardening config for LDPC decoder (50 MHz)

- config.json: 20ns clock period, AREA 2 synth strategy, 2800x1760um die
- pin_order.cfg: Wishbone pins on south, outputs on north
- base_ldpc.sdc: Caravel-calibrated timing constraints adapted for LDPC ports
- Updated wrapper config to reference ldpc_decoder_top macro

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
cah
2026-02-25 20:08:39 -07:00
parent 412c51a632
commit 81cffda1cb
4 changed files with 209 additions and 8 deletions

View File

@@ -0,0 +1,116 @@
# SDC constraints for ldpc_decoder_top
# Adapted from Caravel user_proj_example SDC
# Target: 50 MHz (20 ns period)
### Note:
# - input clock transition and latency are set for clk port.
# - IO ports are assumed to be asynchronous (IO_SYNC=0).
#------------------------------------------#
# Pre-defined Constraints
#------------------------------------------#
set ::env(IO_SYNC) 0
# Clock network
if {[info exists ::env(CLOCK_PORT)] && $::env(CLOCK_PORT) != ""} {
set clk_input $::env(CLOCK_PORT)
create_clock [get_ports $clk_input] -name clk -period $::env(CLOCK_PERIOD)
puts "\[INFO\]: Creating clock {clk} for port $clk_input with period: $::env(CLOCK_PERIOD)"
} else {
set clk_input __VIRTUAL_CLK__
create_clock -name clk -period $::env(CLOCK_PERIOD)
puts "\[INFO\]: Creating virtual clock with period: $::env(CLOCK_PERIOD)"
}
if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL)] } {
set ::env(SYNTH_CLK_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL)
}
if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL_PIN)] } {
set ::env(SYNTH_CLK_DRIVING_CELL_PIN) $::env(SYNTH_DRIVING_CELL_PIN)
}
# Clock non-idealities
set_propagated_clock [all_clocks]
set_clock_uncertainty $::env(SYNTH_CLOCK_UNCERTAINTY) [get_clocks {clk}]
puts "\[INFO\]: Setting clock uncertainity to: $::env(SYNTH_CLOCK_UNCERTAINTY)"
set_clock_transition $::env(SYNTH_CLOCK_TRANSITION) [get_clocks {clk}]
puts "\[INFO\]: Setting clock transition to: $::env(SYNTH_CLOCK_TRANSITION)"
# Maximum transition time for the design nets
set_max_transition $::env(MAX_TRANSITION_CONSTRAINT) [current_design]
puts "\[INFO\]: Setting maximum transition to: $::env(MAX_TRANSITION_CONSTRAINT)"
# Maximum fanout
set_max_fanout $::env(MAX_FANOUT_CONSTRAINT) [current_design]
puts "\[INFO\]: Setting maximum fanout to: $::env(MAX_FANOUT_CONSTRAINT)"
# Timing paths delays derate
set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 100}] %"
# Reset input delay
set_input_delay [expr $::env(CLOCK_PERIOD) * 0.5] -clock [get_clocks {clk}] [get_ports {rst_n}]
# Multicycle paths for Wishbone handshake
set_multicycle_path -setup 2 -through [get_ports {wb_ack_o}]
set_multicycle_path -hold 1 -through [get_ports {wb_ack_o}]
set_multicycle_path -setup 2 -through [get_ports {wb_cyc_i}]
set_multicycle_path -hold 1 -through [get_ports {wb_cyc_i}]
set_multicycle_path -setup 2 -through [get_ports {wb_stb_i}]
set_multicycle_path -hold 1 -through [get_ports {wb_stb_i}]
#------------------------------------------#
# Retrieved Constraints (from Caravel)
#------------------------------------------#
# Clock source latency
set clk_max_latency 5.57
set clk_min_latency 4.65
set_clock_latency -source -max $clk_max_latency [get_clocks {clk}]
set_clock_latency -source -min $clk_min_latency [get_clocks {clk}]
puts "\[INFO\]: Setting clock latency range: $clk_min_latency : $clk_max_latency"
# Clock input Transition
set clk_tran 0.61
set_input_transition $clk_tran [get_ports $clk_input]
puts "\[INFO\]: Setting clock transition: $clk_tran"
# Input delays (scaled from Caravel characterization)
set_input_delay -max 3.17 -clock [get_clocks {clk}] [get_ports {wb_sel_i[*]}]
set_input_delay -max 3.74 -clock [get_clocks {clk}] [get_ports {wb_we_i}]
set_input_delay -max 3.89 -clock [get_clocks {clk}] [get_ports {wb_adr_i[*]}]
set_input_delay -max 4.13 -clock [get_clocks {clk}] [get_ports {wb_stb_i}]
set_input_delay -max 4.61 -clock [get_clocks {clk}] [get_ports {wb_dat_i[*]}]
set_input_delay -max 4.74 -clock [get_clocks {clk}] [get_ports {wb_cyc_i}]
set_input_delay -min 0.79 -clock [get_clocks {clk}] [get_ports {wb_adr_i[*]}]
set_input_delay -min 1.04 -clock [get_clocks {clk}] [get_ports {wb_dat_i[*]}]
set_input_delay -min 1.19 -clock [get_clocks {clk}] [get_ports {wb_sel_i[*]}]
set_input_delay -min 1.65 -clock [get_clocks {clk}] [get_ports {wb_we_i}]
set_input_delay -min 1.69 -clock [get_clocks {clk}] [get_ports {wb_cyc_i}]
set_input_delay -min 1.86 -clock [get_clocks {clk}] [get_ports {wb_stb_i}]
# Input Transition
set_input_transition -max 0.14 [get_ports {wb_we_i}]
set_input_transition -max 0.15 [get_ports {wb_stb_i}]
set_input_transition -max 0.17 [get_ports {wb_cyc_i}]
set_input_transition -max 0.18 [get_ports {wb_sel_i[*]}]
set_input_transition -max 0.84 [get_ports {wb_dat_i[*]}]
set_input_transition -max 0.92 [get_ports {wb_adr_i[*]}]
set_input_transition -min 0.07 [get_ports {wb_adr_i[*]}]
set_input_transition -min 0.07 [get_ports {wb_dat_i[*]}]
set_input_transition -min 0.09 [get_ports {wb_cyc_i}]
set_input_transition -min 0.09 [get_ports {wb_sel_i[*]}]
set_input_transition -min 0.09 [get_ports {wb_we_i}]
set_input_transition -min 0.15 [get_ports {wb_stb_i}]
# Output delays
set_output_delay -max 0.7 -clock [get_clocks {clk}] [get_ports {irq_o}]
set_output_delay -max 3.62 -clock [get_clocks {clk}] [get_ports {wb_dat_o[*]}]
set_output_delay -max 8.41 -clock [get_clocks {clk}] [get_ports {wb_ack_o}]
set_output_delay -min 0 -clock [get_clocks {clk}] [get_ports {irq_o}]
set_output_delay -min 1.13 -clock [get_clocks {clk}] [get_ports {wb_dat_o[*]}]
set_output_delay -min 1.37 -clock [get_clocks {clk}] [get_ports {wb_ack_o}]
# Output loads
set_load 0.19 [all_outputs]

View File

@@ -0,0 +1,69 @@
{
"DESIGN_NAME": "ldpc_decoder_top",
"FP_PDN_MULTILAYER": false,
"VERILOG_FILES": [
"dir::../../verilog/rtl/defines.v",
"dir::../../verilog/rtl/ldpc_decoder_top.sv",
"dir::../../verilog/rtl/ldpc_decoder_core.sv",
"dir::../../verilog/rtl/wishbone_interface.sv"
],
"CLOCK_PERIOD": 20,
"CLOCK_PORT": "clk",
"CLOCK_NET": "u_core.clk",
"FP_SIZING": "absolute",
"DIE_AREA": [
0,
0,
2800,
1760
],
"FP_PIN_ORDER_CFG": "dir::pin_order.cfg",
"MAX_TRANSITION_CONSTRAINT": 1.5,
"MAX_FANOUT_CONSTRAINT": 16,
"PL_RESIZER_SETUP_SLACK_MARGIN": 0.4,
"GRT_RESIZER_SETUP_SLACK_MARGIN": 0.2,
"GRT_RESIZER_HOLD_SLACK_MARGIN": 0.2,
"PL_RESIZER_HOLD_SLACK_MARGIN": 0.4,
"CTS_CLK_MAX_WIRE_LENGTH": 500,
"MAGIC_DEF_LABELS": false,
"SYNTH_ABC_BUFFERING": false,
"RUN_HEURISTIC_DIODE_INSERTION": true,
"HEURISTIC_ANTENNA_THRESHOLD": 110,
"RUN_ANTENNA_REPAIR": true,
"RUN_POST_GRT_DESIGN_REPAIR": true,
"RUN_POST_GRT_RESIZER_TIMING": true,
"VDD_NETS": [
"vccd1"
],
"GND_NETS": [
"vssd1"
],
"FALLBACK_SDC_FILE": "dir::base_ldpc.sdc",
"MAGIC_DRC_USE_GDS": true,
"DPL_CELL_PADDING": 2,
"GPL_CELL_PADDING": 2,
"SYNTH_STRATEGY": "AREA 2",
"PL_TARGET_DENSITY_PCT": 40,
"pdk::sky130*": {
"RT_MAX_LAYER": "met4",
"scl::sky130_fd_sc_hd": {
"CLOCK_PERIOD": 20
},
"scl::sky130_fd_sc_hdll": {
"CLOCK_PERIOD": 10
},
"scl::sky130_fd_sc_hs": {
"CLOCK_PERIOD": 8
},
"scl::sky130_fd_sc_ls": {
"CLOCK_PERIOD": 10,
"SYNTH_MAX_FANOUT": 5
},
"scl::sky130_fd_sc_ms": {
"CLOCK_PERIOD": 10
}
},
"meta": {
"version": 2
}
}

View File

@@ -0,0 +1,16 @@
#BUS_SORT
#S
clk
rst_n
wb_cyc_i
wb_stb_i
wb_we_i
wb_sel_i\[.*\]
wb_adr_i\[.*\]
wb_dat_i\[.*\]
#N
wb_dat_o\[.*\]
wb_ack_o
irq_o

View File

@@ -21,12 +21,12 @@
"//": "Macros configurations",
"MACROS": {
"user_proj_example": {
"ldpc_decoder_top": {
"gds": [
"dir::../../gds/user_proj_example.gds"
"dir::../../gds/ldpc_decoder_top.gds"
],
"lef": [
"dir::../../lef/user_proj_example.lef"
"dir::../../lef/ldpc_decoder_top.lef"
],
"instances": {
"mprj": {
@@ -35,21 +35,21 @@
}
},
"nl": [
"dir::../../verilog/gl/user_proj_example.v"
"dir::../../verilog/gl/ldpc_decoder_top.v"
],
"spef": {
"min_*": [
"dir::../../spef/multicorner/user_proj_example.min.spef"
"dir::../../spef/multicorner/ldpc_decoder_top.min.spef"
],
"nom_*": [
"dir::../../spef/multicorner/user_proj_example.nom.spef"
"dir::../../spef/multicorner/ldpc_decoder_top.nom.spef"
],
"max_*": [
"dir::../../spef/multicorner/user_proj_example.max.spef"
"dir::../../spef/multicorner/ldpc_decoder_top.max.spef"
]
},
"lib": {
"*": "dir::../../lib/user_proj_example.lib"
"*": "dir::../../lib/ldpc_decoder_top.lib"
}
}
},