diff options
author | Sergey Bikovsky <bsv.serg@gmail.com> | 2015-09-17 02:13:38 +0300 |
---|---|---|
committer | Sergey Bikovsky <bsv.serg@gmail.com> | 2015-09-17 02:13:38 +0300 |
commit | b3d9beada656bce070e8aeb2d74a859a29a54b56 (patch) | |
tree | a08f6563de32c4751461549d34e80a0f764b8f67 /hdl/control.v | |
download | MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.zip MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.tar.gz MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.tar.bz2 |
init repo
Diffstat (limited to 'hdl/control.v')
-rw-r--r-- | hdl/control.v | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/hdl/control.v b/hdl/control.v new file mode 100644 index 0000000..58f273f --- /dev/null +++ b/hdl/control.v @@ -0,0 +1,114 @@ +`timescale 1ns / 1ps + +module control( + input [5:0] opcode, + input branch_eq, // result of comparison for conditional branch + + output reg [1:0] if_pc_source, + output id_rt_is_source, // rt is source + + output ex_imm_command, + output reg ex_alu_src_b, + output reg ex_dst_reg_sel, + output reg [1:0] ex_alu_op, + output reg mem_read, + output reg mem_write, + output reg wb_mem_to_reg, + output reg wb_reg_write + ); + + + localparam + LW = 6'b100011, + SW = 6'b101011, + BEQ=6'b000100, + RTYPE = 6'b0, + J=6'd2, + JAL=6'd3, + ADDI = 6'b001000, + ANDI = 6'b001100, + ORI = 6'b001101, + XORI = 6'b001110, + SLTI = 6'b001010; // opcodes + + reg memory_op; + reg r_type_op; + reg immediate_op; + reg branch_op; + reg jump_op; + + + assign ex_imm_command = immediate_op; + assign id_rt_is_source = (r_type_op | branch_op | opcode == SW); + + + always @* + begin + // default values + if_pc_source = 0; + ex_alu_src_b = 0; + ex_dst_reg_sel = 0; + ex_alu_op = 0; + mem_read = 0; + mem_write = 0; + wb_mem_to_reg = 0; + wb_reg_write = 0; + + memory_op = ( (opcode == LW) | (opcode == SW) ); + r_type_op = ( opcode == RTYPE ); + branch_op = ( opcode == BEQ ); + immediate_op = ( (opcode == ADDI) | (opcode == ANDI) | (opcode == ORI) | (opcode == XORI) | (opcode == SLTI) ); + jump_op = ( opcode == J); + + if (memory_op) begin + ex_alu_src_b = 1'b1; // select sign_extend_offset input + ex_dst_reg_sel = 1'b0; // rt + ex_alu_op = 2'b00; // add op + wb_mem_to_reg = 1'b1; // select mem_out + + if ( opcode == LW ) begin + mem_read = 1'b1; + wb_reg_write = 1'b1; + end + else + mem_write = 1'b1; // opcode == SW + + end + + else if (r_type_op) begin + ex_alu_src_b = 1'b0; // select B input + ex_dst_reg_sel = 1'b1; // rd + ex_alu_op = 2'b10; // operaction defined by func code + + wb_mem_to_reg = 1'b0; // alu_out + wb_reg_write = 1'b1; // write result to regfile + end + + else if (immediate_op) begin + ex_alu_src_b = 1'b1; // select sign_extend_offset input + ex_dst_reg_sel = 1'b0; // rt + ex_alu_op = 2'b10; // operation defined by function code + + wb_mem_to_reg = 1'b0; // alu_out + wb_reg_write = 1'b01; + end + + else if (branch_op) begin + if (branch_eq) if_pc_source = 2'b01; // PC <= branch_addr + else if_pc_source = 2'b00; + + end + + else if (jump_op) begin + if_pc_source = 2'b10; // PC <= jump_addr + end + + else begin + // NOP + end + + + end + + +endmodule |