2
\$\begingroup\$

I'm using an IP-Core of Xilinx that was generated using the Vivado IDE's IP Catalog, specifically I'm using the Accumulator and the Multiplier IP Cores.

These cores have a latency configuration of 6 and 3 respectively and do not use a handshake protocol (ready-for-data, done, run signals). When I'm using the cores with a component instantiation, I need circuits to handle the latency delays.

How can I verify that the latency is actually 6 and 3 respectively? Imagine that the IP Core is updated and the latency is changed, or in my code, I have it backwards and assume latencies 3 and 6 respecively. I want to assert component'latency = 3, or something similar. What's the way this is done?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I highly doubt the latency would change between revisions of the IP core. If you don't trust the latency numbers in the datasheets you could always simulate the IP. Also, when running Report IP Status in Vivado to update the IP major changes (port names, etc) will be noted with a pop-up warning. I would think latency would be considered a major change. \$\endgroup\$
    – ks0ze
    Commented Aug 3, 2017 at 11:54
  • \$\begingroup\$ @ks0ze the problem I have is that the latency is something hidden inside the element, and not visible, like the other things (ports), where I give and see the widths and types in the code. It would be best to statically assert the latency in similar ways. If it's not possible, I'll answer my question to say I'm out of luck (you may post an answer aswell if you like). Note I've only written VHDL/fpga for a week, so I'm still unsure about the details. \$\endgroup\$ Commented Aug 3, 2017 at 11:57
  • \$\begingroup\$ You can check the latency by a unique pattern in simulation, but you can't automatically check it at synthesis time if the latency changed in the generated implementation. But why are you using an IP core for a simple multiplication and accumulation? What about y <= a * b; Xilinx tools can automatically move pipeline stages to improve the performance. \$\endgroup\$
    – Paebbels
    Commented Aug 3, 2017 at 12:03
  • \$\begingroup\$ @Paebbels Because y's bitwidth is 63, it will slow down the maximal possible cycle frequency if I put it as an expression VHDL inside the process(clk), since it must finish within a single cycle then. Or am I mistaken? With the IP-Core, I can apply pipelining that accounts for not taking the cycle for too long. \$\endgroup\$ Commented Aug 3, 2017 at 12:06
  • \$\begingroup\$ No as I said, Xilinx can move pipeline stages from before and after a multiplication into the multiplication operation to speed it up. Pipeline stages after are preferred. You can have up to 5 (7?) stages in 7-Series devices. so write: y0 <= a * b; y1 <= y0 when rising_edge(Clock); y <= y1 when rising_edge(Clock); Read the synthesis report and search for retiming or so. Synthesis will map the multiplication and also the accumulation to DSP slices and use the DSP slice internal registers instead of normal registers. \$\endgroup\$
    – Paebbels
    Commented Aug 3, 2017 at 14:26

2 Answers 2

3
\$\begingroup\$

If you need a guarantee that the design will not change with a future tool version, then don't use an IP core for this sort of relatively simple functionality. You can quite easily instantiate one or more DSP slices with a fixed configuration that will not change between tool versions. The DSP slice user guide has everything you need to know. Depending on your use case, you might be able to infer an optimal implementation using a simple x <= a * b;

You might find that in your application, you can time domain multiplex the inputs and mode for one set of DSP slices in order to achieve the same functionality with fewer resources; for example, do you need to multiply and accumulate at the same time? The IP core can never be aware of this.

If your primary goal is to get a design working quickly, then the IP cores will give an effective result.

\$\endgroup\$
6
  • \$\begingroup\$ Can it add a 36 bit number (multiply result) onto a 63 bit number (x) inside of a single 10ns cycle? If it can't, it's my understanding the synthesis tool has to slow down the cycle frequency. \$\endgroup\$ Commented Aug 3, 2017 at 12:11
  • \$\begingroup\$ If you need a 63-bit operand, then you have to use either two DSP slices, or one DSP slice and some external logic. Assuming that you need minimal clock period, whichever approach you take to implementing it (IP core, instantiate, infer), the design will have a multi-cycle latency but the throughput can be one result per clock. If you don't know how to pipeline an operation like this, then this is probably worthy of another question. \$\endgroup\$
    – scary_jeff
    Commented Aug 3, 2017 at 12:14
  • \$\begingroup\$ I see, thanks. Someone told me it's best to use IP Cores for this, becaue you can configure them very flexibly and they are highly optimized. Previously I used a single macro MACC_MACRO (multiply-accumulate, which is implemented with a DSP slice) but then noticed it will overflow. Is it better to use two cascaded MACC_MACROs to build the accumulator instead the two IP-Cores? \$\endgroup\$ Commented Aug 3, 2017 at 12:19
  • \$\begingroup\$ You can use IP cores, but if you do that, you will not have a guarantee that the core will not change at all with a future tool version. If you decide to use DSP slice instantiation instead, the template is under Tools > Language Templates > VHDL > Device Primitive Instantiation. If this seems too time consuming, you will have to use the IP core, and accept that it has the (small) potential to change in the future. \$\endgroup\$
    – scary_jeff
    Commented Aug 3, 2017 at 12:40
  • \$\begingroup\$ Ah, I see. Thanks, the advice is appreciated. I think I will leave this to the IP Core for now and may optimize things later on. \$\endgroup\$ Commented Aug 3, 2017 at 12:42
2
\$\begingroup\$

As explained in my comment, you can just write this:

y0 <= a * b;
y1 <= y0 when rising_edge(Clock);
y2 <= y1 when rising_edge(Clock);
y3 <= y2 when rising_edge(Clock);
y  <= y3 when rising_edge(Clock);

Xilinx tools we use pattern matching and retiming as an optimization:

  • instantiate DSP slices for your multiplication
  • if needed combine multiple DSP slices
  • move register stages into the DSP by enabling internal pipeline registers.

Up to 5 (or was it 7?) pipeline stages can be moved into the DSP48E2. Some might need to be described as registers before the multiplication.

The same techniques apply to accumulate operations.

\$\endgroup\$
13
  • \$\begingroup\$ I'm confused as to why why the synthesizer can split a*b up into multiple clock ticks if it sees this pattern. The answer at stackoverflow.com/a/13956532/34509 states that "However, the synthesis and back-end tools (place and route) guarantee to either obey this model faithfully, or fail and report why they failed. For example, they will add up all the real delays and verify that the sum is less than your specified clock period. (Unless you have set the clock speed too high!).". Now your answer seem to indicate that instead of failing, it can apply pipelining?. \$\endgroup\$ Commented Aug 3, 2017 at 15:10
  • \$\begingroup\$ But.. I think I see what you did there. The multiplication is not sensitive to the clock, so it's different. \$\endgroup\$ Commented Aug 3, 2017 at 15:13
  • \$\begingroup\$ @JohannesSchaub-litb it can work because the code says that there are 4 registers after the multiplication that simply shift the same data through. The tool can take advantage of these 'wasted' clock cycles, and split the multiplication into several stages, with each stage then having a lower minimum clock period. \$\endgroup\$
    – scary_jeff
    Commented Aug 3, 2017 at 15:31
  • \$\begingroup\$ @scary_jeff But if the optimization is not done, the behavior of this pattern is not defined if you use it as a 1-cycle-throughput-pipeline. So after each synthesis one has to check again, or am I missing something? \$\endgroup\$ Commented Aug 3, 2017 at 15:43
  • \$\begingroup\$ @JohannesSchaub-litb the result will be defined in any case. If no automatic pipelining is performed, the design will not pass timing at the implementation stage. \$\endgroup\$
    – scary_jeff
    Commented Aug 3, 2017 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.