A small 16-bit microprocessor built in VHDL, featuring a compact 14-bit instruction set inspired by the 8051 style, an 8×16-bit register file, 128×14-bit program ROM, and 128×16-bit data RAM. The project includes a complete top-level, control path, datapath (register bank + ALU), memory, and testbench with example program: a sieve (Crivo) routine.
- 16-bit datapath with signed/unsigned-friendly arithmetic
- 14-bit instruction width: 4-bit opcode, 3-bit reg fields, 7-bit immediate/relative address
- 8 general-purpose registers (R0–R7), with R0 hardwired to zero (read-only)
- Program ROM: 128 instructions (addressed by a 7-bit PC)
- Data RAM: 128 words × 16 bits
- Simple 2-stage control (fetch/execute) via
maq_estados - Branches with 7-bit signed relative offsets
- Example program implements a sieve-like routine (see
CRIVO-ASSEMBLY.txt), already encoded invhds/rom.vhd
vhds/- Core RTL modules:
toplevel.vhd,bank_and_ula.vhd,decoder.vhd,ula.vhd,operations.vhd,bancoDeRegs.vhd,ram.vhd,rom.vhd,PC.vhd, multiplexers, registers, and testbenches. - Testbench:
toplevel_tb.vhd
- Core RTL modules:
ghws/- Saved waveforms (
*.ghw) from previous simulations
- Saved waveforms (
CRIVO-ASSEMBLY.txt- Assembly for the example sieve program
MANUAL.txt- Instruction formats and mnemonics used in this design
+-----------------+ +-----------------+
| ROM | 14 bits | reg14bits |
PC[6:0] -> | 128 x 14 instr. |---------> | instr register |----+
+-----------------+ +-----------------+ |
+--v---------+
+----------> | decoder |
| +------------+
| | control signals
| v
+------------+ +---------------------+ data/addr +------------------+
| UnitAdder |<----| PC |<-------------| mux7bits (PC) |
+------------+ +---------------------+ +------------------+
^ |
| v
PC+1 next PC (jump/seq)
+---------------------------+
| bank_and_ula |
| - bancoDeRegs (R0..R7) |
| - ULA (ALU) |
+-------------+-------------+
| dataA (R[regA])
v
+----------------------------+ +-----------------+
| RAM |<-----| dataOut (ULA) |
| 128 x 16 data words |----->| to reg write |
+----------------------------+ +-----------------+
- PC is 7 bits (0–127), addressing ROM.
reg14bitslatches the current instruction.decoderextracts fields and generates control signals (register selects, immediate, flags, memory control, and branch enables).bank_and_ulawraps the 8×16-bit register file and the ALU, including flag updates and multiplexing of immediate/ram/alu paths.- RAM is addressed by the value in register A (
regA), i.e., usingdataAfrom the register bank (lower 7 bits).
- Register file: 8 registers × 16 bits
R0is hardwired to zero (always reads 0, not writable)R1..R7are general purpose
- ALU ops: add, sub, inc, dec, move, and compare (A < B produces 1/0)
- Flags: Z and C
- Z: set when the write-back value equals 0
- C: used by conditional logic (see branches). In this implementation it is updated on specific ops per
decoder.
Encoding uses: 4-bit opcode, 3-bit reg fields, and 7-bit immediate or address. Detailed formats from MANUAL.txt:
- Register–Register format (OP[13:10], Rd[9:7], Rs[6:4], ignored[3:0])
ADD A, Rx→0000SUB A, Rx→0010MOV Rx, Ry→0110
- Register–Constant format (OP[13:10], Rd[9:7], Const[6:0])
ADD A, #Const→0001SUB A, #Const→0011MOV Rx, #Const→0111
- Single-register format (OP[13:10], Rd[9:7], ignored[6:0])
INC Rx→0100DEC Rx→0101
- Memory
- Format: (OP[13:10], AddrRegOrImm[9:3], RdOrRs[2:0])
MOV Rx, @Ry(read) →1000(data from RAM to Rx; address from Ry)MOV @Rx, Ry(write) →1001(data from Ry to RAM; address from Rx)
- Branch (relative 7-bit)
- Format: (OP[13:10], ignored[9:7], imm7[6:0]) with sign-extension where applicable
JNZ @addr→1110(jump if Z == 0)JC @addr→1101(jump if C == 1)CJNE Rx,Ry,@addr→1100(jump if Rx != Ry)JMP @addr→1111(unconditional jump)
Notes:
- Relative target is computed as
PC + imm7for conditional branches based onZ/C/Equalssignals. - Sign-extension is applied to CNJE offset in
decoder.
- Program ROM: 128 × 14-bit, addressed by PC[6:0]
- Data RAM: 128 × 16-bit, addressed by the low 7 bits of register A (
dataA(6 downto 0)) when executing memory instructions
The example assembly in CRIVO-ASSEMBLY.txt initializes RAM and iteratively writes/reads values, illustrating memory and branch instructions. The program is pre-encoded into vhds/rom.vhd for simulation.
; CARREGAMENTO DA RAM
MOV R2,0
MOV R3,33
MOV @R2,R2
INC R2
CJNE R2,R3,-2
; EXCLUSÃO DE NÃO PRIMOS
MOV R2,2
MOV A,R2
ADD A,R2
JC 4
MOV @A,R0
ADD A,R2
CJNE R3,A,-3
INC R2
CJNE R3,R2,-7
; LOOP DE LEITURA DA RAM
MOV R7,0
MOV R6,@R7
INC R7
CJNE R3,R7,-2- Design and implementation: Francisco Cardoso Becheli and Henrique Romaniuk Ramalho
- Language: VHDL (IEEE std_logic_1164, numeric_std)
- Tools: GHDL, GTKWave