From 40f46cd1ce93d7f8045dda4e0af91670cd681d57 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 10 Jan 2014 13:57:45 +0100 Subject: Add support for ALU operations on several cycles. --- cpu/alu.ml | 40 +++++++++++++++++++++++----------------- cpu/cpu.ml | 18 +++++++++--------- cpu/os.asm | 1 + 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/cpu/alu.ml b/cpu/alu.ml index f437bd3..828856c 100644 --- a/cpu/alu.ml +++ b/cpu/alu.ml @@ -56,17 +56,17 @@ let nadder n a b = let rec nsubber n a b = zeroes n (* TODO *) -let rec nmul n a b = - zeroes n, zeroes n (* TODO : retuns lo and hi part of 32-bit answer *) +let rec nmul n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : retuns lo and hi part of 32-bit answer *) -let rec ndiv n a b = - zeroes n, zeroes n (* TODO : returns quotient and remainder *) +let rec ndiv n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : returns quotient and remainder *) -let rec nmulu n a b = - zeroes n, zeroes n (* TODO : same as nmul but unsigned *) +let rec nmulu n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : same as nmul but unsigned *) -let rec ndivu n a b = - zeroes n, zeroes n (* TODO : save as ndiv but unsigned *) +let rec ndivu n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : save as ndiv but unsigned *) (* Shifts *) @@ -123,14 +123,14 @@ let alu_comparer n f0 f a b = let lte = mux (f ** 1) lte_signed lte_unsigned in mux f0 eq_ne lte -let alu_arith f1 f a b = +let alu_arith f1 f a b start_signal = (* See table for ALU below *) let add = nadder 16 a b in let sub = nsubber 16 a b in - let mul, mul2 = nmul 16 a b in - let div, div2 = ndiv 16 a b in - let mulu, mulu2 = nmulu 16 a b in - let divu, divu2 = ndivu 16 a b in + let mul, mul2, mul_end_signal = nmul 16 a b start_signal in + let div, div2, div_end_signal = ndiv 16 a b start_signal in + let mulu, mulu2, mulu_end_signal = nmulu 16 a b start_signal in + let divu, divu2, divu_end_signal = ndivu 16 a b start_signal in let q00 = mux (f ** 0) add sub in let q01 = mux (f ** 0) mul div in let q03 = mux (f ** 0) mulu divu in @@ -142,7 +142,12 @@ let alu_arith f1 f a b = let r10 = mux (f ** 1) (zeroes 16) r01 in let r11 = mux (f ** 1) (zeroes 16) r03 in let r = mux f1 r10 r11 in - q, r + let s01 = mux (f ** 0) mul_end_signal div_end_signal in + let s03 = mux (f ** 0) mulu_end_signal divu_end_signal in + let s10 = mux (f ** 1) start_signal s01 in + let s11 = mux (f ** 1) start_signal s03 in + let end_signal = mux f1 s10 s11 in + q, r, end_signal let alu_logic f a b = (* See table for ALU below *) @@ -155,7 +160,7 @@ let alu_shifts f a b = let q1 = mux (f ** 0) (op_lsr 16 a b) (op_asr 16 a b) in mux (f ** 1) (op_lsl 16 a b) q1 -let alu f1 f0 f a b = +let alu f1 f0 f a b start_signal = (* f0 f1 f action -- -- - ------ @@ -176,12 +181,13 @@ let alu f1 f0 f a b = 1 1 2 lsr 1 1 3 asr *) - let arith, arith_r = alu_arith f1 f a b in + let arith, arith_r, arith_end_signal = alu_arith f1 f a b start_signal in let logic = alu_logic f a b in let shifts = alu_shifts f a b in let q0 = mux f1 logic shifts in let s = mux f0 arith q0 in let r = mux f0 arith_r (zeroes 16) in - s, r + let end_signal = mux f0 arith_end_signal start_signal in + s, r, end_signal diff --git a/cpu/cpu.ml b/cpu/cpu.ml index 3f9dd74..75d1c56 100644 --- a/cpu/cpu.ml +++ b/cpu/cpu.ml @@ -157,15 +157,15 @@ let rl, rh, i, ex, exf, pc = let f0 = i_i ** 0 in let f1 = i_i ** 1 in let double_instr_alu = instr_alu ^& (not f1) ^& (i_f ** 1) ^& (ne_n 3 i_r (const "101")) in - let instr_alu = exec ^& instr_alu in - let instr_alu_2 = reg 1 (exec ^& double_instr_alu) in - - let alu_d1, alu_d2 = alu f1 f0 i_f v_ra v_rb in - let wr = mux instr_alu wr i_r in - let rwd = mux instr_alu rwd alu_d1 in - let wr = mux instr_alu_2 wr (const "101") in - let rwd = mux instr_alu_2 rwd alu_d2 in - let exec_finished = mux double_instr_alu exec_finished instr_alu_2 in + + let alu_d1, alu_d2, instr_alu_finished = alu f1 f0 i_f v_ra v_rb (exec ^& instr_alu) in + let instr_alu_store_2 = reg 1 (instr_alu_finished ^& double_instr_alu) in + let wr = mux instr_alu_finished wr i_r in + let rwd = mux instr_alu_finished rwd alu_d1 in + let wr = mux instr_alu_store_2 wr (const "101") in + let rwd = mux instr_alu_store_2 rwd alu_d2 in + let exec_finished = mux instr_alu exec_finished + (mux double_instr_alu instr_alu_finished instr_alu_store_2) in (* instruction : se/sne/slt/slte/sleu/sleu *) diff --git a/cpu/os.asm b/cpu/os.asm index 4a7449a..fd8c50f 100644 --- a/cpu/os.asm +++ b/cpu/os.asm @@ -87,6 +87,7 @@ add_b_to_string: incri C 1 sw C 0(D) pop A + jz A check_input check_input_ret: jr RA -- cgit v1.2.3