Commit cecb91db authored by Daru13's avatar Daru13
Browse files

Added jr instruction handling (still to test)

parent 97bdc22b
......@@ -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
......
......@@ -18,13 +18,16 @@ main (b) = (instruction:[word], syscall, ctrl:[2], alu_result:[32],
(* Reading the next instruction from the ROM *)
(instruction, syscall, ctrl, pc_incr, pc_value) = next_instruction(instruction[6..],
imm, jump, branch and (not(is_beq) xor alu_zero));
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);
......@@ -45,18 +48,20 @@ main (b) = (instruction:[word], syscall, ctrl:[2], alu_result:[32],
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)
= (value:[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);
value = r;
end where
......@@ -49,11 +52,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], syscall, ctrl:[2], pc_incr:[word], pc_value:[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 *)
......
......@@ -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