diff options
Diffstat (limited to 'core/ctrl.v')
| -rw-r--r-- | core/ctrl.v | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/core/ctrl.v b/core/ctrl.v new file mode 100644 index 0000000..3fbee1f --- /dev/null +++ b/core/ctrl.v @@ -0,0 +1,201 @@ + +/** + * Main control logic for our simple processor. + * + * Input: opcode: Opcode from instruction + * + * Output: validinst True if the instruction we're decoding is valid + * Output: _branch true if branch or (jal. update PC with immediate + * Output: _jump True if we want update the PC with pc+imm regardless of the ALU result + * Output: _imm True if we're working on an itype instruction + * Output: pc_from_alu Use the pc from the ALU, not pc+4 or pc+imm + * Output: mem_read true if we should read from memory + * Output: mem_write true if writing to the data memory + * Output: reg_write true if writing to the register file + * Output: to_reg 0 for result from execute, 1 for data from memory + * Output: result_select 00 for result from alu, 01 for immediate, 10 for pc+4 + * Output: alu_src source for the second ALU input (0 is readdata2 and 1 is immediate) + * Output: pc_add Use PC as the input to the ALU + * Output: alu_op 00 for ld/st, 10 for R-type, 01 for branch + **/ + +module op( + input wire [6:0] opcode, + + output reg valid_instr, + output reg _branch, + output reg _jump, + output reg _imm, + output reg pc_from_alu, + output reg mem_read, + output reg mem_write, + output reg reg_write, + output reg to_reg, + output reg [1:0] result_select, + output reg alu_src, + output reg pc_add, + output reg [1:0] alu_op + ); + + // opcodes for all types and formats + assign rtype = 7'b0110011; + assign itype = 7'b0010011; + assign btype = 7'b1100011; + + assign load = 7'b0000011; + assign store = 7'b0100011; + assign lui = 7'b0110111; + assign auipc = 7'b0010111; + assign jal = 7'b1101111; + assign jalr = 7'b1100111; + + always @* begin + case (opcode) + rtype: begin + assign valid_instr = 1; + assign reg_write = 1; + assign alu_op = 2; + + assign _branch = 0; + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign result_select = 0; + assign alu_src = 0; + assign pc_add = 0; + end + itype: begin + assign valid_instr = 1; + assign reg_write = 1; + assign alu_op = 2; + assign alu_src = 1; + assign _imm = 1; + + assign _branch = 0; + assign _jump = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign result_select = 0; + assign pc_add = 0; + end + load: begin + assign valid_instr = 1; + assign mem_read = 1; + assign reg_write = 1; + assign to_reg = 1; + assign alu_src = 1; + + assign _branch = 0; + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_write = 0; + assign to_reg = 0; + assign result_select = 0; + assign pc_add = 0; + assign alu_op = 0; + end + store: begin + assign valid_instr = 1; + assign mem_write = 1; + assign alu_src = 1; + + assign _branch = 0; + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign to_reg = 0; + assign result_select = 0; + assign pc_add = 0; + assign alu_op = 0; + end + btype: begin + assign valid_instr = 1; + assign _branch = 1; + assign alu_op = 1; + + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign reg_write = 0; + assign to_reg = 0; + assign result_select = 0; + assign alu_src = 0; + assign pc_add = 0; + end + lui: begin + assign valid_instr = 1; + assign reg_write = 1; + assign result_select = 1; + + assign _branch = 0; + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign alu_src = 0; + assign pc_add = 0; + assign alu_op = 0; + end + auipc: begin + assign valid_instr = 1; + assign reg_write = 1; + assign alu_src = 1; + assign pc_add = 1; + + assign _branch = 0; + assign _jump = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign result_select = 0; + assign alu_op = 0; + end + jal: begin + assign valid_instr = 1; + assign _jump = 1; + assign reg_write = 1; + assign result_select = 2; + + assign _branch = 0; + assign _imm = 0; + assign pc_from_alu = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign alu_src = 0; + assign pc_add = 0; + assign alu_op = 0; + end + jalr: begin + assign valid_instr = 1; + assign pc_from_alu = 1; + assign _jump = 1; + assign reg_write = 1; + assign result_select = 2; + assign alu_src = 1; + + assign _branch = 0; + assign _imm = 0; + assign mem_read = 0; + assign mem_write = 0; + assign to_reg = 0; + assign pc_add = 0; + assign alu_op = 0; + end + endcase + end // always + +endmodule // op |
