data/full_repos/permissive/163759920/simple_cpu/simple_cpu.v
1: b"%Error: data/full_repos/permissive/163759920/simple_cpu/simple_cpu.v:45: Cannot find file containing module: 'register_file'\nregister_file register_file_inst(\n^~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/163759920/simple_cpu,data/full_repos/permissive/163759920/register_file\n             data/full_repos/permissive/163759920/simple_cpu,data/full_repos/permissive/163759920/register_file.v\n             data/full_repos/permissive/163759920/simple_cpu,data/full_repos/permissive/163759920/register_file.sv\n             register_file\n             register_file.v\n             register_file.sv\n             obj_dir/register_file\n             obj_dir/register_file.v\n             obj_dir/register_file.sv\n%Error: data/full_repos/permissive/163759920/simple_cpu/simple_cpu.v:81: Cannot find file containing module: 'alu'\nalu alu_inst(\n^~~\n%Error: Exiting due to 2 error(s)\n"
module simple_cpu(
clk, reset, read_req, read_addr, read_data, read_data_valid, write_req, write_addr, write_data, memory_mask, error_instruction, debug
);

input wire clk;
input wire reset;
output reg read_req;
output reg [31:0] read_addr;
input wire [31:0] read_data;
input wire read_data_valid;
output reg write_req;
output reg [31:0] write_addr;
output reg [31:0] write_data;
output reg [3:0] memory_mask;
output reg error_instruction;
output reg [31:0] debug;

reg read_1_en;
reg read_2_en;
reg [4:0] read_reg_1;
reg [4:0] read_reg_2;
reg [4:0] write_reg;
reg [31:0] reg_write_data;
reg write_en;
wire [31:0] data_out_1;
wire [31:0] data_out_2;

reg [31:0] pc;
reg misaligned_load;

register_file register_file_inst(
.clk(clk), .reset(reset), .rd_1_en(read_1_en), .rd_2_en(read_2_en), .read_reg_1(read_reg_1), .read_reg_2(read_reg_2), .write_reg(write_reg), .write_data(reg_write_data), .write_en(write_en), .data_out_1(data_out_1), .data_out_2(data_out_2)
);

reg [7:0] state;
reg [7:0] future_state;
reg [31:0] instruction_sav;
reg [31:0] jump_add_reg;


parameter IDLE = 0, IF_MEM = IDLE+1, ID = IF_MEM+1, ID_BUF = ID+1,
          EX_LD = ID_BUF+1, MEM_LD = EX_LD+1, WB_LD = MEM_LD+1,
          EX_R = WB_LD+1, MEM_R=EX_R+1, WB_R = MEM_R+1,
          EX_S=WB_R+1, MEM_S=EX_S+1, WB_S = MEM_S+1,
          EX_IR=WB_S+1, MEM_IR=EX_IR+1, WB_IR=MEM_IR+1,
          EX_J=WB_IR+1, MEM_J=EX_J+1, WB_J=MEM_J+1,
          EX_UPC=WB_J+1, MEM_UPC=EX_UPC+1, WB_UPC=MEM_UPC+1,
          EX_LUI=WB_UPC+1, MEM_LUI=EX_LUI+1, WB_LUI=MEM_LUI+1,
          EX_JALR=WB_LUI+1, MEM_JALR=EX_JALR+1, WB_JALR=MEM_JALR+1,
          EX_BR=WB_JALR+1, MEM_BR=EX_BR+1, WB_BR=MEM_BR+1,
          EX_SYS=WB_BR+1, MEM_SYS=EX_SYS+1, WB_SYS=MEM_SYS+1;



reg [31:0] alu_in1;
reg [31:0] alu_in2;
reg [3:0] alu_control;
wire [31:0] alu_out;
wire alu_zero;
wire alu_neg;


parameter mscratch = 0, mtvec = mscratch+1, mepc = mtvec+1, mcause = mepc+1, mtval = mcause+1;
reg [31:0] CSRegs [0:mtval];


alu alu_inst(
.in1(alu_in1), .in2(alu_in2), .control(alu_control), .out(alu_out), .zero(alu_zero), .neg(alu_neg)
);

initial begin
   read_req = 1'b0;
   read_addr = 32'b0;
   write_req = 1'b0;
   write_addr = 32'b0;
   write_data = 32'b0;

   read_1_en = 1'b0;
   read_2_en = 1'b0;
   read_reg_1 = 5'b0;
   read_reg_2 = 5'b0;
   write_reg = 5'b0;
   write_data = 32'b0;
   write_en = 1'b0;

   pc = 32'b0;
   memory_mask = 4'b0;

   error_instruction = 1'b0;
   debug = 32'b1;

   state = IF_MEM;
end




always @(posedge clk)
begin : main

   reg[31:0] offset;
   reg[31:0] src;
   reg[31:0] csr_idx;

   if(reset == 1) begin
      read_req <= 1'b0;
      read_addr <= 32'b0;
      write_req <= 1'b0;
      write_addr <= 32'b0;
      write_data <= 32'b0;

      read_1_en <= 1'b0;
      read_2_en <= 1'b0;
      read_reg_1 <= 5'b0;
      read_reg_2 <= 5'b0;
      write_reg <= 5'b0;
      write_data <= 32'b0;
      write_en <= 1'b0;

      pc <= 32'b0;
      memory_mask <= 4'b0;

      error_instruction <= 1'b0;
      debug <= 32'b1;

      state <= IF_MEM;
   end else begin


      read_1_en <= 1'b0;
      read_2_en <= 1'b0;
      read_req <= 1'b0;
      write_req <= 1'b0;
      write_en <= 1'b0;
      read_addr <= pc[31:0];
      memory_mask <= 4'b1111;
      misaligned_load <= 1'b0;

      case (state)
      IF_MEM: begin

         if(pc[1:0] == 2'b00) begin
            pc <= pc+4;
            read_req <= 1'b1;
            state <= ID;
         end else begin
            pc <= CSRegs[mtvec];
            CSRegs[mepc] <= pc;
            CSRegs[mtval] <= pc;
            state <= IF_MEM;
         end
      end
      ID: begin

         if( read_data_valid == 1'b1) begin
            instruction_sav <= read_data;
            state <= ID_BUF;
            if ( read_data[6:0] == 7'b0000011) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_LD;
            end else if ( read_data[6:0] == 7'b0110011 ) begin
               read_1_en <= 1'b1;
               read_2_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               read_reg_2 <= read_data[24:20];
               future_state <= EX_R;
            end else if ( read_data[6:0] == 7'b0100011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_S;
            end else if ( read_data[6:0] == 7'b0010011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_IR;
            end else if ( read_data[6:0] == 7'b1101111 ) begin
               future_state <= EX_J;
            end else if ( read_data[6:0] == 7'b0010111 ) begin
               future_state <= EX_UPC;
            end else if ( read_data[6:0] == 7'b0110111 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[11:7];
               future_state <= EX_LUI;
            end else if ( read_data[6:0] == 7'b1100111 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_JALR;
            end else if ( read_data[6:0] == 7'b1100011 ) begin
               read_1_en <= 1'b1;
               read_2_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               read_reg_2 <= read_data[24:20];
               future_state <= EX_BR;
            end else if ( read_data[6:0] == 7'b1110011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_SYS;
            end else begin
               error_instruction <= 1'b1;
               future_state <= IF_MEM;
            end
         end else begin
            read_req <= 1'b1;
            read_addr <= pc[31:0]-4;
         end
      end
      ID_BUF: begin
         state <= future_state;
         if(future_state == EX_S) begin
            read_1_en <= 1'b1;
            read_reg_1 <= instruction_sav[24:20];
         end
      end
      EX_LD: begin

         alu_in1 <= data_out_1;
         alu_in2 <= {{20{instruction_sav[31]}}, instruction_sav[31:20]};
         alu_control <= 4'b0;
         state <= MEM_LD;
      end
      MEM_LD: begin
         read_addr <= alu_out[31:0];
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b100) begin
            memory_mask <= 4'b0001;
            read_req <= 1'b1;
         end else if (instruction_sav[14:12] == 3'b001 || instruction_sav[14:12] == 3'b101) begin
            memory_mask <= 4'b0011;
            if (alu_out[0] == 1'b0) begin
               read_req <= 1'b1;
            end else begin
               misaligned_load <= 1'b1;
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd4;
            end
         end else if (instruction_sav[14:12] == 3'b010) begin
            memory_mask <= 4'b1111;
            if (alu_out[1:0] == 2'b0) begin
               read_req <= 1'b1;
            end else begin
               misaligned_load <= 1'b1;
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd4;
            end
         end
         state <= WB_LD;
      end
      WB_LD: begin
         if( read_data_valid == 1'b1) begin
            if(instruction_sav[14:12] == 3'b000) begin
               reg_write_data <= { {24{read_data[7]}}, read_data[7:0] };
            end else if (instruction_sav[14:12] == 3'b001) begin
               reg_write_data <= { {16{read_data[15]}}, read_data[15:0] };
            end else if (instruction_sav[14:12] == 3'b010) begin
               reg_write_data <= read_data[31:0];
            end else if (instruction_sav[14:12] == 3'b100) begin
               reg_write_data <= {24'b0, read_data[7:0]};
            end else if (instruction_sav[14:12] == 3'b101) begin
               reg_write_data <= {16'b0, read_data[15:0]};
            end

            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
            state <= IF_MEM;
         end else if ( misaligned_load == 1'b1 ) begin
            state <= IF_MEM;
         end else begin
            read_req <= 1'b1;
            read_addr <= read_addr;
         end
      end
      EX_R: begin
         alu_in1 <= data_out_1;
         alu_in2 <= data_out_2;
         alu_control <= {instruction_sav[30], instruction_sav[14:12]};
         state <= MEM_R;
      end
      MEM_R: begin
         state <= WB_R;
      end
      WB_R: begin
         reg_write_data <= alu_out;
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_S: begin

         alu_in1 <= data_out_1;

         alu_in2 <= { {20{instruction_sav[31]}}, instruction_sav[31:25], instruction_sav[11:7]};
         alu_control <= 4'b0;

         state <= MEM_S;
      end
      MEM_S: begin
         if(instruction_sav[14:12] == 3'b000) begin
            memory_mask <= 4'b0001;
            write_req <= 1'b1;
         end else if (instruction_sav[14:12] == 3'b001) begin
            memory_mask <= 4'b0011;
            if (alu_out[0] == 1'b0) begin
               write_req <= 1'b1;
            end else begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd6;
            end
         end else if (instruction_sav[14:12] == 3'b010) begin
            memory_mask <= 4'b1111;
            if (alu_out[1:0] == 2'b00) begin
               write_req <= 1'b1;
            end else begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd6;
            end
         end
         write_addr <= alu_out[31:0];
         write_data <= data_out_1;

         state <= WB_S;
      end
      WB_S : begin
         state <= IF_MEM;
      end
      EX_IR: begin
         alu_control <= {1'b0, instruction_sav[14:12]};
         alu_in1 <= data_out_1;
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b100 || instruction_sav[14:12] == 3'b110|| instruction_sav[14:12] == 3'b111
         || instruction_sav[14:12] == 3'b010 || instruction_sav[14:12] == 3'b011) begin
            alu_in2 <= { {20{instruction_sav[31]}}, instruction_sav[31:20]};
         end else if(instruction_sav[14:12] == 3'b001 || instruction_sav[14:12] == 3'b101) begin
            alu_in2 <= {27'b0, instruction_sav[24:20]};
            alu_control <= {instruction_sav[30], instruction_sav[14:12]};
         end else begin
            alu_in2 <= {20'b0, instruction_sav[31:20]};
         end
         state <= MEM_IR;
      end
      MEM_IR: begin
         state <= WB_IR;
      end
      WB_IR: begin
         reg_write_data <= alu_out;

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_J: begin
         jump_add_reg <= pc + {{11{instruction_sav[31]}}, instruction_sav[31], instruction_sav[19:12], instruction_sav[20], instruction_sav[30:21], 1'b0};
         state <= MEM_J;
      end
      MEM_J: begin

         state <= WB_J;
      end
      WB_J: begin
         reg_write_data <= pc;
         pc <= jump_add_reg-4;
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_UPC: begin
         alu_in1 <= (pc-4);
         alu_in2 <= {instruction_sav[31:12], 12'b0};

         alu_control <= 4'b0;
         state <= MEM_UPC;
      end
      MEM_UPC: begin
         state <= WB_UPC;
      end
      WB_UPC: begin
         reg_write_data <= alu_out;

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_LUI: begin
         state <= MEM_LUI;
      end
      MEM_LUI: begin
         state <= WB_LUI;
      end
      WB_LUI: begin
         reg_write_data <= {instruction_sav[31:12], 12'b0};

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_JALR : begin
         alu_in1 <= data_out_1;
         alu_in2 <= {{20{instruction_sav[31]}}, instruction_sav[31:20]};
         alu_control <= 4'b0;

         state <= MEM_JALR;
      end
      MEM_JALR : begin
         state <= WB_JALR;
      end
      WB_JALR : begin
         reg_write_data <= pc;

         pc <= {alu_out[31:1], 1'b0};
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_BR : begin
         alu_in1 <= data_out_1;
         alu_in2 <= data_out_2;
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b001) begin
            alu_control <= 4'b1000;
         end else if(instruction_sav[14:12] == 3'b110 || instruction_sav[14:12] == 3'b111) begin
            alu_control <= 4'b0011;
         end else begin
            alu_control <= 4'b0010;
         end
         state <= MEM_BR;
      end
      MEM_BR: begin
         state <= WB_BR;
      end
      WB_BR: begin
         offset = { {19{instruction_sav[31]}}, instruction_sav[31], instruction_sav[7], instruction_sav[30:25], instruction_sav[11:8], 1'b0};
         if(instruction_sav[14:12] == 3'b000 && alu_zero == 1'b1) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b001 && alu_zero == 1'b0) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b101 && alu_out == 32'b0 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b111 && alu_out == 32'b0 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b100 && alu_out == 32'b1 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b110 && alu_out == 32'b1 ) begin
            pc <= pc-4+offset;
         end
         state <= IF_MEM;
      end
      EX_SYS: begin
         state <= MEM_SYS;
      end
      MEM_SYS: begin
         state <= WB_SYS;
      end
      WB_SYS: begin

         if(instruction_sav[14] == 1'b0) begin
            src = data_out_1;
         end else begin
            src = {27'b0, instruction_sav[19:15]};
         end


         if(instruction_sav[31:20] == 12'h340) begin
            csr_idx = mscratch;
         end else if (instruction_sav[31:20] == 12'h305) begin
            csr_idx = mtvec;
         end else if (instruction_sav[31:20] == 12'h341) begin
            csr_idx = mepc;
         end else if (instruction_sav[31:20] == 12'h342) begin
            csr_idx = mcause;
         end else if (instruction_sav[31:20] == 12'h343) begin
            csr_idx = mtval;
         end

         if(instruction_sav[14:12] == 3'b000) begin
            if(instruction_sav[31:20] == 12'b000000000000) begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mcause] <= 32'd11;
            end else if(instruction_sav[31:20] == 12'b000000000001) begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mcause] <= 32'd3;
            end else if(instruction_sav[31:20] == 12'b001100000010) begin
               pc <= CSRegs[mepc];
            end
         end else if(instruction_sav[13:12] == 2'b01) begin
            CSRegs[csr_idx] <= src;
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end else if(instruction_sav[13:12] == 2'b10) begin
            CSRegs[csr_idx] <= (CSRegs[csr_idx] | src);
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end else if(instruction_sav[13:12] == 2'b11) begin
            CSRegs[csr_idx] <= (CSRegs[csr_idx] & ~src);
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end

         state <= IF_MEM;
      end
      default: begin
      end
      endcase
   end
end

endmodule
module simple_cpu(
clk, reset, read_req, read_addr, read_data, read_data_valid, write_req, write_addr, write_data, memory_mask, error_instruction, debug
);


input wire clk;
input wire reset;
output reg read_req;
output reg [31:0] read_addr;
input wire [31:0] read_data;
input wire read_data_valid;
output reg write_req;
output reg [31:0] write_addr;
output reg [31:0] write_data;
output reg [3:0] memory_mask;
output reg error_instruction;
output reg [31:0] debug;

reg read_1_en;
reg read_2_en;
reg [4:0] read_reg_1;
reg [4:0] read_reg_2;
reg [4:0] write_reg;
reg [31:0] reg_write_data;
reg write_en;
wire [31:0] data_out_1;
wire [31:0] data_out_2;

reg [31:0] pc;
reg misaligned_load;

register_file register_file_inst(
.clk(clk), .reset(reset), .rd_1_en(read_1_en), .rd_2_en(read_2_en), .read_reg_1(read_reg_1), .read_reg_2(read_reg_2), .write_reg(write_reg), .write_data(reg_write_data), .write_en(write_en), .data_out_1(data_out_1), .data_out_2(data_out_2)
);

reg [7:0] state;
reg [7:0] future_state;
reg [31:0] instruction_sav;
reg [31:0] jump_add_reg;


parameter IDLE = 0, IF_MEM = IDLE+1, ID = IF_MEM+1, ID_BUF = ID+1,
          EX_LD = ID_BUF+1, MEM_LD = EX_LD+1, WB_LD = MEM_LD+1,
          EX_R = WB_LD+1, MEM_R=EX_R+1, WB_R = MEM_R+1,
          EX_S=WB_R+1, MEM_S=EX_S+1, WB_S = MEM_S+1,
          EX_IR=WB_S+1, MEM_IR=EX_IR+1, WB_IR=MEM_IR+1,
          EX_J=WB_IR+1, MEM_J=EX_J+1, WB_J=MEM_J+1,
          EX_UPC=WB_J+1, MEM_UPC=EX_UPC+1, WB_UPC=MEM_UPC+1,
          EX_LUI=WB_UPC+1, MEM_LUI=EX_LUI+1, WB_LUI=MEM_LUI+1,
          EX_JALR=WB_LUI+1, MEM_JALR=EX_JALR+1, WB_JALR=MEM_JALR+1,
          EX_BR=WB_JALR+1, MEM_BR=EX_BR+1, WB_BR=MEM_BR+1,
          EX_SYS=WB_BR+1, MEM_SYS=EX_SYS+1, WB_SYS=MEM_SYS+1;



reg [31:0] alu_in1;
reg [31:0] alu_in2;
reg [3:0] alu_control;
wire [31:0] alu_out;
wire alu_zero;
wire alu_neg;


parameter mscratch = 0, mtvec = mscratch+1, mepc = mtvec+1, mcause = mepc+1, mtval = mcause+1;
reg [31:0] CSRegs [0:mtval];


alu alu_inst(
.in1(alu_in1), .in2(alu_in2), .control(alu_control), .out(alu_out), .zero(alu_zero), .neg(alu_neg)
);

initial begin
   read_req = 1'b0;
   read_addr = 32'b0;
   write_req = 1'b0;
   write_addr = 32'b0;
   write_data = 32'b0;

   read_1_en = 1'b0;
   read_2_en = 1'b0;
   read_reg_1 = 5'b0;
   read_reg_2 = 5'b0;
   write_reg = 5'b0;
   write_data = 32'b0;
   write_en = 1'b0;

   pc = 32'b0;
   memory_mask = 4'b0;

   error_instruction = 1'b0;
   debug = 32'b1;

   state = IF_MEM;
end




always @(posedge clk)
begin : main

   reg[31:0] offset;
   reg[31:0] src;
   reg[31:0] csr_idx;

   if(reset == 1) begin
      read_req <= 1'b0;
      read_addr <= 32'b0;
      write_req <= 1'b0;
      write_addr <= 32'b0;
      write_data <= 32'b0;

      read_1_en <= 1'b0;
      read_2_en <= 1'b0;
      read_reg_1 <= 5'b0;
      read_reg_2 <= 5'b0;
      write_reg <= 5'b0;
      write_data <= 32'b0;
      write_en <= 1'b0;

      pc <= 32'b0;
      memory_mask <= 4'b0;

      error_instruction <= 1'b0;
      debug <= 32'b1;

      state <= IF_MEM;
   end else begin


      read_1_en <= 1'b0;
      read_2_en <= 1'b0;
      read_req <= 1'b0;
      write_req <= 1'b0;
      write_en <= 1'b0;
      read_addr <= pc[31:0];
      memory_mask <= 4'b1111;
      misaligned_load <= 1'b0;

      case (state)
      IF_MEM: begin

         if(pc[1:0] == 2'b00) begin
            pc <= pc+4;
            read_req <= 1'b1;
            state <= ID;
         end else begin
            pc <= CSRegs[mtvec];
            CSRegs[mepc] <= pc;
            CSRegs[mtval] <= pc;
            state <= IF_MEM;
         end
      end
      ID: begin

         if( read_data_valid == 1'b1) begin
            instruction_sav <= read_data;
            state <= ID_BUF;
            if ( read_data[6:0] == 7'b0000011) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_LD;
            end else if ( read_data[6:0] == 7'b0110011 ) begin
               read_1_en <= 1'b1;
               read_2_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               read_reg_2 <= read_data[24:20];
               future_state <= EX_R;
            end else if ( read_data[6:0] == 7'b0100011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_S;
            end else if ( read_data[6:0] == 7'b0010011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_IR;
            end else if ( read_data[6:0] == 7'b1101111 ) begin
               future_state <= EX_J;
            end else if ( read_data[6:0] == 7'b0010111 ) begin
               future_state <= EX_UPC;
            end else if ( read_data[6:0] == 7'b0110111 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[11:7];
               future_state <= EX_LUI;
            end else if ( read_data[6:0] == 7'b1100111 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_JALR;
            end else if ( read_data[6:0] == 7'b1100011 ) begin
               read_1_en <= 1'b1;
               read_2_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               read_reg_2 <= read_data[24:20];
               future_state <= EX_BR;
            end else if ( read_data[6:0] == 7'b1110011 ) begin
               read_1_en <= 1'b1;
               read_reg_1 <= read_data[19:15];
               future_state <= EX_SYS;
            end else begin
               error_instruction <= 1'b1;
               future_state <= IF_MEM;
            end
         end else begin
            read_req <= 1'b1;
            read_addr <= pc[31:0]-4;
         end
      end
      ID_BUF: begin
         state <= future_state;
         if(future_state == EX_S) begin
            read_1_en <= 1'b1;
            read_reg_1 <= instruction_sav[24:20];
         end
      end
      EX_LD: begin

         alu_in1 <= data_out_1;
         alu_in2 <= {{20{instruction_sav[31]}}, instruction_sav[31:20]};
         alu_control <= 4'b0;
         state <= MEM_LD;
      end
      MEM_LD: begin
         read_addr <= alu_out[31:0];
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b100) begin
            memory_mask <= 4'b0001;
            read_req <= 1'b1;
         end else if (instruction_sav[14:12] == 3'b001 || instruction_sav[14:12] == 3'b101) begin
            memory_mask <= 4'b0011;
            if (alu_out[0] == 1'b0) begin
               read_req <= 1'b1;
            end else begin
               misaligned_load <= 1'b1;
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd4;
            end
         end else if (instruction_sav[14:12] == 3'b010) begin
            memory_mask <= 4'b1111;
            if (alu_out[1:0] == 2'b0) begin
               read_req <= 1'b1;
            end else begin
               misaligned_load <= 1'b1;
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd4;
            end
         end
         state <= WB_LD;
      end
      WB_LD: begin
         if( read_data_valid == 1'b1) begin
            if(instruction_sav[14:12] == 3'b000) begin
               reg_write_data <= { {24{read_data[7]}}, read_data[7:0] };
            end else if (instruction_sav[14:12] == 3'b001) begin
               reg_write_data <= { {16{read_data[15]}}, read_data[15:0] };
            end else if (instruction_sav[14:12] == 3'b010) begin
               reg_write_data <= read_data[31:0];
            end else if (instruction_sav[14:12] == 3'b100) begin
               reg_write_data <= {24'b0, read_data[7:0]};
            end else if (instruction_sav[14:12] == 3'b101) begin
               reg_write_data <= {16'b0, read_data[15:0]};
            end

            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
            state <= IF_MEM;
         end else if ( misaligned_load == 1'b1 ) begin
            state <= IF_MEM;
         end else begin
            read_req <= 1'b1;
            read_addr <= read_addr;
         end
      end
      EX_R: begin
         alu_in1 <= data_out_1;
         alu_in2 <= data_out_2;
         alu_control <= {instruction_sav[30], instruction_sav[14:12]};
         state <= MEM_R;
      end
      MEM_R: begin
         state <= WB_R;
      end
      WB_R: begin
         reg_write_data <= alu_out;
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_S: begin

         alu_in1 <= data_out_1;

         alu_in2 <= { {20{instruction_sav[31]}}, instruction_sav[31:25], instruction_sav[11:7]};
         alu_control <= 4'b0;

         state <= MEM_S;
      end
      MEM_S: begin
         if(instruction_sav[14:12] == 3'b000) begin
            memory_mask <= 4'b0001;
            write_req <= 1'b1;
         end else if (instruction_sav[14:12] == 3'b001) begin
            memory_mask <= 4'b0011;
            if (alu_out[0] == 1'b0) begin
               write_req <= 1'b1;
            end else begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd6;
            end
         end else if (instruction_sav[14:12] == 3'b010) begin
            memory_mask <= 4'b1111;
            if (alu_out[1:0] == 2'b00) begin
               write_req <= 1'b1;
            end else begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mtval] <= alu_out;
               CSRegs[mcause] <= 32'd6;
            end
         end
         write_addr <= alu_out[31:0];
         write_data <= data_out_1;

         state <= WB_S;
      end
      WB_S : begin
         state <= IF_MEM;
      end
      EX_IR: begin
         alu_control <= {1'b0, instruction_sav[14:12]};
         alu_in1 <= data_out_1;
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b100 || instruction_sav[14:12] == 3'b110|| instruction_sav[14:12] == 3'b111
         || instruction_sav[14:12] == 3'b010 || instruction_sav[14:12] == 3'b011) begin
            alu_in2 <= { {20{instruction_sav[31]}}, instruction_sav[31:20]};
         end else if(instruction_sav[14:12] == 3'b001 || instruction_sav[14:12] == 3'b101) begin
            alu_in2 <= {27'b0, instruction_sav[24:20]};
            alu_control <= {instruction_sav[30], instruction_sav[14:12]};
         end else begin
            alu_in2 <= {20'b0, instruction_sav[31:20]};
         end
         state <= MEM_IR;
      end
      MEM_IR: begin
         state <= WB_IR;
      end
      WB_IR: begin
         reg_write_data <= alu_out;

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_J: begin
         jump_add_reg <= pc + {{11{instruction_sav[31]}}, instruction_sav[31], instruction_sav[19:12], instruction_sav[20], instruction_sav[30:21], 1'b0};
         state <= MEM_J;
      end
      MEM_J: begin

         state <= WB_J;
      end
      WB_J: begin
         reg_write_data <= pc;
         pc <= jump_add_reg-4;
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_UPC: begin
         alu_in1 <= (pc-4);
         alu_in2 <= {instruction_sav[31:12], 12'b0};

         alu_control <= 4'b0;
         state <= MEM_UPC;
      end
      MEM_UPC: begin
         state <= WB_UPC;
      end
      WB_UPC: begin
         reg_write_data <= alu_out;

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_LUI: begin
         state <= MEM_LUI;
      end
      MEM_LUI: begin
         state <= WB_LUI;
      end
      WB_LUI: begin
         reg_write_data <= {instruction_sav[31:12], 12'b0};

         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_JALR : begin
         alu_in1 <= data_out_1;
         alu_in2 <= {{20{instruction_sav[31]}}, instruction_sav[31:20]};
         alu_control <= 4'b0;

         state <= MEM_JALR;
      end
      MEM_JALR : begin
         state <= WB_JALR;
      end
      WB_JALR : begin
         reg_write_data <= pc;

         pc <= {alu_out[31:1], 1'b0};
         write_reg <= instruction_sav[11:7];
         write_en <= 1'b1;
         state <= IF_MEM;
      end
      EX_BR : begin
         alu_in1 <= data_out_1;
         alu_in2 <= data_out_2;
         if(instruction_sav[14:12] == 3'b000 || instruction_sav[14:12] == 3'b001) begin
            alu_control <= 4'b1000;
         end else if(instruction_sav[14:12] == 3'b110 || instruction_sav[14:12] == 3'b111) begin
            alu_control <= 4'b0011;
         end else begin
            alu_control <= 4'b0010;
         end
         state <= MEM_BR;
      end
      MEM_BR: begin
         state <= WB_BR;
      end
      WB_BR: begin
         offset = { {19{instruction_sav[31]}}, instruction_sav[31], instruction_sav[7], instruction_sav[30:25], instruction_sav[11:8], 1'b0};
         if(instruction_sav[14:12] == 3'b000 && alu_zero == 1'b1) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b001 && alu_zero == 1'b0) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b101 && alu_out == 32'b0 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b111 && alu_out == 32'b0 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b100 && alu_out == 32'b1 ) begin
            pc <= pc-4+offset;
         end else if (instruction_sav[14:12] == 3'b110 && alu_out == 32'b1 ) begin
            pc <= pc-4+offset;
         end
         state <= IF_MEM;
      end
      EX_SYS: begin
         state <= MEM_SYS;
      end
      MEM_SYS: begin
         state <= WB_SYS;
      end
      WB_SYS: begin

         if(instruction_sav[14] == 1'b0) begin
            src = data_out_1;
         end else begin
            src = {27'b0, instruction_sav[19:15]};
         end


         if(instruction_sav[31:20] == 12'h340) begin
            csr_idx = mscratch;
         end else if (instruction_sav[31:20] == 12'h305) begin
            csr_idx = mtvec;
         end else if (instruction_sav[31:20] == 12'h341) begin
            csr_idx = mepc;
         end else if (instruction_sav[31:20] == 12'h342) begin
            csr_idx = mcause;
         end else if (instruction_sav[31:20] == 12'h343) begin
            csr_idx = mtval;
         end

         if(instruction_sav[14:12] == 3'b000) begin
            if(instruction_sav[31:20] == 12'b000000000000) begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mcause] <= 32'd11;
            end else if(instruction_sav[31:20] == 12'b000000000001) begin
               pc <= CSRegs[mtvec];
               CSRegs[mepc] <= pc-4;
               CSRegs[mcause] <= 32'd3;
            end else if(instruction_sav[31:20] == 12'b001100000010) begin
               pc <= CSRegs[mepc];
            end
         end else if(instruction_sav[13:12] == 2'b01) begin
            CSRegs[csr_idx] <= src;
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end else if(instruction_sav[13:12] == 2'b10) begin
            CSRegs[csr_idx] <= (CSRegs[csr_idx] | src);
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end else if(instruction_sav[13:12] == 2'b11) begin
            CSRegs[csr_idx] <= (CSRegs[csr_idx] & ~src);
            reg_write_data <= CSRegs[csr_idx];
            write_reg <= instruction_sav[11:7];
            write_en <= 1'b1;
         end

         state <= IF_MEM;
      end
      default: begin
      end
      endcase
   end
end

endmodule