Skip to content

Spec: Parameterized Components

Overview

Enable components with configurable parameters (e.g., bit width, number of inputs, modulus) that adjust their pin count, behavior, and rendering dynamically. This eliminates the need for separate fixed-size variants of the same logical component.

Motivation

Currently, each gate variant (2-input AND, 3-input AND, 4-input AND) is a separate class. An N-bit adder requires a different component for 4-bit vs 8-bit. Parameterized components let one definition serve all sizes, reducing component library bloat and giving users flexibility to specify exactly what they need.

Requirements

Functional Requirements

  1. Parameter Definition: Components declare typed parameters (int, enum, bool) with defaults and valid ranges.
  2. Parameter Dialog: Double-click a parameterized component to open a configuration dialog.
  3. Dynamic Pin Generation: Pin count/layout adjusts automatically based on parameters.
  4. Dynamic Evaluation: Component logic adapts to parameter values.
  5. Dynamic Rendering: Shape scales and adapts to accommodate variable pin counts.
  6. Parameter Validation: Enforce constraints (min/max values, valid combinations).
  7. Supported Parameters:
    • Bit width (1–64)
    • Input count (2–16)
    • Counter modulus (2–256)
    • Memory depth/width
    • Operation mode (enum selections)
  8. Parameter Persistence: Parameters are saved/loaded with the circuit file.
  9. Live Update: Changing parameters updates the component immediately on the canvas.
  10. Parameter Templates: Save frequently-used parameter combinations as presets.

Non-Functional Requirements

  • Parameter changes do not corrupt existing wire connections (reconnect where possible).
  • No performance penalty during simulation (parameters are resolved at design-time).
  • Backward compatible: existing fixed components continue to work unchanged.

Design

Parameter Model

csharp
public class ComponentParameter
{
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public ParameterType Type { get; set; }  // Int, Enum, Bool
    public object DefaultValue { get; set; }
    public object MinValue { get; set; }
    public object MaxValue { get; set; }
    public object[] AllowedValues { get; set; }  // for enum type
}

public abstract class ParameterizedComponent : Component
{
    public List<ComponentParameter> Parameters { get; }
    public Dictionary<string, object> ParameterValues { get; set; }

    protected abstract void OnParametersChanged();
    protected abstract void GeneratePins();
    protected abstract ShapeDefinition GenerateShape();
}

Example: Parameterized AND Gate

csharp
public class ParameterizedAndGate : ParameterizedComponent
{
    public ParameterizedAndGate()
    {
        Parameters.Add(new ComponentParameter
        {
            Name = "InputCount",
            DisplayName = "Number of Inputs",
            Type = ParameterType.Int,
            DefaultValue = 2,
            MinValue = 2,
            MaxValue = 16
        });
    }

    protected override void GeneratePins()
    {
        int count = (int)ParameterValues["InputCount"];
        ClearPins();
        for (int i = 0; i < count; i++)
            AddPin(new Pin($"In{i}", PinDirection.Input));
        AddPin(new Pin("Out", PinDirection.Output));
    }

    public override void Evaluate()
    {
        var result = InputPins.All(p => p.SignalState == Signal.High);
        OutputPin.SignalState = result ? Signal.High : Signal.Low;
    }
}

Wire Reconnection on Parameter Change

When parameters change and pins are added/removed:

  1. Pins that still exist keep their connections.
  2. Removed pins: disconnect wires (leave dangling end).
  3. Added pins: unconnected by default.
  4. Notify user of any disconnections.

Parameter Dialog UI

┌────────────────────────────────┐
│ Component Parameters           │
├────────────────────────────────┤
│ AND Gate                       │
│                                │
│ Number of Inputs: [4    ▼]    │
│   Range: 2–16                 │
│                                │
│ Presets: [2-input] [4-input]  │
│          [8-input] [Custom]   │
│                                │
│      [OK]  [Cancel]  [Apply]  │
└────────────────────────────────┘

Implementation Tasks

  1. Create ComponentParameter and ParameterizedComponent base classes.
  2. Implement parameter validation and constraint system.
  3. Implement dynamic pin generation/removal with wire reconnection.
  4. Implement dynamic shape generation for variable pin counts.
  5. Convert existing gate variants to parameterized versions.
  6. Implement parameter dialog UI.
  7. Update file serialization to store parameter values.
  8. Implement parameter presets (save/load templates).
  9. Convert adders, counters, and memory to parameterized forms.
  10. Update toolbox to show parameterized components with default configurations.

Risks & Open Questions

  • Should parameterized components replace fixed variants entirely or coexist?
  • How to handle wire connections when pin positions change due to parameter change?
  • Should parameters be changeable during simulation (live reconfiguration)?
  • How do parameterized components interact with macros (can macro pins be parameterized)?
  • Performance: does dynamic pin generation add overhead during circuit loading?

Priority

Medium — Reduces library complexity, improves flexibility for advanced users.