module RISCcore2 ( input rst, input clk, output reg [31:0] pc, output reg [31:0] next_pc, output wire [31:0] instr ); // IMem reg [31:0] imem [0:255]; initial begin $readmemh("program.hex", imem); end assign instr = imem[pc[31:2]]; // Decoder wire isUType = ((instr[6:0] == 7'b0110111) || (instr[6:0] == 7'b0010111)); wire isIType = ((instr[6:0] == 7'b0000011) || (instr[6:0] == 7'b0000111) || (instr[6:0] == 7'b0010011) || (instr[6:0] == 7'b0011011) || (instr [6:0] == 7'b1100111)); wire isRType = ((instr[6:0] == 7'b0101111) || (instr[6:0] == 7'b0110011) || (instr[6:0] == 7'b0111011)); wire isSType = ((instr[6:0] == 7'b0100011) || (instr[6:0] == 7'b0100111)); wire isBType = (instr[6:0] == 7'b1100011); wire isJType = (instr[6:0] == 7'b1101111); wire [4:0] rs1 = instr[19:15]; wire [4:0] rs2 = instr[24:20]; wire [4:0] rd = instr[11:7]; wire rs2Valid = (isRType || isSType || isBType); wire rs1Valid = (~isUType && ~isJType); wire rdValid = (~isSType && ~isBType); wire [3:0] funct3 = instr[14:12]; wire [6:0] funct7 = instr[31:25]; // FIXED: Removed extra spaces in immediate concatenations wire [31:0] Iimm = {{21{instr[31]}}, instr[30:25], instr[24:20]}; wire [31:0] Simm = {{21{instr[31]}}, instr[30:25], instr[11:7]}; wire [31:0] Bimm = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; wire [31:0] Uimm = {instr[31], instr[30:20], instr[19:12], {12{1'b0}}}; wire [31:0] Jimm = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:25], instr[24:21], 1'b0}; // Instructions wire isBEQ = (funct3 == 3'b000 && isBType); wire isBNE = (funct3 == 3'b001 && isBType); wire isBLT = (funct3 == 3'b100 && isBType); wire isBGE = (funct3 == 3'b101 && isBType); wire isBLTU = (funct3 == 3'b110 && isBType); wire isBGEU = (funct3 == 3'b111 && isBType); wire isADDI = (funct3 == 3'b000 && isIType); wire isADD = (funct7[5] == 1'b0 && isRType && (funct3 == 3'b000)); // Register file signals wire rf_wr_en; wire [4:0] rf_wr_index; wire [31:0] rf_wr_data; wire rf_rd_en1, rf_rd_en2; wire [4:0] rf_rd_index1, rf_rd_index2; wire [31:0] rf_rd_data1, rf_rd_data2; wire [31:0] src1_value, src2_value; // Connect register file read ports assign rf_rd_en1 = rs1Valid; assign rf_rd_en2 = rs2Valid; assign rf_rd_index1 = rs1; assign rf_rd_index2 = rs2; // Connect outputs assign src1_value = rf_rd_data1; assign src2_value = rf_rd_data2; // ALU FOR ADD, ADDI wire [31:0] alu_result; wire [31:0] alu_op2 = isADDI ? Iimm : src2_value; assign alu_result = (isADDI || isADD) ? (src1_value + alu_op2) : 32'b0; // x0 support adding assign rf_wr_data = rf_wr_en ? alu_result : 32'b0; assign rf_wr_en = rdValid && (isADD || isADDI) && (rd != 5'b0); assign rf_wr_index = rd; // Branch logic wire taken_br; wire [31:0] br_tgt_pc; // Manual signed comparison for BLT and BGE wire signed_lt = (src1_value[31] && !src2_value[31]) ? 1'b1 : // src1 negative, src2 positive (!src1_value[31] && src2_value[31]) ? 1'b0 : // src1 positive, src2 negative (src1_value < src2_value); // same sign, compare normally wire signed_ge = (src1_value[31] && !src2_value[31]) ? 1'b0 : // src1 negative, src2 positive (!src1_value[31] && src2_value[31]) ? 1'b1 : // src1 positive, src2 negative (src1_value >= src2_value); // same sign, compare normally // Branch condition calculation assign taken_br = isBEQ ? (src1_value == src2_value) : isBNE ? (src1_value != src2_value) : isBLT ? signed_lt : isBGE ? signed_ge : isBLTU ? (src1_value < src2_value) : isBGEU ? (src1_value >= src2_value) : 1'b0; // Branch target calculation assign br_tgt_pc = pc + Bimm; // PC logic always @(posedge clk) begin if(rst) begin pc <= 32'h0; next_pc <= 32'h4; end else begin next_pc <= taken_br ? br_tgt_pc : (pc + 32'h4); pc <= next_pc; end end endmodule