User:Soundandfury/ECLAIR

From Esolang
Jump to: navigation, search

ECLAIR is an HDL for ternary ECL, if ECL were defined as "weighted summing amplifiers and diodes". eclair is a simulator for combinatoric ECLAIR circuits, and ecloop is a simulator for sequential ECLAIR circuits (also called "LOOPY ECLAIR").

General Format

An .ecl file consists of a series of lines, of the form

value=FUNCTION operands...

or one of the special lines

#NAME blockname
#IN inputs...
#OUT outputs...
#LOOPY

or a block definition

{
	ecl-lines...
}

Operands

The universal datatype is the trit, represented with +,0,-.

Operands must not contain '.' as this is used to read members (this should really just be outputs) of instances.

eclair requires that all 'name' operands must have already been defined, thus precluding circular references. ecloop allows circular references (and thereby sequential logic). An ECLAIR circuit with circular references must contain the #LOOPY directive; eclair will reject any circuit with #LOOPY and advise you to use ecloop instead. Also, block definitions and instantiations are only supported in ecloop, not eclair (because the latter has a crummy old version of the parser. Though someday it might be re-done).

Block definitions may not be nested (though instantiations may appear within blocks). Instantiating a block within itself (even indirectly) is illegal and produces undefined behaviour (for example, the synthesis may get stuck in an unbounded recursion, or it may reject the input with a diagnostic, or just produce unexpected results. Just what "expected results" would be, I'm not quite sure). ecloop requires that a block must be defined before it is instantiated, which prevents recursive instantiation.

Functions

The FUNCTIONs are:

INPUT Denotes an input to the block.
SUM operands Computes the sum of its operands, clamped to {-,0,+}. So SUM - - + - returns -.
WSUM weight operand ... Computes the weighted sum of its odd operands, where the even operands are the weights (first operand is operand 0). So WSUM 2 A 3 - always returns -, because even if A is +, SUM + + - - - = -.
DIODE sign operand Returns operand clamped to {0,sign}. So DIODE + + is +, but DIODE + - is 0.

Blocks

A block definition is just an ordinary ECLAIR circuit, enclosed in curly braces. The block can then be instantiated (many times) by using its #NAME as a FUNCTION; the operands should be the inputs in the order they appear in the block's #IN. The instance's outputs can be read with instance.output

An example:

#NAME Saturating counter
## Demonstrates the use of user-defined blocks and instantiations thereof
## When S is nonzero, add it to the value in M.  This can take up to four clocks.
#IN S
#OUT D
#LOOPY
{
	#NAME MEM
	## 1-trit memory cell
	#IN S R
	#OUT D
	S=INPUT
	R=INPUT
	D=WSUM 2 S 1 Up 1 Dn
	DU=DIODE + D
	DD=DIODE - D
	Up=SUM R DU
	Dn=WSUM - R + DD
}
{
	#NAME NZ
	## Tests nonzero
	#IN X
	#OUT NZ
	X=INPUT
	U=DIODE + X
	D=DIODE - X
	NZ=WSUM + U - D
}
S=INPUT
RR=NZ D
R=WSUM 1 + -1 RR.NZ
M=MEM D R
D=SUM S M.D

Implementation

eclair and ecloop have both been implemented. The source is available at [1], together with some example programs.