Design a tick-aligned price accumulator that tracks meaningful price movement by filtering sub-tick noise.

Module name: tick_accum
Parameters:
  - WIDTH = 24         // Total bit width (signed fixed-point)
  - FRAC  = 8          // Fractional bits
  - TICK_SIZE = 24'sh000010  // Default tick size: 0.0625 in Q15.8

Ports:
  - input  clk
  - input  rst_n
  - input  signed [WIDTH-1:0] price_in    // Incoming price
  - input                     valid_in    // New price available
  - input  [WIDTH-1:0]        tick_size   // Minimum price increment
  - output signed [WIDTH-1:0] accum_out   // Accumulated tick-aligned price changes
  - output [15:0]             tick_count  // Number of tick crossings observed
  - output                    valid_out   // Pulses when a tick crossing is detected

Functional specification:
  - Tracks last_price (initialized on first valid sample)
  - On each valid_in: compute delta = price_in - last_price
  - If |delta| >= tick_size: this is a "tick crossing"
    - Compute aligned delta: floor(delta / tick_size) * tick_size
    - Accumulate: accum_out += aligned_delta
    - Increment tick_count
    - Update last_price to last_price + aligned_delta (snapped to tick boundary)
    - Assert valid_out for one cycle
  - If |delta| < tick_size: no update, valid_out stays low
  - This captures "real" price movement, filtering out sub-tick noise
  - Sequential module: one clock cycle latency per update (registered outputs)

Financial motivation:
  In high-frequency trading, tracking tick-level price movement (not raw noise) is
  fundamental to detecting real market signals. Sub-tick changes are noise and should
  be ignored. This module is the front-end filter for any tick-based signal detector.

Example (WIDTH=24, FRAC=8, TICK_SIZE=16 = 0.0625):
  - price_in = 100.0 (first sample) -> initializes last_price, no output
  - price_in = 100.125 (two ticks up) -> delta = 0.125 >= 0.0625
    - aligned_delta = floor(0.125 / 0.0625) * 0.0625 = 0.125
    - accum_out = 0.125, tick_count = 1, valid_out = 1
  - price_in = 100.15 (sub-tick from snapped 100.125) -> delta = 0.025 < 0.0625
    - no update, valid_out = 0
