UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor venco5
Visitor
5,931 Views
Registered: ‎03-28-2016

How to combine two II=1 functions into one keeping the throughput?

I have two functions with II=1 and non-zero latency, output of one is used as input of another.

Both functions have a "state" object that is updated on each call. The update is simple enough to be done in one clock.

How can I combine the functions keeping the same throughput? I'd like also to keep the function's states into single structure so that only one state object reference is passed to the combining function.

 

In the sample code below I've put sqrt calls to make latency noticeable.

The functions stage1() and stage2() both have latency=15 and interval=1. Both need to add a 16-bit integer to different state counters. It works as expected if I inline everything - latency=33 and interval=1, but if I try to generate functions separately pipeline breaks. The reason I see in Analysis window is that both stage1() and stage2() fiunctions read their counters at the very first clock even if the counters are actulally needed only at the end.

Is it possible somehow to fix this problem?

 

 


#include <ap_int.h>
#include <hls_stream.h>
#include <hls_math.h>

typedef ap_int<16> Number;
struct State {
	State() : counter1(0), counter2(0) {}

	Number counter1;
	Number counter2;
};

void stage1_add(State& state, Number in, Number& out)
{
#pragma HLS PIPELINE enable_flush

	Number sum = state.counter1 + in;
	state.counter1 = sum;
	out = sum;
}

void stage1(State& state, Number in, Number& out)
{
#pragma HLS PIPELINE enable_flush

	stage1_add(state, hls::sqrt(ap_ufixed<Number::width, Number::width>(in)), out);
}

void stage2_add(State& state, Number in, Number& out)
{
#pragma HLS PIPELINE enable_flush

	Number sum = state.counter2 + in;
	state.counter2 = sum;
	out = sum;
}

void stage2(State& state, Number in, Number& out)
{
#pragma HLS PIPELINE enable_flush

	stage2_add(state, hls::sqrt(ap_ufixed<Number::width, Number::width>(in)), out);
}

void process_one(State& state, Number in, Number& out)
{
#pragma HLS PIPELINE enable_flush

	Number tmp;
	stage1(state, in, tmp);
	stage2(state, tmp, out);
}

void process_all(
		hls::stream<Number>& in_stream,
		hls::stream<Number>& out_stream)
{
	State state;
	loop_all: for ( ;; ) {
#pragma HLS LOOP_TRIPCOUNT min=1000 max=1000
#pragma HLS PIPELINE enable_flush

		Number in = in_stream.read();
		if ( in < 0 ) break;
		Number out;
		process_one(state, in, out);
		out_stream.write(out);
	}
}

 

Tags (1)
0 Kudos