Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions Examples/HDL/Digital_Filtering/SSR_FIR/BDELAY.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;

use work.TYPES_PKG.all;
--CB use work.TYPES_PKG.all;
use work.fixed_pkg.all; -- VHDL-2008 IEEE standard SFIXED type and functions
use work.cfixed_pkg.all; -- user package, SFIXED_VECTOR, SFIXED_MATRIX and many other goodies
--CB

entity BDELAY is
generic(SIZE:NATURAL:=1; -- SIZE has a default value of 1 and cannot be negative, this would require traveling back in time
Expand All @@ -27,6 +30,7 @@ begin
-- l2n:if (SIZE>=66 and SIZE<=65+33) or (SIZE>=130 and SIZE<=129+65+33) or (SIZE>=258 and SIZE<=257+129+65+33) or (SIZE>513) generate
l2n:if DDR and (SIZE>3) generate
signal ID:BOOLEAN:=FALSE;
signal OB:BOOLEAN:=FALSE;
signal T,TD,SEL:STD_LOGIC:='0';
type TBV is array(0 to SIZE/2-1) of BOOLEAN;
signal OE,OO:TBV:=(others=>FALSE); -- delay line signal is SIZE/2 in length
Expand All @@ -38,7 +42,7 @@ begin
end;
else generate
process(CLK)
begin
begin
if rising_edge(CLK) then
ID<=I after 1 ps;
end if;
Expand Down Expand Up @@ -71,12 +75,28 @@ begin
TD<=T after 1 ps;
SEL<=TD xor T after 1 ps;
if SEL='0' then
O<=OE(OE'high);
OB<=OE(OE'high);
-- BF O<=OE(OE'high);
else
O<=OO(OO'high);
OB<=OO(OO'high);
-- BF O<=OO(OO'high);
end if;
end if;
end process;

--BF Added for DDR Even Filters
o0:if SIZE mod 2=1 generate
O<=OB;
end;
else generate
process(CLK)
begin
if rising_edge(CLK) then
O<=OB after 1 ps;
end if;
end process;
end generate;

end;
elsif (SIZE>=66 and SIZE<=65+33) or (SIZE>=130 and SIZE<=129+65+33) or (SIZE>=258 and SIZE<=257+129+65+33) generate
signal IO:BOOLEAN:=FALSE;
Expand Down Expand Up @@ -158,4 +178,4 @@ begin
O<=D(D'high);
end;
end generate;
end TEST;
end TEST;
13 changes: 8 additions & 5 deletions Examples/HDL/Digital_Filtering/SSR_FIR/DSPx8_WRAPPER.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;

use work.TYPES_PKG.all;
--CB use work.TYPES_PKG.all;
use work.fixed_pkg.all; -- VHDL-2008 IEEE standard SFIXED type and functions
use work.cfixed_pkg.all; -- user package, SFIXED_VECTOR, SFIXED_MATRIX and many other goodies
--CB

library unisims_ver;
library UNISIM;
Expand Down Expand Up @@ -81,11 +84,11 @@ entity DSPx8_WRAPPER is
INMODE:in STD_LOGIC_VECTOR(4 downto 0):=5x"00"; -- 5-bit input: INMODE control
OPMODE:in STD_LOGIC_VECTOR(8 downto 0):=9x"035"; -- 9-bit input: Operation mode - default is P<=C+A*B
-- Data inputs: Data Ports
A:in SFIXED; -- 30/34-bit input: A data
B:in SFIXED; -- 18/24-bit input: B data
C:in SFIXED; -- 48/58-bit input: C data
A:in SFIXED:="0"; -- 30/34-bit input: A data
B:in SFIXED:="0"; -- 18/24-bit input: B data
C:in SFIXED:="0"; -- 48/58-bit input: C data
CARRYIN:in STD_LOGIC:='0'; -- 1-bit input: Carry-in
D:in SFIXED; -- 25/27-bit input: D data
D:in SFIXED:="0"; -- 25/27-bit input: D data
-- Reset/Clock Enable inputs: Reset/Clock Enable Inputs
CEA1:in STD_LOGIC:='1'; -- 1-bit input: Clock enable for 1st stage AREG
CEA2:in STD_LOGIC:='1'; -- 1-bit input: Clock enable for 2nd stage AREG
Expand Down
Binary file modified Examples/HDL/Digital_Filtering/SSR_FIR/Images/SSR_FIR_screen_shot.PNG
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 65 additions & 12 deletions Examples/HDL/Digital_Filtering/SSR_FIR/README.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1 id="high-speed-ssr-fir">High Speed SSR FIR</h1>
<h1 id="high-speed-ssr-fir-—-direct-and-transpose-forms">High Speed SSR FIR — Direct and Transpose Forms</h1>
<a id="openlink" href="" style="display:inline-block; padding:10px 20px; background-color:#007acc; color:white; text-decoration:none; border-radius:5px; font-weight:900">Open Example</a>

<script>
Expand All @@ -19,23 +19,76 @@ <h1 id="high-speed-ssr-fir">High Speed SSR FIR</h1>

a.href = commandURI;
</script>
<p>This reference design can be used as a starting design point when efficient implementations of very high data rate (over 1 Gsps) Single Rate FIRs are required. This PL based design can be used in any modern AMD device - 7-Series/UltraScale/UltraScale+/Versal. <br />
<p>This reference design can be used as a starting design point when efficient implementations of very high data rate (over 1 Gsps) Single Rate FIRs are required. This PL based design can be used in any modern AMD device - 7-Series/UltraScale/UltraScale+/Versal.<br />
<br/><br/></p>
<p align="center">
<img src="Images/SSR_FIR_screen_shot.PNG" align ="center" width = 90%>
</p>
<p><br/><br/><br />
This Single Rate SSR FIR reference design illustrates a number of advanced Vitis Model Composer design techniques: </p>
<p><br/><br/></p>
<p>The model now contains <strong>two functionally-equivalent FIR architectures side by side</strong>, both driven by the same stimulus. The Direct form is checked sample-by-sample against a golden floating-point reference, and the Direct and Transpose outputs are overlaid in the <strong>Output</strong> spectrum analyzer to confirm the two architectures produce equivalent results (matching to within one LSB):</p>
<ul>
<li>This is a fully parameterizable design - you can control the filter order N, the number of clocks per sample SSR, the filter type (non/even/odd-symmetric), the input, output and coefficient fixed point quantization; you can set SSR and TAPS in Model Settings/Model Properties/Callbacks/InitFcnall the rest of the SSR FIR parameters can be set in the Model Composer block dialog</li>
<li>If desired, you can floorplan the DSP blocks directly from Vitis Model Composer</li>
<li>This is achieved through the use of Model Composer HDL Black Box flow, all these features are implemented in the underlying VHDL-2008 code; the reference design shows how to pass ports and parameters with generic sizes between Model Composer and VHDL code; the underlying VHDL-2008 code shows how to use arbitrary precision fixed point types, recursive component instantiations, how to instantiate DSP primitives independent of FPGA family (7-Series/UltraScale+/Versal) and floorplan them from VHDL code</li>
<li>The Vitis Model Composer design includes a top level Simulink self-checking testbench, which compares the fixed point HDL Black Box based implementation to a golden reference floating point model</li>
<li>This is a very high speed design, clock frequencies up to the maximum data sheet values of 741/891/1150 MHz in the fastest speed grade 7-Series/UltraScale+/Versal devices are possible</li>
<li>The design also shows a technique to avoid the Versal 795/824/872 MHz fMAX limitation due to SRL16 minimum pulse width spec</li>
<li>The VHDL code inside the Model Composer HDL Black Box can be instantiated stand alone in a Vivado RTL project. MATLAB and Vitis Model Composer are used here to illustrate the flow and make functional verification easier.</li>
<li><strong><code>DUT</code> – Direct Form</strong> (<code>SSR_FIR.vhd</code>): partial products cascade from the first to the last tap through the DSP <code>PCOUT</code> chain. The cascade is <code>TAPS</code> deep.</li>
<li><strong><code>DUT_T</code> – Transpose Form</strong> (<code>TRANSPOSE_SSR_FIR.vhd</code>): the input is broadcast to all DSPs and partial sums accumulate stage-by-stage through the DSP <code>PREG</code>/<code>PCOUT</code> registers. For SSR&gt;1 each of the SSR lanes implements a transposed sub-FIR, so the cascade is only <strong><code>TAPS/SSR</code> deep per lane</strong>.</li>
</ul>
<p>The two architectures are <strong>functionally equivalent, with outputs agreeing to within one output LSB (2^-16)</strong>. Each form is independently verified against the golden floating-point reference. The two forms have different pipeline latencies (direct = TAPS+2 clocks, transpose = 3×SSR+2 clocks), so the transpose output leads the direct output in time.</p>
<p>To generate code for one architecture, point the <strong>Vitis Model Composer Hub</strong> block's subsystem selection at <code>DUT</code> (direct) or <code>DUT_T</code> (transpose).</p>
<h2 id="why-two-forms">Why two forms?</h2>
<p>The critical path of the direct form grows with <code>TAPS</code> (the <code>PCOUT</code> cascade), while the transpose form's critical path is one DSP multiply-accumulate that is <strong>independent of <code>TAPS</code></strong>. This lets the transpose form close timing at high <code>SSR</code> and large <code>TAPS</code> where the direct form's cascade does not.</p>
<table>
<thead>
<tr>
<th>Property</th>
<th><strong>Direct Form</strong></th>
<th><strong>Transpose Form</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>SSR range</td>
<td>1, 2, 4, 8, 16 (2^n)</td>
<td>1, 2, 4, 8, 16 (2^n)</td>
</tr>
<tr>
<td>Fmax, Versal (SSR≤4)</td>
<td>~822 MHz (device ceiling)</td>
<td>~834–841 MHz</td>
</tr>
<tr>
<td>Fmax, SSR=8</td>
<td>~670–740 MHz</td>
<td>~834 MHz</td>
</tr>
<tr>
<td>Latency (SSR&gt;1, NS)</td>
<td>TAPS + 2</td>
<td>3×SSR + 2</td>
</tr>
<tr>
<td>PCOUT/PREG chain depth</td>
<td>TAPS hops</td>
<td><strong>TAPS/SSR hops per lane</strong></td>
</tr>
<tr>
<td>DSP count, NS</td>
<td>SSR × TAPS</td>
<td>SSR × TAPS</td>
</tr>
</tbody>
</table>
<p><strong>Rule of thumb:</strong> use the <strong>direct form</strong> for SSR 2–4 with TAPS ≤ 64 (shorter latency, simplest dataflow); use the <strong>transpose form</strong> for SSR ≥ 8, or for TAPS &gt; 64 at SSR = 4, or whenever a TAPS-independent (short, fixed) latency is required.</p>
<h2 id="model-configuration">Model configuration</h2>
<p>The model is parameterized through <code>Model Settings → Model Properties → Callbacks → InitFcn</code>:</p>
<pre><code class="matlab language-matlab">SSR = 8; % clocks per sample — MUST be a power of two (1,2,4,8,16,...)
TAPS = 64; % number of FIR coefficients
Ts = 1/SSR; % input sample time; SSR*Ts must equal the Simulink system period (1)
FCOEFF = fir1(TAPS-1,0.25); % shared coefficient set (hardware + golden reference)
</code></pre>
<p>Notes:</p>
<ul>
<li><strong><code>SSR</code> must be a power of two.</strong> Both cores assert this; non-power-of-2 SSR is not supported by the SSR&gt;1 accumulation chain.</li>
<li><strong><code>Ts = 1/SSR</code></strong> keeps the buffered input frame rate aligned with the Vitis Model Composer Hub's Simulink system period so the golden-vs-DUT comparison lines up. Changing <code>SSR</code> automatically rescales <code>Ts</code>.</li>
<li>The remaining FIR parameters (input/output/coefficient fixed-point ranges, rounding, symmetry, optional DSP floorplanning) are set on the <code>SSRFIR</code> Model Composer block mask inside each DUT.</li>
</ul>
<p>This design only works in Vivado 2022.1 or later.</p>
<hr />
<p>Copyright (c) 2026 Advanced Micro Devices, Inc.</p>

Expand Down
54 changes: 42 additions & 12 deletions Examples/HDL/Digital_Filtering/SSR_FIR/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,54 @@
# High Speed SSR FIR
# High Speed SSR FIR — Direct and Transpose Forms

This reference design can be used as a starting design point when efficient implementations of very high data rate (over 1 Gsps) Single Rate FIRs are required. This PL based design can be used in any modern AMD device - 7-Series/UltraScale/UltraScale+/Versal.
This reference design can be used as a starting design point when efficient implementations of very high data rate (over 1 Gsps) Single Rate FIRs are required. This PL based design can be used in any modern AMD device - 7-Series/UltraScale/UltraScale+/Versal.
<br/><br/>

<p align="center">
<img src="Images/SSR_FIR_screen_shot.PNG" align ="center" width = 90%>
</p>

<br/><br/>
This Single Rate SSR FIR reference design illustrates a number of advanced Vitis Model Composer design techniques:

- This is a fully parameterizable design - you can control the filter order N, the number of clocks per sample SSR, the filter type (non/even/odd-symmetric), the input, output and coefficient fixed point quantization; you can set SSR and TAPS in Model Settings/Model Properties/Callbacks/InitFcnall the rest of the SSR FIR parameters can be set in the Model Composer block dialog
- If desired, you can floorplan the DSP blocks directly from Vitis Model Composer
- This is achieved through the use of Model Composer HDL Black Box flow, all these features are implemented in the underlying VHDL-2008 code; the reference design shows how to pass ports and parameters with generic sizes between Model Composer and VHDL code; the underlying VHDL-2008 code shows how to use arbitrary precision fixed point types, recursive component instantiations, how to instantiate DSP primitives independent of FPGA family (7-Series/UltraScale+/Versal) and floorplan them from VHDL code
- The Vitis Model Composer design includes a top level Simulink self-checking testbench, which compares the fixed point HDL Black Box based implementation to a golden reference floating point model
- This is a very high speed design, clock frequencies up to the maximum data sheet values of 741/891/1150 MHz in the fastest speed grade 7-Series/UltraScale+/Versal devices are possible
- The design also shows a technique to avoid the Versal 795/824/872 MHz fMAX limitation due to SRL16 minimum pulse width spec
- The VHDL code inside the Model Composer HDL Black Box can be instantiated stand alone in a Vivado RTL project. MATLAB and Vitis Model Composer are used here to illustrate the flow and make functional verification easier.
The model now contains **two functionally-equivalent FIR architectures side by side**, both driven by the same stimulus. The Direct form is checked sample-by-sample against a golden floating-point reference, and the Direct and Transpose outputs are overlaid in the **Output** spectrum analyzer to confirm the two architectures produce equivalent results (matching to within one LSB):

- **`DUT` – Direct Form** (`SSR_FIR.vhd`): partial products cascade from the first to the last tap through the DSP `PCOUT` chain. The cascade is `TAPS` deep.
- **`DUT_T` – Transpose Form** (`TRANSPOSE_SSR_FIR.vhd`): the input is broadcast to all DSPs and partial sums accumulate stage-by-stage through the DSP `PREG`/`PCOUT` registers. For SSR>1 each of the SSR lanes implements a transposed sub-FIR, so the cascade is only **`TAPS/SSR` deep per lane**.

The two architectures are **functionally equivalent, with outputs agreeing to within one output LSB (2^-16)**. Each form is independently verified against the golden floating-point reference. The two forms have different pipeline latencies (direct = TAPS+2 clocks, transpose = 3×SSR+2 clocks), so the transpose output leads the direct output in time.

To generate code for one architecture, point the **Vitis Model Composer Hub** block's subsystem selection at `DUT` (direct) or `DUT_T` (transpose).

## Why two forms?

The critical path of the direct form grows with `TAPS` (the `PCOUT` cascade), while the transpose form's critical path is one DSP multiply-accumulate that is **independent of `TAPS`**. This lets the transpose form close timing at high `SSR` and large `TAPS` where the direct form's cascade does not.

| Property | **Direct Form** | **Transpose Form** |
|---|---|---|
| SSR range | 1, 2, 4, 8, 16 (2^n) | 1, 2, 4, 8, 16 (2^n) |
| Fmax, Versal (SSR≤4) | ~822 MHz (device ceiling) | ~834–841 MHz |
| Fmax, SSR=8 | ~670–740 MHz | ~834 MHz |
| Latency (SSR>1, NS) | TAPS + 2 | 3×SSR + 2 |
| PCOUT/PREG chain depth | TAPS hops | **TAPS/SSR hops per lane** |
| DSP count, NS | SSR × TAPS | SSR × TAPS |

**Rule of thumb:** use the **direct form** for SSR 2–4 with TAPS ≤ 64 (shorter latency, simplest dataflow); use the **transpose form** for SSR ≥ 8, or for TAPS > 64 at SSR = 4, or whenever a TAPS-independent (short, fixed) latency is required.

## Model configuration

The model is parameterized through `Model Settings → Model Properties → Callbacks → InitFcn`:

```matlab
SSR = 8; % clocks per sample — MUST be a power of two (1,2,4,8,16,...)
TAPS = 64; % number of FIR coefficients
Ts = 1/SSR; % input sample time; SSR*Ts must equal the Simulink system period (1)
FCOEFF = fir1(TAPS-1,0.25); % shared coefficient set (hardware + golden reference)
```

Notes:

This design only works in Vivado 2022.1 or later.
- **`SSR` must be a power of two.** Both cores assert this; non-power-of-2 SSR is not supported by the SSR>1 accumulation chain.
- **`Ts = 1/SSR`** keeps the buffered input frame rate aligned with the Vitis Model Composer Hub's Simulink system period so the golden-vs-DUT comparison lines up. Changing `SSR` automatically rescales `Ts`.
- The remaining FIR parameters (input/output/coefficient fixed-point ranges, rounding, symmetry, optional DSP floorplanning) are set on the `SSRFIR` Model Composer block mask inside each DUT.

--------------
Copyright (c) 2026 Advanced Micro Devices, Inc.
Loading