module Decoder( clk, instruction, branch_op, imm, write_addr, rs1_addr, rs2_addr, // write_transfer, we, mem_we, operand_B_sel, writeBack_sel, ALU_control ); input clk; input [31:0] instruction; output reg branch_op; output reg [31:0] imm; output [4:0] write_addr; // N.B. write_addr to register output [4:0] rs1_addr; // rs1_addr output reg operand_B_sel; output [4:0] rs2_addr; // rs2_addr output reg we; output reg mem_we; // output [4:0] write_transfer; // address of data to memory output reg writeBack_sel; output reg [5:0] ALU_control; localparam [6:0] R_type = 7'b0110011, I_type = 7'b0010011, S_type = 7'b0100011, SB_type = 7'b1100011, L_type = 7'b0000011; wire [31:0] i_imm; wire [31:0] s_imm; wire [31:0] sb_imm; wire [6:0] opcode; wire [2:0] funct3; wire [6:0] funct7; //instruction decoding and write registers assign opcode = instruction[6:0]; assign write_addr = instruction[11:7]; assign funct3 = instruction[14:12]; assign rs1_addr = instruction[19:15]; assign rs2_addr = instruction[24:20]; assign funct7 = instruction[31:25]; //immediates assign i_imm = { {20 {funct7[6]} },{funct7,rs2_addr} }; assign s_imm = { {20 {funct7[6]} },{funct7,write_addr} }; assign sb_imm = { {19 {instruction[31]} },{instruction[31], instruction[7], instruction[30:25], instruction[11:8], 1'b0} }; // assign immediate always @(*)begin case(opcode) 7'b0010011: imm <= i_imm; 7'b0100011: imm <= s_imm; 7'b1100011: imm <= sb_imm; default: imm <= 0; endcase end always@(*) begin case(opcode) // R-Type 7'b0110011: begin branch_op = 0; operand_B_sel = 0; mem_we = 0; we = 1; writeBack_sel = 0; $display("It might be here!"); case({funct7,funct3}) 10'b0000000000: ALU_control <= 6'b000000; //add 10'b0100000000: ALU_control <= 6'b000111; //sub 10'b0000000100: ALU_control <= 6'b000100; //xor 10'b0000000010: ALU_control <= 6'b000010; //slt default: ALU_control <= 0; endcase end // I-Type 7'b0010011: begin branch_op = 0; operand_B_sel = 1; mem_we = 0; we = 1; writeBack_sel = 0; $display("OR here!"); casez({funct7,funct3}) 10'b???????000: ALU_control <= 6'b000000; //addi 10'b???????100: ALU_control <= 6'b000100; //xori default: ALU_control <= 0; //loadi endcase end //having issues with branching.... think think think // and also pc counter... i guess it's better for both to have their own functions // as the architechture shows... and think on how to integrate it with the code on-hand // S-Type 7'b0100011: begin branch_op = 0; operand_B_sel = 1; mem_we = 1; we = 0; writeBack_sel = 0; ALU_control = 6'b000000; end // L-Type 7'b0000011: begin branch_op = 0; operand_B_sel = 1; mem_we = 0; we = 1; writeBack_sel = 1; ALU_control = 6'b000000; end //SB-Type 7'b1100011: begin $display("Branched here."); branch_op = 1; operand_B_sel = 0; mem_we = 0; we = 0; writeBack_sel = 0; // if branch and stuff to be done in the branch_ing module case(funct3) 3'b101: ALU_control <= 6'b010000; //bge 3'b100: ALU_control <= 6'b000011; //blt default: ALU_control <= 0; endcase end endcase end endmodule