summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/alu.ml54
-rw-r--r--cpu/cpu.ml7
-rw-r--r--cpu/os.asm36
3 files changed, 72 insertions, 25 deletions
diff --git a/cpu/alu.ml b/cpu/alu.ml
index 96e2ae4..ff98c23 100644
--- a/cpu/alu.ml
+++ b/cpu/alu.ml
@@ -119,35 +119,47 @@ let rec split_list = function
| [_] -> assert false
| x::y::tl -> let a, b = split_list tl in x::a, y::b
-(* n must be a power of two *)
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
+ (* 'mule' est intialisé à b au début de la multiplication,
+ puis à chaque cycle est shifté de 1 bit vers la droite (donc perd le bit de poid faible) *)
+ let mule, set_mule = loop n in
+ let mule = set_mule (mux start_signal (((reg n mule) % (1, n-1)) ++ const "0") b) in
+ (* 'adde' est initialisé à a étendu sur 32 bits au début de la multiplication,
+ puis à chaque cycle est shifté de 1 bit vers la gauche (donc multiplié par 2) *)
+ let adde, set_adde = loop (2*n) in
+ let adde = set_adde (mux start_signal (const "0" ++ ((reg (2*n) adde) % (0, 2*n-2))) (a ++ (zeroes n))) in
+
+ (* 'res' est un accumulateur qui contient le résultat que l'on calcule,
+ il est initialisé à 0 au début de la multiplication, et à chaque cycle
+ si mule[0] est non nul, on lui rajoute adde (c'est correct) *)
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 t_res = mux start_signal (reg (2*n) res) (zeroes (2*n)) in
+ let res = set_res (mux (mule ** 0) t_res (nadder (2*n) adde t_res)) in
+ let work_remains = nonnull (n - 1) (mule % (1, n-1)) in
let finished =
- set_next_busy (busy ^& add) ^.
- (not add) ^& busy in
+ set_next_busy (busy ^& work_remains) ^.
+ (not work_remains) ^& busy in
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 *)
+ zeroes (n-3) ++ const "110", zeroes (n-3) ++ const "110", start_signal
+ (* TODO : unsigned division, 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 *)
+ zeroes (n-3) ++ const "101", zeroes (n-3) ++ const "101", 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 *)
+ zeroes (n - 3) ++ const "011", zeroes (n - 3) ++ const "011", start_signal
+ (* TODO : signed division *)
(* Shifts *)
@@ -205,7 +217,7 @@ 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 start_signal =
+let alu_arith f0 f a b start_signal =
(* See table for ALU below *)
let add = nadder 16 a b in
let sub = nsubber 16 a b in
@@ -218,17 +230,17 @@ let alu_arith f1 f a b start_signal =
let q03 = mux (f ** 0) mulu divu in
let q10 = mux (f ** 1) q00 q01 in
let q11 = mux (f ** 1) q00 q03 in
- let q = mux f1 q10 q11 in
+ let q = mux f0 q10 q11 in
let r01 = mux (f ** 0) mul2 div2 in
let r03 = mux (f ** 0) mulu2 divu2 in
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
+ let r = mux f0 r10 r11 in
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
+ let end_signal = mux f0 s10 s11 in
q, r, end_signal
let alu_logic f a b =
@@ -244,7 +256,7 @@ let alu_shifts f a b =
let alu f1 f0 f a b start_signal =
(*
- f0 f1 f action
+ f1 f0 f action
-- -- - ------
0 0 0 add
0 0 1 sub
@@ -263,13 +275,13 @@ let alu f1 f0 f a b start_signal =
1 1 2 lsr
1 1 3 asr
*)
- let arith, arith_r, arith_end_signal = alu_arith f1 f a b start_signal in
+ let arith, arith_r, arith_end_signal = alu_arith f0 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
- let end_signal = mux f0 arith_end_signal start_signal in
+ let q0 = mux f0 logic shifts in
+ let s = mux f1 arith q0 in
+ let r = mux f1 arith_r (zeroes 16) in
+ let end_signal = mux f1 arith_end_signal start_signal in
s, r, end_signal
diff --git a/cpu/cpu.ml b/cpu/cpu.ml
index 14b1f2a..78caa30 100644
--- a/cpu/cpu.ml
+++ b/cpu/cpu.ml
@@ -154,8 +154,8 @@ let rl, rh, i, ex, exf, pc =
(* instruction : add/sub/mul/div/unsigned/or/and/xor/nor/lsl/lsr/asr *)
let instr_alu = eq_c 3 (i_i % (2, 4)) 0b000 in
- let f0 = i_i ** 0 in
let f1 = i_i ** 1 in
+ let f0 = i_i ** 0 in
let double_instr_alu = instr_alu ^& (not f1) ^& (i_f ** 1) ^& (ne_n 3 i_r (const "101")) in
let alu_d1, alu_d2, instr_alu_finished = alu f1 f0 i_f v_ra v_rb (exec ^& instr_alu) in
@@ -278,6 +278,11 @@ let rl, rh, i, ex, exf, pc =
( (* lil *) i_id ++ (mux instr_lixz (v_r % (8, 15)) (zeroes 8)))
( (* liu *) (mux instr_lixz (v_r % (0, 7)) (zeroes 8)) ++ i_id)) in
+ (* instruction : lie *)
+ let instr_lie = eq_c 5 i_i 0b11100 in
+ let wr = mux instr_lie wr i_r in
+ let rwd= mux instr_lie rwd (sign_extend 8 16 i_id) in
+
save_cpu_regs wr rwd ^.
save_ram_read (cpu_ram ra we wa d) ^.
save_next_read exec_finished ^.
diff --git a/cpu/os.asm b/cpu/os.asm
index c7abde3..6c5d162 100644
--- a/cpu/os.asm
+++ b/cpu/os.asm
@@ -141,7 +141,7 @@ t3fail:
pop RA
jr RA
-unit_test_0:
+unit_test_0: # Addition / substraction
li B 1
li C 12
@@ -150,16 +150,46 @@ unit_test_0:
sei A C 56
and B B A
- li C -7
+ li C 7
+ sub C Z C
li D 7
add C C D
se A C Z
and B B A
+ li C 32767
+ li D 32767
+ add C C D
+ li D 2
+ sub D Z D
+ se A C D
+ and B B A
+
jr RA
-unit_test_1:
+
+unit_test_1: # Unsigned multiplication
li B 1
+
+ li C 12
+ li D 44
+ mulu C C D
+ move D E
+ sei A C 528
+ and B B A
+ se A D Z
+ and B B A
+
+ li C 744
+ li D 1244
+ mulu C C D
+ move D E
+ sei A C 8032
+ and B B A
+ sei A D 14
+ and B B A
+
jr RA
+
unit_test_2:
li B 1
jr RA