Commit 8f6d25c0 authored by Martin Pépin's avatar Martin Pépin
Browse files

Go to hell shift

parent 889afe2d
......@@ -14,15 +14,10 @@ ALU(input1:[32], input2:[32], alu_control:[4]) = (alu_zero, result:[32]) where
mux_n<word>(alu_control[2], (* if 1 then HI/LO, else logical shift *)
(* 1.1. *)
zero_n<word>(), (* HI/LO *)
(* 1.0. *)
mux_n<word>(alu_control[1], (* Case logical shift *)
(* 110. *)
shift_by_reg_ALU(input1, input2, 1, alu_control[3]),
(* 100. *)
shift_by_reg_ALU(input1, input2, 0, 0)
)
),
(* 110. -> shift right *)
(* 100. -> shift left *)
shift_logical(input1, input2, alu_control[1], alu_control[3])
),
(* 0*** *)
mux_n<word>(alu_control[1], (* if 1 then logical else arihtmetical *)
......@@ -30,7 +25,9 @@ ALU(input1:[32], input2:[32], alu_control:[4]) = (alu_zero, result:[32]) where
mux_n<word>(alu_control[2],
(* 011. *)
mux_n<word>(alu_control[3],
(* 0111 *)
xor_ALU(input1, input2),
(* 0110 *)
nor_ALU(input1, input2)
),
......@@ -53,8 +50,6 @@ ALU(input1:[32], input2:[32], alu_control:[4]) = (alu_zero, result:[32]) where
)
)
);
(* Signal pour les branchements *)
alu_zero = equal_zero_n<32>(result);
(* Traitement de la multiplication *)
write_hilo = equal_n<3>(0.0.1, alu_control[..2]);
read_hilo = alu_control[0] & alu_control[2];
......@@ -66,4 +61,6 @@ ALU(input1:[32], input2:[32], alu_control:[4]) = (alu_zero, result:[32]) where
result_aux,
mux_n<word>(alu_control[3], hi_val, lo_val)
);
(* Signal pour les branchements *)
alu_zero = equal_zero_n<32>(result);
end where
......@@ -30,14 +30,6 @@ extand_const_n<n, offset>(c:[n]) = (o:[n + offset]) where
o = extand_left_n<n, offset>(c, c[0])
end where
cut_tail<n>(x:[n]) = out:[n-1] where
if n = 1 then
out = [];
else
out = x[..n-2];
end if
end where
(* logical shifts *)
shift_by_const<n,m,shift_val>(input:[n], cst:[m], is_right, signed)
= out:[n] where
......@@ -50,9 +42,9 @@ shift_by_const<n,m,shift_val>(input:[n], cst:[m], is_right, signed)
extand_right_n<n-shift_val,shift_val>(input[..n-shift_val-1], bit)
);
else
new_cst = cut_tail<m>(cst);
new_cst = cst[1..];
out = mux_n<n>(
cst[m-1],
cst[0],
shift_by_const<n,m-1,shift_val*2+1>(input, new_cst, is_right, signed),
shift_by_const<n,m-1,shift_val*2>(input, new_cst, is_right, signed)
);
......@@ -62,15 +54,12 @@ shift_by_const<n,m,shift_val>(input:[n], cst:[m], is_right, signed)
end if
end where
(* shift by shamt, either to the right or to the left. Arithmetic or not.*)
shift_by_shamt_ALU(input:[32], shamt:[5], is_right, keep_sign) = (out:[32]) where
out = shift_by_const<32, 5, 1>(input, shamt, is_right, keep_sign)
(* shift by value to the right or left, arithmetic or not *)
shift_logical(input:[32], value:[32], is_right, keep_sign) = (out:[32]) where
out = shift_by_const<32,32,1>(input, value, is_right, keep_sign)
(* ^ ça devrait être un 0 FIXME *)
end where
(* shift by value stored in reg, to the right or left, arithmetic or not *)
shift_by_reg_ALU(input:[32], cst:[32], is_right, keep_sign) = (out:[32]) where
out = shift_by_const<32, 32, 1>(input, cst, is_right, keep_sign)
end where
(* ------------------------------------------------------------------------- *)
(* Opérations booléennes *)
......
......@@ -33,12 +33,13 @@ main (b) = (instruction:[word], syscall, ctrl:[2]) where
(* Processing the calculi *)
imm = extand_const_n<16,16>(instruction[16..31]);
alu_input_1 = read_data1;
alu_input_2 = mux_n<word>(
use_shamt,
extand_left_n<5,word-5>(instruction[21..25], 0),
mux_n<word>(alu_src, imm, read_data2)
);
(alu_zero, alu_result) = ALU(read_data1, alu_input_2, alu_ctrl);
(alu_zero, alu_result) = ALU(alu_input_1, alu_input_2, alu_ctrl);
(* Reading/writing RAM *)
read_data_mem = data_mem<32,word>(alu_result, read_data2, mem_read,
......
......@@ -179,7 +179,7 @@ let interp asm_file n script_mode input_c output_c p =
let expected = input_line output_c in
let result = str_of_val value in
if expected <> result then begin
Format.eprintf "Unexpected output at %d-th iteration:\n" (!loop+1);
Format.eprintf "Unexpected output at %d-th iteration:\n" !loop;
Format.eprintf "%s instead of %s.@." result expected;
exit 1 end
)
......
......@@ -4,6 +4,8 @@ open Utils
type t = bool array array
exception Invalid_RAM_access of string
let array_err s n = raise @@ Invalid_RAM_access
(Printf.sprintf "%s: out of bouds (%d)" s n)
let init size =
if size mod 4 = 0 then
......@@ -28,21 +30,22 @@ let bits_of_int size n =
bits
let get_byte ram addr =
try ram.(addr)
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.get_byte" addr
let get_halfword ram addr =
if addr mod 2 = 0 then
try Array.concat [ram.(addr) ; ram.(addr+1)]
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.get_halfword" addr
else
raise @@ Invalid_RAM_access "Address must be even."
let get_word ram addr =
if addr mod 4 = 0 then
try Array.concat [ram.(addr) ; ram.(addr+1) ; ram.(addr+2) ; ram.(addr+3)]
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.get_word" addr
else
raise @@ Invalid_RAM_access "Address must be a multiple of 4."
......@@ -50,7 +53,7 @@ let get_word ram addr =
let write_byte ram addr b =
if Array.length b = 8 then
try ram.(addr) <- Array.copy(b)
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.write_byte" addr
else raise @@ Invalid_RAM_access "A byte must be 8 bits"
......@@ -65,7 +68,7 @@ let write_halfword ram addr hw =
raise @@ Invalid_RAM_access "A halfword must be 16 bits"
else
raise @@ Invalid_RAM_access "Address must be even."
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.write_halfword" addr
let write_word ram addr w =
......@@ -78,7 +81,7 @@ let write_word ram addr w =
ram.(addr+3) <- sub 24 8
end else
raise @@ Invalid_RAM_access "Address must be a multiple of 4."
with Invalid_argument s -> raise @@ Invalid_RAM_access s
with Invalid_argument _ -> array_err "Ram.write_word" addr
let print_ram oc ?(range=(0,-1)) ram =
......
1001
00000000000000000000000000000110
00000000000000000000000010000100
0000
00000000000000000000000000011011
00000000000000000000000000001101
0001
00000000000000000000000000111001
00000000000000000000000011101010
0011
00000000000000000001000110011100
00000000000000001001011000001010
0101
00000000000000000001000110011100
00000000000000001001011000001010
0100
00000000000000000001000110011100
00000000000000001001011000001010
0110
00000000000000000001000110011100
00000000000000001001011000001010
0111
00000000000000000001000110011100
00000000000000000000000000000011
1100
00000000000000000001000110011100
00000000000000000000000000000011
1000
1011
require alu/utils
require alu/main
main(x:[4], y:[4]) = (res:[8], carry) where
(res_short, carry) = adder_n<4>(x, y, 0);
res = extand_left_n<4,4>(res_short, 0);
main(x:[32], y:[32], ctrl:[4]) = (zero, res:[32]) where
(zero, res) = ALU(x, y, ctrl);
end where
00001100
0
00000011
00000000000000000000000010001010
0
00000000000000000000000000001110
1
00000000000000000000000000000000
0
00000000000000001001011110011110
0
00000000000000000001000000001000
0
11111111111111110110100001100001
0
00000000000000001000011110010110
0
00000000000000000000001000110011
0
00000000000000001000110011100000
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment