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:
reset→NR(active-low reset)set→NS(active-low set)clock→C(clock)data→D(data input)
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:
<net>- Net name to connect<pin>- Pin name of the primitive or macro
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:
<net_list>- Comma-separated list of net names<pin_list>- Comma-separated list of pin names (same order as net list)< >- Angle brackets (required only if net_list contains commas)
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]
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:
LEVEL(LEV) - Standard level format (0, 1, X, Z)OCTAL(OCT) - Octal formatHEXADECIMAL(HEX) - Hexadecimal formatINTEGER1(INT1) - One's complement formatINTEGER2(INT) - Two's complement formatPOSINTEGER(POSINT) - Positive integer format
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
- If only the root name is used, the entire array is substituted in declared order
- For specific selections, all dimension ranges must be specified
- If start and end values are identical, the colon and end value may be omitted (e.g.,
q[2]instead ofq[2:2]) - 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:
- The
%declarestatement specifiesqconsists of three signals:q[1],q[2],q[3] - The default display format is octal (useful when viewing in simulation)
- In the TYPE statement,
o=qrepresents all array elements in declared order - This is equivalent to:
o=q[1],q[2],q[3] - Each PART statement references individual array elements
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)>