
# TP Modul 8 - Microprogramming (Finite State Machine)
> Pembuat Soal: MF
```txt
Nama : M. Avicenna Raffaiz Adiharsa
NPM : 2206062844
```
## Teori (25 pts)
### 1. Jelaskan apa itu Finite State Machine (FSM) serta jenis-jenisnya dan kegunannya masing-masing! (10 pts)
Finite State Machine (FSM) adalah model komputasi yang terdiri dari status terbatas, input, output, fungsi transisi (menentukan status berikutnya), dan fungsi output. FSM adalah mesin abstrak yang berpindah status sebagai respons terhadap input, penting untuk logika sekuensial.
Ada dua jenis utama:
- **Moore Machine:** Output hanya bergantung pada status saat ini. Lebih "aman" karena output stabil, ideal untuk control unit atau counter.
- **Mealy Machine**: Output bergantung pada status saat ini DAN input saat ini. Merespons input lebih cepat, efisien untuk pendeteksi urutan, namun output bisa asinkron.
#### Referensi:
- Finite State Machines: Features & State Diagrams [Online]. Available: https://study.com/academy/lesson/finite-state-machines-features-state-diagrams.html . [Diakses: 10-Nov-2025]
- Difference between Mealy Machine and Moore Machine [Online]. Available: https://www.naukri.com/code360/library/moore-and-mealy-machine . [Diakses: 10-Nov-2025]
### 2. Jelaskan keyword-keyword berikut dalam konteks VHDL! (5 pts) <ul><li>Record</li><li>Alias</li><li>Aggregate</li></ul>
#### Record
- Tipe data komposit untuk mengelompokkan sinyal/variabel dengan tipe data berbeda ke dalam satu objek tunggal.
- Contoh: Record `cpu_status` berisi `std_logic_vector` untuk flags dan integer untuk instruction_count.
#### Alias
- Memberikan nama alternatif (nama panggilan) pada objek yang sudah ada atau pada bagian tertentu dari sebuah objek.
- Contoh: `alias opcode : std_logic_vector(3 downto 0) is instruction(15 downto 12);` untuk memudahkan pembacaan kode.
#### Aggregate
- Notasi untuk menetapkan nilai ke seluruh elemen tipe data komposit (array, vector, record) secara bersamaan.
- Contoh: Penggunaan `(others => '0')` seperti: `reset_signal <= (others => '0');` untuk menetapkan nilai '0' ke semua bit.
#### Referensi:
- Introduction to Digital Systems: Modeling, Synthesis, and Simulation Using VHDL [Online]. Available: https://www.oreilly.com/library/view/introduction-to-digital/9780470900550/chap4-sec009.html. [Diakses: 10-Nov-2025]
- VHDL Reference Guide - Alias Declaration [Online]. Available: https://ics.uci.edu/~jmoorkan/vhdlref/aliasdec.html. [Diakses: 10-Nov-2025]
- VHDL Reference Guide - Aggregates [Online]. Available: https://ics.uci.edu/~jmoorkan/vhdlref/aggregat.html [Diakses: 10-Nov-2025]
### 3. Apa itu microprogramming? Apa itu datapath dan control unit? (10 pts)
**Mikroprogram** adalah metode mengimplementasikan Control Unit dengan memperlakukannya sebagai komputer mini.
* Setiap instruksi mesin dipecah menjadi mikroinstruksi yang lebih kecil.
* Urutan mikroinstruksi (mikroprogram) disimpan dalam memori cepat khusus (Control Store/ROM).
* Saat dieksekusi, mikroinstruksi langsung menghasilkan sinyal kontrol (seperti RAO, CNT) untuk mengendalikan Datapath.
**Datapath** adalah "otot" CPU yang berisi komponen pemroses data, meliputi:
* Register (penyimpanan sementara).
* ALU (operasi matematika/logika).
* Bus (jalur pemindahan data).
* Datapath hanya menjalankan operasi yang diperintahkan oleh Control Unit.
**Control Unit** adalah otak CPU. Tugasnya:
* Mengambil dan menerjemahkan instruksi (fetch, decode).
* Menghasilkan sinyal kontrol yang tepat (misalnya RAO, RAI, PCO) pada waktu yang tepat untuk mengoordinasikan Datapath dan mengeksekusi instruksi (execute).
#### Referensi:
- Data Path Components and Designs [Online]. Available: https://www.geeksforgeeks.org/computer-organization-architecture/differences-between-data-paths. [Diakses: 10-Nov-2025]
- Introduction to Control Unit and its Design [Online]. Available: https://www.geeksforgeeks.org/computer-organization-architecture/introduction-of-control-unit-and-its-design [Diakses: 10-Nov-2025]
- Microprogramming Basics [Online]. Available: https://www.geeksforgeeks.org/computer-organization-architecture/microprogramming-basics-1 [Diakses: 10-Nov-2025]
## Praktik (35)
> Tidak perlu referensi
### Diketahui state diagram dari sebuah FSM dengan input 2 bit Q (Q1Q0) berikut:

### FSM mulai pada `S0` dan setiap state juga menghasilkan output 3 bit O (O2O1O0) dengan spesifikasi berikut:
| State | OUTPUT |
|-------|--------|
| S0 | 000 |
| S1 | 001 |
| S2 | 100 |
| S3 | 101 |
| S4 | 010 |
#### A. Buatlah state transition table berdasarkan spesifikasi-spesifikasi tersebut! (10 pts)
| State | Input | Next State | Output |
| :---: | :---: | :---: | :---: |
| S0 | 00 | S0 | 000 |
| S0 | 01 | S1 | 000 |
| S0 | 10 | S2 | 000 |
| S0 | 11 | S3 | 000 |
| S1 | 00 | S1 | 001 |
| S1 | 01 | S2 | 001 |
| S1 | 10 | S0 | 001 |
| S1 | 11 | S0 | 001 |
| S2 | 00 | S2 | 100 |
| S2 | 01 | S1 | 100 |
| S2 | 10 | S3 | 100 |
| S2 | 11 | S0 | 100 |
| S3 | 00 | S3 | 101 |
| S3 | 01 | S4 | 101 |
| S3 | 10 | S1 | 101 |
| S3 | 11 | S0 | 101 |
| S4 | 00 | S4 | 010 |
| S4 | 01 | S1 | 010 |
| S4 | 10 | S4 | 010 |
| S4 | 11 | S0 | 010 |
#### B. Lengkapi kode berikut untuk mengimplementasikan FSM tersebut dalam VHDL! (20 pts)
```vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity fsm_tp_8 is
port (
CLK : in std_logic;
RST : in std_logic;
Q : in std_logic_vector(1 downto 0);
O : out std_logic_vector(2 downto 0)
);
end entity fsm_tp_8;
architecture rtl of fsm_tp_8 is
type t_State is (S0, S1, S2, S3, S4);
signal State : t_State := S0;
signal NextState : t_State;
begin
STATE_TRANSITION: process(CLK) is
begin
if rising_edge(CLK) then
if RST = '1' then
State <= S0;
else
State <= NextState;
end if;
end if;
end process;
STATE_OUTPUT: process(State)
begin
case State is
when S0 =>
O <= "000";
when S1 =>
O <= "001";
when S2 =>
O <= "100";
when S3 =>
O <= "101";
when S4 =>
O <= "010";
when others =>
O <= "000";
end case;
end process STATE_OUTPUT;
STATE_CONDITION: process(State, Q)
begin
NextState <= State;
case State is
when S0 =>
if Q = "01" then
NextState <= S1;
elsif Q = "10" then
NextState <= S2;
elsif Q = "11" then
NextState <= S3;
else
NextState <= S0;
end if;
when S1 =>
if Q = "01" then
NextState <= S2;
elsif Q = "10" then
NextState <= S0;
elsif Q = "11" then
NextState <= S0;
else
NextState <= S1;
end if;
when S2 =>
if Q = "01" then
NextState <= S1;
elsif Q = "10" then
NextState <= S3;
elsif Q = "11" then
NextState <= S0;
else
NextState <= S2;
end if;
when S3 =>
if Q = "01" then
NextState <= S4;
elsif Q = "10" then
NextState <= S1;
elsif Q = "11" then
NextState <= S0;
else
NextState <= S3;
end if;
when S4 =>
if Q = "01" then
NextState <= S1;
elsif Q = "11" then
NextState <= S0;
elsif Q = "10" then
NextState <= S4;
else
NextState <= S4;
end if;
when others =>
NextState <= S0;
end case;
end process STATE_CONDITION;
end architecture rtl;
```
#### C. Jalankan rangkaian dengan input dan timing yang sesuai sehingga output menghasilkan perubahan state
##### S0 -> S1 -> S2 -> S2 -> S0 -> S1 -> S1 -> S2 -> S3 -> S4 -> S4 -> S1 -> S0
#### Screenshot! (5 pts)

## Pre-CS (40 pts)
### Perhatikan diagram arsitektur CPU sederhana 8 bit berikut!

### CPU tersebut memiliki 8 buah komponen yang terhubung dengan satu bus 8 bit serta 14 sinyal kontrol (control signals) untuk microprogram. CPU menggunakan instruction word 8 bit yang terdiri atas 4 bit opcode serta 4 bit operand yang dapat berupa baik address maupun immediate value. CPU tersebut memiliki RAM dengan addressing 4 bit yang mampu menyimpan 16 buah data 8 bit.
### Penjelasan Arsitektur
<details>
<summary>
Click to expand.
</summary>
#### Register (A & B)
##### Keterangan
- Menyimpan data 8 bit.
##### Control Signals
- RXO: Menulis data dari register X ke bus.
- RXI: Membaca data dari bus ke register X.
#### Arithmatic Logic Unit (ALU)
##### Keterangan
- Menjumlahkan atau mengurangi register A dengan B.
##### Control Signals
- SUB: Jika diset ke 1, output berupa A - B, sebaliknya akan menghasilkan A + B.
- ALO: Menulis output dari ALU ke bus.
##### Flags
- Zero Flag: Diset ke 1 jika output berupa nol.
- Carry Flag: Diset ke 1 jika operasi aritmatika menghasilkan carry/borrow.
#### Program Counter (PC)
##### Keterangan
- Counter dari lokasi memori instruksi.
- Dapat melakukan increment untuk instruksi selanjutnya ataupun melakukan jump dengan membaca dari bus.
##### Control Signals
- PCI: Mengambil data instruksi selanjutnya dari bus. Dapat digunakan untuk melakukan jump.
- PCO: Menulis data dari PC ke bus.
- CNT: Melakukan increment counter instruksi di dalamnya.
#### Memory Address Register (MAR)
##### Keterangan
- Menyimpan lokasi memori 4 bit untuk RAM.
- Mempengaruhi lokasi data yang diubah dalam RAM.
##### Control Signals
- MRI: Menulis 4 least significant bits (4 bit terakhir) dari bus ke dalamm MAR.
#### Program Counter (RAM)
##### Keterangan
- Menyimpan data 8 bit dalam lokasi 4 bit.
- Mampu menyimpan 16 buah data 8 bit.
##### Control Signals
- RMI: Membaca data dari bus dan menyimpannya ke lokasi memori yang diset oleh MAR.
- RMO: Menulis data dari lokasi memori yang diset MAR ke bus.
#### Instruction Register (IR)
##### Keterangan
- Menyimpan instruction byte yang diambil dari RAM berdasarkan PC.
- Instruction byte terdiri atas 4 bit MSB opcode dan 4 bit LSB operand.
##### Control Signals
- IRI: Menyimpan data dari bus ke IR.
- IRO: Menulis 4 bit LSB dari IR ke bus.
#### Control Unit (CU)
##### Keterangan
- Merupakan pengendali keseluruhan control signal dari datapath setiap component sebelumnya.
- Melakukan decoding instruksi yang ada di IR dan mengatur microprogram yang sesuai.
- Mengandung state machine yang mengatur urutan control signal microprogram untuk setiap siklus clock.
</details>
### CPU memiliki siklus fetch - execute. Untuk setiap instruksi yang ada di dalam instruction set, CPU melakukan fetching dengan microprogram berikut:
#### MP - Fetch
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
### dilanjutkan dengan instruksi yang sesuai dengan opcode yang ada pada IR.
### Set Instruksi
#### Instruksi 1 - LDA [MEM]
##### Opcode: 0001 MMMM
##### Keterangan: Menyimpan data dari memori berlokasi `MEM` ke register A.
##### Microprogram:
MP - Fetch lalu...
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
`CNT` diset ke 1 untuk melakukan increment PC agar mengeksekusi instruksi selanjutnya pada siklus clock setelah ini.
### Tugas anda adalah mengimplementasikan Control Unit dengan menerapkan instruction set CPU ini.
```vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity control_unit is
port (
CLK : in std_logic;
enable : in std_logic;
RST : in std_logic;
carry_flag : in std_logic;
zero_flag : in std_logic;
opcode : in std_logic_vector(3 downto 0);
control_signals : out std_logic_vector(13 downto 0)
);
end entity control_unit;
architecture rtl of control_unit is
type t_State is (IDLE, FETCH, DECODE, LDA1, LDA2);
signal State : t_State := IDLE;
signal NextState : t_State;
begin
STATE_TRANSITION: process(CLK) is
begin
if enable = '1' and rising_edge(CLK) then
if RST = '1' then
State <= IDLE;
else
State <= NextState;
end if;
end if;
end process;
STATE_OUTPUT: process(State)
begin
case State is
when IDLE =>
control_signals <= "00000000000000";
when FETCH =>
control_signals <= "00000001010000";
when DECODE =>
control_signals <= "00000000000110";
when LDA1 =>
control_signals <= "00000000010001";
when LDA2 =>
control_signals <= "01000000100100";
end case;
end process STATE_OUTPUT;
STATE_CONDITION: process(State, carry_flag, zero_flag)
begin
case State is
when IDLE =>
NextState <= FETCH;
when FETCH =>
NextState <= DECODE;
when DECODE =>
case opcode is
when "0001" =>
NextState <= LDA1;
-- when OPCODE LAIN => ... (kembangkan)
when others =>
NextState <= IDLE;
end case;
when LDA1 =>
NextState <= LDA2;
when LDA2 =>
NextState <= FETCH;
-- Kembangkan untuk instruksi lebih lanjut
end case;
end process STATE_CONDITION;
end architecture rtl;
```
### Kerjakan sejumlah instruksi berikut dan lalu cantumkan kode VHDL akhir anda!
#### Instruksi 2 - STA [MEM] (5 pts)
##### Opcode: 0010 MMMM
##### Keterangan: Mengambil data dari MEM ke register A.
##### Microprogram:
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
| :--------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
#### Instruksi 3 - LDB [MEM] (5 pts)
##### Opcode: 0101 MMMM
##### Keterangan: Mengambil data dari MEM ke register B.
##### Microprogram:
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 2 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
#### Instruksi 4 - STB [MEM] (5 pts)
##### Opcode: 0110 MMMM
##### Keterangan: Menyimpan data dari memori berlokasi `MEM` ke register B.
##### Microprogram:
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | **1** | 0 | 0 | 0 | **1** |
| 2 | 0 | 0 | **1** | 0 | 0 | 0 | 0 | 0 | **1** | 0 | **1** | 0 | 0 | 0 |
#### Instruksi 5 - MAB (5 pts)
##### Opcode: 0100 XXXX
##### Keterangan: Memindahkan data register A ke register B.
##### Microprogram:
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
#### Instruksi 6 - MBA (5 pts)
##### Opcode: 0111 XXXX
##### Keterangan: Memindahkan data register B ke register A.
##### Microprogram:
| CC | RAO | RAI | RBO | RBI | SUB | ALO | PCI | PCO | CNT | MRI | RMI | RMO | IRI | IRO |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
### Cantumkan kode VHDL akhir anda! (10 pts)
```vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity control_unit is
port (
CLK : in std_logic;
enable : in std_logic;
RST : in std_logic;
carry_flag : in std_logic;
zero_flag : in std_logic;
opcode : in std_logic_vector(3 downto 0);
control_signals : out std_logic_vector(13 downto 0)
);
end entity control_unit;
architecture rtl of control_unit is
type t_State is (
IDLE, FETCH, DECODE,
LDA1, LDA2,
STA1, STA2,
LDB1, LDB2,
STB1, STB2,
MAB1,
MBA1
);
signal State : t_State := IDLE;
signal NextState : t_State;
begin
STATE_TRANSITION: process(CLK) is
begin
if enable = '1' and rising_edge(CLK) then
if RST = '1' then
State <= IDLE;
else
State <= NextState;
end if;
end if;
end process;
STATE_OUTPUT: process(State)
begin
case State is
when IDLE =>
control_signals <= "00000000000000";
when FETCH =>
control_signals <= "00000001010000";
when DECODE =>
control_signals <= "00000000000110";
when LDA1 =>
control_signals <= "00000000010001";
when LDA2 =>
control_signals <= "01000000100100";
when STA1 =>
control_signals <= "00000000010001";
when STA2 =>
control_signals <= "10000000101000";
when LDB1 =>
control_signals <= "00000000010001";
when LDB2 =>
control_signals <= "00010000100100";
when STB1 =>
control_signals <= "00000000010001";
when STB2 =>
control_signals <= "00100000101000";
when MAB1 =>
control_signals <= "10010000100000";
when MBA1 =>
control_signals <= "01100000100000";
when others =>
control_signals <= "00000000000000";
end case;
end process STATE_OUTPUT;
STATE_CONDITION: process(State, carry_flag, zero_flag, opcode)
begin
case State is
when IDLE =>
NextState <= FETCH;
when FETCH =>
NextState <= DECODE;
when DECODE =>
case opcode is
when "0001" =>
NextState <= LDA1;
when "0010" =>
NextState <= STA1;
when "0100" =>
NextState <= MAB1;
when "0101" =>
NextState <= LDB1;
when "0110" =>
NextState <= STB1;
when "0111" =>
NextState <= MBA1;
when others =>
NextState <= FETCH;
end case;
when LDA1 =>
NextState <= LDA2;
when LDA2 =>
NextState <= FETCH;
when STA1 =>
NextState <= STA2;
when STA2 =>
NextState <= FETCH;
when LDB1 =>
NextState <= LDB2;
when LDB2 =>
NextState <= FETCH;
when STB1 =>
NextState <= STB2;
when STB2 =>
NextState <= FETCH;
when MAB1 =>
NextState <= FETCH;
when MBA1 =>
NextState <= FETCH;
when others =>
NextState <= IDLE;
end case;
end process STATE_CONDITION;
end architecture rtl;
```
### Dengan kode testbench berikut, cantumkan screenshot hasil jalan rangkaian anda! (5 pts)
```vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity control_unit_tb is
end entity control_unit_tb;
architecture sim of control_unit_tb is
component control_unit is
port (
CLK : in std_logic;
enable : in std_logic;
RST : in std_logic;
carry_flag : in std_logic;
zero_flag : in std_logic;
opcode : in std_logic_vector(3 downto 0);
control_signals : out std_logic_vector(13 downto 0)
);
end component;
signal CLK : std_logic := '0';
signal enable : std_logic := '0';
signal RST : std_logic := '0';
signal carry_flag : std_logic := '0';
signal zero_flag : std_logic := '0';
signal opcode : std_logic_vector(3 downto 0) := (others => '0');
signal control_signals : std_logic_vector(13 downto 0);
constant CLK_PERIOD : time := 10 ns;
begin
DUT: control_unit
port map (
CLK => CLK,
enable => enable,
RST => RST,
carry_flag => carry_flag,
zero_flag => zero_flag,
opcode => opcode,
control_signals => control_signals
);
CLK_PROCESS : process
begin
while true loop
CLK <= '0';
wait for CLK_PERIOD / 2;
CLK <= '1';
wait for CLK_PERIOD / 2;
end loop;
end process;
STIM_PROC: process
begin
enable <= '1';
RST <= '1';
wait for 2 * CLK_PERIOD;
RST <= '0';
-- LDA
opcode <= "0001";
wait for 6 * CLK_PERIOD;
-- MAB
opcode <= "0100";
wait for 6 * CLK_PERIOD;
-- STA
opcode <= "0010";
wait for 6 * CLK_PERIOD;
-- LDB
opcode <= "0101";
wait for 6 * CLK_PERIOD;
-- MBA
opcode <= "0111";
wait for 6 * CLK_PERIOD;
-- STB
opcode <= "0110";
wait for 6 * CLK_PERIOD;
enable <= '0';
wait;
end process;
end architecture sim;
```
> Pastikan setiap bit control unit terlihat. Expand supaya kelihatan.
