diff options
Diffstat (limited to 'cpu/alu.ml')
-rw-r--r-- | cpu/alu.ml | 67 |
1 files changed, 34 insertions, 33 deletions
@@ -120,41 +120,36 @@ let rec split_list = function | x::y::tl -> let a, b = split_list tl in x::a, y::b (* n must be a power of two *) -let nmul n a b = +let nmulu n a b start_signal = + let next_busy, set_next_busy = loop 1 in + let busy = start_signal ^| (reg 1 next_busy) in - let summands = List.map (fun i -> - mux (b ** i) - (zeroes (2*n)) - ((zeroes i) ++ a ++ (zeroes (n - i))) - - ) (range 0 (n-1)) in + let res, set_res = loop (2*n) in + let t_res = mux start_signal (const "0" ++ ((reg (2*n) res) % (0, 2*n-2))) (zeroes (2*n)) in + let mul, set_mul = loop n in + let mul = set_mul (mux start_signal (((reg n mul) % (1, n-1)) ++ const "0") b) in + let add = nonnull n mul in + let res = set_res (mux add t_res (nadder (2*n) (a ++ zeroes n) t_res)) in - - let rec sum_list = function - | [x] -> x - | l -> - let s1, s2 = split_list l in - nadder (2*n) (sum_list s1) (sum_list s2) + let finished = + set_next_busy (busy ^& add) ^. + (not add) ^& busy in - in - let r = sum_list summands in - (r % (0, n-1)), (r % (n, 2*n - 1)) + res % (0, n-1), res % (n, 2*n-1), finished +let rec ndivu n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : unsigned division, returns quotient and remainder *) -let rec ndiv n a b = - zeroes n, zeroes n (* TODO : returns quotient and remainder *) +let rec nmul n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : signed multiplication ; returns low part and high part *) +let rec ndiv n a b start_signal = + zeroes n, zeroes n, start_signal (* TODO : signed division *) -let rec nmulu n a b = - zeroes n, zeroes n (* TODO : same as nmul but unsigned *) - -let rec ndivu n a b = - zeroes n, zeroes n (* TODO : save as ndiv but unsigned *) - (* Shifts *) let npshift_signed n p a b = @@ -210,14 +205,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 @@ -229,7 +224,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 *) @@ -242,7 +242,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 -- -- - ------ @@ -263,12 +263,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 |