From c72a42e8274987f2560ed36541946a4a365b47f3 Mon Sep 17 00:00:00 2001 From: Jaehyun Kim Date: Mon, 23 Feb 2026 00:22:31 +0900 Subject: [PATCH] test: strengthen liberty and verilog test assertions Add meaningful verification to liberty ECSM, sky130 corners, writer, and roundtrip tests. Expand verilog specify, escaped-write, remove-cells, write, and writer tests with content checks, roundtrip validation, and error guards. Update corresponding .ok golden files. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Jaehyun Kim --- liberty/test/liberty_ecsm.tcl | 29 ++++++++++ liberty/test/liberty_sky130_corners.ok | 2 + liberty/test/liberty_sky130_corners.tcl | 28 ++++++++-- liberty/test/liberty_write_roundtrip.tcl | 41 ++++++++++++++ liberty/test/liberty_writer.tcl | 31 +++++++++++ verilog/test/verilog_escaped_write_const.tcl | 37 +++++++++++++ verilog/test/verilog_escaped_write_supply.tcl | 23 ++++++++ verilog/test/verilog_remove_cells_complex.ok | 5 +- verilog/test/verilog_remove_cells_complex.tcl | 49 ++++++++++++++++- verilog/test/verilog_remove_cells_hier.ok | 9 ++-- verilog/test/verilog_remove_cells_hier.tcl | 50 ++++++++++++++++- .../test/verilog_remove_cells_multigate.ok | 7 +-- .../test/verilog_remove_cells_multigate.tcl | 53 +++++++++++++++++-- verilog/test/verilog_remove_cells_supply.ok | 5 +- verilog/test/verilog_remove_cells_supply.tcl | 47 +++++++++++++++- verilog/test/verilog_specify.tcl | 38 +++++++++++++ verilog/test/verilog_write_asap7.tcl | 41 ++++++++++++++ verilog/test/verilog_write_assign_types.tcl | 19 +++++++ verilog/test/verilog_write_bus_types.tcl | 21 ++++++++ .../test/verilog_write_complex_bus_types.tcl | 21 ++++++++ verilog/test/verilog_write_options.tcl | 39 ++++++++++++++ verilog/test/verilog_write_sky130.tcl | 20 +++++++ verilog/test/verilog_writer_asap7.tcl | 41 ++++++++++++++ verilog/test/verilog_writer_modify.ok | 4 +- verilog/test/verilog_writer_modify.tcl | 39 ++++++++++++-- verilog/test/verilog_writer_nangate.tcl | 29 ++++++++++ verilog/test/verilog_writer_sky130.tcl | 29 ++++++++++ 27 files changed, 720 insertions(+), 37 deletions(-) diff --git a/liberty/test/liberty_ecsm.tcl b/liberty/test/liberty_ecsm.tcl index 9000d6b5..36235a55 100644 --- a/liberty/test/liberty_ecsm.tcl +++ b/liberty/test/liberty_ecsm.tcl @@ -2,6 +2,15 @@ source ../../test/helpers.tcl read_liberty liberty_ecsm.lib +set ecsm_src [open liberty_ecsm.lib r] +set ecsm_text [read $ecsm_src] +close $ecsm_src +foreach token {ecsm_waveform ecsm_waveform_set ecsm_capacitance} { + if {[string first $token $ecsm_text] < 0} { + error "liberty_ecsm.lib is missing expected ECSM token '$token'" + } +} + set cell_names {} foreach cell [get_lib_cells test_ecsm_lib/*] { lappend cell_names [get_name $cell] @@ -11,3 +20,23 @@ puts "ecsm cell count: [llength $cell_names]" foreach cell_name $cell_names { puts "ecsm cell: $cell_name" } + +if {$cell_names ne [list ECSM1 ECSM2]} { + error "unexpected ECSM cell list: $cell_names" +} + +foreach cell_name $cell_names { + set cell [get_lib_cell test_ecsm_lib/$cell_name] + set arc_sets [$cell timing_arc_sets] + if {[llength $arc_sets] == 0} { + error "$cell_name has no timing arc sets" + } + + set arc_count 0 + foreach arc_set $arc_sets { + incr arc_count [llength [$arc_set timing_arcs]] + } + if {$arc_count == 0} { + error "$cell_name has no timing arcs" + } +} diff --git a/liberty/test/liberty_sky130_corners.ok b/liberty/test/liberty_sky130_corners.ok index 62d21156..02416425 100644 --- a/liberty/test/liberty_sky130_corners.ok +++ b/liberty/test/liberty_sky130_corners.ok @@ -1,3 +1,5 @@ +Warning: ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib line 1, library sky130_fd_sc_hd__ff_n40C_1v95 already exists. +Warning: ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib line 1, library sky130_fd_sc_hd__ss_n40C_1v40 already exists. --- Fast corner, max --- Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk) Endpoint: out1 (output port clocked by clk) diff --git a/liberty/test/liberty_sky130_corners.tcl b/liberty/test/liberty_sky130_corners.tcl index d6f675e5..b3b7bedd 100644 --- a/liberty/test/liberty_sky130_corners.tcl +++ b/liberty/test/liberty_sky130_corners.tcl @@ -2,12 +2,14 @@ source ../../test/helpers.tcl ############################################################ -# Define corners and read Sky130HD libraries per corner +# Define corners and read Sky130HD libraries with explicit -max/-min views ############################################################ define_corners fast slow -read_liberty -corner fast ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib -read_liberty -corner slow ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib +read_liberty -corner fast -max ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib +read_liberty -corner fast -min ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib +read_liberty -corner slow -min ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib +read_liberty -corner slow -max ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib ############################################################ # Read design and link @@ -39,6 +41,22 @@ report_checks -corner fast -path_delay min puts "--- Slow corner, min ---" report_checks -corner slow -path_delay min +# Additional non-printing checks ensure report_checks emits corner-specific paths +# for both max and min views loaded with -max/-min. +with_output_to_variable fast_max_rep { + report_checks -corner fast -path_delay max +} +if {![regexp {Corner:\s+fast} $fast_max_rep] || ![regexp {Path Type:\s+max} $fast_max_rep]} { + error "fast corner max report did not include expected corner/path markers" +} + +with_output_to_variable slow_min_rep { + report_checks -corner slow -path_delay min +} +if {![regexp {Corner:\s+slow} $slow_min_rep] || ![regexp {Path Type:\s+min} $slow_min_rep]} { + error "slow corner min report did not include expected corner/path markers" +} + ############################################################ # Comprehensive cell reports - fast corner library ############################################################ @@ -79,7 +97,7 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__buf_1 sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dlxtp_1 sky130_fd_sc_hd__sdfxtp_1 sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__mux2_1 sky130_fd_sc_hd__fa_1} { - set cell [get_lib_cell sky130_fd_sc_hd__ss_n40C_1v40/$cell_name] + set cell [lindex [get_lib_cell sky130_fd_sc_hd__ss_n40C_1v40/$cell_name] 0] set area [get_property $cell area] set du [get_property $cell dont_use] puts "$cell_name: area=$area dont_use=$du" @@ -104,7 +122,7 @@ foreach {cell_name pin_name} { sky130_fd_sc_hd__dfrtp_1 RESET_B sky130_fd_sc_hd__dfrtp_1 Q } { - set pin [get_lib_pin sky130_fd_sc_hd__ff_n40C_1v95/$cell_name/$pin_name] + set pin [lindex [get_lib_pin sky130_fd_sc_hd__ff_n40C_1v95/$cell_name/$pin_name] 0] set cap [get_property $pin capacitance] set dir [sta::liberty_port_direction $pin] puts "$cell_name/$pin_name: cap=$cap dir=$dir" diff --git a/liberty/test/liberty_write_roundtrip.tcl b/liberty/test/liberty_write_roundtrip.tcl index e8f78ee1..41550dd2 100644 --- a/liberty/test/liberty_write_roundtrip.tcl +++ b/liberty/test/liberty_write_roundtrip.tcl @@ -7,6 +7,29 @@ # Liberty.cc (property queries during write) source ../../test/helpers.tcl +proc assert_written_liberty {path lib_name} { + if {![file exists $path]} { + error "missing written liberty file: $path" + } + if {[file size $path] <= 0} { + error "written liberty file is empty: $path" + } + + set in [open $path r] + set text [read $in] + close $in + + if {[string first "library (" $text] < 0} { + error "written liberty file has no library block: $path" + } + if {[string first $lib_name $text] < 0} { + error "written liberty file does not contain library name '$lib_name': $path" + } + if {![regexp {cell[[:space:]]*\(} $text]} { + error "written liberty file has no cell blocks: $path" + } +} + ############################################################ # Read and write Nangate45 (comprehensive cell library) ############################################################ @@ -16,6 +39,7 @@ read_liberty ../../test/nangate45/Nangate45_typ.lib # Write liberty - this exercises most of LibertyWriter.cc set outfile1 [make_result_file liberty_roundtrip_nangate.lib] sta::write_liberty NangateOpenCellLibrary $outfile1 +assert_written_liberty $outfile1 NangateOpenCellLibrary puts "Nangate45 write: [file size $outfile1] bytes" @@ -27,6 +51,7 @@ read_liberty ../../test/sky130hd/sky130hd_tt.lib set outfile2 [make_result_file liberty_roundtrip_sky130.lib] sta::write_liberty sky130_fd_sc_hd__tt_025C_1v80 $outfile2 +assert_written_liberty $outfile2 sky130_fd_sc_hd__tt_025C_1v80 puts "Sky130 write: [file size $outfile2] bytes" @@ -38,6 +63,7 @@ read_liberty ../../test/ihp-sg13g2/sg13g2_stdcell_typ_1p20V_25C.lib set outfile3 [make_result_file liberty_roundtrip_ihp.lib] sta::write_liberty sg13g2_stdcell_typ_1p20V_25C $outfile3 +assert_written_liberty $outfile3 sg13g2_stdcell_typ_1p20V_25C puts "IHP write: [file size $outfile3] bytes" @@ -49,6 +75,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz set outfile4 [make_result_file liberty_roundtrip_asap7_simple.lib] sta::write_liberty asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 $outfile4 +assert_written_liberty $outfile4 asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 puts "ASAP7 SIMPLE write: [file size $outfile4] bytes" @@ -60,6 +87,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib set outfile5 [make_result_file liberty_roundtrip_asap7_seq.lib] sta::write_liberty asap7sc7p5t_SEQ_RVT_FF_nldm_220123 $outfile5 +assert_written_liberty $outfile5 asap7sc7p5t_SEQ_RVT_FF_nldm_220123 puts "ASAP7 SEQ write: [file size $outfile5] bytes" @@ -71,6 +99,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz set outfile6 [make_result_file liberty_roundtrip_asap7_invbuf.lib] sta::write_liberty asap7sc7p5t_INVBUF_RVT_FF_nldm_211120 $outfile6 +assert_written_liberty $outfile6 asap7sc7p5t_INVBUF_RVT_FF_nldm_211120 puts "ASAP7 INVBUF write: [file size $outfile6] bytes" @@ -82,6 +111,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz set outfile7 [make_result_file liberty_roundtrip_asap7_ao.lib] sta::write_liberty asap7sc7p5t_AO_RVT_FF_nldm_211120 $outfile7 +assert_written_liberty $outfile7 asap7sc7p5t_AO_RVT_FF_nldm_211120 ############################################################ # Read and write ASAP7 OA (OR-AND cells) @@ -91,6 +121,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz set outfile8 [make_result_file liberty_roundtrip_asap7_oa.lib] sta::write_liberty asap7sc7p5t_OA_RVT_FF_nldm_211120 $outfile8 +assert_written_liberty $outfile8 asap7sc7p5t_OA_RVT_FF_nldm_211120 ############################################################ # Read and write fakeram (SRAM macro with bus ports) @@ -100,6 +131,7 @@ read_liberty ../../test/asap7/fakeram7_256x32.lib set outfile9 [make_result_file liberty_roundtrip_fakeram.lib] sta::write_liberty fakeram7_256x32 $outfile9 +assert_written_liberty $outfile9 fakeram7_256x32 puts "fakeram write: [file size $outfile9] bytes" @@ -111,6 +143,7 @@ read_liberty ../../test/nangate45/fake_macros.lib set outfile10 [make_result_file liberty_roundtrip_fake_macros.lib] sta::write_liberty fake_macros $outfile10 +assert_written_liberty $outfile10 fake_macros ############################################################ # Read and write Nangate45 fast (different corner parameters) @@ -120,6 +153,7 @@ read_liberty ../../test/nangate45/Nangate45_fast.lib set outfile11 [make_result_file liberty_roundtrip_nangate_fast.lib] sta::write_liberty NangateOpenCellLibrary_fast $outfile11 +assert_written_liberty $outfile11 NangateOpenCellLibrary_fast ############################################################ # Read and write Nangate45 slow @@ -129,6 +163,7 @@ read_liberty ../../test/nangate45/Nangate45_slow.lib set outfile12 [make_result_file liberty_roundtrip_nangate_slow.lib] sta::write_liberty NangateOpenCellLibrary_slow $outfile12 +assert_written_liberty $outfile12 NangateOpenCellLibrary_slow ############################################################ # Read and write Nangate45 LVT @@ -138,6 +173,7 @@ read_liberty ../../test/nangate45/Nangate45_lvt.lib set outfile13 [make_result_file liberty_roundtrip_nangate_lvt.lib] sta::write_liberty NangateOpenCellLibrary_lvt $outfile13 +assert_written_liberty $outfile13 NangateOpenCellLibrary_lvt ############################################################ # Read and write multiple fakeram sizes @@ -147,11 +183,13 @@ read_liberty ../../test/nangate45/fakeram45_256x16.lib set outfile14 [make_result_file liberty_roundtrip_fakeram45_256x16.lib] sta::write_liberty fakeram45_256x16 $outfile14 +assert_written_liberty $outfile14 fakeram45_256x16 read_liberty ../../test/nangate45/fakeram45_64x32.lib set outfile15 [make_result_file liberty_roundtrip_fakeram45_64x32.lib] sta::write_liberty fakeram45_64x32 $outfile15 +assert_written_liberty $outfile15 fakeram45_64x32 ############################################################ # Read and write ASAP7 SS corner (different operating conditions) @@ -161,6 +199,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz set outfile17 [make_result_file liberty_roundtrip_asap7_ss.lib] sta::write_liberty asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120 $outfile17 +assert_written_liberty $outfile17 asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120 ############################################################ # Read and write Sky130 FF corner @@ -170,6 +209,7 @@ read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib set outfile18 [make_result_file liberty_roundtrip_sky130_ff.lib] sta::write_liberty sky130_fd_sc_hd__ff_n40C_1v95 $outfile18 +assert_written_liberty $outfile18 sky130_fd_sc_hd__ff_n40C_1v95 ############################################################ # Read and write Sky130 SS corner @@ -179,3 +219,4 @@ read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib set outfile19 [make_result_file liberty_roundtrip_sky130_ss.lib] sta::write_liberty sky130_fd_sc_hd__ss_n40C_1v40 $outfile19 +assert_written_liberty $outfile19 sky130_fd_sc_hd__ss_n40C_1v40 diff --git a/liberty/test/liberty_writer.tcl b/liberty/test/liberty_writer.tcl index fc284796..5ddb3bbd 100644 --- a/liberty/test/liberty_writer.tcl +++ b/liberty/test/liberty_writer.tcl @@ -2,6 +2,29 @@ # Targets: LibertyWriter.cc, LibertyReader.cc (more paths), LibertyBuilder.cc source ../../test/helpers.tcl +proc assert_written_liberty {path lib_name} { + if {![file exists $path]} { + error "missing written liberty file: $path" + } + if {[file size $path] <= 0} { + error "written liberty file is empty: $path" + } + + set in [open $path r] + set text [read $in] + close $in + + if {[string first "library (" $text] < 0} { + error "written liberty file has no library block: $path" + } + if {[string first $lib_name $text] < 0} { + error "written liberty file does not contain library name '$lib_name': $path" + } + if {![regexp {cell[[:space:]]*\(} $text]} { + error "written liberty file has no cell blocks: $path" + } +} + ############################################################ # Read and write various libraries ############################################################ @@ -11,24 +34,28 @@ read_liberty ../../test/nangate45/Nangate45_typ.lib set outfile1 [make_result_file liberty_write_nangate.lib] sta::write_liberty NangateOpenCellLibrary $outfile1 +assert_written_liberty $outfile1 NangateOpenCellLibrary # Read ASAP7 SEQ (exercises different cell types) read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib set outfile2 [make_result_file liberty_write_asap7_seq.lib] sta::write_liberty asap7sc7p5t_SEQ_RVT_FF_nldm_220123 $outfile2 +assert_written_liberty $outfile2 asap7sc7p5t_SEQ_RVT_FF_nldm_220123 # Read ASAP7 SIMPLE (combinational cells) read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz set outfile3 [make_result_file liberty_write_asap7_simple.lib] sta::write_liberty asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 $outfile3 +assert_written_liberty $outfile3 asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 # Read IHP library read_liberty ../../test/ihp-sg13g2/sg13g2_stdcell_typ_1p20V_25C.lib set outfile4 [make_result_file liberty_write_ihp.lib] sta::write_liberty sg13g2_stdcell_typ_1p20V_25C $outfile4 +assert_written_liberty $outfile4 sg13g2_stdcell_typ_1p20V_25C # Read Sky130 library read_liberty ../../test/sky130hd/sky130hd_tt.lib @@ -114,3 +141,7 @@ read_liberty ../../test/sky130hs/sky130_fd_sc_hs__tt_025C_1v80.lib # GF180MCU SRAM read_liberty ../../test/gf180mcu_sram.lib.gz + +if {[llength [get_libs *]] < 20} { + error "expected to load many liberty libraries, but got [llength [get_libs *]]" +} diff --git a/verilog/test/verilog_escaped_write_const.tcl b/verilog/test/verilog_escaped_write_const.tcl index d3251fa2..1f397c97 100644 --- a/verilog/test/verilog_escaped_write_const.tcl +++ b/verilog/test/verilog_escaped_write_const.tcl @@ -2,6 +2,21 @@ # Exercises: writeChildren with constant pin connections source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 6: Write constant/concat design # Exercises: writeChildren with constant pin connections @@ -13,9 +28,15 @@ link_design verilog_const_concat set out9 [make_result_file verilog_escaped_const.v] write_verilog $out9 +assert_file_nonempty $out9 +assert_file_contains $out9 "module verilog_const_concat" +assert_file_contains $out9 "one_" +assert_file_contains $out9 "zero_" set out10 [make_result_file verilog_escaped_const_pwr.v] write_verilog -include_pwr_gnd $out10 +assert_file_nonempty $out10 +assert_file_contains $out10 "module verilog_const_concat" # Roundtrip constant design read_liberty ../../test/nangate45/Nangate45_typ.lib @@ -24,6 +45,22 @@ link_design verilog_const_concat set rt4_cells [get_cells *] puts "const roundtrip cells: [llength $rt4_cells]" +if {[llength $rt4_cells] < 8} { + error "unexpected roundtrip cell count: [llength $rt4_cells]" +} set rt4_nets [get_nets *] puts "const roundtrip nets: [llength $rt4_nets]" +if {[llength $rt4_nets] < 10} { + error "unexpected roundtrip net count: [llength $rt4_nets]" +} + +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {in1 in2 in3}] +set_output_delay -clock clk 0 [get_ports {out1 out2 out3 out4}] +set_input_transition 0.1 [all_inputs] + +with_output_to_variable rt4_rep { report_checks } +if {![regexp {Path Type:\s+max} $rt4_rep]} { + error "roundtrip timing report missing max path section" +} diff --git a/verilog/test/verilog_escaped_write_supply.tcl b/verilog/test/verilog_escaped_write_supply.tcl index ea3847bb..a9c67577 100644 --- a/verilog/test/verilog_escaped_write_supply.tcl +++ b/verilog/test/verilog_escaped_write_supply.tcl @@ -2,6 +2,21 @@ # Exercises: verilogPortDir for tristate/supply, writePortDcls source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 5: Write supply/tristate design (special port directions) # Exercises: verilogPortDir for tristate/supply, writePortDcls @@ -14,6 +29,14 @@ link_design verilog_supply_tristate set out7 [make_result_file verilog_escaped_supply.v] write_verilog $out7 +assert_file_nonempty $out7 +assert_file_contains $out7 "module verilog_supply_tristate" +assert_file_contains $out7 "tri out1;" +assert_file_contains $out7 "assign out3 = n6;" set out8 [make_result_file verilog_escaped_supply_pwr.v] write_verilog -include_pwr_gnd $out8 +assert_file_nonempty $out8 +assert_file_contains $out8 "module verilog_supply_tristate" +assert_file_contains $out8 "wire gnd_net;" +assert_file_contains $out8 "wire vdd_net;" diff --git a/verilog/test/verilog_remove_cells_complex.ok b/verilog/test/verilog_remove_cells_complex.ok index 9427a34e..d39d7c7b 100644 --- a/verilog/test/verilog_remove_cells_complex.ok +++ b/verilog/test/verilog_remove_cells_complex.ok @@ -1,4 +1,3 @@ --- Test 5: complex bus with removes --- -Warning: verilog_remove_cells_complex.tcl line 1, object 'NangateOpenCellLibrary/BUF_X1' not found. -Warning: verilog_remove_cells_complex.tcl line 1, object 'NangateOpenCellLibrary/DFF_X1' not found. -complex remove sizes: buf=2075 dff=2075 +complex remove sizes: buf=1552 dff=1571 +Warning: ../../test/nangate45/Nangate45_typ.lib line 37, library NangateOpenCellLibrary already exists. diff --git a/verilog/test/verilog_remove_cells_complex.tcl b/verilog/test/verilog_remove_cells_complex.tcl index 188659b6..4830334e 100644 --- a/verilog/test/verilog_remove_cells_complex.tcl +++ b/verilog/test/verilog_remove_cells_complex.tcl @@ -1,6 +1,30 @@ # Test 5: Write and re-read complex bus design with removes source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + +proc assert_file_not_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] >= 0} { + error "did not expect '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 5: Write and re-read complex bus design with removes #--------------------------------------------------------------- @@ -10,11 +34,32 @@ read_verilog verilog_complex_bus_test.v link_design verilog_complex_bus_test set out_cb_rm [make_result_file verilog_remove_complex_buf.v] -write_verilog -remove_cells {NangateOpenCellLibrary/BUF_X1} $out_cb_rm +write_verilog -remove_cells {BUF_X1} $out_cb_rm +assert_file_nonempty $out_cb_rm +assert_file_contains $out_cb_rm "module verilog_complex_bus_test" +assert_file_not_contains $out_cb_rm " BUF_X1 " set out_cb_rm2 [make_result_file verilog_remove_complex_dff.v] -write_verilog -remove_cells {NangateOpenCellLibrary/DFF_X1} $out_cb_rm2 +write_verilog -remove_cells {DFF_X1} $out_cb_rm2 +assert_file_nonempty $out_cb_rm2 +assert_file_contains $out_cb_rm2 "module verilog_complex_bus_test" +assert_file_not_contains $out_cb_rm2 " DFF_X1 " set sz_cb_rm1 [file size $out_cb_rm] set sz_cb_rm2 [file size $out_cb_rm2] puts "complex remove sizes: buf=$sz_cb_rm1 dff=$sz_cb_rm2" + +read_liberty ../../test/nangate45/Nangate45_typ.lib +read_verilog $out_cb_rm +link_design verilog_complex_bus_test +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {data_a[*]}] +set_input_delay -clock clk 0 [get_ports {data_b[*]}] +set_output_delay -clock clk 0 [get_ports {result[*]}] +set_output_delay -clock clk 0 [get_ports carry] +set_output_delay -clock clk 0 [get_ports overflow] +set_input_transition 0.1 [all_inputs] +with_output_to_variable rm_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $rm_rep]} { + error "remove_cells complex roundtrip timing report missing max path" +} diff --git a/verilog/test/verilog_remove_cells_hier.ok b/verilog/test/verilog_remove_cells_hier.ok index e40e1721..b8ebc1d1 100644 --- a/verilog/test/verilog_remove_cells_hier.ok +++ b/verilog/test/verilog_remove_cells_hier.ok @@ -1,8 +1,5 @@ --- Test 7: hierarchical with removes --- -Warning: verilog_remove_cells_hier.tcl line 1, object 'NangateOpenCellLibrary/BUF_X1' not found. -Warning: verilog_remove_cells_hier.tcl line 1, object 'NangateOpenCellLibrary/AND2_X1' not found. -Warning: verilog_remove_cells_hier.tcl line 1, object 'NangateOpenCellLibrary/INV_X1' not found. -hier remove sizes: buf=704 and_inv=704 +hier remove sizes: buf=587 and_inv=615 Warning: ../../test/nangate45/Nangate45_typ.lib line 37, library NangateOpenCellLibrary already exists. -hier roundtrip cells: 7 -hier roundtrip hier cells: 11 +hier roundtrip cells: 5 +hier roundtrip hier cells: 7 diff --git a/verilog/test/verilog_remove_cells_hier.tcl b/verilog/test/verilog_remove_cells_hier.tcl index fbda9e95..43fb8eb9 100644 --- a/verilog/test/verilog_remove_cells_hier.tcl +++ b/verilog/test/verilog_remove_cells_hier.tcl @@ -2,6 +2,30 @@ # Exercises: findHierChildren, writeChild remove path source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + +proc assert_file_not_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] >= 0} { + error "did not expect '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 7: Write hierarchical design with removes # Exercises: findHierChildren, writeChild remove path @@ -12,10 +36,17 @@ read_verilog ../../network/test/network_hier_test.v link_design network_hier_test set out_h_rm [make_result_file verilog_remove_hier_buf.v] -write_verilog -remove_cells {NangateOpenCellLibrary/BUF_X1} $out_h_rm +write_verilog -remove_cells {BUF_X1} $out_h_rm +assert_file_nonempty $out_h_rm +assert_file_contains $out_h_rm "module network_hier_test" +assert_file_not_contains $out_h_rm "BUF_X1" set out_h_rm2 [make_result_file verilog_remove_hier_and.v] -write_verilog -remove_cells {NangateOpenCellLibrary/AND2_X1 NangateOpenCellLibrary/INV_X1} $out_h_rm2 +write_verilog -remove_cells {AND2_X1 INV_X1} $out_h_rm2 +assert_file_nonempty $out_h_rm2 +assert_file_contains $out_h_rm2 "module network_hier_test" +assert_file_not_contains $out_h_rm2 "AND2_X1" +assert_file_not_contains $out_h_rm2 "INV_X1" set sz_h_rm [file size $out_h_rm] set sz_h_rm2 [file size $out_h_rm2] @@ -28,6 +59,21 @@ link_design network_hier_test set rt_h_cells [get_cells *] puts "hier roundtrip cells: [llength $rt_h_cells]" +if {[llength $rt_h_cells] == 0} { + error "roundtrip hierarchy has no cells" +} set rt_h_hier [get_cells -hierarchical *] puts "hier roundtrip hier cells: [llength $rt_h_hier]" +if {[llength $rt_h_hier] < [llength $rt_h_cells]} { + error "hierarchical cell count is smaller than flat cell count" +} + +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {in1 in2 in3}] +set_output_delay -clock clk 0 [get_ports {out1 out2}] +set_input_transition 0.1 [all_inputs] +with_output_to_variable hier_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $hier_rep]} { + error "hierarchical remove_cells roundtrip timing report missing max path" +} diff --git a/verilog/test/verilog_remove_cells_multigate.ok b/verilog/test/verilog_remove_cells_multigate.ok index 4e786419..fb56e9d6 100644 --- a/verilog/test/verilog_remove_cells_multigate.ok +++ b/verilog/test/verilog_remove_cells_multigate.ok @@ -1,6 +1,3 @@ --- Test 2: remove_cells on multi-gate design --- -Warning: verilog_remove_cells_multigate.tcl line 1, object 'NangateOpenCellLibrary/INV_X1' not found. -Warning: verilog_remove_cells_multigate.tcl line 1, object 'NangateOpenCellLibrary/AND2_X1' not found. -Warning: verilog_remove_cells_multigate.tcl line 1, object 'NangateOpenCellLibrary/NAND2_X1' not found. -Warning: verilog_remove_cells_multigate.tcl line 1, object 'NangateOpenCellLibrary/NOR2_X1' not found. -multigate sizes: basic=810 inv=810 and=810 gates=810 +multigate sizes: basic=810 inv=774 and=758 gates=704 +Warning: ../../test/nangate45/Nangate45_typ.lib line 37, library NangateOpenCellLibrary already exists. diff --git a/verilog/test/verilog_remove_cells_multigate.tcl b/verilog/test/verilog_remove_cells_multigate.tcl index 99303abc..e64a20a9 100644 --- a/verilog/test/verilog_remove_cells_multigate.tcl +++ b/verilog/test/verilog_remove_cells_multigate.tcl @@ -1,6 +1,31 @@ # Test 2: Write with remove_cells for multi-gate design source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + +proc assert_file_not_has_cell {path cell_name} { + set in [open $path r] + set text [read $in] + close $in + set cell_pat [format {(^|[^A-Za-z0-9_])%s([^A-Za-z0-9_]|$)} $cell_name] + if {[regexp -- $cell_pat $text]} { + error "did not expect cell '$cell_name' in $path" + } +} + #--------------------------------------------------------------- # Test 2: Write with remove_cells for multi-gate design #--------------------------------------------------------------- @@ -14,15 +39,25 @@ write_verilog $out_md_basic # Remove INV_X1 set out_md_inv [make_result_file verilog_remove_md_inv.v] -write_verilog -remove_cells {NangateOpenCellLibrary/INV_X1} $out_md_inv +write_verilog -remove_cells {INV_X1} $out_md_inv +assert_file_nonempty $out_md_inv +assert_file_not_has_cell $out_md_inv INV_X1 +assert_file_contains $out_md_inv "module dcalc_multidriver_test" # Remove AND2_X1 set out_md_and [make_result_file verilog_remove_md_and.v] -write_verilog -remove_cells {NangateOpenCellLibrary/AND2_X1} $out_md_and +write_verilog -remove_cells {AND2_X1} $out_md_and +assert_file_nonempty $out_md_and +assert_file_not_has_cell $out_md_and AND2_X1 +assert_file_contains $out_md_and "module dcalc_multidriver_test" # Remove NAND2_X1 and NOR2_X1 set out_md_gates [make_result_file verilog_remove_md_gates.v] -write_verilog -remove_cells {NangateOpenCellLibrary/NAND2_X1 NangateOpenCellLibrary/NOR2_X1} $out_md_gates +write_verilog -remove_cells {NAND2_X1 NOR2_X1} $out_md_gates +assert_file_nonempty $out_md_gates +assert_file_not_has_cell $out_md_gates NAND2_X1 +assert_file_not_has_cell $out_md_gates NOR2_X1 +assert_file_contains $out_md_gates "module dcalc_multidriver_test" # Compare sizes set sz_md [file size $out_md_basic] @@ -30,3 +65,15 @@ set sz_md_inv [file size $out_md_inv] set sz_md_and [file size $out_md_and] set sz_md_gates [file size $out_md_gates] puts "multigate sizes: basic=$sz_md inv=$sz_md_inv and=$sz_md_and gates=$sz_md_gates" + +read_liberty ../../test/nangate45/Nangate45_typ.lib +read_verilog $out_md_inv +link_design dcalc_multidriver_test +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {in1 in2 in3 in4 sel}] +set_output_delay -clock clk 0 [get_ports {out1 out2 out3}] +set_input_transition 0.1 [all_inputs] +with_output_to_variable md_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $md_rep]} { + error "remove_cells multigate roundtrip timing report missing max path" +} diff --git a/verilog/test/verilog_remove_cells_supply.ok b/verilog/test/verilog_remove_cells_supply.ok index f5d14dbd..2b247319 100644 --- a/verilog/test/verilog_remove_cells_supply.ok +++ b/verilog/test/verilog_remove_cells_supply.ok @@ -1,4 +1,3 @@ --- Test 6: supply/tristate with removes --- -Warning: verilog_remove_cells_supply.tcl line 1, object 'NangateOpenCellLibrary/BUF_X1' not found. -Warning: verilog_remove_cells_supply.tcl line 1, object 'NangateOpenCellLibrary/INV_X1' not found. -supply remove sizes: buf=911 inv_pwr=941 +supply remove sizes: buf=804 inv_pwr=904 +Warning: ../../test/nangate45/Nangate45_typ.lib line 37, library NangateOpenCellLibrary already exists. diff --git a/verilog/test/verilog_remove_cells_supply.tcl b/verilog/test/verilog_remove_cells_supply.tcl index a1f272fc..1c01f4b4 100644 --- a/verilog/test/verilog_remove_cells_supply.tcl +++ b/verilog/test/verilog_remove_cells_supply.tcl @@ -1,6 +1,30 @@ # Test 6: Write assign/tristate design with removes source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + +proc assert_file_not_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] >= 0} { + error "did not expect '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 6: Write assign/tristate design with removes #--------------------------------------------------------------- @@ -10,12 +34,31 @@ read_verilog verilog_supply_tristate.v link_design verilog_supply_tristate set out_st_rm [make_result_file verilog_remove_supply_buf.v] -write_verilog -remove_cells {NangateOpenCellLibrary/BUF_X1} $out_st_rm +write_verilog -remove_cells {BUF_X1} $out_st_rm +assert_file_nonempty $out_st_rm +assert_file_contains $out_st_rm "module verilog_supply_tristate" +assert_file_not_contains $out_st_rm "BUF_X1" set out_st_pwr [make_result_file verilog_remove_supply_pwr.v] -write_verilog -include_pwr_gnd -remove_cells {NangateOpenCellLibrary/INV_X1} $out_st_pwr +write_verilog -include_pwr_gnd -remove_cells {INV_X1} $out_st_pwr +assert_file_nonempty $out_st_pwr +assert_file_contains $out_st_pwr "module verilog_supply_tristate" +assert_file_not_contains $out_st_pwr "INV_X1" +assert_file_contains $out_st_pwr "wire gnd_net;" # Sizes set sz_st_rm [file size $out_st_rm] set sz_st_pwr [file size $out_st_pwr] puts "supply remove sizes: buf=$sz_st_rm inv_pwr=$sz_st_pwr" + +read_liberty ../../test/nangate45/Nangate45_typ.lib +read_verilog $out_st_rm +link_design verilog_supply_tristate +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {in1 in2 in3 en}] +set_output_delay -clock clk 0 [get_ports {out1 out2 out3 outbus[*]}] +set_input_transition 0.1 [all_inputs] +with_output_to_variable st_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $st_rep]} { + error "remove_cells supply roundtrip timing report missing max path" +} diff --git a/verilog/test/verilog_specify.tcl b/verilog/test/verilog_specify.tcl index b302a698..6061cd61 100644 --- a/verilog/test/verilog_specify.tcl +++ b/verilog/test/verilog_specify.tcl @@ -5,6 +5,21 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test: Read verilog with specify blocks and parameters #--------------------------------------------------------------- @@ -15,12 +30,30 @@ link_design counter set cells [get_cells *] puts "cells: [llength $cells]" +if {[llength $cells] != 0} { + error "unexpected cell count in specify test: [llength $cells]" +} set nets [get_nets *] puts "nets: [llength $nets]" +if {[llength $nets] < 4} { + error "unexpected net count in specify test: [llength $nets]" +} set ports [get_ports *] puts "ports: [llength $ports]" +if {[llength $ports] != 4} { + error "unexpected port count in specify test: [llength $ports]" +} + +set src_in [open ../../test/verilog_specify.v r] +set src_text [read $src_in] +close $src_in +foreach token {specify parameter defparam} { + if {[string first $token $src_text] < 0} { + error "missing expected token '$token' in source verilog_specify.v" + } +} #--------------------------------------------------------------- # Write and verify @@ -28,3 +61,8 @@ puts "ports: [llength $ports]" puts "--- write_verilog ---" set outfile [make_result_file verilog_specify_out.v] write_verilog $outfile +assert_file_nonempty $outfile +assert_file_contains $outfile "module counter" +assert_file_contains $outfile "input clk;" +assert_file_contains $outfile "output out;" +assert_file_contains $outfile "endmodule" diff --git a/verilog/test/verilog_write_asap7.tcl b/verilog/test/verilog_write_asap7.tcl index 8ea7c7e3..c6e1d16b 100644 --- a/verilog/test/verilog_write_asap7.tcl +++ b/verilog/test/verilog_write_asap7.tcl @@ -2,6 +2,21 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz @@ -13,16 +28,42 @@ link_design top set out1 [make_result_file verilog_write_asap7.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module top" +assert_file_contains $out1 "BUFx2_ASAP7_75t_R" set out2 [make_result_file verilog_write_asap7_pwr.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module top" # Write with remove_cells set out3 [make_result_file verilog_write_asap7_remove.v] write_verilog -remove_cells {} $out3 +assert_file_nonempty $out3 +assert_file_contains $out3 "module top" # Compare sizes set sz1 [file size $out1] set sz2 [file size $out2] set sz3 [file size $out3] puts "ASAP7 basic: $sz1, pwr_gnd: $sz2, remove_cells: $sz3" + +set in1 [open $out1 r] +set txt1 [read $in1] +close $in1 +set in3 [open $out3 r] +set txt3 [read $in3] +close $in3 +if {$txt1 ne $txt3} { + error "empty -remove_cells output should match baseline output" +} + +create_clock -name clk -period 10 [get_ports {clk1 clk2 clk3}] +set_input_delay -clock clk 0 [get_ports {in1 in2}] +set_output_delay -clock clk 0 [get_ports out] +set_input_transition 0.1 [all_inputs] +with_output_to_variable asap7_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $asap7_rep]} { + error "ASAP7 timing report missing max path" +} diff --git a/verilog/test/verilog_write_assign_types.tcl b/verilog/test/verilog_write_assign_types.tcl index cdcc6b69..2d693342 100644 --- a/verilog/test/verilog_write_assign_types.tcl +++ b/verilog/test/verilog_write_assign_types.tcl @@ -2,9 +2,28 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/nangate45/Nangate45_typ.lib read_verilog verilog_assign_test.v link_design verilog_assign_test set out1 [make_result_file verilog_write_assign_types.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module verilog_assign_test" +assert_file_contains $out1 ".A2(in3)" +assert_file_contains $out1 ".D(in3)" diff --git a/verilog/test/verilog_write_bus_types.tcl b/verilog/test/verilog_write_bus_types.tcl index 28f81eed..c20e2428 100644 --- a/verilog/test/verilog_write_bus_types.tcl +++ b/verilog/test/verilog_write_bus_types.tcl @@ -2,12 +2,33 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/nangate45/Nangate45_typ.lib read_verilog verilog_bus_test.v link_design verilog_bus_test set out1 [make_result_file verilog_write_bus_types.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module verilog_bus_test" +assert_file_contains $out1 "data_in[0]" +assert_file_contains $out1 "data_out[3]" set out2 [make_result_file verilog_write_bus_types_pwr.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module verilog_bus_test" diff --git a/verilog/test/verilog_write_complex_bus_types.tcl b/verilog/test/verilog_write_complex_bus_types.tcl index 5a4535ec..59f13bc1 100644 --- a/verilog/test/verilog_write_complex_bus_types.tcl +++ b/verilog/test/verilog_write_complex_bus_types.tcl @@ -2,12 +2,33 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/nangate45/Nangate45_typ.lib read_verilog verilog_complex_bus_test.v link_design verilog_complex_bus_test set out1 [make_result_file verilog_write_complex_bus_types.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module verilog_complex_bus_test" +assert_file_contains $out1 "data_a[7]" +assert_file_contains $out1 "result[0]" set out2 [make_result_file verilog_write_complex_bus_types_pwr.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module verilog_complex_bus_test" diff --git a/verilog/test/verilog_write_options.tcl b/verilog/test/verilog_write_options.tcl index e902b207..51a0d2aa 100644 --- a/verilog/test/verilog_write_options.tcl +++ b/verilog/test/verilog_write_options.tcl @@ -1,6 +1,21 @@ # Test verilog writer options source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/nangate45/Nangate45_typ.lib read_verilog verilog_test1.v link_design verilog_test1 @@ -8,14 +23,21 @@ link_design verilog_test1 puts "--- write_verilog basic ---" set out1 [make_result_file verilog_write_options_out1.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module verilog_test1" +assert_file_contains $out1 "BUF_X1" puts "--- write_verilog -include_pwr_gnd ---" set out2 [make_result_file verilog_write_options_out2.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module verilog_test1" puts "--- write_verilog -remove_cells (empty list) ---" set out3 [make_result_file verilog_write_options_out3.v] write_verilog -remove_cells {} $out3 +assert_file_nonempty $out3 +assert_file_contains $out3 "module verilog_test1" puts "--- compare pwr_gnd vs basic output ---" set sz1 [file size $out1] @@ -26,11 +48,28 @@ puts "--- compare remove_cells vs basic output ---" set sz3 [file size $out3] puts "basic size: $sz1, remove_cells size: $sz3" +set in1 [open $out1 r] +set txt1 [read $in1] +close $in1 +set in3 [open $out3 r] +set txt3 [read $in3] +close $in3 +if {$txt1 ne $txt3} { + error "empty -remove_cells output should match baseline output" +} + puts "--- write_verilog -sort (deprecated, should warn) ---" set out4 [make_result_file verilog_write_options_out4.v] set msg_sort [write_verilog -sort $out4] puts "write_verilog -sort: $msg_sort" +assert_file_nonempty $out4 +assert_file_contains $out4 "module verilog_test1" +if {$msg_sort ne ""} { + error "write_verilog -sort returned unexpected message: '$msg_sort'" +} puts "--- read_verilog / write_verilog roundtrip ---" # Read back the written verilog to exercise reader code paths set out5 [make_result_file verilog_write_options_out5.v] write_verilog $out5 +assert_file_nonempty $out5 +assert_file_contains $out5 "module verilog_test1" diff --git a/verilog/test/verilog_write_sky130.tcl b/verilog/test/verilog_write_sky130.tcl index d557f492..69fa1032 100644 --- a/verilog/test/verilog_write_sky130.tcl +++ b/verilog/test/verilog_write_sky130.tcl @@ -2,12 +2,32 @@ source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + read_liberty ../../test/sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib read_verilog ../../test/verilog_attribute.v link_design counter set out1 [make_result_file verilog_write_sky130_attr.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module counter" +assert_file_contains $out1 "sky130_fd_sc_hd__dfrtp_1" set out2 [make_result_file verilog_write_sky130_attr_pwr.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module counter" diff --git a/verilog/test/verilog_writer_asap7.tcl b/verilog/test/verilog_writer_asap7.tcl index 59bfd723..a2ac9300 100644 --- a/verilog/test/verilog_writer_asap7.tcl +++ b/verilog/test/verilog_writer_asap7.tcl @@ -1,6 +1,21 @@ # Test advanced verilog writer options - ASAP7 design source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 1: Write verilog from ASAP7 design (has more complexity) #--------------------------------------------------------------- @@ -21,14 +36,21 @@ puts "ports: [llength [get_ports *]]" # Write basic set out1 [make_result_file verilog_advanced_out1.v] write_verilog $out1 +assert_file_nonempty $out1 +assert_file_contains $out1 "module top" +assert_file_contains $out1 "BUFx2_ASAP7_75t_R" # Write with pwr_gnd set out2 [make_result_file verilog_advanced_out2.v] write_verilog -include_pwr_gnd $out2 +assert_file_nonempty $out2 +assert_file_contains $out2 "module top" # Write with remove_cells set out3 [make_result_file verilog_advanced_out3.v] write_verilog -remove_cells {} $out3 +assert_file_nonempty $out3 +assert_file_contains $out3 "module top" # Compare sizes set sz1 [file size $out1] @@ -37,3 +59,22 @@ set sz3 [file size $out3] puts "basic size: $sz1" puts "pwr_gnd size: $sz2" puts "remove_cells size: $sz3" + +set in1 [open $out1 r] +set txt1 [read $in1] +close $in1 +set in3 [open $out3 r] +set txt3 [read $in3] +close $in3 +if {$txt1 ne $txt3} { + error "empty -remove_cells output should match baseline output" +} + +create_clock -name clk -period 10 [get_ports {clk1 clk2 clk3}] +set_input_delay -clock clk 0 [get_ports {in1 in2}] +set_output_delay -clock clk 0 [get_ports out] +set_input_transition 0.1 [all_inputs] +with_output_to_variable asap7_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $asap7_rep]} { + error "writer_asap7 timing report missing max path" +} diff --git a/verilog/test/verilog_writer_modify.ok b/verilog/test/verilog_writer_modify.ok index 48f33c79..c287b6eb 100644 --- a/verilog/test/verilog_writer_modify.ok +++ b/verilog/test/verilog_writer_modify.ok @@ -1,4 +1,2 @@ --- Test 2: Write after modification --- -Warning: verilog_writer_modify.tcl line 1, library 'asap7sc7p5t_INVBUF_RVT' not found. -modified size: 211 -Warning: verilog_writer_modify.tcl line 1, pin extra_buf/A not found. +modified size: 246 diff --git a/verilog/test/verilog_writer_modify.tcl b/verilog/test/verilog_writer_modify.tcl index f0a84c27..66f1403e 100644 --- a/verilog/test/verilog_writer_modify.tcl +++ b/verilog/test/verilog_writer_modify.tcl @@ -1,6 +1,21 @@ # Test advanced verilog writer options - Write after modification source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 2: Write after network modification #--------------------------------------------------------------- @@ -8,18 +23,32 @@ puts "--- Test 2: Write after modification ---" # Need to load a design first to modify read_liberty ../../test/nangate45/Nangate45_typ.lib -read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz read_verilog verilog_test1.v link_design verilog_test1 +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports in1] +set_output_delay -clock clk 0 [get_ports out1] +set_input_transition 0.1 [all_inputs] +with_output_to_variable base_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $base_rep]} { + error "baseline timing report missing max path" +} + # Add an instance and net set new_net [make_net extra_net] -# Using ASAP7 cell here as in original test -set new_inst [make_instance extra_buf asap7sc7p5t_INVBUF_RVT/BUFx2_ASAP7_75t_R] +set new_inst [make_instance extra_buf NangateOpenCellLibrary/BUF_X2] connect_pin extra_net extra_buf/A +with_output_to_variable mod_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $mod_rep]} { + error "modified timing report missing max path" +} set out4 [make_result_file verilog_advanced_out4.v] write_verilog $out4 +assert_file_nonempty $out4 +assert_file_contains $out4 "module verilog_test1" +assert_file_contains $out4 "extra_buf" set sz4 [file size $out4] puts "modified size: $sz4" @@ -27,3 +56,7 @@ puts "modified size: $sz4" disconnect_pin extra_net extra_buf/A delete_instance extra_buf delete_net extra_net +with_output_to_variable final_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $final_rep]} { + error "post-cleanup timing report missing max path" +} diff --git a/verilog/test/verilog_writer_nangate.tcl b/verilog/test/verilog_writer_nangate.tcl index b1d1175a..3bd84034 100644 --- a/verilog/test/verilog_writer_nangate.tcl +++ b/verilog/test/verilog_writer_nangate.tcl @@ -1,6 +1,21 @@ # Test advanced verilog writer options - Nangate45 write source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 4: Write verilog for Nangate45 design #--------------------------------------------------------------- @@ -11,10 +26,24 @@ link_design verilog_test1 set out7 [make_result_file verilog_advanced_out7.v] write_verilog $out7 +assert_file_nonempty $out7 +assert_file_contains $out7 "module verilog_test1" +assert_file_contains $out7 "BUF_X1" set out8 [make_result_file verilog_advanced_out8.v] write_verilog -include_pwr_gnd $out8 +assert_file_nonempty $out8 +assert_file_contains $out8 "module verilog_test1" set sz7 [file size $out7] set sz8 [file size $out8] puts "nangate45 basic: $sz7, pwr_gnd: $sz8" + +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports in1] +set_output_delay -clock clk 0 [get_ports out1] +set_input_transition 0.1 [all_inputs] +with_output_to_variable ng_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $ng_rep]} { + error "writer_nangate timing report missing max path" +} diff --git a/verilog/test/verilog_writer_sky130.tcl b/verilog/test/verilog_writer_sky130.tcl index 54b9e8a8..fa5b1810 100644 --- a/verilog/test/verilog_writer_sky130.tcl +++ b/verilog/test/verilog_writer_sky130.tcl @@ -1,6 +1,21 @@ # Test advanced verilog writer options - Sky130 with attributes source ../../test/helpers.tcl +proc assert_file_nonempty {path} { + if {![file exists $path] || [file size $path] <= 0} { + error "expected non-empty file: $path" + } +} + +proc assert_file_contains {path token} { + set in [open $path r] + set text [read $in] + close $in + if {[string first $token $text] < 0} { + error "expected '$token' in $path" + } +} + #--------------------------------------------------------------- # Test 3: Write verilog for sky130 design with attributes #--------------------------------------------------------------- @@ -12,10 +27,24 @@ link_design counter set out5 [make_result_file verilog_advanced_out5.v] write_verilog $out5 +assert_file_nonempty $out5 +assert_file_contains $out5 "module counter" +assert_file_contains $out5 "sky130_fd_sc_hd__dfrtp_1" set out6 [make_result_file verilog_advanced_out6.v] write_verilog -include_pwr_gnd $out6 +assert_file_nonempty $out6 +assert_file_contains $out6 "module counter" set sz5 [file size $out5] set sz6 [file size $out6] puts "sky130 basic: $sz5, pwr_gnd: $sz6" + +create_clock -name clk -period 10 [get_ports clk] +set_input_delay -clock clk 0 [get_ports {reset in}] +set_output_delay -clock clk 0 [get_ports out] +set_input_transition 0.1 [all_inputs] +with_output_to_variable sky_rep { report_checks -path_delay max } +if {![regexp {Path Type:\s+max} $sky_rep]} { + error "writer_sky130 timing report missing max path" +}