General-purpose computer from scratch

The Nand to Tetris saga

In the "Nand to Tetris" course, I completed a series of 12 projects based on Elements of Computing Systems. This comprehensive course guided me through building a computer system from the ground up, starting with basic logic gates and culminating in the creation of a fully functional computer system. Each project tackled a fundamental aspect of computing, including hardware design, assembly language, and operating systems, providing a deep understanding of the entire computing stack.

In the "Nand to Tetris" course, I completed a series of 12 projects based on Elements of Computing Systems. This comprehensive course guided me through building a computer system from the ground up, starting with basic logic gates and culminating in the creation of a fully functional computer system. Each project tackled a fundamental aspect of computing, including hardware design, assembly language, and operating systems, providing a deep understanding of the entire computing stack.

Organization

The University of Chicago

Core Technologies

Python Hardware Simulator CPU Emulator VM Emulator Assembler Compiler

Domain

Computer Systems Architecture

Date

October 2023

Nand to Tetris overview
Nand to Tetris overview
Nand to Tetris overview

Technical highlight

Each component in this big picture was built from scratch in a bottom up manner i.e starting from the hardware platform's logic gates designed in VHDL to the software platform's compiler.

CPU Architecture
CPU Architecture
CPU Architecture

Technical highlight

Functional Computer System Project

The first half of the course culminated in building a functional computer system by integrating key components developed earlier in the course:

Memory Components

  • RAM16K: Serves as the computer's short-term memory, where data and programs are temporarily stored while the system is running.

  • Screen and Keyboard: Facilitate user interaction by displaying output and receiving input.

CPU (Central Processing Unit) Components

  • A Register: A temporary storage area for data the CPU is currently processing, crucial for operations like calculations and data manipulation.

  • D Register: Holds the result of CPU operations, such as calculations or data fetched from memory, ensuring that results are available for subsequent steps.

  • ALU (Arithmetic Logic Unit): Performs arithmetic and logical operations, such as addition and comparison, required by the CPU.

Computer System

  • ROM32K: Stores the program code executed by the CPU, allowing the system to load and perform various tasks based on the given instructions.

By integrating these components, you gained a deeper understanding of how memory, CPU, and instruction storage work together to enable a computer to execute programs and interact with users.

Assembler
Assembler
Assembler

Technical highlight

Assembler Development for Hack Hardware Platform

The project involved creating an assembler that translates programs written in Hack assembly language into binary code executable by the Hack hardware platform. The assembler handles two main types of instructions:

1. A-instructions

  • Function: Loads a specific value or memory address into a register.

2. C-instructions

  • Function: Defines computations, such as arithmetic operations or data transfer between registers and memory.

The project was completed in two stages:

1. Symbol-less Assembler

  • Objective: Create an assembler capable of directly converting A-instructions and C-instructions into binary code, without handling symbolic references.

  • Approach: Focused on translating instructions directly into the binary format that the Hack hardware understands.

2. Symbol Handling

  • Objective: Extend the assembler to handle symbolic references, such as memory addresses or variables.

  • Approach:

    • First Pass: The assembler scanned the entire program, building a symbol table to record the locations of labels and predefined variables.

    • Second Pass: The assembler replaced each symbolic reference with its corresponding binary address or value, ensuring the program could be executed correctly on the Hack hardware.

This approach enabled the assembler to handle both direct values and symbolic references, ensuring full functionality for programs targeting the Hack platform.

Compiler Architecture
Compiler Architecture
Compiler Architecture

Technical highlight

Compiler Development Project

The project focused on developing a compiler to translate high-level code written in a procedural programming language into machine-readable instructions. The development was divided into two main phases:

1. Implementing a Procedural Programming Language

  • Variables: Managed the declaration and usage of variables within the code.

  • Expressions: Implemented the evaluation of mathematical and logical expressions.

  • Statements: Enabled the execution of various control structures, such as loops and conditionals.

2. Adding Object-Based Programming Features

  • Objects: Introduced the ability to define and manipulate objects, enabling more complex data structures.

  • Constructors: Implemented methods for initializing objects.

  • Methods: Enabled the definition and execution of functions tied to specific objects, expanding the language's capabilities.

Key Techniques Employed

  • Parsing: Handled the syntax analysis of the code, breaking it down into manageable components.

  • Symbol Tables: Used to track variable and function names, ensuring correct usage and scope management.

  • Compilation Engine: Coordinated the overall translation process from high-level code to machine code.

  • Code Generation: Produced final machine code, ensuring the translated code accurately represented the original source.

Takeaways

This project allowed me to visualize the inner workings of a computer at the low level, from writing a complete game to seeing it run on a computer I built. It also deepened my skills in both procedural and object-based programming paradigms.

This project allowed me to visualize the inner workings of a computer at the low level, from writing a complete game to seeing it run on a computer I built. It also deepened my skills in both procedural and object-based programming paradigms.

This project allowed me to visualize the inner workings of a computer at the low level, from writing a complete game to seeing it run on a computer I built. It also deepened my skills in both procedural and object-based programming paradigms.