Commit 5eaa6853 authored by Martin Pépin's avatar Martin Pépin
Browse files

Merge branch 'master' into theend

parents 2d934160 8b8c4010
......@@ -9,7 +9,8 @@ require utils
control(instruction:[6],
funct:[6]) = (reg_dst, jump, branch, mem_read, mem_to_reg, alu_op:[3],
mem_write, alu_src, reg_write, write_pc, is_beq, is_jal)
mem_write, alu_src, reg_write, write_pc, is_beq, is_jal,
is_jr)
where
(* Variable interne : bit à 1 si instruction est nulle *)
......@@ -84,6 +85,9 @@ where
(* is_jal à 1 => instruction jal *)
is_jal = equal_n<6>(instruction, 0.0.0.0.1.1);
(* is_jr à 1 => instruction jr *)
is_jr = null_instr and ((not funct[1]) and funct[2] and (not funct[3]));
end where
(* Bloc de contrôle de l'ALU
......
......@@ -11,16 +11,19 @@ require alu/main
(* --------------------------- *)
main () = () where
(* Reading the next instruction from the ROM *)
(instruction, pc_incr) = next_instruction(instruction[6..],
imm, jump, branch and (not(is_beq) xor alu_zero));
(instruction, pc_incr) = next_instruction(
instruction[6..], imm_addr, jump,
branch and (not(is_beq) xor alu_zero), is_jr);
(* If is_jr is set, the immediate value is replaced by the 1st read register value *)
imm_addr = mux_n<word>(is_jr, read_data1, extended_imm);
(* Setting the control flags *)
(reg_dst, jump, branch, mem_read,
mem_to_reg, alu_op, mem_write, alu_src,
reg_write, write_pc, is_beq, is_jal) = control(instruction[0..5],
instruction[26..31]);
reg_write, write_pc, is_beq, is_jal, is_jr) = control(instruction[0..5],
instruction[26..31]);
funct = mux_n<6>(reg_dst, instruction[26..], 0.0.0.0.0.0);
(alu_ctrl, use_shamt) = ALU_control(funct, alu_op);
......@@ -41,18 +44,20 @@ main () = () where
reg_write);
(* Processing the calculi *)
imm = extend_const_n<16,16>(instruction[16..31]);
extended_imm = extend_const_n<16,16>(instruction[16..31]);
alu_input_1 = read_data1;
alu_input_2 = mux_n<word>(
use_shamt,
extend_left_n<5,word-5>(instruction[21..25], 0),
mux_n<word>(alu_src, imm, read_data2)
mux_n<word>(alu_src, extended_imm, read_data2)
);
(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,
mem_write);
(* If is_jal is set, PC+4 is taken as input for registers *)
write_data = mux_n<word>(is_jal,
pc_incr,
......
......@@ -16,16 +16,19 @@ require registers
Note: if [jump] and [branch] are both set, the jump wins.
*)
calc_address(addr:[word], partial_jump_addr:[word-6], imm:[word], jump, branch)
calc_address(addr:[word], partial_jump_addr:[word-6], imm:[word], jump, branch, is_jr)
= (new_addr:[word], incr_addr:[word])
where
(incr_addr, c0) = adder_n<word>(addr, zero_n<word-3>().1.0.0, false);
(* Jump address *)
jump_addr = incr_addr[0..3] . partial_jump_addr . 0.0;
(* Jump address
If is_jr is set, this is equal to imm (see main block) *)
jump_addr = mux_n<word>(is_jr,
branch_addr,
incr_addr[0..3] . partial_jump_addr . 0.0);
(* Branch address *)
(* Branch address [this is a register value if is_jr is set!] *)
branch_addr = (imm.0.0)[2..];
(* Computing the next value of PC *)
......@@ -35,9 +38,9 @@ where
end where
(* Gives the last value of PC and sets PC to the next instruction's address. *)
PC (partial_jump_addr:[word-6], imm:[word], jump, branch, wait)
PC (partial_jump_addr:[word-6], imm:[word], jump, branch, is_jr, wait)
= (r:[word], incr_addr:[word]) where
(next_addr, incr_addr) = calc_address(r, partial_jump_addr, imm, jump, branch);
(next_addr, incr_addr) = calc_address(r, partial_jump_addr, imm, jump, branch, is_jr);
r = meta_reg<word>(next_addr, not wait);
end where
......@@ -48,11 +51,11 @@ couter4(init) = ctrl:[2] where
end where
(* Reads the next instruction and handles the syscalls *)
next_instruction(partial_jump_addr:[word-6], imm:[word], jump, branch)
next_instruction(partial_jump_addr:[word-6], imm:[word], jump, branch, is_jr)
= (instruction:[word], pc_incr:[word]) where
(* The real instruction read from the ROM *)
(pc_value, pc_incr) = PC(partial_jump_addr, imm, jump, branch, wait);
(pc_value, pc_incr) = PC(partial_jump_addr, imm, jump, branch, is_jr, wait);
instruction_code = rom<word,word>(pc_value);
(* If a syscall is in progress, we change the instruction *)
......
......@@ -490,7 +490,7 @@ similaire à celle de MIPS. A défaut de décrire précisément chacune de ces
\subsection{Synchronisation de la montre}\label{sync}
Pour gérer la synchronisation de la montrer avec l'heure extérieure, nous
utilisons la même technique : l'adresse mémoire \texttt{0x00000002} contient
utilisons la même technique : l'adresse mémoire \texttt{0x00000000} contient
une valeur égale à $0$ si cette case mémoire a été lue depuis moins d'une
seconde et $1$ si cela fait plus d'une seconde. C'est le simulateur qui
assure que cette propriété reste vraie.
......@@ -508,8 +508,8 @@ similaire à celle de MIPS. A défaut de décrire précisément chacune de ces
lu à l'adresse \texttt{0x00000002}. Autrement dit :
\begin{tabular}{rl}
\texttt{sync\_n\footnote{Ici \texttt{sync\_n} désigne un label unique}:}
& \texttt{lb \ \$t0, 2(\$zero)} \\
\texttt{\_\_sync\_n\footnote{Ici \texttt{\_\_sync\_n} désigne un label unique}:}
& \texttt{lw \ \$t0, 0(\$zero)} \\
& \texttt{beq \$t0, \$zero, sync\_n}
\end{tabular}
......
true: use_menhir
true: warn(A-4-41)
<*.ml>: debug
<*.byte>: use_unix, debug
<*.byte> or <*.native>: use_unix, debug
<asm> or <netlist>: include
......@@ -56,7 +56,7 @@ module Env = struct
instr
let get_ram word_size env addr =
let value = _get word_size env.ram addr in
if Ram.int_of_bits addr = 2 && Ram.int_of_bits value = 1 then
if Ram.int_of_bits addr = 0 && Ram.int_of_bits value = 1 then
set_tick_byte env 0;
value
let write_on_ram word_size env bin_addr data =
......@@ -163,7 +163,7 @@ let interp_exp env = function
let interp asm_file n script_mode input_c output_c p =
(* Initiating memory *)
let env = Env.init asm_file 4096 4096 in
let tick = ref @@ Sys.time() in
let tick = ref @@ Unix.gettimeofday() in
(* Main loop *)
let loop = ref 0 in
while !loop <> n do
......@@ -194,7 +194,7 @@ let interp asm_file n script_mode input_c output_c p =
)
p.p_outputs;
(* Handling the sync property *)
let now = Sys.time () in
let now = Unix.gettimeofday() in
if now -. !tick >= 1. then begin
tick := now;
Env.set_tick_byte env 1
......
......@@ -9,11 +9,11 @@ where
(* Pour un confort de lecture lors du debug : concaténation de bits *)
pre_alu_op = reg_dst . jump . branch . mem_read . mem_to_reg;
post_alu_op = mem_write . alu_src . reg_write . write_pc . is_beq . is_jal;
post_alu_op = mem_write . alu_src . reg_write . write_pc . is_beq . is_jal (* . is_jr *);
(* Bloc de contrôle général *)
(reg_dst, jump, branch, mem_read, mem_to_reg, alu_op, mem_write, alu_src,
reg_write, write_pc, is_beq, is_jal) = control(instruction, funct);
reg_write, write_pc, is_beq, is_jal, is_jr) = control(instruction, funct);
(* Bloc de contrôle de l'ALU *)
(*(op_to_alu, use_shamt) = ALU_control(funct, alu_op); *)
......
......@@ -10,7 +10,7 @@ where
(* Bloc de contrôle général *)
(reg_dst, jump, branch, mem_read, mem_to_reg, alu_op, mem_write, alu_src,
reg_write, write_pc, is_beq, is_jal) = control(instruction, funct);
reg_write, write_pc, is_beq, is_jal, is_jr) = control(instruction, funct);
(* Bloc de contrôle de l'ALU *)
(op_to_alu, use_shamt) = ALU_control(funct, alu_op);
......
......@@ -2,7 +2,11 @@ require constants
require prog_counter
main(partial_jump_addr:[word-6], imm:[word], jump, branch)
= (next_instr:[word]) where
(next_instr, pc_incr) = PC(partial_jump_addr, imm, jump, branch, false);
= (next_instr:[word])
where
(* should be an input, but this require to update in and out test files *)
is_jr = false;
(next_instr, pc_incr) = PC(partial_jump_addr, imm, jump, is_jr, branch, false);
end where
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