<commit_before>// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

////////////////////////////////////////////////////////////////////////////////
// Engineer:       <NAME> - <EMAIL>              //
//                                                                            //
// Design Name:    Prefetcher Buffer for 32 bit memory interface              //
// Project Name:   littleRISCV                                                //
// Language:       SystemVerilog                                              //
//                                                                            //
// Description:    Prefetch buffer to cache 16 bit instruction part.          //
//                 Reduces gate count but might increase CPI.                 //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////


`include "riscv_config.sv"


module riscv_prefetch_buffer_small
(
  input  logic        clk,
  input  logic        rst_n,

  // ID interface
  input  logic        req_i,

  input  logic        branch_i,
  input  logic [31:0] addr_i,

  input  logic        ready_i,
  output logic        valid_o,
  output logic [31:0] rdata_o,
  output logic [31:0] addr_o,

  // goes to instruction memory / instruction cache
  output logic        instr_req_o,
  input  logic        instr_gnt_i,
  output logic [31:0] instr_addr_o,
  input  logic [31:0] instr_rdata_i,
  input  logic        instr_rvalid_i,

  // Prefetch Buffer Status
  output logic        busy_o
);
  

  /// Regs
  enum logic [1:0] {IDLE, WAIT_GNT, WAIT_RVALID, WAIT_ABORTED } CS, NS; // Will handle the steps for the memory interface


  logic [31:0]  fetch_addr_Q, fetch_addr_n; // The adress from the current fetch
  logic [15:0]  last_fetch_rdata_Q, last_fetch_rdata_n; // A 16 bit register to store one compressed instruction or half of a full instruction for next fetch
  logic [31:0]  current_fetch_rdata_Q, current_fetch_rdata_n; // A 32 bit register to store full instruction when valid fetch was stalled. Reduces memory accesses

  logic         last_fetch_valid_Q, last_fetch_valid_n; // Fetch was stalled so we need instruction word in register
  logic         last_addr_misaligned_Q, last_addr_misaligned_n; // Indicates whether we need to fetch the second part of an misaligned full instruction
  logic         fetch_stalled_Q, fetch_stalled_n; // Current fetch is stalled and we need to store full 32 bit instruction to memory to reduce memory accesses

  logic [31:0]  last_fetch_addr_Q, last_fetch_addr_n; // The adress from the last fetch



  /// Combinational signals
  logic [31:0]  addr_pc_next; // Calculate the next adress (adder as process counter)
  logic [31:0]  addr_mux; // The next address mux to be used

  logic [31:0]  instr_mux;

  logic addr_is_misaligned;
  logic instr_is_in_regs; // Indicates if address mod 4 is already fetched. 
  //                         It is implicitely assumed that the fetch is consecutive to the last fetch to spare a comparator.
  //                         In the other case we devalidate the cache which we check.
  logic instr_in_regs_is_compressed;


  enum logic [2:0] {FULL_INSTR_ALIGNED, C_INSTR_ALIGNED_DIRECT, C_INSTR_MISALIGNED_DIRECT, C_INSTR_IN_REG_OR_FIRST_FETCH, INSTR_IN_REG} instruction_format;
  //                        upper lower
  // FULL_INSTR_ALIGNED:  [ iiii, iiii] from mem
  // C_INSTR_DIRECT:      [ xxxx, iiii] from mem
  // C_INSTR_IN_REG:      [ iiii, xxxx] from reg
  // INSTR_IN_REG:        [ iiii, xxxx] 1st part in reg
  //                      [ xxxx, iiii] 2nd part from mem


  assign busy_o = (CS != IDLE) || instr_req_o;

  assign addr_is_misaligned = (fetch_addr_Q[1] == 1'b1); // Check if address is misaligned

  assign instr_is_in_regs = ( last_fetch_valid_Q && addr_is_misaligned);
  assign instr_in_regs_is_compressed = (last_fetch_rdata_Q[1:0] != 2'b11); // Upper half is compressed instruction

  assign instr_mux = fetch_stalled_Q ? current_fetch_rdata_Q : instr_rdata_i;

  // Calculate next address. This is the actual PC of littleRISCV. Will use same adder instance for all cases
  always_comb
  begin
    unique case (instruction_format)
      FULL_INSTR_ALIGNED:             addr_pc_next = fetch_addr_Q + 32'h4;
      C_INSTR_ALIGNED_DIRECT:         addr_pc_next = fetch_addr_Q + 32'h2;
      C_INSTR_MISALIGNED_DIRECT:      addr_pc_next = fetch_addr_Q + 32'h2;
      C_INSTR_IN_REG_OR_FIRST_FETCH:  addr_pc_next = fetch_addr_Q + 32'h2;
      INSTR_IN_REG:                   addr_pc_next = fetch_addr_Q + 32'h2;
      default:                        addr_pc_next = fetch_addr_Q + 32'h4;
    endcase
  end

  // Construct the outgoing instruction<commit_msg>Fix missing fetch reg assignment<commit_after>// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

////////////////////////////////////////////////////////////////////////////////
// Engineer:       <NAME> - <EMAIL>              //
//                                                                            //
// Design Name:    Prefetcher Buffer for 32 bit memory interface              //
// Project Name:   littleRISCV                                                //
// Language:       SystemVerilog                                              //
//                                                                            //
// Description:    Prefetch buffer to cache 16 bit instruction part.          //
//                 Reduces gate count but might increase CPI.                 //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////


`include "riscv_config.sv"


module riscv_prefetch_buffer_small
(
  input  logic        clk,
  input  logic        rst_n,

  // ID interface
  input  logic        req_i,

  input  logic        branch_i,
  input  logic [31:0] addr_i,

  input  logic        ready_i,
  output logic        valid_o,
  output logic [31:0] rdata_o,
  output logic [31:0] addr_o,

  // goes to instruction memory / instruction cache
  output logic        instr_req_o,
  input  logic        instr_gnt_i,
  output logic [31:0] instr_addr_o,
  input  logic [31:0] instr_rdata_i,
  input  logic        instr_rvalid_i,

  // Prefetch Buffer Status
  output logic        busy_o
);
  

  /// Regs
  enum logic [1:0] {IDLE, WAIT_GNT, WAIT_RVALID, WAIT_ABORTED } CS, NS; // Will handle the steps for the memory interface


  logic [31:0]  fetch_addr_Q, fetch_addr_n; // The adress from the current fetch
  logic [15:0]  last_fetch_rdata_Q, last_fetch_rdata_n; // A 16 bit register to store one compressed instruction or half of a full instruction for next fetch
  logic [31:0]  current_fetch_rdata_Q, current_fetch_rdata_n; // A 32 bit register to store full instruction when valid fetch was stalled. Reduces memory accesses

  logic         last_fetch_valid_Q, last_fetch_valid_n; // Fetch was stalled so we need instruction word in register
  logic         last_addr_misaligned_Q, last_addr_misaligned_n; // Indicates whether we need to fetch the second part of an misaligned full instruction
  logic         fetch_stalled_Q, fetch_stalled_n; // Current fetch is stalled and we need to store full 32 bit instruction to memory to reduce memory accesses

  logic [31:0]  last_fetch_addr_Q, last_fetch_addr_n; // The adress from the last fetch



  /// Combinational signals
  logic [31:0]  addr_pc_next; // Calculate the next adress (adder as process counter)
  logic [31:0]  addr_mux; // The next address mux to be used

  logic [31:0]  instr_mux;

  logic addr_is_misaligned;
  logic instr_is_in_regs; // Indicates if address mod 4 is already fetched. 
  //                         It is implicitely assumed that the fetch is consecutive to the last fetch to spare a comparator.
  //                         In the other case we devalidate the cache which we check.
  logic instr_in_regs_is_compressed;


  enum logic [2:0] {FULL_INSTR_ALIGNED, C_INSTR_ALIGNED_DIRECT, C_INSTR_MISALIGNED_DIRECT, C_INSTR_IN_REG_OR_FIRST_FETCH, INSTR_IN_REG} instruction_format;
  //                        upper lower
  // FULL_INSTR_ALIGNED:  [ iiii, iiii] from mem
  // C_INSTR_DIRECT:      [ xxxx, iiii] from mem
  // C_INSTR_IN_REG:      [ iiii, xxxx] from reg
  // INSTR_IN_REG:        [ iiii, xxxx] 1st part in reg
  //                      [ xxxx, iiii] 2nd part from mem


  assign busy_o = (CS != IDLE) || instr_req_o;

  assign addr_is_misaligned = (fetch_addr_Q[1] == 1'b1); // Check if address is misaligned

  assign instr_is_in_regs = ( last_fetch_valid_Q && addr_is_misaligned);
  assign instr_in_regs_is_compressed = (last_fetch_rdata_Q[1:0] != 2'b11); // Upper half is compressed instruction

  assign instr_mux = fetch_stalled_Q ? current_fetch_rdata_Q : instr_rdata_i;
  assign current_fetch_rdata_n = instr_mux;

  // Calculate next address. This is the actual PC of littleRISCV. Will use same adder instance for all cases
  always_comb
  begin
    unique case (instruction_format)
      FULL_INSTR_ALIGNED:             addr_pc_next = fetch_addr_Q + 32'h4;
      C_INSTR_ALIGNED_DIRECT:         addr_pc_next = fetch_addr_Q + 32'h2;
      C_INSTR_MISALIGNED_DIRECT:      addr_pc_next = fetch_addr_Q + 32'h2;
      C_INSTR_IN_REG_OR_FIRST_FETCH:  addr_pc_next = fetch_addr_Q + 32'h2;
      INSTR_IN_REG:                   addr_pc_next = fetch_addr_Q + 32'h2;
      default:                        addr_pc_next = fetch_addr_Q + 32'h4;
    endcase
  end

  // Construct the outgoing instruction
{'fraction_non_alphanumeric': 0.09390886403549312, 'fraction_numerical': 0.016452537203068676, 'mean_word_length': 2.0316615298402914, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1648107', 'n_tokens_mistral': 3269, 'n_tokens_neox': 3060, 'n_words': 1042}