Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tcl versions of Python unit tests #6501

Merged
merged 4 commits into from
Jan 11, 2025
Merged
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
5 changes: 4 additions & 1 deletion src/odb/src/swig/common/odb.i
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ using namespace odb;
%typemap(out) (uint) = (int);
%typemap(out) (uint64) = (long);
%typemap(out) (int64_t) = (long);
%apply int* OUTPUT {int* x, int* y};
%apply int* OUTPUT {int* x, int* y, int& ext};

%ignore odb::dbTechLayerAntennaRule::pwl_pair;
%ignore odb::dbTechLayerAntennaRule::getDiffPAR() const;
Expand Down Expand Up @@ -88,6 +88,8 @@ using namespace odb;
%include "dbhelpers.i"
%include "dbdiff.i"

%rename(getPoint_ext) odb::dbWireDecoder::getPoint(int& x, int& y, int& ext) const;

%include "odb/dbViaParams.h"
%include "odb/dbWireCodec.h"
%include "odb/dbBlockCallBackObj.h"
Expand All @@ -98,3 +100,4 @@ using namespace odb;
%include "odb/wOrder.h"

std::string generateMacroPlacementString(odb::dbBlock* block);

1 change: 1 addition & 0 deletions src/odb/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ or_integration_tests(
test_iterm
test_module
test_net
test_wire_codec
)

# Skipped
Expand Down
211 changes: 211 additions & 0 deletions src/odb/test/helper.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# Converted from helper.py

proc createSimpleDB {{use_default_db 0}} {
if {$use_default_db} {
set db [ord::get_db]
} else {
set db [odb::dbDatabase_create]
}
set tech [odb::dbTech_create $db "simple_tech"]
set L1 [odb::dbTechLayer_create $tech "L1" "ROUTING"]
set lib [odb::dbLib_create $db "lib" $tech "/"]
set chip [odb::dbChip_create $db]
set and2 [createMaster2X1 $lib "and2" 1000 1000 "a" "b" "o"]
set or2 [createMaster2X1 $lib "or2" 500 500 "a" "b" "o"]
return [list $db $lib]
}

proc createMultiLayerDB {} {
set db [odb::dbDatabase_create]
set tech [odb::dbTech_create $db "multi_tech"]

set m1 [odb::dbTechLayer_create $tech "M1" "ROUTING"]
$m1 setWidth 2000
set m2 [odb::dbTechLayer_create $tech "M2" "ROUTING"]
$m2 setWidth 2000
set m3 [odb::dbTechLayer_create $tech "M3" "ROUTING"]
$m3 setWidth 2000

set v12 [odb::dbTechVia_create $tech "VIA12"]
odb::dbBox_create $v12 $m1 0 0 2000 2000
odb::dbBox_create $v12 $m2 0 0 2000 2000

set v23 [odb::dbTechVia_create $tech "VIA23"]
odb::dbBox_create $v23 $m2 0 0 2000 2000
odb::dbBox_create $v23 $m3 0 0 2000 2000

return [list $db $tech $m1 $m2 $m3 $v12 $v23]
}

# logical expr OUT = (IN1&IN2)
#
# (n1) +-----
# IN1--------|a \ (n3)
# (n2) | (i1)o|-----------OUT
# IN2--------|b /
# +-----
proc create1LevelBlock {db lib parent} {
set blockName "1LevelBlock"
set block [odb::dbBlock_create $parent $blockName [$lib getTech] ","]
# Creating Master and2 and instance inst
set and2 [$lib findMaster "and2"]
set inst [odb::dbInst_create $block $and2 "inst"]
# creating our nets
set n1 [odb::dbNet_create $block "n1"]
set n2 [odb::dbNet_create $block "n2"]
set n3 [odb::dbNet_create $block "n3"]
set IN1 [odb::dbBTerm_create $n1 "IN1"]
$IN1 setIoType "INPUT"
set IN2 [odb::dbBTerm_create $n2 "IN2"]
$IN2 setIoType "INPUT"
set OUT [odb::dbBTerm_create $n3 "OUT"]
$OUT setIoType "OUTPUT"
# connecting nets
set a [$inst findITerm "a"]
$a connect $n1
set b [$inst findITerm "b"]
$b connect $n2
set o [$inst findITerm "o"]
$o connect $n3
return $block
}


# logical expr OUT = (IN1&IN2) | (IN3&IN4)
# (n1) +-----
# IN1--------|a \ (n5)
# (n2) | (i1)o|-----------+
# IN2--------|b / | +-------
# +----- +--------\a \ (n7)
# ) (i3)o|---------------OUT
# (n3) +----- +--------/b /
# IN3--------|a \ (n6) | +-------
# (n4) | (i2)o|-----------+
# IN4--------|b /
# +-----
proc create2LevelBlock { db lib parent } {
set blockName "2LevelBlock"
set block [odb::dbBlock_create $parent $blockName [$lib getTech] ","]

set and2 [$lib findMaster "and2"]
set or2 [$lib findMaster "or2"]
# creating instances
set i1 [odb::dbInst_create $block $and2 "i1"]
set i2 [odb::dbInst_create $block $and2 "i2"]
set i3 [odb::dbInst_create $block $or2 "i3"]
# creating nets and block terms
set n1 [odb::dbNet_create $block "n1"]
set n2 [odb::dbNet_create $block "n2"]
set n3 [odb::dbNet_create $block "n3"]
set n4 [odb::dbNet_create $block "n4"]
set n5 [odb::dbNet_create $block "n5"]
set n6 [odb::dbNet_create $block "n6"]
set n7 [odb::dbNet_create $block "n7"]

set IN1 [odb::dbBTerm_create $n1 "IN1"]
$IN1 setIoType "INPUT"
set IN2 [odb::dbBTerm_create $n2 "IN2"]
$IN2 setIoType "INPUT"
set IN3 [odb::dbBTerm_create $n3 "IN3"]
$IN3 setIoType "INPUT"
set IN4 [odb::dbBTerm_create $n4 "IN4"]
$IN4 setIoType "INPUT"
set OUT [odb::dbBTerm_create $n7 "OUT"]
$OUT setIoType "OUTPUT"
# connecting $nets
set i1_a [$i1 findITerm "a"]
$i1_a connect $n1
set i1_b [$i1 findITerm "b"]
$i1_b connect $n2
set i1_o [$i1 findITerm "o"]
$i1_o connect $n5

set i2_a [$i2 findITerm "a"]
$i2_a connect $n3
set i2_b [$i2 findITerm "b"]
$i2_b connect $n4
set i2_o [$i2 findITerm "o"]
$i2_o connect $n6

set i3_a [$i3 findITerm "a"]
$i3_a connect $n5
set i3_b [$i3 findITerm "b"]
$i3_b connect $n6
set i3_o [$i3 findITerm "o"]
$i3_o connect $n7

set P1 [odb::dbBPin_create $IN1]
set P2 [odb::dbBPin_create $IN2]
set P3 [odb::dbBPin_create $IN3]
set P4 [odb::dbBPin_create $IN4]
set P5 [odb::dbBPin_create $OUT]

return $block
}

# +-----
# |in1 \
# out|
# |in2 /
# +-----
proc createMaster2X1 {lib name width height in1 in2 out} {
set master [odb::dbMaster_create $lib $name]
$master setWidth $width
$master setHeight $height
$master setType "CORE"
odb::dbMTerm_create $master $in1 "INPUT"
odb::dbMTerm_create $master $in2 "INPUT"
odb::dbMTerm_create $master $out "OUTPUT"
$master setFrozen
return $master
}

proc createMaster3X1 {lib name width height in1 in2 in3 out} {
set master [odb::dbMaster_create $lib $name]
$master setWidth $width
$master setHeight $height
$master setType "CORE"
odb::dbMTerm_create $master $in1 "INPUT"
odb::dbMTerm_create $master $in2 "INPUT"
odb::dbMTerm_create $master $in3 "INPUT"
odb::dbMTerm_create $master $out "OUTPUT"
$master setFrozen
return $master
}

#
# Assertion helper
#
proc assert { condition { message "assertion failed" } } {
# Try to evaluate the condition as an expression.
# This will work for numeric comparisons (e.g., $x == 5)
if {![catch {uplevel 1 expr $condition}]} {
# If the expression evaluates successfully and returns false, raise an error
if {![uplevel 1 expr $condition]} {
error $message
}
} else {
# If the condition involves string comparison, use string equal or eq.
if {[string equal $condition ""]} {
error $message
}
}
}

#
# List comparison helper, since struct::list isn't available
# returns true if two lists are the same
#
proc lequal {l1 l2} {
foreach elem $l1 {
if { $elem ni $l2 } {
return false
}
}
foreach elem $l2 {
if { $elem ni $l1 } {
return false
}
}
return true
}
156 changes: 156 additions & 0 deletions src/odb/test/test_block.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#package require control
#control::control assert enabled 1
#
# Converted from test_block.py
# TclTest isn't available so just calling tests sequentially
#
source "helper.tcl"

proc placeInst {inst x y} {
$inst setLocation $x $y
$inst setPlacementStatus "PLACED"
}

proc placeBPin {bpin layer x1 y1 x2 y2} {
odb::dbBox_create $bpin $layer $x1 $y1 $x2 $y2
$bpin setPlacementStatus "PLACED"
}

# Set up data
proc setUp {} {
lassign [createSimpleDB] db lib
set parentBlock [odb::dbBlock_create [$db getChip] "Parent"]
set block [create2LevelBlock $db $lib $parentBlock]
$block setCornerCount 4
set extcornerblock [$block createExtCornerBlock 1]
odb::dbTechNonDefaultRule_create $block "non_default_1"
set parentRegion [odb::dbRegion_create $block "parentRegion"]
return [list $db $lib $block $parentBlock]
}

proc tearDown {db} {
odb::dbDatabase_destroy $db
}

proc test_find {} {
lassign [setUp] db lib block parentBlock
# bterm
assert {[[$block findBTerm "IN1"] getName] == "IN1"}
assert {[$block findBTerm "in1"] == "NULL"}
# child
assert {[[$parentBlock findChild "2LevelBlock"] getName] == "2LevelBlock"}
assert {[$parentBlock findChild "1LevelBlock"] == "NULL"}
# inst
assert {[[$block findInst "i3"] getName] == "i3"}
assert {[$parentBlock findInst "i3"] == "NULL"}
# net
assert {[[$block findNet "n2"] getName] == "n2"}
assert {[$block findNet "a"] == "NULL"}
# iterm
set iterm [$block findITerm "i1o"]
assert {[[$iterm getInst] getName] == "i1"}
assert {[[$iterm getMTerm] getName] == "o"}
assert {[$block findITerm "i1\o"] == "NULL"}
# extcornerblock
assert {[[$block findExtCornerBlock 1] getName] == "extCornerBlock__1"}
assert {[$block findExtCornerBlock 0] == "NULL"}
# nondefaultrule
assert {[[$block findNonDefaultRule "non_default_1"] getName] == "non_default_1"}
assert {[$block findNonDefaultRule "non_default_2"] == "NULL"}
# region
assert {[[$block findRegion "parentRegion"] getName] == "parentRegion"}
tearDown $db
}

proc check_box_rect {block min_x min_y max_x max_y} {
set box [$block getBBox]
assert {[$box xMin] == $min_x} [format "bbox xMin doesn't match: %d %d" [$box xMin] $min_x]
assert {[$box xMax] == $max_x} [format "bbox xMax doesn't match: %d %d" [$box xMax] $max_x]
assert {[$box yMin] == $min_y} [format "bbox yMin doesn't match: %d %d" [$box yMin] $min_y]
assert {[$box yMax] == $max_y} [format "bbox yMax doesn't match: %d %d" [$box yMax] $max_y]
}

proc block_placement {block lib test_num flag} {
if {($flag && $test_num == 1) || (!$flag && $test_num >= 1)} {
if {$flag} {
puts "here"
}
placeInst [$block findInst "i1"] 0 3000
placeInst [$block findInst "i2"] -1000 0
placeInst [$block findInst "i3"] 2000 -1000
}
if {($flag && $test_num == 2) || (!$flag && $test_num >= 2)} {
placeBPin [lindex [[$block findBTerm "OUT"] getBPins] 0] \
[[$lib getTech] findLayer "L1"] 2500 -1000 2550 -950
}
if {($flag && $test_num == 3) || (!$flag && $test_num >= 3)} {
odb::dbObstruction_create $block [[$lib getTech] findLayer "L1"] \
-1500 0 -1580 50
}
if {($flag && $test_num == 4) || (!$flag && $test_num >= 4)} {
set n_s [odb::dbNet_create $block "n_s"]
set swire [odb::dbSWire_create $n_s "NONE"]
odb::dbSBox_create $swire [[$lib getTech] findLayer "L1"] \
0 4000 100 4100 "NONE"
}
if {($flag && $test_num == 5) || (!$flag && $test_num >= 5)} {
# TODO ADD WIRE
}
}

proc test_bbox0 {} {
lassign [setUp] db lib block parentBlock
set box [$block getBBox]
check_box_rect $block 0 0 0 0
tearDown $db
}

proc test_bbox1 {} {
lassign [setUp] db lib block parentBlock
set box [$block getBBox]
block_placement $block $lib 1 false
check_box_rect $block -1000 -1000 2500 4000
tearDown $db
}

proc test_bbox2 {} {
lassign [setUp] db lib block parentBlock
set box [$block getBBox]
block_placement $block $lib 2 false
check_box_rect $block -1000 -1000 2550 4000
tearDown $db
}

proc test_bbox3 {} {
lassign [setUp] db lib block parentBlock
# block_placement $block 2 false
# set box [$block getBBox]
# block_placement $block 3 true
set layer [[$lib getTech] findLayer "L1"]
placeInst [$block findInst "i1"] 0 3000
placeInst [$block findInst "i2"] -1000 0
placeInst [$block findInst "i3"] 2000 -1000
placeBPin [lindex [[$block findBTerm "OUT"] getBPins] 0] \
$layer 2500 -1000 2550 -950
set box [$block getBBox]
odb::dbObstruction_create $block $layer -1500 0 -1580 50
check_box_rect $block -1580 -1000 2550 4000
tearDown $db
}

proc test_bbox4 {} {
lassign [setUp] db lib block parentBlock
set box [$block getBBox]
block_placement $block $lib 4 false
check_box_rect $block -1580 -1000 2550 4100
tearDown $db
}

test_find
test_bbox0
test_bbox1
test_bbox2
test_bbox3
test_bbox4
puts "pass"
exit 0
Loading
Loading