name: "G-Share Branch Predictor"
category: "Soft Processors & Memory"
complexity: "Medium"
description: >
  Implement a G-Share branch predictor with 7-bit PC and 7-bit global history register (GHR).
  The PC and GHR are XORed together to form a 7-bit index into a 128-entry Pattern History Table (PHT).
  Each PHT entry is a 2-bit saturating counter: 00 = strongly not-taken, 01 = weakly not-taken, 
  10 = weakly taken, 11 = strongly taken. Prediction is taken if counter[1] == 1.
  
  The predictor has two independent interfaces: prediction (fetch stage) and training (execute stage).
  
  PREDICTION (predict_valid=1): Given predict_pc, compute PHT index = predict_pc XOR current_GHR.
  Output the prediction (predict_taken) and the GHR value used (predict_history). At the next 
  positive clock edge, update GHR by shifting in the predicted direction.
  
  TRAINING (train_valid=1): Given train_pc, train_history (GHR at prediction time), train_taken 
  (actual outcome), and train_mispredicted flag. Compute PHT index = train_pc XOR train_history.
  Update the corresponding PHT counter based on train_taken (increment if taken, decrement if not, 
  saturating at 00 and 11). If train_mispredicted=1, also recover the GHR to {train_history[5:0], train_taken}.
  
  SIMULTANEOUS OPERATIONS:
  - Training takes priority over prediction for GHR updates when both occur in the same cycle.
  - PHT is updated at the positive clock edge, so prediction sees the pre-training state if both 
    access the same PHT entry in the same cycle.
  
  RESET: Asynchronous active-high reset (areset) clears all PHT entries to 2'b01 (weakly not-taken) 
  and GHR to 7'b0.

sources:
  - "McFarling (1993) - Combining Branch Predictors"
  - "HDLBITS Problem - cs450/gshare"

interface:
  module_name: "gshare_predictor"
  clocked: true
  ports:
    - name: "clk"
      type: "input"
      width: "1"
      description: "Clock signal"
    - name: "areset"
      type: "input"
      width: "1"
      description: "Asynchronous active-high reset"
    - name: "predict_valid"
      type: "input"
      width: "1"
      description: "Prediction request valid"
    - name: "predict_pc"
      type: "input"
      width: "7"
      description: "Program counter for prediction (lower 7 bits)"
    - name: "predict_taken"
      type: "output"
      width: "1"
      description: "Predicted branch direction (1=taken, 0=not-taken)"
    - name: "predict_history"
      type: "output"
      width: "7"
      description: "Global history register value used for this prediction"
    - name: "train_valid"
      type: "input"
      width: "1"
      description: "Training request valid"
    - name: "train_taken"
      type: "input"
      width: "1"
      description: "Actual branch outcome (1=taken, 0=not-taken)"
    - name: "train_mispredicted"
      type: "input"
      width: "1"
      description: "Branch was mispredicted, requires GHR recovery"
    - name: "train_history"
      type: "input"
      width: "7"
      description: "GHR value used when the branch was originally predicted"
    - name: "train_pc"
      type: "input"
      width: "7"
      description: "Program counter of the branch being trained"

target_platform:
  device_family: "AMD Xilinx Spartan-7"

tasks:
  - name: "Resource-Efficient G-Share Predictor"
    constraints:
      max_lut: 200
      max_ff: 300
      max_bram: 1
      min_frequency: 70
    objective:
      goal: "minimise"
      target: "LUTs"
