mirror of
https://github.com/diodeinc/pcb.git
synced 2026-09-14 20:17:19 +08:00
e0fe28daec
Signed-off-by: akhilles <akhilvelagapudi@gmail.com>
801 lines
24 KiB
Rust
801 lines
24 KiB
Rust
#[macro_use]
|
|
mod common;
|
|
|
|
snapshot_eval!(interface_net_symbol_copy, {
|
|
"test.zen" => r#"
|
|
# Create a symbol
|
|
power_symbol = Symbol(
|
|
name = "PowerSymbol",
|
|
definition = [
|
|
("VCC", ["1"]),
|
|
("GND", ["2"])
|
|
]
|
|
)
|
|
|
|
# Create a net template with a symbol
|
|
power_net_template = Net("POWER", symbol = power_symbol)
|
|
|
|
# Create an interface using the net template
|
|
PowerInterface = interface(
|
|
power = power_net_template,
|
|
ground = Net("GND") # Net without symbol
|
|
)
|
|
|
|
# Instantiate the interface
|
|
power_instance = PowerInterface("PWR")
|
|
|
|
# Print everything
|
|
print("Template net:", power_net_template)
|
|
print("Instance power net:", power_instance.power)
|
|
print("Instance ground net:", power_instance.ground)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_nested_symbol_copy, {
|
|
"test.zen" => r#"
|
|
# Create symbols
|
|
data_symbol = Symbol(
|
|
name = "DataSymbol",
|
|
definition = [("DATA", ["1", "2"])]
|
|
)
|
|
|
|
power_symbol = Symbol(
|
|
name = "PowerSymbol",
|
|
definition = [("VCC", ["1"]), ("GND", ["2"])]
|
|
)
|
|
|
|
# Create net templates
|
|
data_net = Net("DATA", symbol = data_symbol)
|
|
power_net = Net("POWER", symbol = power_symbol)
|
|
|
|
# Create nested interfaces
|
|
DataInterface = interface(
|
|
data = data_net
|
|
)
|
|
|
|
SystemInterface = interface(
|
|
data = DataInterface,
|
|
power = power_net
|
|
)
|
|
|
|
# Instantiate
|
|
system = SystemInterface("SYS")
|
|
|
|
# Print the nets
|
|
print("Data net:", system.data.data)
|
|
print("Power net:", system.power)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_multiple_instances_independent_symbols, {
|
|
"test.zen" => r#"
|
|
# Create a symbol
|
|
io_symbol = Symbol(
|
|
name = "IOSymbol",
|
|
definition = [("IO", ["1"])]
|
|
)
|
|
|
|
# Create interface with net template
|
|
IOInterface = interface(
|
|
io = Net("IO", symbol = io_symbol)
|
|
)
|
|
|
|
# Create multiple instances
|
|
io1 = IOInterface("IO1")
|
|
io2 = IOInterface("IO2")
|
|
|
|
# Print both instances
|
|
print("IO1 net:", io1.io)
|
|
print("IO2 net:", io2.io)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_invoke_with_net_override, {
|
|
"test.zen" => r#"
|
|
# Create symbols
|
|
default_symbol = Symbol(
|
|
name = "DefaultSymbol",
|
|
definition = [("A", ["1"])]
|
|
)
|
|
|
|
override_symbol = Symbol(
|
|
name = "OverrideSymbol",
|
|
definition = [("B", ["2"])]
|
|
)
|
|
|
|
# Create interface with default net
|
|
TestInterface = interface(
|
|
signal = Net("DEFAULT", symbol = default_symbol)
|
|
)
|
|
|
|
# Instance with default
|
|
default_instance = TestInterface("INST1")
|
|
|
|
# Instance with override
|
|
override_net = Net("OVERRIDE", symbol = override_symbol)
|
|
override_instance = TestInterface("INST2", signal = override_net)
|
|
|
|
# Print results
|
|
print("Default instance net:", default_instance.signal)
|
|
print("Override instance net:", override_instance.signal)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_field_specifications, {
|
|
"test.zen" => r#"
|
|
# Interface with field() specifications (basic types only)
|
|
ConfigInterface = interface(
|
|
enable = field(bool, True),
|
|
count = field(int, 42),
|
|
label = field(str, "Default Config"),
|
|
ratio = field(float, 3.14),
|
|
)
|
|
|
|
# Test defaults
|
|
config1 = ConfigInterface("CFG1")
|
|
print("Config1 enable:", config1.enable)
|
|
print("Config1 count:", config1.count)
|
|
print("Config1 label:", config1.label)
|
|
print("Config1 ratio:", config1.ratio)
|
|
|
|
# Test overrides
|
|
config2 = ConfigInterface("CFG2", enable=False, count=100, ratio=2.71)
|
|
print("Config2 enable:", config2.enable)
|
|
print("Config2 count:", config2.count)
|
|
print("Config2 label:", config2.label)
|
|
print("Config2 ratio:", config2.ratio)
|
|
|
|
# Test serialization
|
|
print("--- Serialized JSON ---")
|
|
print(serialize(config1))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_post_init_callback, {
|
|
"test.zen" => r#"
|
|
# Interface with __post_init__ callback
|
|
def validate_power(self):
|
|
print("Validating power interface:", self.net.name)
|
|
if self.net.name.endswith("_VCC"):
|
|
print("Power validation: PASS")
|
|
else:
|
|
print("Power validation: FAIL - name should end with _VCC")
|
|
|
|
PowerInterface = interface(
|
|
net = Net("VCC"),
|
|
__post_init__ = validate_power,
|
|
)
|
|
|
|
# Test post_init execution
|
|
power1 = PowerInterface("MAIN")
|
|
power2 = PowerInterface("CPU")
|
|
|
|
# Test serialization of interface with __post_init__
|
|
print("--- Serialized JSON ---")
|
|
print(serialize(power1))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_mixed_field_types, {
|
|
"test.zen" => r#"
|
|
# Interface mixing regular nets and field() specifications
|
|
MixedInterface = interface(
|
|
power = Net("VCC"),
|
|
ground = Net("GND"),
|
|
enable_pin = Net(), # Auto-generated name
|
|
debug_mode = field(bool, False),
|
|
voltage_level = field(str, "3.3V"),
|
|
)
|
|
|
|
# Test mixed instantiation
|
|
mixed1 = MixedInterface("CTRL")
|
|
print("Mixed power:", mixed1.power.name)
|
|
print("Mixed ground:", mixed1.ground.name)
|
|
print("Mixed enable_pin:", mixed1.enable_pin.name)
|
|
print("Mixed debug_mode:", mixed1.debug_mode)
|
|
print("Mixed voltage_level:", mixed1.voltage_level)
|
|
|
|
# Test with overrides
|
|
custom_power = Net("CUSTOM_VCC")
|
|
mixed2 = MixedInterface("ALT", power=custom_power, debug_mode=True)
|
|
print("Alt power:", mixed2.power.name)
|
|
print("Alt debug_mode:", mixed2.debug_mode)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_nested_composition, {
|
|
"test.zen" => r#"
|
|
# Test interface composition with UART/USART example
|
|
|
|
# Basic UART interface
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
# USART interface that embeds UART
|
|
Usart = interface(
|
|
uart = Uart(TX=Net("USART_TX"), RX=Net("USART_RX")), # Embedded UART instance
|
|
CK = Net("USART_CK"),
|
|
RTS = Net("USART_RTS"),
|
|
CTS = Net("USART_CTS"),
|
|
)
|
|
|
|
# Test basic UART
|
|
uart1 = Uart("MCU_UART")
|
|
print("UART TX:", uart1.TX.name)
|
|
print("UART RX:", uart1.RX.name)
|
|
|
|
# Test USART composition
|
|
usart1 = Usart("MCU_USART")
|
|
print("USART embedded UART TX:", usart1.uart.TX.name)
|
|
print("USART embedded UART RX:", usart1.uart.RX.name)
|
|
print("USART CK:", usart1.CK.name)
|
|
print("USART RTS:", usart1.RTS.name)
|
|
print("USART CTS:", usart1.CTS.name)
|
|
|
|
# Test with field() in composition
|
|
EnhancedUsart = interface(
|
|
uart = Uart(), # Use default UART
|
|
clock_source = field(str, "internal"),
|
|
baud_rate = field(int, 115200),
|
|
flow_control = field(bool, True),
|
|
)
|
|
|
|
eusart1 = EnhancedUsart("ENHANCED")
|
|
print("Enhanced UART TX:", eusart1.uart.TX.name)
|
|
print("Enhanced clock_source:", eusart1.clock_source)
|
|
print("Enhanced baud_rate:", eusart1.baud_rate)
|
|
print("Enhanced flow_control:", eusart1.flow_control)
|
|
|
|
# Test serialization of nested composition
|
|
print("--- USART Serialized JSON ---")
|
|
print(serialize(usart1))
|
|
|
|
print("--- Enhanced USART Serialized JSON ---")
|
|
print(serialize(eusart1))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_serialization_formats, {
|
|
"test.zen" => r#"
|
|
# Test serialization formats for different interface types
|
|
|
|
# Simple Net
|
|
simple_net = Net("SIMPLE_NET")
|
|
print("=== Simple Net ===")
|
|
print(serialize(simple_net))
|
|
|
|
# Simple Interface
|
|
Power = interface(NET = Net("VCC"))
|
|
power = Power("PWR")
|
|
print("=== Simple Interface ===")
|
|
print(serialize(power))
|
|
|
|
# Complex Interface with field() specs
|
|
Config = interface(
|
|
enable = field(bool, True),
|
|
mode = field(str, "auto"),
|
|
count = field(int, 10),
|
|
)
|
|
config = Config("TEST", enable=False)
|
|
print("=== Complex Interface ===")
|
|
print(serialize(config))
|
|
|
|
# Nested Interface (just Power for simplicity)
|
|
System = interface(
|
|
power = Power(),
|
|
debug = field(bool, False),
|
|
)
|
|
system = System("SYS")
|
|
print("=== Nested Interface ===")
|
|
print(serialize(system))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_promotion_serialization, {
|
|
"test.zen" => r#"
|
|
# Test using() promotion target serialization
|
|
|
|
# Power interface with using() Net field
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
# UART interface without using() (baseline)
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
# USART interface with using() Interface field
|
|
Usart = interface(
|
|
uart = using(Uart()),
|
|
CK = Net("USART_CK"),
|
|
)
|
|
|
|
# Complex interface with multiple using() fields of different types (no conflicts)
|
|
ComplexInterface = interface(
|
|
uart_field = using(Uart()), # Direct: Uart
|
|
power_field = using(Power()), # Direct: Power, Transitive: Net via power_field.NET
|
|
regular_net = Net("REGULAR"), # Regular field, no promotion
|
|
config = field(str, "default"), # Regular field, no promotion
|
|
)
|
|
|
|
# Create instances
|
|
power = Power("MAIN")
|
|
uart = Uart("DEBUG")
|
|
usart = Usart("COMM")
|
|
complex = ComplexInterface("COMPLEX")
|
|
|
|
# Test serialization output
|
|
print("=== Power Interface (Net promotion) ===")
|
|
print(serialize(power))
|
|
|
|
print("=== UART Interface (no promotion) ===")
|
|
print(serialize(uart))
|
|
|
|
print("=== USART Interface (Interface promotion) ===")
|
|
print(serialize(usart))
|
|
|
|
print("=== Complex Interface (multiple promotions) ===")
|
|
print(serialize(complex))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_transitive_promotion, {
|
|
"test.zen" => r#"
|
|
# Test transitive promotion path discovery and conflict detection
|
|
|
|
# Base interfaces
|
|
Control = interface(
|
|
reset = using(Net("RESET")),
|
|
)
|
|
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
# Valid transitive promotion - no conflicts
|
|
ValidSystem = interface(
|
|
power = using(Power()), # Direct: Power, Transitive: Net via power.NET
|
|
uart = using(Uart()), # Direct: Uart (no conflicts)
|
|
)
|
|
|
|
# Create instances and test serialization
|
|
control = Control("CTRL")
|
|
power = Power("PWR")
|
|
uart = Uart("UART")
|
|
system = ValidSystem("SYS")
|
|
|
|
print("=== Control Interface ===")
|
|
print(serialize(control))
|
|
|
|
print("=== Power Interface (with transitive to Control and Net) ===")
|
|
print(serialize(power))
|
|
|
|
print("=== UART Interface (no promotions) ===")
|
|
print(serialize(uart))
|
|
|
|
print("=== System Interface (multiple transitive paths) ===")
|
|
print(serialize(system))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_chain_validation, {
|
|
"test.zen" => r#"
|
|
# Test using() chain validation - only complete using() chains create promotion paths
|
|
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
# Define Uart interface first
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
# Test 1: Complete using() chain - should create transitive promotion
|
|
CompleteChain = interface(
|
|
power = using(Power()), # using() → Power → NET using() → Net
|
|
uart = using(Uart()),
|
|
)
|
|
|
|
# Test 2: Broken chain - regular field blocks transitive promotion
|
|
BrokenChain = interface(
|
|
power = Power(), # Regular field - NO transitive promotion
|
|
uart = using(Uart()),
|
|
)
|
|
|
|
# Create instances
|
|
complete = CompleteChain("COMPLETE")
|
|
broken = BrokenChain("BROKEN")
|
|
|
|
print("=== Complete using() Chain ===")
|
|
print(serialize(complete))
|
|
|
|
print("=== Broken Chain (regular field) ===")
|
|
print(serialize(broken))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_direct_conflict_error, {
|
|
"test.zen" => r#"
|
|
# Test direct conflict detection - should error
|
|
BadInterface = interface(
|
|
net1 = using(Net("NET1")),
|
|
net2 = using(Net("NET2")), # CONFLICT: Two using() fields for same type
|
|
)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_transitive_conflict_error, {
|
|
"test.zen" => r#"
|
|
# Test transitive conflict detection - should error
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
)
|
|
|
|
ConflictInterface = interface(
|
|
power = using(Power()), # Transitive Net via power.NET
|
|
direct_net = using(Net("GND")), # CONFLICT: Direct Net path
|
|
)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_deep_recursion, {
|
|
"test.zen" => r#"
|
|
# Test deep recursion in promotion path discovery
|
|
|
|
# Level 1: Basic interface with using()
|
|
Level1 = interface(
|
|
net = using(Net("LEVEL1")),
|
|
)
|
|
|
|
# Level 2: Interface that uses Level1
|
|
Level2 = interface(
|
|
level1 = using(Level1()),
|
|
)
|
|
|
|
# Level 3: Interface that uses Level2
|
|
Level3 = interface(
|
|
level2 = using(Level2()),
|
|
)
|
|
|
|
# This should create transitive promotion: Level3 → Net via "level2.level1.net"
|
|
l3_factory = Level3
|
|
l3_instance = Level3("L3")
|
|
|
|
print("=== Level3 Factory ===")
|
|
print(serialize(l3_factory))
|
|
|
|
print("=== Level3 Instance ===")
|
|
print(serialize(l3_instance))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_serialization_roundtrip, {
|
|
"test.zen" => r#"
|
|
# Test that using() information survives serialization and actual deserialization
|
|
|
|
# Create interface with using()
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
System = interface(
|
|
power = using(Power()),
|
|
uart = using(Uart()),
|
|
)
|
|
|
|
# Create original instance
|
|
original = System("ORIGINAL")
|
|
print("=== Original Instance ===")
|
|
print(serialize(original))
|
|
|
|
# ACTUAL SERIALIZATION/DESERIALIZATION ROUNDTRIP
|
|
serialized = serialize(original)
|
|
deserialized = deserialize(System, serialized)
|
|
|
|
print("=== Deserialized Instance ===")
|
|
print(serialize(deserialized))
|
|
|
|
# Verify they behave the same way
|
|
print("=== Comparison ===")
|
|
print("Original:", original)
|
|
print("Deserialized:", deserialized)
|
|
|
|
# Test that factories still work
|
|
new_from_original = System("NEW_ORIGINAL")
|
|
new_from_deserialized = System("NEW_DESERIALIZED")
|
|
|
|
print("=== Both factories still work ===")
|
|
print("New from original factory:", serialize(new_from_original))
|
|
print("New from deserialized factory:", serialize(new_from_deserialized))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_using_deserialization_roundtrip, {
|
|
"test.zen" => r#"
|
|
# Test complex deserialization with deep using() chains
|
|
|
|
# Level 1: Basic interface with using()
|
|
Level1 = interface(
|
|
net = using(Net("LEVEL1")),
|
|
)
|
|
|
|
# Level 2: Interface that uses Level1
|
|
Level2 = interface(
|
|
level1 = using(Level1()),
|
|
)
|
|
|
|
# Uart interface
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
# Level 3: Interface that uses Level2 plus a different type
|
|
Level3 = interface(
|
|
level2 = using(Level2()),
|
|
uart = using(Uart()),
|
|
)
|
|
|
|
# Create and serialize complex instance
|
|
original = Level3("DEEP")
|
|
print("=== Original Deep Instance ===")
|
|
print(serialize(original))
|
|
|
|
# REAL DESERIALIZATION TEST
|
|
serialized = serialize(original)
|
|
deserialized = deserialize(Level3, serialized)
|
|
|
|
print("=== Deserialized Deep Instance ===")
|
|
print(serialize(deserialized))
|
|
|
|
# Test that the complex promotion paths are preserved
|
|
print("=== Verification ===")
|
|
print("Original display:", original)
|
|
print("Deserialized display:", deserialized)
|
|
|
|
# Create new instances from both to verify factory integrity
|
|
new_original = Level3("NEW_FROM_ORIGINAL")
|
|
new_deserialized = Level3("NEW_FROM_DESERIALIZED")
|
|
|
|
print("=== Factory Integrity Check ===")
|
|
print("New from original:", serialize(new_original))
|
|
print("New from deserialized:", serialize(new_deserialized))
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_promotion_deserialization, {
|
|
"test.zen" => r#"
|
|
# Test automatic promotion during deserialization
|
|
|
|
# Basic interface with Net promotion
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
# Interface with interface promotion
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
Usart = interface(
|
|
uart = using(Uart()),
|
|
CK = Net("USART_CK"),
|
|
)
|
|
|
|
print("=== Test 1: Net promotion ===")
|
|
power = Power()
|
|
power_ser = serialize(power)
|
|
|
|
net_de = deserialize(Net, power_ser)
|
|
print("Power -> Net:", net_de)
|
|
|
|
print("=== Test 2: Interface promotion ===")
|
|
usart = Usart()
|
|
usart_ser = serialize(usart)
|
|
|
|
uart_de = deserialize(Uart, usart_ser)
|
|
print("Usart -> Uart:", uart_de)
|
|
|
|
print("=== Test 3: Deep transitive promotion ===")
|
|
# Create deep nesting
|
|
Level1 = interface(net = using(Net("L1")))
|
|
Level2 = interface(level1 = using(Level1()))
|
|
Level3 = interface(level2 = using(Level2()))
|
|
|
|
l3 = Level3()
|
|
l3_ser = serialize(l3)
|
|
|
|
# Should be able to deserialize as any level
|
|
l2_de = deserialize(Level2, l3_ser)
|
|
l1_de = deserialize(Level1, l3_ser)
|
|
net_de = deserialize(Net, l3_ser)
|
|
|
|
print("Level3 -> Level2:", l2_de)
|
|
print("Level3 -> Level1:", l1_de)
|
|
print("Level3 -> Net:", net_de)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_promotion_error_messages, {
|
|
"test.zen" => r#"
|
|
# Test error messages for invalid promotion targets
|
|
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
Uart = interface(
|
|
TX = Net("UART_TX"),
|
|
RX = Net("UART_RX"),
|
|
)
|
|
|
|
Usart = interface(
|
|
uart = using(Uart()),
|
|
CK = Net("USART_CK"),
|
|
)
|
|
|
|
# Create test data
|
|
usart = Usart()
|
|
usart_ser = serialize(usart)
|
|
|
|
# This should fail with helpful error message
|
|
invalid = deserialize(Power, usart_ser)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_anonymous_interface_error, {
|
|
"test.zen" => r#"
|
|
# Test error for anonymous interface usage in using()
|
|
|
|
# Create a proper interface that would use an anonymous one
|
|
System = interface(
|
|
power = using(interface(NET = using(Net("VCC")))), # Anonymous interface should error
|
|
)
|
|
|
|
# This should fail when the interface tries to get promotion key
|
|
system = System()
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_comprehensive_net_promotion, {
|
|
"test.zen" => r#"
|
|
# Comprehensive Net promotion testing
|
|
|
|
# Basic Net promotion
|
|
Power = interface(
|
|
NET = using(Net("VCC")),
|
|
voltage = field(str, "3.3V"),
|
|
)
|
|
|
|
power = Power()
|
|
net_from_power = deserialize(Net, serialize(power))
|
|
print("Basic Net promotion - Power -> Net:", net_from_power)
|
|
|
|
# Deep Net promotion through multiple levels
|
|
Level1 = interface(
|
|
net = using(Net("DEEP")),
|
|
meta = field(str, "level1"),
|
|
)
|
|
|
|
Level2 = interface(
|
|
level1 = using(Level1()),
|
|
extra = field(int, 42),
|
|
)
|
|
|
|
Level3 = interface(
|
|
level2 = using(Level2()),
|
|
)
|
|
|
|
l3 = Level3()
|
|
print("Deep promotion test - Level3 instance:", l3)
|
|
|
|
# Should extract Net via path "level2.level1.net"
|
|
deep_net = deserialize(Net, serialize(l3))
|
|
print("Deep Net promotion - Level3 -> Net:", deep_net)
|
|
|
|
# Intermediate level promotions
|
|
l2_from_l3 = deserialize(Level2, serialize(l3))
|
|
l1_from_l3 = deserialize(Level1, serialize(l3))
|
|
|
|
print("Intermediate promotions:")
|
|
print(" Level3 -> Level2:", l2_from_l3)
|
|
print(" Level3 -> Level1:", l1_from_l3)
|
|
|
|
# Verify same Net is extracted at all levels
|
|
l2_net = deserialize(Net, serialize(l2_from_l3))
|
|
l1_net = deserialize(Net, serialize(l1_from_l3))
|
|
|
|
print("Net consistency check:")
|
|
print(" Direct from Level3:", deep_net)
|
|
print(" Via Level2:", l2_net)
|
|
print(" Via Level1:", l1_net)
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_field_validation_errors, {
|
|
"test.zen" => r#"
|
|
# Test interface field validation error messages
|
|
|
|
Ground = interface(
|
|
NET = Net("GND")
|
|
)
|
|
|
|
Power = interface(
|
|
NET = Net("VCC")
|
|
)
|
|
|
|
Gpio = interface(
|
|
NET = Net("GPIO")
|
|
)
|
|
|
|
Uart = interface(
|
|
TX = Net("TX"),
|
|
RX = Net("RX"),
|
|
)
|
|
|
|
System = interface(
|
|
power = Ground(),
|
|
uart = Uart(),
|
|
)
|
|
|
|
# Valid cases first
|
|
gnd = Ground("MAIN_GND")
|
|
gpio_valid = Gpio("GPIO1", NET=gnd.NET) # Net -> Net: valid
|
|
print("Valid case:", gpio_valid.NET.name)
|
|
|
|
system_valid = System("SYS1", power=gnd) # Ground -> Ground: valid
|
|
print("Valid system:", system_valid.power.NET.name)
|
|
|
|
# Test error case: Interface where Net expected
|
|
bad_gpio = Gpio("BAD", NET=gnd) # Ground -> Net: error
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_field_validation_mixed_types, {
|
|
"test.zen" => r#"
|
|
# Test validation: string where Net expected
|
|
|
|
Gpio = interface(NET = Net("GPIO"))
|
|
|
|
# This should error: string where Net expected
|
|
bad_gpio = Gpio("BAD", NET="not_a_net")
|
|
"#
|
|
});
|
|
|
|
snapshot_eval!(interface_field_validation_net_to_interface, {
|
|
"test.zen" => r#"
|
|
# Test error when Net provided where Interface expected
|
|
|
|
Ground = interface(NET = Net("GND"))
|
|
System = interface(power = Ground())
|
|
|
|
net = Net("SOME_NET")
|
|
|
|
# This should error: Net where Ground interface expected
|
|
bad_system = System("BAD", power=net)
|
|
"#
|
|
});
|