Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mano Machine implementation in SystemVerilog

For the Computer Architecture class, I created a project that simulates the Mano machine. It consists of synthesizable modules for the components that do not involve input/output, a macro-based assembler, and a module that can run the simulation.

Requirements

To run the simulator along with the preloaded assembly program, you will need the following tools:

To run everything else, you will need the following tools too:

Usage

  • Prepare the VPI modules: ./sv.py make.
  • Simulate preloaded with the assembly program in src/program.asm.sv: ./sv.py run src/VirtualComputer.sv.
  • Synthesize to logic gates: (A) ./sv.py synthesize --online http://localhost:15555 src/SOC.sv or (B) ./sv.py synthesize --vscode src/SOC.sv or (C) ./sv.py synthesize src/SOC.sv.
  • Translate to VHDL (not tested): ./sv.py compile src/SOC.sv --type vhdl --out SOC.vhdl.
  • Run linter: ./sv.py lint.
  • Run tests: ./sv.py test.
  • Run the formatter: ./sv.py format.

Project structure

  • src
    • Virtual*.sv: non-synthesizable modules
    • /[a-z].*\.sv/: non-module source files
    • Anything else: synthesizable modules
  • test
    • /[a-z].*\.sv/: utility files
    • Anything else: testbench modules
  • vpi
    • *.c: VPI source files for iverilog
    • Makefile: configuration for Make
  • ckl: C-like programming language which compiles to the Mano machine
  • sv.py: Script which wraps almost any command that you will run
  • extended_instructions.py: Script which generates new (and dare I say mostly useless) instructions for the current CPU architecture.

The preamble

The files src/preamble.sv and test/preamble.sv contain macros which will be loaded at the top of every file.

An important macro from the preamble is IMPORT. Instead of wrapping each module in ifndef-define, we will wrap the include which will import that module. As long as no module is circularly importing itself, it is a more elegant solution to importing a file only once and in order.

In test/preamble.sv, the IMPORT macro will be redirected to the src directory, so IMPORT(RAM) imports src/RAM.sv and not test/RAM.sv. Additionally, test/preamble.sv includes some macros to assist in running testbenches.

The assembler

We use SystemVerilog macros to implement the assembler. In a module which will accept the assembler, you should implement the _ASM_SET_MEMORY_ macro which will be called with the bytes from the assembled program.

Inside the module body, you will use the ASM_DEFINE_PROGRAM macro and pass the program as its argument. For multiline programs, I recommend moving the content of the argument into a macro. For very long programs, I recommend using include and the .asm.sv suffix. (The formatter correctly indents the instructions with this suffix.)

Non-memory-reference instructions are available as ASM_<name>. Memory-reference instructions are available as ASM_<name>_<mode><operand_type>. See assembler.sv for more information.

Labels can be created via ASM_LABEL. Some labels can be marked private, e.g., subroutine branches and variables. These can be defined via ASM_SUBLABEL and are only accessible between two ASM_LABELs (or the end of the program).

You can set the assembler address via ASM_ADDR and ASM_ADDR_REL.

You can set raw data via ASM_DATA. If the data is the address of a label, you can use ASM_DATA_LABEL and ASM_DATA_SUBLABEL. If the data is a string, you can use ASM_DATA_STR. (It will not append a null character). Finally, you can use ASM_DATA_FILL to initialize a span in the memory.

There are some shortcuts available, such as ASM_SUBROUTINE, ASM_CALL, ASM_RETURN, ASM_ARG_SKIP, ASM_ARG_NEXT, ASM_SHR, ASM_SHL, and ASM_ASR. See assembler.sv for more information.

Finally, there is the disassemble task which will decode an instruction.

The test library

There is an implementation of a Test Anything Protocol (TAP) producer inside test/preamble.sv. For every test case, it will output a ok or not ok line to the stdout which will be picked up by a tap consumer.

There is a test runner implemented in Python in sv.py. You can use the test sub-command to run some or all testbenches. If you are running this command via a TTY and have tap-mocha-reporter installed, the output will be passed into it.

For asynchronous modules, you can use TAP_TEST and TAP_CASE. For synchronous modules, you can also use TAP_CASE_AT and TAP_CASE_AT_NEGEDGE.

See test/preamble.sv for more information.

The VPI module for IO

While SystemVerilog has $fgetc, the standard input is line-buffered, so it cannot be used for the keyboard module. Additionally, $fgetc waits for user input, blocking the simulation.

To replace $fgetc, we will implement the necessary logic in C and load it into the iverilog simulation. This is implemented inside vpi/io.c. It supports both Windows (untested) and Linux. If you would like to avoid using this module for some reason, you can pass the --no-vpi option to the ./sv.py run command.

The CKL programming language

Pronounced like “sickle”, it is a C-like programming language specifically for the Mano Machine. It is currently a work in progress and also lacks many optimizations.

// Top-level variable declaration
a;
// Top-level variable declaration with initializer
b = 123;

// Forward declaration
add(a, b);

// Function declaration
add(a, b) {
  // Last expression is returned automatically.
  a + b;
}

// Special function declarations
$start() { /* … */ }
$isr()   { /* … */ }

io() {
  // Asynchronous input
  a = $input;
  // Synchronous input
  a = $input();

  // Asynchronous input
  $output = a;
  // Synchronous input
  $output(a);

  // I/O flags
  do; while (!$fgo);
  do; while (!$fgi);

  // IEN flag
  $ien = 1;
  $ien = 0;

  // Address of the word immediately after the assembly program.
  string = $post;

  // Inline assembly
  asm("`ASM_ISZ_DL(%s)", a);
}

// Also inline assembly
asm("`ASM_ADDR_REL(2)");

About

🖥️🤖 Mano Machine implementation in SystemVerilog

Topics

Resources

Code of conduct

Stars

1 star

Watchers

1 watching

Forks

Used by

Contributors

Languages