X_eTaL-fpga

X_eTaL programs as hardware: a typed array program becomes a circuit, simulated and checked bit for bit against the X_eTaL evaluator, and on its way to a Tang Nano.

c := a + b on eight 16-bit numbers is eight adders; '+ r_/ v is a tree of adders; a step function over a state vector is registers and the logic between them. Every example here is an X_eTaL program first. Its output is the reference, and the intermediate form, the simulated circuit and the generated Verilog must all reproduce it. The first machine, HEX1000, is a 4-bit calculator in the spirit of the TI TMS1000, sized for a Tang Nano 1K; larger machines go to the Tang Nano 9K and 20K and the Tang Primer boards.

            X_eTaL program (.xtl)
                    |
   +----------------+----------------+
   v                v                v
evaluator    intermediate form   simulated circuit, Verilog
   |                |                |
   +----------------+----------------+
                    v
             the same answers

HEX1000

A 4-bit machine of our own design in the spirit of the TMS1000: a 4-bit accumulator, 64 words of 4-bit RAM, a ROM of 1024 instructions, a program counter that steps as a shift register (docs/machine.md). It is written in X_eTaL (the Hex1000 library: one instruction is a pure step function of the machine's state), and its ROM holds a program in its own instructions (rom/calc.asm, about 330 of them) that makes it an eight-digit hexadecimal calculator. Keys go in through its key matrix and the digits come out on its output latches, nothing else computing; every screen is checked against the specification, the Radix library. The screens below were made by running it while this page was built:

HEX1000 at a terminal: 12+34= shows 46, C0DE+BEEF= shows 17FCD, A*B= shows 6E, FFFFFFFF*FFFFFFFF= shows 1

Keys typedScreen
12+34=
      46
FF+1=
     100
A*B=
      6E
C0DE+BEEF=
   17FCD
5-7=
FFFFFFFE
FFFFFFFF+1=
       0
2*3+4=
       A
FFFFFFFF*FFFFFFFF=
       1

12+34= takes the machine 1752 instructions, FFFFFFFF*FFFFFFFF= 16406: on a Tang Nano at 13.5 million instructions a second, about a millisecond. Try HEX1000 in your browser: the same program, X_eTaL running in the page. Or at a terminal: clone the repository and run just calc (keys 0-9 A-F + - * = X, q to quit); just demo-lib Hex1000 listing shows its ROM, page by page. Next: the machine as a circuit, then on a Tang Nano 1K.

Libraries

Each links to its documentation, generated by xetal doc from the ## comments in its source; every ## >> example there is run as a test. The documentation index also has the demo programs, a search, the built-ins, and each source file.

LibraryAliasWhat
Clockedck:clocked circuits as X_eTaL step functions: counters, accumulators, shift registers, a sequence detector, a RAM, and the harness that clocks them
Datapathdp:the vector examples at a stated width: the whole-array operations a circuit realizes directly
Fixedfx:fixed-width two's complement numbers at a stated width, the arithmetic a w-bit circuit does
Hex1000hx:HEX1000, a 4-bit machine in the spirit of the TMS1000: its state, one instruction as a pure step, a run harness, an assembler
Radixrx:an eight-digit calculator in any radix (hexadecimal, octal, decimal): the specification HEX1000's ROM program must meet
Uartua:a serial port (UART: 8 data bits, no parity, 1 stop bit) as X_eTaL step functions: a transmitter, a receiver, and the two looped back

Circuits

The Verilog-2005 of every example circuit, as pinned in the repository. Each is checked by a simulator of the same netlist against the X_eTaL evaluator, and every module passes its self-checking testbench under iverilog, Verilator's lint and Yosys's synthesis.

LibraryModuleSchedule
Clockedaccumulator.vClocked: registers from reset, one stream item per clock.
Clockedcounter.vClocked: registers from reset, one stream item per clock.
Clockeddetect.vClocked: registers from reset, one stream item per clock.
Clockedram.vClocked: registers from reset, one stream item per clock.
Clockedshift.vClocked: registers from reset, one stream item per clock.
Datapathpipeline.lanes1.vTemporal schedule: 1 lane(s), done after 8 clock(s) from reset.
Datapathpipeline.vSpatial schedule: 8 lane(s), combinational.
Datapathreduce-sum.lanes1.vTemporal schedule: 1 lane(s), done after 8 clock(s) from reset.
Datapathreduce-sum.vSpatial schedule: 8 lane(s), combinational.
Datapathsaxpy.lanes1.vTemporal schedule: 1 lane(s), done after 8 clock(s) from reset.
Datapathsaxpy.vSpatial schedule: 8 lane(s), combinational.
Datapaththreshold.lanes1.vTemporal schedule: 1 lane(s), done after 8 clock(s) from reset.
Datapaththreshold.vSpatial schedule: 8 lane(s), combinational.
Datapathvector-add.lanes1.vTemporal schedule: 1 lane(s), done after 8 clock(s) from reset.
Datapathvector-add.vSpatial schedule: 8 lane(s), combinational.
Fixedcounter.vClocked: registers from reset, one stream item per clock.
Hex1000hex1000.vClocked: registers from reset, one stream item per clock.
Uartloopback.vClocked: registers from reset, one stream item per clock.

Documents