HACK.v is a 16 bit RISC processor in Verilog. HACK is a microarchitecture specified in Elements of Computing System by Noam Nisan and Shimon Schocken which is informally known as nand2tetris. The authors implemented the architecture in an indigenous HDL(Hardware Description Language), but HACK.v is an implementation of the architecture in much standard HDL, Verilog.
HACK.v is a structural implementation of the HACK microarchitecture. This is modified Von Neumann architecture with separate instruction memory and data memory. The main components being the Instruction memory, CPU and Data memory.
The files are listed in the logical order they were created and reside in /HACK verilog directory
- Mux16_2way.v: 2 input 16 bit Multiplexer
- Adder16.v: 2 input 16 bit adder
- ALU.v: Arithmetic and Logic Unit
- register.v: 16 bit register for A register and D register
- CPU.v: Central Processing Unit
- Instrn_mem.v: 64K instruction memory
- data_mem.v: 64K data memory
- HACK.v: complete integration of the microarchitecture components.
- HACK_sim.v: Simulation File to be executed
- *tb.v: all these files are testbenches for checking their corresponding functionality
The HACK assembly Language mainly consists of two types of instructions A-type and C-type.
@value
, where value is either a decimal non-negative number or a Symbol.
Examples:
@21
@R0
@SCREEN
0xxxxxxxxxxxxxxx
, where x
is a bit, either 0 or 1. A-Instructions always have their MSB set to 0.
Examples:
000000000001010
011111111111111
Sets the contents of the A register to the specified value. The value is either a non-negative number (i.e. 21) or a Symbol. If the value is a Symbol, then the contents of the A register is set to the value that the Symbol refers to but not the actual data in that Register or Memory Location.
dest = comp ; jmp, where:
- dest: Destination register in which the result of computation will be stored.
- comp: Computation code.
- jmp: The jump directive.
Examples:
D=0
M=1
D=D+1;JMP
M=M-D;JEQ
1 1 1 a c1 c2 c3 c4 c5 c6 d1 d2 d3 j1 j2 j3
, where:
111
bits: C-Instructions always begin with bits111
.a
bit: Chooses to load the contents of either A register or M (Main Memory register addressed by A) into the ALU for computation.- Bits
c1
throughc6
: Control bits expected by the ALU to perform arithmetic or bit-wise logic operations. - Bits
d1
throughd3
: Specify which memory location to store the result of ALU computation into: A, D or M. - Bits
j1
throughj3
: Specify which JUMP directive to execute (either conditional or uncoditional).
Performs a computation on the CPU (arithmetic or bit-wise logic) and stores it into a destination register or memory location, and then (optionally) JUMPS to an instruction memory location that is usually addressed by a value or a Symbol (label).
A Verilog Simulator like ModelSim
- Download all the verilog files into a single folders.
- Create a file code.txt and type in the machine language(binary) instructions inside it.
- Create a file InitialRam.txt and type in the initial values inside the RAM (both the text files should be in the same folder as the verilog files).
- Compile all the verilog files
- Simulate the HACK_sim component
- Add the variables to the wave window (ModelSim).
- Run the Simulation
- Any value written in RAM will be displayed in the simulation output window.
// Computes 1+2+...+RAM[0]
// And the sum is stored in RAM[1]
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i // if i>RAM[0] goto WRITE
D=M
@R0
D=D‐M
@WRITE
D;JGT
@i // sum += i
D=M
@sum
M=D+M
@i // i++
M=M+1
@LOOP // goto LOOP
0;JMP
(WRITE)
@sum
D=M
@R1
M=D // RAM[1] = the sum
(END)
@END
0;JMP
machine code of the above source code
0000000000010000
1110111111001000
0000000000010001
1110101010001000
0000000000010000
1111110000010000
0000000000000000
1111010011010000
0000000000010010
1110001100000001
0000000000010000
1111110000010000
0000000000010001
1111000010001000
0000000000010000
1111110111001000
0000000000000100
1110101010000111
0000000000010001
1111110000010000
0000000000000001
1110001100001000
0000000000010110
1110101010000111
RAM[0] is initialised with 10 (0000000000001010)
000000000001010