aboutsummaryrefslogtreecommitdiff
path: root/core/ctrl.v
diff options
context:
space:
mode:
Diffstat (limited to 'core/ctrl.v')
-rw-r--r--core/ctrl.v201
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