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: 
Highlighted
Visitor simonefonta
Visitor
3,338 Views
Registered: ‎08-29-2017

FSM not changing the state - Vivado HLS

Jump to solution

Hello, 

 

I am trying to convert a SystemC model into Verilog/VHDL for FPGA synthesis (Spartan 7) using Vivado HLS 2017.2.

I managed to convert all the .cpp/.h modules and start a simulation, but I am having problems with all the FSMs.

To replicate the problem I have written a simple state machine (code attached below).

This simple state machine should move from one state to the next, changing the value of the output from 0 to 6.

However, both the output and the state variable are always stuck at the same value.

Could you please check my code and simulation results and explain me why it is not working? It looks to me that the code is really similar to what is explained in the "Designing Protocol Processing Systems with Vivado High-Level Synthesis" application note (link).

 

Thank you very much,

Simone

 

FSM.h

#include <systemc>

SC_MODULE(fsm)
{
    /// sc ports
    sc_core::sc_in_clk clk_i;
    sc_core::sc_in<bool  > rst_n_i;
    sc_core::sc_out<unsigned int> state_out_o;

    //states
    static enum state_t { zero, first, second, third, fourth, fifth, sixth} state_variable;

    /// parameters
    struct params
    {

        params()
        {
        }
    } p;

    void fsm_method();



    SC_HAS_PROCESS(fsm);

    /// constructor
    fsm(sc_core::sc_module_name nm) : clk_i("clk_i"),
                                                       rst_n_i("rst_n_i"),
                                                       state_out_o("state_out_o"),
                                                       p(params())
    {

        SC_METHOD(fsm_method);
        sensitive << clk_i.pos();
        sensitive << rst_n_i.neg();

        //initialize variables
		state_variable = zero;

        this->construct();

    }

    /// destructor
    virtual ~fsm();

    private:
        void construct();

};

FSM.cpp

#include "fsm.h"

// adds SystemC namespaces for user convenience
#include <systemc.h>

//////////////////////////////////////////////
// method called by constructor             //
//////////////////////////////////////////////
void fsm::construct()
{

}

//////////////////////////////////////////////
// destructor                               //
//////////////////////////////////////////////
fsm::~fsm()
{

}

//////////////////////////////////////////////
// SC_METHOD tracking_method
// sensitive << clk_i.pos();
// sensitive << rst_n_i.neg();
//////////////////////////////////////////////
void fsm::fsm_method()
{

	//reset the machine
	if(rst_n_i.read() == false){
		state_variable = zero;
		state_out_o.write(0);
	}
	//normal clocked functioning
	else{
			switch(state_variable){
				case zero:
					state_variable = first;
					state_out_o.write(0);
					break;
				case first:
					state_variable = second;
					state_out_o.write(1);
					break;
				case second:
					state_variable = third;
					state_out_o.write(2);
					break;
				case third:
					state_variable = fourth;
					state_out_o.write(3);
					break;
				case fourth:
					state_variable = fifth;
					state_out_o.write(4);
					break;
				case fifth:
					state_variable = sixth;
					state_out_o.write(5);
					break;
				case sixth:
					state_variable = zero;
					state_out_o.write(6);
					break;
			}
	}
}

Testbench

tb.JPG

Simulation results

sim.JPG

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Explorer
Explorer
5,295 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta
I think I know the reason, refer to the code below, and Xilinx's technical documentation, the 402nd page of UG902.

 

    /// constructor
    fsm(sc_core::sc_module_name nm) : clk_i("clk_i"),
                                                       rst_n_i("rst_n_i"),
                                                       state_out_o("state_out_o"),
                                                       p(params())
    {

//        SC_METHOD(fsm_method);
//        sensitive << clk_i.pos();
//        sensitive << rst_n_i.neg();

        SC_CTHREAD(fsm_method, clk_i.pos());
        reset_signal_is(rst_n_i, false);	// active low: false ,  active high: true

//      //initialize variables
//		state_variable = zero;

        this->construct();

    }
void fsm::fsm_method()
{

	//initialize variables
	state_variable = zero;
	state_out_o.write(0);

	while(true){
		switch(state_variable){
			case zero:
				state_variable = first;
				state_out_o.write(0);
				break;
			case first:
				state_variable = second;
				state_out_o.write(1);
				break;
			case second:
				state_variable = third;
				state_out_o.write(2);
				break;
			case third:
				state_variable = fourth;
				state_out_o.write(3);
				break;
			case fourth:
				state_variable = fifth;
				state_out_o.write(4);
				break;
			case fifth:
				state_variable = sixth;
				state_out_o.write(5);
				break;
			case sixth:
				state_variable = zero;
				state_out_o.write(6);
				break;
		}
	}
}

If I understand correctly, I think SC_METHOD is for combinational logic, and SC_CTHREAD is for sequential logic.

 

 

 

 

0 Kudos
11 Replies
Explorer
Explorer
3,308 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta
Try removing the reset part.

 

void fsm::fsm_method()
{

//	//reset the machine
//	if(rst_n_i.read() == false){
//		state_variable = zero;
//		state_out_o.write(0);
//	}
//	//normal clocked functioning
//	else{
			switch(state_variable){
				case zero:
					state_variable = first;
					state_out_o.write(0);
					break;
				case first:
					state_variable = second;
					state_out_o.write(1);
					break;
				case second:
					state_variable = third;
					state_out_o.write(2);
					break;
				case third:
					state_variable = fourth;
					state_out_o.write(3);
					break;
				case fourth:
					state_variable = fifth;
					state_out_o.write(4);
					break;
				case fifth:
					state_variable = sixth;
					state_out_o.write(5);
					break;
				case sixth:
					state_variable = zero;
					state_out_o.write(6);
					break;
			}
//	}
}
0 Kudos
Visitor simonefonta
Visitor
3,301 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

Hi @avcon_lee thanks for your answer. 

 

If I try to comment out the reset part I get the following warning (among others):

WARNING: [RTGEN 206-101] Signal "clk_i" was created as a non-reset signal; try name "clk_i_r"  fsm_proj:solution1  30.08.2017 11:12:43

Then, when I import the file in Vivado block diagram I see an extra input pin coming out:

new_tb.JPG

Simulation results are shown here:

new_sim.JPG

 

 

The proposed suggestion unfortunately does not solve the problem and introduces a mysterious (at least for me) extra pin. Do you have any idea what is happening?

 

Thank you very much for your help,

Simone

0 Kudos
Explorer
Explorer
3,292 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta

Please ignore the answer just now. But It looks like the state machine is always in the zero state.

Have you tried single step debugging?

0 Kudos
Visitor simonefonta
Visitor
3,287 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

@avcon_lee I did not try single step debugging.

In the SystemC environment the state machine works as expected, so I guess it is a problem of Vivado not understanding the FSM correctly. Looking at the original simulation the state_variable is always 1 and the output always 0, so it is like if the FSM is always in the following state:

case zero:
state_variable = first;
state_out_o.write(0);
break;

Any idea how to debug this further?

 

Thanks,
Simone

0 Kudos
Visitor simonefonta
Visitor
3,267 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

UPDATE: if I remove the else before the switch the FSM works correctly (I see the output changing from 0 to 6). However I need the if/else construct to manage the reset condition. I really don't understand what is happening here...

0 Kudos
Explorer
Explorer
5,296 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta
I think I know the reason, refer to the code below, and Xilinx's technical documentation, the 402nd page of UG902.

 

    /// constructor
    fsm(sc_core::sc_module_name nm) : clk_i("clk_i"),
                                                       rst_n_i("rst_n_i"),
                                                       state_out_o("state_out_o"),
                                                       p(params())
    {

//        SC_METHOD(fsm_method);
//        sensitive << clk_i.pos();
//        sensitive << rst_n_i.neg();

        SC_CTHREAD(fsm_method, clk_i.pos());
        reset_signal_is(rst_n_i, false);	// active low: false ,  active high: true

//      //initialize variables
//		state_variable = zero;

        this->construct();

    }
void fsm::fsm_method()
{

	//initialize variables
	state_variable = zero;
	state_out_o.write(0);

	while(true){
		switch(state_variable){
			case zero:
				state_variable = first;
				state_out_o.write(0);
				break;
			case first:
				state_variable = second;
				state_out_o.write(1);
				break;
			case second:
				state_variable = third;
				state_out_o.write(2);
				break;
			case third:
				state_variable = fourth;
				state_out_o.write(3);
				break;
			case fourth:
				state_variable = fifth;
				state_out_o.write(4);
				break;
			case fifth:
				state_variable = sixth;
				state_out_o.write(5);
				break;
			case sixth:
				state_variable = zero;
				state_out_o.write(6);
				break;
		}
	}
}

If I understand correctly, I think SC_METHOD is for combinational logic, and SC_CTHREAD is for sequential logic.

 

 

 

 

0 Kudos
Visitor simonefonta
Visitor
3,242 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

@avcon_lee thanks for the answer and the very good suggestion. I tried your code and is working, even if I do not understand why it takes four clock cycles to change the output (see image below). Do you have any ideas?

sim.JPG

Regarding the SC_METHOD, in the SystemC Synthesizable subset user manual there is an example with an SC_METHOD to describe a sequential state machine with async. reset. Link here.

This is the example:

9.2 SC_METHOD
The body of a SystemC Method process (SC_METHOD) must not contain any wait statement
or any invocation of a function which may directly or indirectly cause the execution of a wait
statement. Consequently, it must not contain any loop which is not unrollable.
9.2.1 Synthesis semantics
Dependent on the coding style used within the body of a method process and dependent on
the sensitivity list, a process may describe sequential logic as well as purely combinational
logic.
Example:
SC_MODULE( L_AND ) {
sc_in< sc_logic > in_a, in_b;
sc_out< sc_logic > output;
void comb() { // This process describes purely combinational logic.

output.write( in_a.read() & in_b.read() );
}
SC_CTOR( L_AND ) {
SC_METHOD( comb );
sensitive << in_a << in_b;
}
};
Example:
SC_MODULE( Counter ) {
sc_in_clk clk;
sc_in< bool > rst_n;
sc_in< bool > enable;
sc_out< unsigned int > val;
unsigned int countVar;
void seq() { // This process describes sequential logic.
if ( !rst_n.read() ) {
countVar = 0;
}
else if ( enable.read() )
{
countVar += 1;
val.write( countVar );
}
}
SC_CTOR( Counter ) {
SC_METHOD( seq );
sensitive << rst_n.neg() << clk.pos();
}
};

 Can someone from Xilinx comment on this? It would be nice to know what is really supported and what not. 

Thank you very much,

Simone

0 Kudos
Explorer
Explorer
3,236 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta
1. With respect to the 4 clock cycles, the code geneerated from the HLS shows that this is internal action               initialization and output delay. And i don't think that will have an impact on your design.

 

2. The document you link to does not seem to be official data from xilinx.
   HLS may not support certain functions or statements, at least from the UG902 point of view, using SC_CTHREAD is        more appropriate.

0 Kudos
Visitor simonefonta
Visitor
3,232 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

@avcon_lee

1) Yes you are right I don't think it can have impact on the design, but still I was curious to understand why is that happening (since it is not what we meant in the cpp code)

2) Agree on this too

 

Thanks a lot for your help, I will try to convert all my sequential SC_METHOD in SC_CTHREAD then!

 

BR,

Simone

0 Kudos
Explorer
Explorer
1,706 Views
Registered: ‎07-17-2014

回复: FSM not changing the state - Vivado HLS

Jump to solution

@simonefonta
If you write RTL directly, you can do less than 4 clock cycles.
But for HLS, when you turn C into Verilog/VHDL, it may need to add additional D flip-flop to ensure the results are correct, and a D flip-flop causes a clock delay.

 

HLS, after all , is a tool, and performance and resource utilization are definitely not as good as writing RTL directly. Of course, with the release of the updata, i believe there will be a day to say goodbye to handwritten RTL.

0 Kudos
Visitor simonefonta
Visitor
1,704 Views
Registered: ‎08-29-2017

回复: FSM not changing the state - Vivado HLS

Jump to solution

@avcon_lee Agree with you! I will mark your solution as accepted :)

0 Kudos