Tecs Built-in Chip API
Here is the API for the chips built into the Tecs hardware
simulator, listed in alphabetical order.
Add16
16-bit integer adder. out = a + b where a,b are 16-bit
2's complement representations of integers. Overflow is
neither detected nor handled.
IN a[16], b[16];
OUT out[16];
ALU
The ALU. Computes a pre-defined set of functions out = f(x,y)
where x and y are two 16-bit inputs. The function f is selected
by a set of 6 control bits denoted zx, nx, zy, ny, f, no.
The ALU operation can be described using the following pseudocode:
if zx=1 set x = 0 // 16-bit zero constant
if nx=1 set x = !x // Bit-wise negation
if zy=1 set y = 0 // 16-bit zero constant
if ny=1 set y = !y // Bit-wise negation
if f=1 set out = x + y // Integer 2's complement addition
else set out = x & y // Bit-wise And
if no=1 set out = !out // Bit-wise negation
In addition to computing out, the ALU computes two 1-bit outputs:
if out=0 set zr = 1 else zr = 0 // 16-bit equality comparison
if out<0 set ng = 1 else ng = 0 // 2's complement comparison
IN // 16-bit inputs:
x[16], y[16],
// Control bits:
zx, // Zero the x input
nx, // Negate the x input
zy, // Zero the y input
ny, // Negate the y input
f, // Function code: 1 for add, 0 for and
no; // Negate the out output
OUT // 16-bit output
out[16],
// ALU output flags
zr, // 1 if out=0, 0 otherwise
ng; // 1 if out<0, 0 otherwise
And
And gate: out = a and b.
IN a, b;
OUT out;
And16
16-bit and gate. For i=0..15 out[i] = a[i] and b[i]
IN a[16], b[16];
OUT out[16];
ARegister
A 16-Bit register called "A Register".
If load[t-1]=1 then out[t] = in[t-1]
else out does not change (out[t] = out[t-1])
This built-in chip implementation has the side effect of
providing a GUI representation of a 16-bit register
called "A register" (typically used to store an address).
IN in[16], load;
OUT out[16];
Bit
1-bit memory register.
If load[t-1]=1 then out[t] = in[t-1]
else out does not change (out[t] = out[t-1])
IN in, load;
OUT out;
DFF
Data Flip-flop: out(t)=in(t-1)
where t is the current time unit, or clock cycle.
IN in;
OUT out;
DMux
Demultiplexer. If sel = 0 then {a = in; b = 0} else {a = 0; b = in}
IN in, sel;
OUT a, b;
DMux4Way
4-way demultiplexor. The 2-bit sel input selects the output to which
the in input will be channeled: 00 to a, 01 to b, 10 to c, 11 to d.
The other outputs are set to 0.
IN in, sel[2];
OUT a, b, c, d;
DMux8Way
8-way demultiplexor. The 3-bit sel input selects the output to which
the in input will be channeled: (000 to a, 001 to b, ..., 111 to h).
The other outputs are set to 0.
IN in, sel[3];
OUT a, b, c, d, e, f, g, h;
DRegister
A 16-Bit register called "D Register".
If load[t-1]=1 then out[t] = in[t-1]
else out does not change (out[t] = out[t-1])
This built-in chip implementation has the side effect of
providing a GUI representation of a 16-bit register
called "D register" (typically used to store data).
IN in[16], load;
OUT out[16];
FullAdder
Full adder. Computes sum, the least significant bit of
a + b + c, and carry, the most significant bit of a + b + c.
IN a, b, c;
OUT sum, // LSB of a + b + c
carry; // MSB of a + b + c
HalfAdder
Half adder. Computes sum, the least significnat bit of a + b,
and carry, the most significnat bit of a + b.
IN a, b;
OUT sum, // LSB of a + b
carry; // MSB of a + b
Inc16
16-bit incrementer. out = in + 1 (16-bit addition).
Overflow is neither detected nor handled.
IN in[16];
OUT out[16];
Keyboard
The keyboard (memory map).
Outputs the code of the currently pressed key.
The built-in chip implementation has two side effects supplied
by the simulator. First, the keyboard memory map is continuously
being refreshed from the physical keyboard unit. Second, it
displays a keyboard icon and data entry GUI.
Mux
Multiplexor. If sel=0 then out = a else out = b.
IN a, b, sel;
OUT out;
Mux16
16-bit multiplexor. If sel=0 then out = a else out = b.
IN a[16], b[16], sel;
OUT out[16];
Mux4Way16
4-way 16-bit multiplexor.
out = a -- if sel=00
b -- if sel=01
c -- if sel=10
d -- if sel=11
IN a[16], b[16], c[16], d[16], sel[2];
OUT out[16];
Mux8Way16
8-way 16-bit multiplexor.
out = a -- if sel=000
b -- if sel=001
...
h -- if sel=111
IN a[16], b[16], c[16], d[16],
e[16], f[16], g[16], h[16],
sel[3];
OUT out[16];
Nand
Nand gate: out = a nand b.
IN a, b;
OUT out;
Not
Not gate. out = not in.
IN in;
OUT out;
Not16
16-bit negation gate: for i=0..15 out[i] = not in[i]
IN in[16];
OUT out[16];
Or
Or gate. out = a or b
IN a, b;
OUT out;
Or16
16-bit Or gate. For i=0..15 out[i] = a[i] or b[i]
IN a[16], b[16];
OUT out[16];
Or8Way
8-way Or gate. out = in[0] or in[1] or ... or in[7]
IN in[8];
OUT out;
PC
16-bit counter with load and reset controls.
If reset(t-1) then out(t) = 0
else if load(t-1) then out(t) = in(t-1)
else if inc(t-1) then out(t) = out(t-1) + 1 (integer addition)
else out(t) = out(t-1)
IN in[16], load, inc, reset;
OUT out[16];
RAM16K
Memory of 16K registers, each 16-bit wide.
The chip facilitates read and write operations, as follows:
Read: out(t) = RAM16K[address(t)](t)
Write: If load(t-1) then RAM16K[address(t-1)](t) = in(t-1)
In words: the chip always outputs the value stored at the memory
location specified by address. If load=1, the in value is loaded
into the memory location specified by address. This value becomes
available through the out output starting from the next time step.
IN in[16], load, address[14];
OUT out[16];
RAM4K
Memory of 4K registers, each 16-bit wide.
The chip facilitates read and write operations, as follows:
Read: out(t) = RAM4K[address(t)](t)
Write: If load(t-1) then RAM4K[address(t-1)](t) = in(t-1)
In words: the chip always outputs the value stored at the memory
location specified by address. If load=1, the in value is loaded
into the memory location specified by address. This value becomes
available through the out output starting from the next time step.
IN in[16], load, address[12];
OUT out[16];
RAM512
Memory of 512 registers, each 16-bit wide.
The chip facilitates read and write operations, as follows:
Read: out(t) = RAM512[address(t)](t)
Write: If load(t-1) then RAM512[address(t-1)](t) = in(t-1)
In words: the chip always outputs the value stored at the memory
location specified by address. If load=1, the in value is loaded
into the memory location specified by address. This value becomes
available through the out output starting from the next time step.
IN in[16], load, address[9];
OUT out[16];
RAM64
Memory of 64 registers, each 16-bit wide.
The chip facilitates read and write operations, as follows:
Read: out(t) = RAM64[address(t)](t)
Write: If load(t-1) then RAM64[address(t-1)](t) = in(t-1)
In words: the chip always outputs the value stored at the memory
location specified by address. If load=1, the in value is loaded
into the memory location specified by address. This value becomes
available through the out output starting from the next time step.
IN in[16], load, address[6];
OUT out[16];
RAM8
Memory of 8 registers, each 16-bit wide.
The chip facilitates read and write operations, as follows:
Read: out(t) = RAM8[address(t)](t)
Write: If load(t-1) then RAM8[address(t-1)](t) = in(t-1)
In words: the chip always outputs the value stored at the memory
location specified by address. If load=1, the in value is loaded
into the memory location specified by address. This value becomes
available through the out output starting from the next time step.
IN in[16], load, address[3];
OUT out[16];
Register
16-Bit register.
If load[t-1]=1 then out[t] = in[t-1]
else out does not change (out[t] = out[t-1])
IN in[16], load;
OUT out[16];
ROM32K
Read-Only memory (ROM) of 16K registers, each 16-bit wide.
The chip is designed to facilitate data read, as follows:
out(t) = ROM32K[address(t)](t)
In words: the chip always outputs the value stored at the
memory location specified by address.
The built-in chip implementation has a GUI side-effect,
showing an array-like component that displays the ROM's
contents. The ROM32K chip is supposed to be pre-loaded with
a machine language program. To that end, the built-in chip
implementation also knows how to handle the "ROM32K load Xxx"
script command, where Xxx is the name of a text file containing
a program written in the Hack machine language. When the
simulator encounters such a command in a test script, the code
found in the file is loaded into the simulated ROM32K unit.
IN address[15];
OUT out[16];
Screen
The Screen (memory map).
Functions exactly like a 16-bit 8K RAM:
1. out(t)=Screen[address(t)](t)
2. If load(t-1) then Screen[address(t-1)](t)=in(t-1)
The built-in chip implementation has the side effect of continuously
refreshing a visual 256 by 512 black-and-white screen, simulated
by the simulator. Each row in the visual screen is represented
by 32 consecutive 16-bit words, starting at the top left corner
of the visual screen. Thus the pixel at row r from the top and
column c from the left (0<=r<=255, 0<=c<=511) reflects the c%16
bit (counting from LSB to MSB) of the word found in
Screen[r32+c/16].
IN in[16], // what to write
load, // write-enable bit
address[13]; // where to read/write
OUT out[16]; // Screen value at the given address
Xor
Exclusive-or gate. out = a xor b.
IN a, b;
OUT out;