name: "Fixed-Point Softmax Approximation Layer"
category: "AI/ML Accelerators"
complexity: "Medium"
description: >
  Implement a combinational softmax approximation layer for a 4-element vector.

  This problem is METHOD-FIXED. Your implementation must match the exact fixed-point
  algorithm below (not an alternative LUT/CORDIC/curve fit):

  1) Inputs:
     - x0..x3 are signed 8-bit two's-complement Q4.4 values.
     - Real range is [-8.0, +7.9375].

  2) Max subtraction (signed compare):
     - m = max(x0, x1, x2, x3) using signed comparison.
     - di = xi - m (signed integer difference in raw Q4.4 steps).

  3) Required exp approximation (integer arithmetic, output in Q0.8-like scale):
     Let e(d) be:
       if d > -4:      e = 256 + d*16
       else if d > -8: e = 192 + (d+4)*12
       else if d > -16:e = 144 + (d+8)*9
       else if d > -32:e = 92 + (((d+16)*92) >> 4)
       else if d > -64:e = 34 + (((d+32)*34) >> 4)
       else:           e = 0
     Then clamp e to [0, 255].

  4) Normalization:
     - sum_e = e0 + e1 + e2 + e3.
     - If sum_e == 0, output y0=y1=y2=y3=64.
     - Otherwise yi = min(255, (ei*256) / sum_e).
     - Division is integer truncation toward zero.

  5) Outputs:
     - y0..y3 are unsigned 8-bit Q0.8 probabilities.

  6) Interface:
     - Purely combinational. No clock/reset, no pipelining.

  The evaluator checks exact output equality against vectors generated from this
  exact algorithm.

interface:
  module_name: "softmax_approx"
  clocked: false
  ports:
    - name: "x0"
      type: "input"
      width: "8"
      description: "Input 0, signed Q4.4 fixed-point"
    - name: "x1"
      type: "input"
      width: "8"
      description: "Input 1, signed Q4.4 fixed-point"
    - name: "x2"
      type: "input"
      width: "8"
      description: "Input 2, signed Q4.4 fixed-point"
    - name: "x3"
      type: "input"
      width: "8"
      description: "Input 3, signed Q4.4 fixed-point"
    - name: "y0"
      type: "output"
      width: "8"
      description: "Output 0, unsigned Q0.8 probability"
    - name: "y1"
      type: "output"
      width: "8"
      description: "Output 1, unsigned Q0.8 probability"
    - name: "y2"
      type: "output"
      width: "8"
      description: "Output 2, unsigned Q0.8 probability"
    - name: "y3"
      type: "output"
      width: "8"
      description: "Output 3, unsigned Q0.8 probability"

target_platform:
  device_family: "AMD Xilinx Spartan-7"

tasks:
  - name: "Area-Efficient Softmax Approximation"
    constraints:
      max_lut: 200
      max_ff: 0
      max_bram: 0
      max_dsp: 0
      min_frequency: 50
    objective:
      goal: "minimise"
      target: "LUT"
