[Project Blog] Resuming Work on the TTA Processor Core

Starting a casual dev blog here.
Don’t expect super in-depth updates or for things to be in any kind of intelligent order, but I’m gonna chronicle the interesting bits that I’ve been working on here instead of dumping it in The Lounge to be buried.

I’ll toss links to sections here as I put them up as a kinda table of contents.

For the people reading this who have no idea what the title’s talking about:

This is a continuation of the Devember 2021 project. My task was to create an entirely new CPU core from the ground up, built on a transport-triggered architecture and implemented on an FPGA. If this sounds interesting, I’ll be putting up more detailed explanations in this thread as I improve and re-implement the Devember proof-of-concept.

The ultimate goal here is to have the entire system built and assembled for Devember 2022 (…it’s happening, right? :kissing:), where my next challenge will be to write as assembler and maybe even start on porting a C compiler to the architecture.

1 Like

Getting Xilinx Foundation 1.5i Running

Some context first. Because I have a lot of them, I’m using Xilinx XC3000A-series FPGAs for the project. The -A variant is an improved refresh of the original XC3000 series that launched… in 1989. To go with the ancient FPGAs, I also need ancient software, and through some unconventional means I’ve managed to get my hands on both a version that I need, Foundation 1.5i, and a working license.

Some of you have probably seen me shitposting Windows 95 screenshots around the forums. I’ve been running it in 86Box, and while it’s been doing an admirable job of pretending to be a '486, the entire experience is apocalyptically awful. Mouse control is awful, input drops out and crashes 86Box sometimes, getting files in/out of the .IMG is tedious, etc etc.

Foundation 1.5i originally ran under DOS, and old DOS at that. But, I’ve found that the latest OS that can run it is actually Windows Embedded POSReady 2009 (the ultimate form of XP Embedded). Which is weird, because the NTVDM - the virtual DOS compatibility layer that makes it possible at all - fails to run it under standard Windows XP, but not POSReady.

You might’ve also seen me shitposting into the Lounge about paying $29 for an old HP ProBook 6555b. In add’n to running all my programming cables/etc to get them away from the daily driver, its purpose is to run this one very specific piece of software.

Normally, POSReady 2009 must be installed from a disc. I don’t know the details, but Rufus/similar are unable to handle the ISO 9660 boot structure the install media uses. But, late versions came with a USB media creation tool:

And so after spending some quality time finding an XP 32-bit driver for every single device in a machine meant to run Windows 7 64-bit, it’s ready to go.


I hope someone at Xilinx is horrified by this.


Updated Instruction Set

I suspect this won’t mean much to anybody without context since I mostly just wrote it for myself, but I threw together an updated + reorganized instruction set list. It’s mildly interesting.

Remember that this thing ‘executes’ with what you’d call a single ‘instruction’ on a conventional register-to-register architecture, by doing MOVE {SOURCE} > {TARGET} - sources are on the left of the sheet, targets on the right.

Fixes to the ISA include -

  • Number of general purpose registers increased to 32 from 8.
  • Branch on Set instruction added.
  • Stack implementation made less useless, now depends directly on the first level of memory/cache.
  • Improved interrupt- and subroutine return address linking to better support recursion and deep stacks of function calls.

Other changes include revising + increasing the System Bus “PORT” width from 2-bit to 8-bit; BUS_PORT is effectively an extension of the 64-bit BUS_ADDRESS but is arbitrated by the core itself and selects which of 255 ‘ports’ that instruction fetch requests (selected by PORT.F / “Bus Fetch Port”) and memory transaction requests (selected by PORT.M / “Bus Memory Transaction Port”) are executed from.

That doesn’t make much sense, so example -

The core resets to address 0x0000_0000_0000_0000, fetch port 0x00, transaction port 0x00.

0x00 is decoded by the First Stage Bootloader ROM, (the BIOS on an x86 system). So, it starts fetching instructions from this ROM.

Let’s say the program wants to enumerate PCI devices. The PCI configuration space is at 0x06, and PCI memory space at 0x07. So, you would set the transaction port to 0x06 - now, instructions are still fetched from 0x00 but memory LOAD/STORE operations target 0x06.

Then let’s say you reach the end of your bootloader, have transferred some OS kernel into memory, and want to start executing from memory. The main memory controller is at 0x01. So, set the fetch port to 0x01. Writing to the fetch port register also causes the core to reset to address zero and so you’ve essentially rebooted into system memory.

I plan on adding a RESET_VECTOR register to control where execution starts at, but you get the idea.