Pin Connections & Signal Routing

Understanding connection methods: by-order, by-name, and signal vectorization.

Introduction

SIMIC provides flexible methods for connecting signals to component pins. You can use positional (by-order) connections for compact descriptions, or named (by-name) connections when working with schematic capture tools or complex interfaces. Signal arrays enable efficient handling of buses and multi-bit data paths.

By-Order Pin Connections (Default)

The default connection method associates net names with pins positionally according to the type's defined pin order. This is the most compact form and simplifies manual entry.

Example: D-Latch with By-Order Connections

PART=q TYPE=dl I=reset,set,clock,data O=l_out

The DL primitive has pins defined in order as: NR, NS, C, D (inputs) and Q (output). The connection list reset,set,clock,data maps:

Critical: For primitives with dissimilar pin functions (like flip-flops or memories), you must specify net names in the exact order expected by the primitive. Always consult the Built-in Primitives Catalog for pin orders.

By-Name Pin Connections

An alternative form specifies connections using named association rather than positional association. This is important for schematic capture programs that lack pin ordering attributes, or when you want self-documenting code.

Simple Form: Single Net to Single Pin

Syntax:

<net>(<pin>)

Where:

Important: There must be NO whitespace before the left parenthesis.

Example: Simple By-Name Connections

PART=q TYPE=dl I=reset(nr),set(ns),clock(c),data(d)

This explicitly connects reset to pin nr, set to ns, etc. The order in the input list no longer matters when using named connections.

Full Form: Multiple Nets to Multiple Pins

Syntax:

<<net_list>(<pin_list>)>

Where:

Examples: Full Form By-Name Connections

These statements are all equivalent:

* Original by-order:
PART=q TYPE=dl I=reset,set,clock,data

* Simple by-name (one-by-one):
PART=q TYPE=dl I=reset(nr),set(ns),clock(c),data(d)

* Full form (grouped):
PART=q TYPE=dl I=<data,clock(d,c)>,<reset,set(nr,ns)>

* Full form (all at once):
PART=q TYPE=dl I=<data,reset,set,clock(d,nr,ns,c)>

Mixing By-Order and By-Name

You can mix both styles within a single statement. By-order entries fill pins sequentially, while by-name entries override specific positions.

Special Connection Cases

SIMIC provides reserved signal names for common scenarios involving constant values and unconnected pins.

Unconnected Outputs: UNUSED

When instantiating a type with multiple outputs but only some are needed, use the UNUSED reserved word to mark outputs or bus pins as intentionally not connected:

* Type with two outputs:
TYPE=dff I=nr,ns,cl,d O=q,nq

* Instance using both outputs:
PART=ff1 TYPE=dff I=nr1,ns1,cl1,d1 O=q1,nq1

* Instance where q is not needed:
PART=ff2 TYPE=dff I=nr2,ns2,cl2,d2 O=unused,nq2

The UNUSED keyword is self-documenting and prevents pin count mismatch errors. The unused pin is "pushed into" the macro instance and can still be examined hierarchically (e.g., ff2.q).

Constant Connections: ONE and ZERO

Connect inputs to logical constants using the ONE (logical-1) and ZERO (logical-0) reserved words:

* Disable set input by tying to constant high:
PART=latch TYPE=dl I=reset,one,clock,data

* Tie chip select low to enable device:
PART=mem TYPE=sram I=zero,addr,we,data

* PLA with enable and chip-select tied high:
PART=decoder TYPE=pla I=one,one,addr[3:0] O=out[15:0]
Case Insensitivity: All three reserved signal names (ONE, ZERO, UNUSED) are case-insensitive. unused, Unused, and UNUSED are equivalent.

Combining with By-Name Connections

Reserved signals work with both by-order and by-name connection methods:

* By-order with UNUSED:
PART=ff TYPE=dffe I=nr,ns,clk,d O=unused,q,nq

* By-name with constants:
PART=gate TYPE=and4 I=one(a),zero(b),sig1(c),sig2(d)

Signal Arrays (Vectors)

Signals can be grouped into arrays of up to 2 dimensions. Arrays provide compact notation for buses, data paths, and memory interfaces. The terms "array" and "vector" are used interchangeably.

Declaring Signal Arrays

Arrays are declared with the %DECLARE statement, which specifies array bounds and a default display radix for simulation. The scope is local to the containing type.

Syntax:

%DECLARE <format>=<array_list>

Available Formats:

Array Specification:

Single-dimensional array:

<root_name>[<start>:<end>]

Two-dimensional array:

<root_name>[<start2>:<end2>][<start1>:<end1>]

Where <start> and <end> are integers defining the array extents.

Using Signal Arrays

Array Reference Rules

  1. If only the root name is used, the entire array is substituted in declared order
  2. For specific selections, all dimension ranges must be specified
  3. If start and end values are identical, the colon and end value may be omitted (e.g., q[2] instead of q[2:2])
  4. Only signals may use array notation (not parts or types)

Example: Johnson Counter with Signal Arrays

!format p= t= i= o=
t=johnson_counter i=clock,reset o=q

%declare octal=q[1:3]

buf     and     reset           rbuf
f1      dcf     rbuf,one,clock,back    q[1]
f2      dcf     rbuf,one,clock,q[1]    q[2]
f3      dcf     rbuf,one,clock,q[2]    q[3]
back    inv     q[3]

Breaking this down:

Tip: Using arrays with appropriate display formats (octal, hex) makes debugging multi-bit buses much easier during simulation.

Multidimensional Arrays

Two-dimensional arrays are useful for memory arrays, matrices, or grid structures:

Example: 4x8 Memory Array

%declare hex=mem[0:3][0:7]

* Access entire array:
t=memory_block o=mem

* Access specific row:
p=driver1 t=driver o=mem[0][0:7]

* Access specific cell:
p=latch1 t=latch o=mem[2][5]

Array dimensions follow right-to-left indexing: name[row][column]

Practical Examples

8-bit Data Bus

%declare hex=data[0:7],addr[0:15]

t=cpu i=clk o=data,addr

* Connect full bus:
p=mem1 t=ram i=clk,data,addr

* Connect partial bus:
p=port1 t=io_port i=data[0:3]

By-Name with Arrays

%declare hex=d[0:7],a[0:15]

* Mix by-name and array notation:
p=ram1 t=ram i=<clk,d,a(clock,data,address)>