Commit 875c4b81 authored by Quentin Aristote's avatar Quentin Aristote
Browse files

corrected ram and rom handling

parent d13c37ba
......@@ -66,7 +66,6 @@ let bit_of_bool = function
| false -> 0
| true -> 1
(* Fast integer exponentiation *)
let pow2 n = 1 lsl n
(* Prints a type fully. Used to print error messages. *)
......@@ -82,7 +81,7 @@ let eval_arg env = function
(* Converts an address from BitArray to integer *)
let eval_addr env a = match eval_arg env a with
| VBitArray t -> (* big-endian, but could be small-endian *)
Array.fold_right (fun b n -> 2 * n + bit_of_bool b) t 0
Array.fold_left (fun n b -> 2 * n + bit_of_bool b) 0 t
| VBit b -> bit_of_bool b
(* Evaluates an equation *)
......@@ -114,13 +113,17 @@ let eval_expr env roms rams id = function
end
| Emux (s, a1, a2) -> begin
match eval_arg env s with
| VBit false -> eval_arg env a1
| VBit true -> eval_arg env a2
| VBit true | VBitArray [|true|] -> eval_arg env a1
| VBit false | VBitArray [|false|] -> eval_arg env a2
| VBitArray t -> raise (Wrong_type (id, s, TBitArray (Array.length t)))
end
| Erom (addr_size, word_size, read_addr) ->
VBitArray (Env.find id roms).(eval_addr env read_addr)
| Eram (addr_size, word_size, read_addr, write_enable, write_addr, data) ->
| Erom (_, word_size, read_addr) -> begin
try
VBitArray (Env.find id roms).(eval_addr env read_addr)
with
| Invalid_argument _ -> VBitArray (Array.make word_size false)
end
| Eram (_, _, read_addr, _, _, _) ->
(* The writing part of this instruction is done after
all variables have seen their value computed. *)
VBitArray (Env.find id rams).(eval_addr env read_addr)
......@@ -143,9 +146,14 @@ let eval_expr env roms rams id = function
end
| Eselect (i, a) -> begin
match eval_arg env a with
| VBitArray t -> VBit t.(i)
| VBitArray t -> begin
try
VBit t.(i)
with
| Invalid_argument _ -> raise (Out_of_bounds id)
end
| VBit b when i = 0 -> VBit b
| _ -> raise (Wrong_type (id, a, TBit))
| _ -> raise (Out_of_bounds id)
end
(* Asks the user to input variable <id> and outputs the value
......@@ -155,7 +163,10 @@ let rec read_value id t =
let input_length = match t with
| TBit | TBitArray 1 -> 1
| TBitArray n -> n in
Printf.printf "%s : %d ? " id input_length;
Printf.printf "%s (%d bit%s) = "
id
input_length
(if input_length <= 1 then "" else "s");
let input = read_line () in
try
let v = Array.init
......@@ -168,7 +179,8 @@ let rec read_value id t =
match input_length with
| 1 when Array.length v = 1 -> VBit v.(0)
| n when Array.length v = n -> VBitArray v
| _ -> raise (Invalid_argument (Format.sprintf "length : %d" (Array.length v)))
| _ -> raise (Invalid_argument
(Format.sprintf "length : %d" (Array.length v)))
with
| Invalid_argument s -> Format.printf "Wrong input %s.@." s;
read_value id t
......@@ -177,12 +189,13 @@ let rec read_value id t =
let print_only = ref false
let number_steps = ref (-1)
let rom_directory = ref "./"
let cycle_duration = ref 0.
let cycle_duration = ref 0.05
(* The main part of the program *)
let compile filename =
(* We first check for any combinational cycle and order the netlist. *)
Format.printf "scheduling ...@." ;
let p = try
Scheduler.schedule (Netlist.read_file filename)
with
......@@ -227,35 +240,50 @@ let compile filename =
| TBitArray n -> VBitArray (Array.make n false))
!env
| Erom (addr_size, word_size, _) ->
| Erom (_, word_size, _) ->
(* Loads the ROM block associated
to each variable whose value is
read through a ROM statement. *)
Format.printf "loading rom ...@." ;
let file = (* Tries to open <id>.rom *)
try
open_in_bin "/home/qaristote/documents/DI/SystèmeDigital/microprocesseur/command.rom" (*(!rom_directory ^ id ^ ".rom")*)
with
| Sys_error s when (s = id ^ ": No such file or directory"
| Sys_error s when (s = !rom_directory ^
id ^
".rom: No such file or directory"
|| s = "Is a directory") ->
Format.eprintf
"%s.rom either does not exist or is a directory."
id;
exit 2 in
let size = pow2 addr_size in
let r = Array.make size (Array.make word_size false) in
for i = 0 to size / 256 - 1 do
let n = (* Tries to read from <id>.rom *)
try
input_byte file
with
| End_of_file -> 0 in
for j = 7 downto 0 do
let addr = (256 * i + j) in
r.(addr / word_size).(addr mod word_size) <-
bool_of_bit ((n / (pow2 j)) mod 2)
done
done;
close_in file;
let bits = ref [] in
let size = ref 0 in
begin try
while true do
let n = (* Tries to read from <id>.rom *)
input_byte file in
for j = 7 downto 0 do
bits := bool_of_bit ((n / (pow2 j)) mod 2) :: !bits ;
size := !size + 1
done ;
done ;
with
| End_of_file -> () end ;
close_in file ;
bits := List.rev !bits ;
let r = Array.init
(!size / word_size)
(fun i -> Array.init
word_size
(fun i ->
try
let result = List.hd !bits in
bits := List.tl !bits ;
result
with
| Failure _ -> false)) in
roms := Env.add id r !roms
| Eram (addr_size, word_size, _, _, _, _) ->
......@@ -275,7 +303,6 @@ let compile filename =
let i = ref 0 in
let start_time = ref (Unix.time ()) in
while !i <> !number_steps do
Format.printf "cycle %d@." !i ;
(* --- Input ---
For each variable in p.p_inputs, we
ask for its value and add it to env *)
......@@ -362,7 +389,11 @@ let compile filename =
we print it in stdout *)
List.iter
(fun id -> try
Format.printf "=> %s = %a@." id print_value (Env.find id !env)
let value = Env.find id !env in
Format.printf "=> %s = %a -> 0x%x@."
id print_value
value
(eval_addr !env (Aconst value))
with
| Not_found -> Format.eprintf "Outbound output variable %s.@." id;
exit 2)
......@@ -373,7 +404,6 @@ let compile filename =
Unix.sleepf (!cycle_duration -. end_time +. !start_time);
start_time := end_time ;
i := 1 + !i;
Format.printf "fin du cycle@." ;
done)
let main () =
......
Supports Markdown
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