data/full_repos/permissive/214620165/rtl/core/riscv_load_store_unit.sv
 line:85: before: "logic"
data/verilator_xmls/f4736898-3ec8-40a0-b4ba-2bb436fd51dd.xml
module riscv_load_store_unit
(
    input  logic         clk,
    input  logic         rst_n,


    output logic         data_req_o,
    input  logic         data_gnt_i,
    input  logic         data_rvalid_i,
    input  logic         data_err_i,

    output logic [31:0]  data_addr_o,
    output logic         data_we_o,
    output logic [3:0]   data_be_o,
    output logic [31:0]  data_wdata_o,
    input  logic [31:0]  data_rdata_i,


    input  logic         data_we_mem_i,
    input  logic [1:0]   data_type_mem_i,
    input  logic [31:0]  data_wdata_mem_i,
    input  logic [1:0]   data_reg_offset_mem_i,
    input  logic         data_sign_ext_mem_i,

    output logic [31:0]  data_rdata_wb_o,
    input  logic         data_req_mem_i,
    input  logic [31:0]  data_addr_mem_i,


    input  logic         data_misaligned_ex_i,
    output logic         data_misaligned_o,


    output logic         load_err_o,
    output logic         store_err_o,


    output logic         lsu_ready_mem_o,
    output logic         lsu_ready_wb_o,

    input  logic         ex_valid_i,
    output logic         busy_o
);

  logic [31:0]  data_addr_int;


  logic [1:0]   data_type_q;
  logic [1:0]   rdata_offset_q;
  logic         data_sign_ext_q;
  logic         data_we_q;

  logic [1:0]   wdata_offset;

  logic [3:0]   data_be;
  logic [31:0]  data_wdata;

  logic         misaligned_st;


  enum logic [1:0]  { IDLE, WAIT_RVALID, WAIT_RVALID_EX_STALL, IDLE_EX_STALL } CS, NS;

  logic [31:0]  rdata_q;


  always_comb
  begin
    case (data_type_mem_i)
      2'b00:
      begin
        if (misaligned_st == 1'b0)
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b1111;
            2'b01: data_be = 4'b1110;
            2'b10: data_be = 4'b1100;
            2'b11: data_be = 4'b1000;
          endcase;
        end
        else
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b0000;
            2'b01: data_be = 4'b0001;
            2'b10: data_be = 4'b0011;
            2'b11: data_be = 4'b0111;
          endcase;
        end
      end

      2'b01:
      begin
        if (misaligned_st == 1'b0)
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b0011;
            2'b01: data_be = 4'b0110;
            2'b10: data_be = 4'b1100;
            2'b11: data_be = 4'b1000;
          endcase;
        end
        else
        begin
          data_be = 4'b0001;
        end
      end

      2'b10,
      2'b11: begin
        case (data_addr_int[1:0])
          2'b00: data_be = 4'b0001;
          2'b01: data_be = 4'b0010;
          2'b10: data_be = 4'b0100;
          2'b11: data_be = 4'b1000;
        endcase;
      end
    endcase;
  end




  assign wdata_offset = data_addr_int[1:0] - data_reg_offset_mem_i[1:0];
  always_comb
  begin
    case (wdata_offset)
      2'b00: data_wdata = data_wdata_mem_i[31:0];
      2'b01: data_wdata = {data_wdata_mem_i[23:0], data_wdata_mem_i[31:24]};
      2'b10: data_wdata = {data_wdata_mem_i[15:0], data_wdata_mem_i[31:16]};
      2'b11: data_wdata = {data_wdata_mem_i[ 7:0], data_wdata_mem_i[31: 8]};
    endcase;
  end



  always_ff @(posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
    begin
      data_type_q     <= '0;
      rdata_offset_q  <= '0;
      data_sign_ext_q <= '0;
      data_we_q       <= 1'b0;
    end
    else if (data_gnt_i == 1'b1)
    begin
      data_type_q     <= data_type_mem_i;
      rdata_offset_q  <= data_addr_int[1:0];
      data_sign_ext_q <= data_sign_ext_mem_i;
      data_we_q       <= data_we_mem_i;
    end
  end











  logic [31:0] data_rdata_ext;

  logic [31:0] rdata_w_ext;
  logic [31:0] rdata_h_ext;
  logic [31:0] rdata_b_ext;


  always_comb
  begin
    case (rdata_offset_q)
      2'b00: rdata_w_ext = data_rdata_i[31:0];
      2'b01: rdata_w_ext = {data_rdata_i[ 7:0], rdata_q[31:8]};
      2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]};
      2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]};
    endcase
  end


  always_comb
  begin
    case (rdata_offset_q)
      2'b00:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
        else
          rdata_h_ext = {{16{data_rdata_i[15]}}, data_rdata_i[15:0]};
      end

      2'b01:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[23:8]};
        else
          rdata_h_ext = {{16{data_rdata_i[23]}}, data_rdata_i[23:8]};
      end

      2'b10:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[31:16]};
        else
          rdata_h_ext = {{16{data_rdata_i[31]}}, data_rdata_i[31:16]};
      end

      2'b11:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[7:0], rdata_q[31:24]};
        else
          rdata_h_ext = {{16{data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]};
      end
    endcase
  end


  always_comb
  begin
    case (rdata_offset_q)
      2'b00:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[7:0]};
        else
          rdata_b_ext = {{24{data_rdata_i[7]}}, data_rdata_i[7:0]};
      end

      2'b01: begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[15:8]};
        else
          rdata_b_ext = {{24{data_rdata_i[15]}}, data_rdata_i[15:8]};
      end

      2'b10:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[23:16]};
        else
          rdata_b_ext = {{24{data_rdata_i[23]}}, data_rdata_i[23:16]};
      end

      2'b11:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[31:24]};
        else
          rdata_b_ext = {{24{data_rdata_i[31]}}, data_rdata_i[31:24]};
      end
    endcase
  end


  always_comb
  begin
    case (data_type_q)
      2'b00:       data_rdata_ext = rdata_w_ext;
      2'b01:       data_rdata_ext = rdata_h_ext;
      2'b10,2'b11: data_rdata_ext = rdata_b_ext;
    endcase
  end



  always_ff @(posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
    begin
      CS            <= IDLE;
      rdata_q       <= '0;
    end
    else
    begin
      CS            <= NS;

      if (data_rvalid_i && (~data_we_q))
      begin





        if ((data_misaligned_ex_i == 1'b1) || (data_misaligned_o == 1'b1))
          rdata_q  <= data_rdata_i;
        else
          rdata_q  <= data_rdata_ext;
      end
    end
  end


  assign data_rdata_wb_o = (data_rvalid_i == 1'b1) ? data_rdata_ext : rdata_q;


  assign data_addr_o   = data_addr_int;
  assign data_wdata_o  = data_wdata;
  assign data_we_o     = data_we_mem_i;
  assign data_be_o     = data_be;

  assign misaligned_st = data_misaligned_ex_i;

  assign load_err_o    = data_gnt_i && data_err_i && ~data_we_o;
  assign store_err_o   = data_gnt_i && data_err_i && data_we_o;


  always_comb
  begin
    NS             = CS;

    data_req_o     = 1'b0;

    lsu_ready_mem_o = 1'b1;
    lsu_ready_wb_o = 1'b1;

    case(CS)

      IDLE:
      begin
        data_req_o = data_req_mem_i;
        if(data_req_mem_i) begin
          lsu_ready_mem_o = 1'b0;



          if(data_gnt_i) begin
            lsu_ready_mem_o = 1'b1;


            if (ex_valid_i)
              NS = WAIT_RVALID;
            else
              NS = WAIT_RVALID_EX_STALL;
          end
        end
      end


      WAIT_RVALID:
      begin
        lsu_ready_wb_o = 1'b0; 

        if (data_rvalid_i) begin


          lsu_ready_wb_o = 1'b1;

          data_req_o = data_req_mem_i;

          if (data_req_mem_i) begin
            lsu_ready_mem_o = 1'b0;

            if (data_gnt_i) begin
              lsu_ready_mem_o = 1'b1;
 
              if(ex_valid_i)
                NS = WAIT_RVALID;
              else
                NS = WAIT_RVALID_EX_STALL;
            end else begin
              NS = IDLE;
            end
          end else begin
            if (data_rvalid_i) begin

              NS = IDLE;
            end
          end
        end
      end




      WAIT_RVALID_EX_STALL:
      begin
        data_req_o = 1'b0;

        if (data_rvalid_i) begin
          if (ex_valid_i) begin


            NS = IDLE;
          end else begin

            NS = IDLE_EX_STALL;
          end
        end else begin



          if (ex_valid_i)
            NS = WAIT_RVALID;
        end
      end

      IDLE_EX_STALL:
      begin

        if (ex_valid_i) begin
          NS = IDLE;
        end
      end

      default: begin
        NS = IDLE;
      end
    endcase
  end




  always_comb
  begin
    data_misaligned_o = 1'b0;

    if((data_req_mem_i == 1'b1) && (data_misaligned_ex_i == 1'b0))
    begin
      case (data_type_mem_i)
        2'b00:
        begin
          if(data_addr_int[1:0] != 2'b00)
            data_misaligned_o = 1'b1;
        end
        2'b01:
        begin
          if(data_addr_int[1:0] == 2'b11)
            data_misaligned_o = 1'b1;
        end
      endcase
    end
  end


  assign data_addr_int =data_addr_mem_i;

  assign busy_o = (CS == WAIT_RVALID) || (CS == WAIT_RVALID_EX_STALL) || (CS == IDLE_EX_STALL) || (data_req_o == 1'b1);






  `ifndef SIMULATION

    assert property (
      @(posedge clk) ((CS == WAIT_RVALID) && (data_gnt_i == 1'b1)) |-> (data_rvalid_i == 1'b1) ) else $display("It should not be possible to get a grand without an rvalid for the last request %t", $time);

    assert property (
      @(posedge clk) (CS == IDLE) |-> (data_rvalid_i == 1'b0) ) else $display("There should be no rvalid when we the LSU is IDLE %t", $time);


    assert property ( @(posedge clk) (data_req_o) |-> (!$isunknown(data_addr_o)) ) else $display("There has been a data request but the address is unknown %t", $time);
  `endif
endmodule
module riscv_load_store_unit
(
    input  logic         clk,
    input  logic         rst_n,


    output logic         data_req_o,
    input  logic         data_gnt_i,
    input  logic         data_rvalid_i,
    input  logic         data_err_i,

    output logic [31:0]  data_addr_o,
    output logic         data_we_o,
    output logic [3:0]   data_be_o,
    output logic [31:0]  data_wdata_o,
    input  logic [31:0]  data_rdata_i,


    input  logic         data_we_mem_i,
    input  logic [1:0]   data_type_mem_i,
    input  logic [31:0]  data_wdata_mem_i,
    input  logic [1:0]   data_reg_offset_mem_i,
    input  logic         data_sign_ext_mem_i,

    output logic [31:0]  data_rdata_wb_o,
    input  logic         data_req_mem_i,
    input  logic [31:0]  data_addr_mem_i,


    input  logic         data_misaligned_ex_i,
    output logic         data_misaligned_o,


    output logic         load_err_o,
    output logic         store_err_o,


    output logic         lsu_ready_mem_o,
    output logic         lsu_ready_wb_o,

    input  logic         ex_valid_i,
    output logic         busy_o
);


  logic [31:0]  data_addr_int;


  logic [1:0]   data_type_q;
  logic [1:0]   rdata_offset_q;
  logic         data_sign_ext_q;
  logic         data_we_q;

  logic [1:0]   wdata_offset;

  logic [3:0]   data_be;
  logic [31:0]  data_wdata;

  logic         misaligned_st;


  enum logic [1:0]  { IDLE, WAIT_RVALID, WAIT_RVALID_EX_STALL, IDLE_EX_STALL } CS, NS;

  logic [31:0]  rdata_q;


  always_comb
  begin
    case (data_type_mem_i)
      2'b00:
      begin
        if (misaligned_st == 1'b0)
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b1111;
            2'b01: data_be = 4'b1110;
            2'b10: data_be = 4'b1100;
            2'b11: data_be = 4'b1000;
          endcase;
        end
        else
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b0000;
            2'b01: data_be = 4'b0001;
            2'b10: data_be = 4'b0011;
            2'b11: data_be = 4'b0111;
          endcase;
        end
      end

      2'b01:
      begin
        if (misaligned_st == 1'b0)
        begin
          case (data_addr_int[1:0])
            2'b00: data_be = 4'b0011;
            2'b01: data_be = 4'b0110;
            2'b10: data_be = 4'b1100;
            2'b11: data_be = 4'b1000;
          endcase;
        end
        else
        begin
          data_be = 4'b0001;
        end
      end

      2'b10,
      2'b11: begin
        case (data_addr_int[1:0])
          2'b00: data_be = 4'b0001;
          2'b01: data_be = 4'b0010;
          2'b10: data_be = 4'b0100;
          2'b11: data_be = 4'b1000;
        endcase;
      end
    endcase;
  end




  assign wdata_offset = data_addr_int[1:0] - data_reg_offset_mem_i[1:0];
  always_comb
  begin
    case (wdata_offset)
      2'b00: data_wdata = data_wdata_mem_i[31:0];
      2'b01: data_wdata = {data_wdata_mem_i[23:0], data_wdata_mem_i[31:24]};
      2'b10: data_wdata = {data_wdata_mem_i[15:0], data_wdata_mem_i[31:16]};
      2'b11: data_wdata = {data_wdata_mem_i[ 7:0], data_wdata_mem_i[31: 8]};
    endcase;
  end



  always_ff @(posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
    begin
      data_type_q     <= '0;
      rdata_offset_q  <= '0;
      data_sign_ext_q <= '0;
      data_we_q       <= 1'b0;
    end
    else if (data_gnt_i == 1'b1)
    begin
      data_type_q     <= data_type_mem_i;
      rdata_offset_q  <= data_addr_int[1:0];
      data_sign_ext_q <= data_sign_ext_mem_i;
      data_we_q       <= data_we_mem_i;
    end
  end











  logic [31:0] data_rdata_ext;

  logic [31:0] rdata_w_ext;
  logic [31:0] rdata_h_ext;
  logic [31:0] rdata_b_ext;


  always_comb
  begin
    case (rdata_offset_q)
      2'b00: rdata_w_ext = data_rdata_i[31:0];
      2'b01: rdata_w_ext = {data_rdata_i[ 7:0], rdata_q[31:8]};
      2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]};
      2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]};
    endcase
  end


  always_comb
  begin
    case (rdata_offset_q)
      2'b00:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
        else
          rdata_h_ext = {{16{data_rdata_i[15]}}, data_rdata_i[15:0]};
      end

      2'b01:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[23:8]};
        else
          rdata_h_ext = {{16{data_rdata_i[23]}}, data_rdata_i[23:8]};
      end

      2'b10:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[31:16]};
        else
          rdata_h_ext = {{16{data_rdata_i[31]}}, data_rdata_i[31:16]};
      end

      2'b11:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_h_ext = {16'h0000, data_rdata_i[7:0], rdata_q[31:24]};
        else
          rdata_h_ext = {{16{data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]};
      end
    endcase
  end


  always_comb
  begin
    case (rdata_offset_q)
      2'b00:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[7:0]};
        else
          rdata_b_ext = {{24{data_rdata_i[7]}}, data_rdata_i[7:0]};
      end

      2'b01: begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[15:8]};
        else
          rdata_b_ext = {{24{data_rdata_i[15]}}, data_rdata_i[15:8]};
      end

      2'b10:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[23:16]};
        else
          rdata_b_ext = {{24{data_rdata_i[23]}}, data_rdata_i[23:16]};
      end

      2'b11:
      begin
        if (data_sign_ext_q == 1'b0)
          rdata_b_ext = {24'h00_0000, data_rdata_i[31:24]};
        else
          rdata_b_ext = {{24{data_rdata_i[31]}}, data_rdata_i[31:24]};
      end
    endcase
  end


  always_comb
  begin
    case (data_type_q)
      2'b00:       data_rdata_ext = rdata_w_ext;
      2'b01:       data_rdata_ext = rdata_h_ext;
      2'b10,2'b11: data_rdata_ext = rdata_b_ext;
    endcase
  end



  always_ff @(posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
    begin
      CS            <= IDLE;
      rdata_q       <= '0;
    end
    else
    begin
      CS            <= NS;

      if (data_rvalid_i && (~data_we_q))
      begin





        if ((data_misaligned_ex_i == 1'b1) || (data_misaligned_o == 1'b1))
          rdata_q  <= data_rdata_i;
        else
          rdata_q  <= data_rdata_ext;
      end
    end
  end


  assign data_rdata_wb_o = (data_rvalid_i == 1'b1) ? data_rdata_ext : rdata_q;


  assign data_addr_o   = data_addr_int;
  assign data_wdata_o  = data_wdata;
  assign data_we_o     = data_we_mem_i;
  assign data_be_o     = data_be;

  assign misaligned_st = data_misaligned_ex_i;

  assign load_err_o    = data_gnt_i && data_err_i && ~data_we_o;
  assign store_err_o   = data_gnt_i && data_err_i && data_we_o;


  always_comb
  begin
    NS             = CS;

    data_req_o     = 1'b0;

    lsu_ready_mem_o = 1'b1;
    lsu_ready_wb_o = 1'b1;

    case(CS)

      IDLE:
      begin
        data_req_o = data_req_mem_i;
        if(data_req_mem_i) begin
          lsu_ready_mem_o = 1'b0;



          if(data_gnt_i) begin
            lsu_ready_mem_o = 1'b1;


            if (ex_valid_i)
              NS = WAIT_RVALID;
            else
              NS = WAIT_RVALID_EX_STALL;
          end
        end
      end


      WAIT_RVALID:
      begin
        lsu_ready_wb_o = 1'b0; 

        if (data_rvalid_i) begin


          lsu_ready_wb_o = 1'b1;

          data_req_o = data_req_mem_i;

          if (data_req_mem_i) begin
            lsu_ready_mem_o = 1'b0;

            if (data_gnt_i) begin
              lsu_ready_mem_o = 1'b1;
 
              if(ex_valid_i)
                NS = WAIT_RVALID;
              else
                NS = WAIT_RVALID_EX_STALL;
            end else begin
              NS = IDLE;
            end
          end else begin
            if (data_rvalid_i) begin

              NS = IDLE;
            end
          end
        end
      end




      WAIT_RVALID_EX_STALL:
      begin
        data_req_o = 1'b0;

        if (data_rvalid_i) begin
          if (ex_valid_i) begin


            NS = IDLE;
          end else begin

            NS = IDLE_EX_STALL;
          end
        end else begin



          if (ex_valid_i)
            NS = WAIT_RVALID;
        end
      end

      IDLE_EX_STALL:
      begin

        if (ex_valid_i) begin
          NS = IDLE;
        end
      end

      default: begin
        NS = IDLE;
      end
    endcase
  end




  always_comb
  begin
    data_misaligned_o = 1'b0;

    if((data_req_mem_i == 1'b1) && (data_misaligned_ex_i == 1'b0))
    begin
      case (data_type_mem_i)
        2'b00:
        begin
          if(data_addr_int[1:0] != 2'b00)
            data_misaligned_o = 1'b1;
        end
        2'b01:
        begin
          if(data_addr_int[1:0] == 2'b11)
            data_misaligned_o = 1'b1;
        end
      endcase
    end
  end


  assign data_addr_int =data_addr_mem_i;

  assign busy_o = (CS == WAIT_RVALID) || (CS == WAIT_RVALID_EX_STALL) || (CS == IDLE_EX_STALL) || (data_req_o == 1'b1);






  `ifndef SIMULATION

    assert property (
      @(posedge clk) ((CS == WAIT_RVALID) && (data_gnt_i == 1'b1)) |-> (data_rvalid_i == 1'b1) ) else $display("It should not be possible to get a grand without an rvalid for the last request %t", $time);

    assert property (
      @(posedge clk) (CS == IDLE) |-> (data_rvalid_i == 1'b0) ) else $display("There should be no rvalid when we the LSU is IDLE %t", $time);


    assert property ( @(posedge clk) (data_req_o) |-> (!$isunknown(data_addr_o)) ) else $display("There has been a data request but the address is unknown %t", $time);
  `endif
endmodule