Claude
Skills
Sign in
Back

synthesis-optimization

Included with Lifetime
$97 forever

Expertise in RTL optimization for FPGA synthesis tools. Analyzes synthesis reports, applies attributes, and guides resource inference for optimal QoR.

General

What this skill does


# Synthesis Optimization Skill

Expert skill for FPGA synthesis optimization targeting Vivado and Quartus tools. Provides deep expertise in synthesis report analysis, attribute application, resource inference control, and QoR (Quality of Results) improvement.

## Overview

The Synthesis Optimization skill enables comprehensive synthesis optimization for FPGA designs, supporting:
- Synthesis report analysis and resource utilization review
- Synthesis attributes (keep, max_fanout, ram_style, etc.)
- DSP and BRAM inference guidance
- FSM encoding optimization (one-hot, binary, Gray)
- Retiming and register balancing
- Logic optimization strategies
- High-fanout net reduction
- Multi-vendor synthesis flows

## Capabilities

### 1. Synthesis Report Analysis

Parse and analyze synthesis reports:

```tcl
# Vivado synthesis report analysis
report_utilization -hierarchical
report_utilization -cells [get_cells -hier -filter {IS_PRIMITIVE}]
report_timing_summary -setup -hold

# Resource utilization breakdown
report_utilization -format csv -file utilization.csv

# Check specific resource types
report_utilization -cells [get_cells -hier -filter {REF_NAME =~ DSP*}]
report_utilization -cells [get_cells -hier -filter {REF_NAME =~ RAM*}]
```

### 2. Synthesis Attributes

Apply Xilinx/Vivado synthesis attributes:

```systemverilog
// Keep hierarchy for debugging
(* KEEP_HIERARCHY = "yes" *)
module critical_path_module (
  // ...
);

// Prevent register optimization
(* DONT_TOUCH = "yes" *) logic debug_reg;

// Control register duplication for timing
(* MAX_FANOUT = 50 *) logic high_fanout_signal;

// Force specific implementation
(* KEEP = "true" *) logic preserved_signal;

// RAM style control
(* RAM_STYLE = "block" *) logic [7:0] large_mem [1024];
(* RAM_STYLE = "distributed" *) logic [7:0] small_mem [16];
(* RAM_STYLE = "registers" *) logic [7:0] tiny_mem [4];
(* RAM_STYLE = "ultra" *) logic [7:0] uram_mem [4096];  // UltraRAM

// ROM style control
(* ROM_STYLE = "block" *) logic [7:0] lookup_table [256];

// Use DSP for arithmetic
(* USE_DSP = "yes" *) logic [47:0] mult_result;
(* USE_DSP = "no" *) logic [15:0] small_mult;  // Use fabric

// Shreg extraction control
(* SHREG_EXTRACT = "yes" *) logic [15:0] shift_reg;
(* SRL_STYLE = "register" *) logic [7:0] no_srl_shift;

// Async register for CDC synchronizers
(* ASYNC_REG = "TRUE" *) logic [1:0] sync_reg;

// FSM encoding
(* FSM_ENCODING = "one_hot" *) enum logic [3:0] {
  IDLE, INIT, RUN, DONE
} state;

(* FSM_ENCODING = "sequential" *)  // Binary encoding
(* FSM_ENCODING = "gray" *)        // Gray code
(* FSM_ENCODING = "johnson" *)     // Johnson encoding
(* FSM_ENCODING = "auto" *)        // Tool decides
```

### 3. Intel/Quartus Attributes

Apply Quartus synthesis attributes:

```systemverilog
// RAM style
(* ramstyle = "M20K" *) logic [7:0] intel_bram [1024];
(* ramstyle = "MLAB" *) logic [7:0] intel_lutram [32];
(* ramstyle = "logic" *) logic [7:0] intel_ff_mem [8];
(* ramstyle = "no_rw_check" *) logic [7:0] dual_port_mem [256];

// Preserve signal
(* preserve *) logic keep_signal;
(* noprune *) logic unused_but_keep;

// DSP usage
(* multstyle = "dsp" *) logic [31:0] use_dsp;
(* multstyle = "logic" *) logic [7:0] use_fabric;

// Synchronizer
(* altera_attribute = "-name SYNCHRONIZER_IDENTIFICATION FORCED" *)
logic [1:0] altera_sync;

// Maximum fanout
(* maxfan = 32 *) logic fanout_limited;
```

### 4. DSP Inference Optimization

Guide DSP48/DSP block inference:

```systemverilog
// Optimal DSP48 inference pattern (multiply-accumulate)
module dsp_mac #(
  parameter int A_WIDTH = 18,
  parameter int B_WIDTH = 18,
  parameter int P_WIDTH = 48
) (
  input  logic                 clk,
  input  logic                 rst_n,
  input  logic                 ce,
  input  logic signed [A_WIDTH-1:0] a,
  input  logic signed [B_WIDTH-1:0] b,
  input  logic signed [P_WIDTH-1:0] c,
  input  logic                 load,  // Load C vs accumulate
  output logic signed [P_WIDTH-1:0] p
);

  // Pipeline registers for timing
  logic signed [A_WIDTH-1:0] a_reg;
  logic signed [B_WIDTH-1:0] b_reg;
  logic signed [P_WIDTH-1:0] mult_reg;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      a_reg <= '0;
      b_reg <= '0;
      mult_reg <= '0;
      p <= '0;
    end else if (ce) begin
      // Input registers (A and B)
      a_reg <= a;
      b_reg <= b;
      // Multiplier register (M)
      mult_reg <= a_reg * b_reg;
      // Accumulator/output (P)
      p <= load ? c + mult_reg : p + mult_reg;
    end
  end

endmodule

// Prevent DSP for small multiplies
(* USE_DSP = "no" *)
module small_mult (
  input  logic [7:0] a, b,
  output logic [15:0] p
);
  assign p = a * b;  // Will use fabric LUTs
endmodule
```

### 5. BRAM Inference Optimization

Ensure correct Block RAM inference:

```systemverilog
// Simple dual-port RAM (correct inference pattern)
module sdp_ram #(
  parameter int DATA_WIDTH = 32,
  parameter int DEPTH = 1024,
  parameter int ADDR_WIDTH = $clog2(DEPTH)
) (
  input  logic                    clk,
  // Write port
  input  logic                    wr_en,
  input  logic [ADDR_WIDTH-1:0]   wr_addr,
  input  logic [DATA_WIDTH-1:0]   wr_data,
  // Read port
  input  logic [ADDR_WIDTH-1:0]   rd_addr,
  output logic [DATA_WIDTH-1:0]   rd_data
);

  (* RAM_STYLE = "block" *)
  logic [DATA_WIDTH-1:0] mem [DEPTH];

  // Write port
  always_ff @(posedge clk) begin
    if (wr_en) begin
      mem[wr_addr] <= wr_data;
    end
  end

  // Read port (registered output for BRAM)
  always_ff @(posedge clk) begin
    rd_data <= mem[rd_addr];
  end

endmodule

// True dual-port RAM
module tdp_ram #(
  parameter int DATA_WIDTH = 32,
  parameter int DEPTH = 1024
) (
  // Port A
  input  logic                    clk_a,
  input  logic                    en_a,
  input  logic                    wr_en_a,
  input  logic [$clog2(DEPTH)-1:0] addr_a,
  input  logic [DATA_WIDTH-1:0]   wr_data_a,
  output logic [DATA_WIDTH-1:0]   rd_data_a,
  // Port B
  input  logic                    clk_b,
  input  logic                    en_b,
  input  logic                    wr_en_b,
  input  logic [$clog2(DEPTH)-1:0] addr_b,
  input  logic [DATA_WIDTH-1:0]   wr_data_b,
  output logic [DATA_WIDTH-1:0]   rd_data_b
);

  (* RAM_STYLE = "block" *)
  logic [DATA_WIDTH-1:0] mem [DEPTH];

  // Port A
  always_ff @(posedge clk_a) begin
    if (en_a) begin
      if (wr_en_a)
        mem[addr_a] <= wr_data_a;
      rd_data_a <= mem[addr_a];  // Read-first mode
    end
  end

  // Port B
  always_ff @(posedge clk_b) begin
    if (en_b) begin
      if (wr_en_b)
        mem[addr_b] <= wr_data_b;
      rd_data_b <= mem[addr_b];  // Read-first mode
    end
  end

endmodule
```

### 6. FSM Encoding Optimization

Choose optimal FSM encoding:

```systemverilog
// One-hot encoding (fast, more registers)
(* FSM_ENCODING = "one_hot" *)
typedef enum logic [7:0] {
  IDLE    = 8'b00000001,
  INIT    = 8'b00000010,
  CONFIG  = 8'b00000100,
  RUN     = 8'b00001000,
  PAUSE   = 8'b00010000,
  DONE    = 8'b00100000,
  ERROR   = 8'b01000000,
  RESET   = 8'b10000000
} state_t;

// Binary encoding (compact, slower decode)
(* FSM_ENCODING = "sequential" *)
typedef enum logic [2:0] {
  S_IDLE  = 3'd0,
  S_INIT  = 3'd1,
  S_RUN   = 3'd2,
  S_DONE  = 3'd3
} compact_state_t;

// Gray encoding (low power, one-bit transitions)
(* FSM_ENCODING = "gray" *)
typedef enum logic [2:0] {
  G_IDLE  = 3'b000,
  G_INIT  = 3'b001,
  G_RUN   = 3'b011,
  G_DONE  = 3'b010
} gray_state_t;

// Safe FSM with illegal state recovery
module safe_fsm (
  input  logic clk,
  input  logic rst_n,
  input  logic start,
  input  logic done,
  output state_t state
);

  state_t current_state, next_state;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n)
      current_state <= IDLE;
    else
      current_state <= next_state;
  end

  always_comb begin
    next_state = current_state;
    case (current_state)
      IDLE:   if (start) next_state = INIT;
      INIT:   next_state =

Related in General