# TP Modul 9 - Microprogramming > Pembuat Soal: AX ```txt Nama : Danish Al Fayydh Sunarta NPM : 2406416951 ``` ## Teori (30 pts) ### 1. Jelaskan perbedaan control unit dengan menggunakan microprogramming dan FSM (hardwired) (15 poin) |poin|microprogramming|FSM (hardwired)| |:-:|:-:|:-:| |implementasi|menggunakan pendekatan berbasis memori. control signals disimpan di dalam ROM sebagai microinstructions dan digunakan untuk mengontrol CPU|menggunakan rangkaian logika sekuensial murni yang terdiri dari gerbang logika, flip-flop, dan decoder. control signals bersifat statis karena dihasilkan langsung oleh hardware berdasarkan state saat ini dan input.| |kecepatan|biasanya lebih lambat karena perlu mengakses momori, sehingga terdapat delay pada saat mengakses microinstructions dan fetching.|biasanya lebih cepat karena tidak perlu mengakses memori.| |fleksibilitas|untuk mengubah (menambah/mengganti/menghapus) instruksi hanya perlu dilakukan dengan mengubah isi memori|perubahan pada suatu set instruksi memerulukan perancangan ulang pada design keseluruhannya.| ### Referensi - Geeksforgeeks, “Difference between Hardwired and Micro-programmed Control Unit | Set 2,” Geeksforgeeks, 11 Jul, 2025. [Online]. Available: https://www.geeksforgeeks.org/computer-organization-architecture/difference-between-hardwired-and-micro-programmed-control-unit-set-2/. [Accessed: 16 Nov, 2025]. - unstop, “Hardwired Vs. Microprogrammed Control Unit: Differences & Examples,” unstop. [Online]. Available: https://unstop.com/blog/differences-between-hardwired-control-unit-and-microprogrammed-control-unit. [Accessed: 16 Nov, 2025]. ### 2. Apa keuntungan menggunakan microprogramming dibanding dengan FSM (hardwired) (15 poin) - hanya perlu mengubah isi memori untuk mengubah microinstructions - rangkaian lebih sederhana untuk instruction set yang besar sehingga biayanya lebih rendah dan lebih mudah untuk di-maintain - dapat meniru set instruksi dari komputer/perangkat lain ### Referensi - Geeksforgeeks, “Difference Between Hardwired and Microprogrammed Control Unit,” Geeksforgeeks, 12 Jul, 2025. [Online]. Available: https://www.geeksforgeeks.org/computer-organization-architecture/difference-between-hardwired-and-microprogrammed-control-unit/. [Accessed: 16 Nov, 2025]. - unstop, “Hardwired Vs. Microprogrammed Control Unit: Differences & Examples,” unstop. [Online]. Available: https://unstop.com/blog/differences-between-hardwired-control-unit-and-microprogrammed-control-unit. [Accessed: 16 Nov, 2025]. ## Praktik (70 pts) Buka kembali code LP8 yang kalian kerjakan dan pastikan bahwa semua tabel control wordnya sudah benar (TP + CS) yang berarti total ada 12 instruction : - LDA - STA - LDB - STB - MAB - MBA - NOP - JMP - CMP - ADD - SUB - HLT Sekarang baca kembali daste (jika belum ya baca lah) : https://learn.digilabdte.com/books/digital-sistem-design-psddsg/chapter/module-9-microprogramming ### A. Dari sini ubahlah code yang anda kerjakan dari yang tadinya merupakan FSM menjadi bentuk microprogrammingnya (25 pts) ISI **TODO** : ```vhdl library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -- Entity tetap sama persis 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) -- [RAO,RAI,RBO,RBI,SUB,ALO,PCI,PCO,CNT,MRI,RMI,RMO,IRI,IRO] ); end entity control_unit; architecture rtl_classic_microprogram of control_unit is -- ### 1. Definisi Format Micro-Instruction ### -- Bit sekuensial (seperti di kode hipotetis Anda) constant C_CTRL_BITS : integer := 14; -- 14 bit untuk sinyal kontrol constant C_SEQ_BITS : integer := 2; -- 2 bit untuk sequencing constant C_UCODE_WIDTH : integer := C_CTRL_BITS + C_SEQ_BITS; -- Total 16 bit -- Perintah sequencing constant SEQ_NEXT : std_logic_vector(1 downto 0) := "00"; -- Ambil uPC + 1 constant SEQ_DECODE : std_logic_vector(1 downto 0) := "01"; -- Lompat berdasarkan opcode constant SEQ_FETCH : std_logic_vector(1 downto 0) := "10"; -- Kembali ke alamat Fetch (0) constant SEQ_HLT : std_logic_vector(1 downto 0) := "11"; -- Berhenti (loop di uPC) -- ### 2. Control Store (ROM) ### -- Kita butuh uPC yang lebih besar untuk memetakan alamat subtype t_uAddress is unsigned(7 downto 0); type t_control_store is array(0 to 255) of std_logic_vector(C_UCODE_WIDTH - 1 downto 0); -- Helper function untuk membangun micro-instruction function to_ucode( ctrl : std_logic_vector(C_CTRL_BITS - 1 downto 0); seq : std_logic_vector(C_SEQ_BITS - 1 downto 0) ) return std_logic_vector is begin -- Format: [Seq(1:0), Ctrl(13:0)] return seq & ctrl; end function; -- Alamat untuk Fetch & Alamat "lompat" untuk Opcode constant uADDR_FETCH1 : t_uAddress := "00000000"; -- Alamat 0 constant uADDR_FETCH2 : t_uAddress := "00000001"; -- Alamat 1 constant uADDR_FETCH3 : t_uAddress := "00000010"; -- Alamat 2 -- =============TODO: Definisikan konstanta untuk alamat micro-routine setiap instruksi============= -- Buat konstanta uADDR untuk setiap instruksi (NOP, LDA, STA, ADD, MAB, LDB, STB, MBA, JMP, CMP, SUB, HLT) -- Format: constant uADDR_XXX1 : t_uAddress := "XXXXXXXX"; -- Contoh: constant uADDR_NOP1 : t_uAddress := "00010000"; -- Opcode 0000 -> alamat 16 -- Berikan jarak antar alamat untuk instruksi multi-cycle (jarak 2 untuk tiap instruction) -- ================================================================================================= constant uADDR_NOP1 : t_uAddress := x"10"; constant uADDR_LDA1 : t_uAddress := x"12"; constant uADDR_STA1 : t_uAddress := x"14"; constant uADDR_ADD1 : t_uAddress := x"16"; constant uADDR_MAB1 : t_uAddress := x"18"; constant uADDR_LDB1 : t_uAddress := x"1A"; constant uADDR_STB1 : t_uAddress := x"1C"; constant uADDR_MBA1 : t_uAddress := x"1E"; constant uADDR_JMP1 : t_uAddress := x"20"; constant uADDR_CMP1 : t_uAddress := x"22"; constant uADDR_SUB1 : t_uAddress := x"24"; constant uADDR_HLT1 : t_uAddress := x"26"; -- Inisialisasi ROM function init_rom return t_control_store is variable rom : t_control_store := (others => (others => '0')); -- Konstanta 14-bit untuk sinyal kontrol FETCH (sudah lengkap sebagai contoh) constant C_FETCH1 : std_logic_vector(13 downto 0) := "00000001010000"; -- PCO=1, MRI=1 constant C_FETCH2 : std_logic_vector(13 downto 0) := "00000000000110"; -- RMO=1, IRI=1 constant C_FETCH3 : std_logic_vector(13 downto 0) := "00000000000110"; -- RMO=1, IRI=1 -- =============TODO: Definisikan konstanta 14-bit untuk sinyal kontrol setiap instruksi============= -- -- Format konstanta: constant C_XXX1 : std_logic_vector(13 downto 0) := "XXXXXXXXXXXXXX"; -- -- Untuk bit Control Wordnya ingat kembali TP dan CS dan pastikan sudah benar -- ================================================================================================== constant C_LDA1 : std_logic_vector(13 downto 0) := "00000000010001"; constant C_LDA2 : std_logic_vector(13 downto 0) := "01000000100100"; constant C_STA1 : std_logic_vector(13 downto 0) := "00000000010001"; constant C_STA2 : std_logic_vector(13 downto 0) := "10000000101000"; constant C_ADD1 : std_logic_vector(13 downto 0) := "01000100100000"; constant C_MAB1 : std_logic_vector(13 downto 0) := "10010000100000"; constant C_LDB1 : std_logic_vector(13 downto 0) := "00000000010001"; constant C_LDB2 : std_logic_vector(13 downto 0) := "00010000100100"; constant C_STB1 : std_logic_vector(13 downto 0) := "00000000010001"; constant C_STB2 : std_logic_vector(13 downto 0) := "00100000101000"; constant C_MBA1 : std_logic_vector(13 downto 0) := "01100000100000"; constant C_JMP1 : std_logic_vector(13 downto 0) := "00000010000001"; constant C_CMP1 : std_logic_vector(13 downto 0) := "00001000100000"; constant C_SUB1 : std_logic_vector(13 downto 0) := "01001100100000"; constant C_NOP1 : std_logic_vector(13 downto 0) := "00000000100000"; constant C_HLT1 : std_logic_vector(13 downto 0) := "00000000000000"; begin -- ### Siklus Fetch (3 cycles) - SORRY INI HARUSNYA BEGINI ### rom(to_integer(uADDR_FETCH1)) := to_ucode(C_FETCH1, SEQ_NEXT); -- CC1: PCO=1, MRI=1 -> lanjut ke FETCH2 rom(to_integer(uADDR_FETCH2)) := to_ucode(C_FETCH2, SEQ_NEXT); -- CC2: RMO=1, IRI=1 -> lanjut ke FETCH3 rom(to_integer(uADDR_FETCH3)) := to_ucode(C_FETCH3, SEQ_DECODE); -- CC3: RMO=1, IRI=1 -> decode opcode -- ===========TODO: Isi ROM dengan micro-routines untuk setiap instruksi============= -- -- Gunakan fungsi to_ucode(control_signal_constant, sequencing_command) -- - Parameter 1: Konstanta control signal (misal C_NOP1, C_LDA1, dll) -- - Parameter 2: Perintah sequencing (SEQ_NEXT, SEQ_FETCH, SEQ_DECODE, atau SEQ_HLT) -- -- Sequencing command menentukan kemana uPC akan melompat setelah cycle ini: -- - SEQ_NEXT : Lanjut ke alamat berikutnya (uPC + 1) -- - SEQ_FETCH : Kembali ke awal FETCH (uADDR_FETCH1) -- - SEQ_DECODE : Decode opcode dan lompat ke instruksi yang sesuai -- - SEQ_HLT : Berhenti, tetap di alamat yang sama (loop forever) -- -- Ini akan mirip dengan state machine pada modul sebelumnya, tapi di sini kita hanya mengisi ROM -- dengan micro-instructions yang sesuai untuk setiap instruksi. -- Kalo bingung liat yang fetch kayak gimana ngisinya. -- ==================================================================================== rom(to_integer(uADDR_NOP1)) := to_ucode(C_NOP1, SEQ_FETCH); rom(to_integer(uADDR_LDA1)) := to_ucode(C_LDA1, SEQ_NEXT); rom(to_integer(uADDR_LDA1) + 1) := to_ucode(C_LDA2, SEQ_FETCH); rom(to_integer(uADDR_STA1)) := to_ucode(C_STA1, SEQ_NEXT); rom(to_integer(uADDR_STA1) + 1) := to_ucode(C_STA2, SEQ_FETCH); rom(to_integer(uADDR_ADD1)) := to_ucode(C_ADD1, SEQ_FETCH); rom(to_integer(uADDR_MAB1)) := to_ucode(C_MAB1, SEQ_FETCH); rom(to_integer(uADDR_LDB1)) := to_ucode(C_LDB1, SEQ_NEXT); rom(to_integer(uADDR_LDB1) + 1) := to_ucode(C_LDB2, SEQ_FETCH); rom(to_integer(uADDR_STB1)) := to_ucode(C_STB1, SEQ_NEXT); rom(to_integer(uADDR_STB1) + 1) := to_ucode(C_STB2, SEQ_FETCH); rom(to_integer(uADDR_MBA1)) := to_ucode(C_MBA1, SEQ_FETCH); rom(to_integer(uADDR_JMP1)) := to_ucode(C_JMP1, SEQ_FETCH); rom(to_integer(uADDR_CMP1)) := to_ucode(C_CMP1, SEQ_FETCH); rom(to_integer(uADDR_SUB1)) := to_ucode(C_SUB1, SEQ_FETCH); rom(to_integer(uADDR_HLT1)) := to_ucode(C_HLT1, SEQ_HLT); return rom; end function; -- Buat ROM constant Control_Store : t_control_store := init_rom; -- ### 3. Sinyal Internal ### -- Micro-Program Counter (uPC) signal uPC : t_uAddress := uADDR_FETCH1; signal Next_uPC : t_uAddress; -- Micro-Instruction Register (uIR) signal uIR : std_logic_vector(C_UCODE_WIDTH - 1 downto 0); begin -- ### PROSES 1: uPC Register (State Register) ### uPC_REGISTER: process(CLK) is begin if enable = '1' and rising_edge(CLK) then if RST = '1' then uPC <= uADDR_FETCH1; -- Reset kembali ke Fetch (alamat 0) else uPC <= Next_uPC; end if; end if; end process uPC_REGISTER; -- ### PROSES 2: Pembacaan ROM (Moore) ### -- Baca micro-instruction dari ROM berdasarkan uPC saat ini uIR <= Control_Store(to_integer(uPC)); -- ### PROSES 3: Sequencer Logic (Menentukan uPC Berikutnya) ### -- Ini adalah "otak" yang "bodoh" dari kode hipotetis Anda. SEQUENCER_LOGIC: process(uPC, uIR, opcode, carry_flag, zero_flag) variable seq_control : std_logic_vector(1 downto 0); begin -- Ekstrak 2 bit sequencing dari micro-instruction saat ini seq_control := uIR(C_UCODE_WIDTH - 1 downto C_CTRL_BITS); -- Default: selalu increment (untuk jaga-jaga) Next_uPC <= uPC + 1; case seq_control is when SEQ_NEXT => -- Perintah: Ambil micro-instruction berikutnya secara berurutan Next_uPC <= uPC + 1; when SEQ_FETCH => -- Perintah: Kembali ke awal siklus Fetch Next_uPC <= uADDR_FETCH1; when SEQ_HLT => -- Perintah: Berhenti! Tetap di alamat ini selamanya. Next_uPC <= uPC; when SEQ_DECODE => -- =============TODO: Implementasikan decoding opcode ke alamat micro-routine============= -- Perintah: Lihat opcode dan lompat ke alamat micro-routine yang sesuai -- Yaudah, mirip lah yak dengan state machine di modul sebelumnya. -- ======================================================================================= case opcode is when "0000" => Next_uPC <= uADDR_NOP1; when "0001" => Next_uPC <= uADDR_LDA1; when "0010" => Next_uPC <= uADDR_STA1; when "0011" => Next_uPC <= uADDR_ADD1; when "0100" => Next_uPC <= uADDR_MAB1; when "0101" => Next_uPC <= uADDR_LDB1; when "0110" => Next_uPC <= uADDR_STB1; when "0111" => Next_uPC <= uADDR_MBA1; when "1000" => Next_uPC <= uADDR_JMP1; when "1001" => Next_uPC <= uADDR_CMP1; when "1100" => Next_uPC <= uADDR_SUB1; when "1111" => Next_uPC <= uADDR_HLT1; when others => Next_uPC <= uADDR_FETCH1; end case; when others => -- Pengaman jika terjadi error Next_uPC <= uADDR_FETCH1; end case; end process SEQUENCER_LOGIC; -- ### PROSES 4: Output Logic ### -- Output-nya hanyalah 14 bit sinyal kontrol dari micro-instruction control_signals <= uIR(13 downto 0); end architecture rtl_classic_microprogram; ``` Codenya dicopas di atas ajah ### B. Tes kode anda dengan testbench di bawah ini (25 pts): ```vhdl library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -- This is the entity for the testbench. It's empty. entity tb_cpu is end entity tb_cpu; architecture sim of tb_cpu is -- ### 1. Component Declaration ### -- This is our "Device Under Test" (DUT), the brain. 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 control_unit; -- ### 2. Signal Declarations (The "Wires") ### -- Testbench control signal s_clk : std_logic := '0'; signal s_rst : std_logic := '0'; signal s_enable : std_logic := '1'; constant CLK_PERIOD : time := 10 ns; -- Connections to/from the Control Unit signal s_carry_flag : std_logic; signal s_zero_flag : std_logic; signal s_opcode : std_logic_vector(3 downto 0); signal s_control_signals : std_logic_vector(13 downto 0); -- ### 3. Datapath Components (as signals) ### -- The Main 8-bit Bus signal s_bus : std_logic_vector(7 downto 0); -- Registers signal s_reg_a : std_logic_vector(7 downto 0) := (others => '0'); -- Register A signal s_reg_b : std_logic_vector(7 downto 0) := (others => '0'); -- Register B signal s_pc : std_logic_vector(7 downto 0) := (others => '0'); -- Program Counter (8-bit) signal s_ir : std_logic_vector(7 downto 0) := (others => '0'); -- Instruction Register signal s_mar : std_logic_vector(3 downto 0) := (others => '0'); -- Memory Address Register (4-bit) -- ALU signal s_alu_out : std_logic_vector(7 downto 0); -- ALU's internal output -- RAM (16 locations, 8 bits wide) type t_ram is array (0 to 15) of std_logic_vector(7 downto 0); -- This is our "Program" and "Data" signal s_ram : t_ram := ( 0 => "00011000", -- x"18" Program: LDA 8 (Opcode=0001, Addr=1000) 1 => "01011001", -- x"59" Program: LDB 9 (Opcode=0101, Addr=1001) 2 => "00110000", -- x"30" Program: ADD (Opcode=0011, Addr=0000) 3 => "01011010", -- x"5A" Program: LDB 10 (Opcode=0101, Addr=1010) 4 => "11000000", -- x"C0" Program: SUB (Opcode=1100, Addr=0000) 5 => "11110000", -- x"F0" Program: HLT (Opcode=1111, Addr=0000) 6 => (others => '0'), 7 => (others => '0'), 8 => "00001010", -- x"0A" Data: 10 9 => "00000101", -- x"05" Data: 5 10 => "00000011", -- x"03" Data: 3 others => (others => '0') ); -- ### 4. Control Signal Aliases (for readability) ### -- This makes the code MUCH easier to understand. alias s_RAO : std_logic is s_control_signals(13); -- Register A Out alias s_RAI : std_logic is s_control_signals(12); -- Register A In alias s_RBO : std_logic is s_control_signals(11); -- Register B Out alias s_RBI : std_logic is s_control_signals(10); -- Register B In alias s_SUB : std_logic is s_control_signals(9); -- ALU Subtract alias s_ALO : std_logic is s_control_signals(8); -- ALU Out alias s_PCI : std_logic is s_control_signals(7); -- Program Counter In alias s_PCO : std_logic is s_control_signals(6); -- Program Counter Out alias s_CNT : std_logic is s_control_signals(5); -- Program Counter Increment (Count) alias s_MRI : std_logic is s_control_signals(4); -- Memory Register In alias s_RMI : std_logic is s_control_signals(3); -- RAM In (Write) alias s_RMO : std_logic is s_control_signals(2); -- RAM Out (Read) alias s_IRI : std_logic is s_control_signals(1); -- Instruction Register In alias s_IRO : std_logic is s_control_signals(0); -- Instruction Register Out begin -- ### 5. Instantiate the "Brain" ### UUT_Control_Unit: control_unit port map ( CLK => s_clk, enable => s_enable, RST => s_rst, carry_flag => s_carry_flag, zero_flag => s_zero_flag, opcode => s_opcode, control_signals => s_control_signals ); -- ### 6. Clock and Stimulus ### -- Clock Generator CLK_GEN: process begin s_clk <= '0'; wait for CLK_PERIOD / 2; s_clk <= '1'; wait for CLK_PERIOD / 2; end process CLK_GEN; -- Stimulus (Reset and Run) STIMULUS: process begin s_rst <= '1'; wait for CLK_PERIOD * 5; -- Hold reset s_rst <= '0'; wait for CLK_PERIOD * 100; -- Let the simulation run for 100 cycles report "Simulation Halted. Check waveforms." severity note; wait; end process STIMULUS; -- ### 7. Datapath Implementation ### -- ## The 8-bit Bus (Concurrent Multiplexer) ## -- This is the heart of the CPU. It selects who gets to "talk" -- on the bus based on the control signals. s_bus <= s_alu_out when s_ALO = '1' else -- ALU Output s_reg_a when s_RAO = '1' else -- Register A Output s_reg_b when s_RBO = '1' else -- Register B Output s_pc when s_PCO = '1' else -- PC Output s_ram(to_integer(unsigned(s_mar))) when s_RMO = '1' else -- RAM Output "0000" & s_ir(3 downto 0) when s_IRO = '1' else -- IR LSB Output (for JMP) "ZZZZZZZZ"; -- High-Impedance (nothing writing) -- Monitor bus conflicts (for debugging) BUS_MONITOR: process(s_clk) variable driver_count : integer; begin if rising_edge(s_clk) then driver_count := 0; if s_ALO = '1' then driver_count := driver_count + 1; end if; if s_RAO = '1' then driver_count := driver_count + 1; end if; if s_RBO = '1' then driver_count := driver_count + 1; end if; if s_PCO = '1' then driver_count := driver_count + 1; end if; if s_RMO = '1' then driver_count := driver_count + 1; end if; if s_IRO = '1' then driver_count := driver_count + 1; end if; -- Report bus conflicts if driver_count > 1 then report "BUS CONFLICT! Multiple drivers active at PC=" & integer'image(to_integer(unsigned(s_pc))) severity error; end if; end if; end process BUS_MONITOR; -- ## Clocked Registers (The "Listeners") ## -- These processes describe all the components that load -- data from the bus on the rising edge of the clock. -- Register A REG_A_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_RAI = '1' then s_reg_a <= s_bus; end if; end if; end process REG_A_PROC; -- Register B REG_B_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_RBI = '1' then s_reg_b <= s_bus; end if; end if; end process REG_B_PROC; -- Instruction Register (IR) IR_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_IRI = '1' then s_ir <= s_bus; end if; end if; end process IR_PROC; -- Memory Address Register (MAR) MAR_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_MRI = '1' then s_mar <= s_bus(3 downto 0); -- Only takes 4 LSB end if; end if; end process MAR_PROC; -- Program Counter (PC) -- This one is special: it can Reset, Load (for JMP), or Increment PC_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_rst = '1' then s_pc <= (others => '0'); elsif s_PCI = '1' then -- Priority 1: Load (JMP) s_pc <= s_bus; elsif s_CNT = '1' then -- Priority 2: Increment s_pc <= std_logic_vector(unsigned(s_pc) + 1); end if; end if; end process PC_PROC; -- RAM Write Logic (RMI) RAM_WRITE_PROC: process(s_clk) begin if rising_edge(s_clk) then if s_RMI = '1' then -- Write data from bus to RAM at address in MAR if s_bus /= "ZZZZZZZZ" then s_ram(to_integer(unsigned(s_mar))) <= s_bus; end if; end if; end if; end process RAM_WRITE_PROC; -- ## Combinatorial Logic (Always Active) ## -- Opcode to Control Unit -- The Opcode is the 4 *upper* bits of the Instruction Register s_opcode <= s_ir(7 downto 4); -- ALU Logic (Generates output and flags) ALU_PROC: process(s_reg_a, s_reg_b, s_SUB) -- Use 9-bit intermediates to easily capture carry/borrow variable res_add : unsigned(8 downto 0); variable res_sub : unsigned(8 downto 0); begin -- Perform both calculations res_add := unsigned('0' & s_reg_a) + unsigned('0' & s_reg_b); res_sub := unsigned('0' & s_reg_a) - unsigned('0' & s_reg_b); -- Select the result based on the SUB signal if s_SUB = '1' then s_alu_out <= std_logic_vector(res_sub(7 downto 0)); s_carry_flag <= res_sub(8); -- '1' indicates a borrow if res_sub(7 downto 0) = 0 then s_zero_flag <= '1'; else s_zero_flag <= '0'; end if; else s_alu_out <= std_logic_vector(res_add(7 downto 0)); s_carry_flag <= res_add(8); -- '1' indicates a carry if res_add(7 downto 0) = 0 then s_zero_flag <= '1'; else s_zero_flag <= '0'; end if; end if; end process ALU_PROC; end architecture sim; ``` ***Kalo bener harusnya hasilnya Begini :*** ![image](https://hackmd.io/_uploads/rJUqY4zgbx.png) #### Hasil dijalankan : ![image](https://hackmd.io/_uploads/H1VuYO_eZg.png) ### A. Jelaskan apa yang testbench tersebut lakukan dengan memakai control unit anda. Berikan cuplikan kodenya bagian mana yang melakukannya (HINT : liat di RAM di testbench) (tidak usah referensi) (20 pts) testbench mengeksekusi operasi aritmatika (10 + 5) - 3menggunakan register A dan B. isi memori: ![image](https://hackmd.io/_uploads/ryYGetue-x.png) - instruksi yang dijalankan (s_ram): 1. hex 18 = 0001 1000 = LDA 8 load register A dengan isi dari memori 8 (10) 2. hex 59 = 0101 1001 = LDB 9 load register B dengan isi dari memori 9 (5) 3. hex 30 = 0011 0000 = ADD A + B, hasilnya disimpan di register A 4. hex 5A = 0101 1010 = LDB 10 load register B dengan isi dari memori 10 (3) 5. hex c0 = 1100 0000 = SUB A - B, hasilnya disimpan di register A # BoNUS (0 poin) ### 1. Modul PSD siapa yang paling sulit (sebutkan aslabnya) semuanya (selalu gosong di cs) ### 2. Apakah anda senang belajar PSD selama ini nope. PSD? more like PtSD 💀 ### 3. Siapkah anda belajar assembly (teaser) alamak