Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21611 Discussions

Why Quartus cannot recognise my state machine

Altera_Forum
Honored Contributor II
6,880 Views

Hi all, 

 

We have implemented a state machine in a Stratix V project however we cannot find it in either state machine viewer or compilation report. Could anyone give some hints that does Quartus require some special format to recognise the state machine or we missed something? We have compared our state machine with others (automatically generated by Quartus) that can be recognised and we cannot see any format difference... 

 

Thanks
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
4,721 Views

Well cant comment like this. 

A share of your code for FSM would be required to comments anything.
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Look in the Quartus Language Templates, that will show if you edit a text-file in the Quartus-editor. 

Go to [Verilog HDL|VHDL]/Full Designs/State Machines. 

There you'll find aproppriate code. 

 

We usually use the Moore State Machine Construct, with the exception that we clock the output states too. 

We never had any problems with that, but we never compiled designs for Stratix V either. 

 

Apart from that, ashihkaps is right: 

If you don't post your code you're lost.
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Thanks for all the reply. Please see the code of the state machine. It is written by systemverilog so we use structure to define variables. Any suggestion would be highly appreciated 

 

typedef struct packed { logic writedata; logic address; logic read; logic write; } cpld_output_t; localparam cpld_output_t cpld_default_output = '{ default : 'x, read : 1'b0, write : 1'b0 }; typedef struct packed { logic readdata; logic readdatavalid; logic waitrequest; } fabric_output_t; localparam fabric_output_t fabric_default_output = '{ default : 'x, readdatavalid : 1'b0, waitrequest : 1'b1 }; typedef enum logic { NO_OWNER = 2'b01, MM_OWNS = 2'b10, RAW_OWNS = 2'b11 } cpld_owner_e; typedef enum { IDLE, RAW_WRITE, RAW_READ } flash_mm_access_e; typedef struct packed { logic mm_address_high; // 12 bits cpld_owner_e owner; // 2 bits flash_mm_access_e status; // 3 bits cpld_output_t cpld; // 22 bits fabric_output_t cpld_raw; // 18 bits logic mm_burstcount; // normally 8 bits } state_t; state_t state, next_state; localparam state_t default_state = '{ mm_address_high : 'x, owner : NO_OWNER, status : IDLE, cpld : cpld_default_output, cpld_raw : fabric_default_output, mm_burstcount : 'x}; always_comb begin // default assignments next_state = state; next_state.cpld_raw = fabric_default_output; case (state.status) IDLE: begin if (cpld_raw_read) begin next_state.status = RAW_READ; next_state.owner = RAW_OWNS; next_state.cpld_raw.waitrequest = 0; next_state.cpld.address = cpld_raw_address; next_state.cpld.write = 0; next_state.cpld.read = cpld_raw_read; end else if (cpld_raw_write) begin next_state.status = RAW_WRITE; next_state.owner = RAW_OWNS; next_state.cpld_raw.waitrequest = 0; next_state.cpld.address = cpld_raw_address; next_state.cpld.writedata = cpld_raw_writedata; next_state.cpld.write = cpld_raw_write; next_state.cpld.read = 0; end end RAW_WRITE: begin next_state.cpld_raw.waitrequest = 1; if (!cpld_waitrequest) begin next_state.cpld.write = 0; next_state.status = IDLE; next_state.owner = NO_OWNER; end end RAW_READ: begin next_state.cpld_raw.waitrequest = 1; if (!cpld_waitrequest) begin next_state.cpld.read = 0; end if (cpld_readdatavalid) begin next_state.cpld.read = 0; next_state.cpld_raw.readdatavalid = 1; next_state.cpld_raw.readdata = cpld_readdata; next_state.status = IDLE; next_state.owner = NO_OWNER; end end default: begin next_state = default_state; end endcase end always @(posedge clk or negedge reset_n) begin if (~reset_n) state <= default_state; else state <= next_state; end
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Dear skid, 

 

first of all, i'm pretty bad at (system)verilog. 

But nevertheless i've wrapped a module around your code as I understand it. 

 

Because my module has only "dangling" ports as Quartus reports, it is synthesized away. 

 

It's hard for me to predict what Quartus will do, if Ican't analyze it's output. 

 

Best regards, 

jb123
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Did you try with a simple state enumeration type, just in case Quartus has problems to pick the state variable from the structure?

0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Thanks for all the suggestions. now we found that Quartus cannot deal with state machine defined within structures. Once we move the state variable out of the structure, quartus can detect it. However the state machine still does not behave correctly...

0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

 

--- Quote Start ---  

However the state machine still does not behave correctly... 

--- Quote End ---  

 

A popular fault is not to register external signals before using them as inputs to the state machine, assumed the behavioral description is correct as such.
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

Thanks. However the state machine still does not behave even after registering all the external signals...We are pretty sure that the state switch logic described in the code is correct. We have signaltapped the internal signals and it seems that the state will jump to another unrelated one even all the triggers are correct, or will not quit current state when it shoud do.  

 

BTW, if we use state variable declared in this way: 

 

reg [6:0] state, next_state; 

parameter S0=1, S1=2, S2=3... 

 

Should we expect to see the 7-bit state variable in signaltap? Currently we can only find  

 

state.S0 

state.S1 

... 

 

in signaltap, which are all single-bit signals. 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

You will see the states that way since Quartus will see the state machine and encode the states. Looks like Quartus re-encoded your states as one-hot and this happens to be Quartus's default. 

 

/Boris
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

 

--- Quote Start ---  

You will see the states that way since Quartus will see the state machine and encode the states. Looks like Quartus re-encoded your states as one-hot and this happens to be Quartus's default. 

 

/Boris 

--- Quote End ---  

 

 

Thanks. However even if we set (* syn_encoding = "user" *), signaltap still gives the same result. Is there any way to prevent quartus to do such encoding things and just to use the registers defined in the code. In xilinx ISE and chipscope, you can definitely see the state registers if you want to. 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
4,721 Views

 

--- Quote Start ---  

You will see the states that way since Quartus will see the state machine and encode the states. Looks like Quartus re-encoded your states as one-hot and this happens to be Quartus's default. 

 

/Boris 

--- Quote End ---  

 

 

This is common. If you use Enums the synthesis tools may reencode the states. It is not just Quartus, Synopsys DC will do the same thing, but will use a binary encoding optimized to reduce the logic or perhaps the transitions. 

 

Now Quartus uses binary encoding as it is nicer for the FPGA structure, that gives you lots of flops and a little logic for each flop. A binary encoded FSM needs less flops but then requires much more complex combinatorial encoding. You can tell quartus to force a different encoding though, but the default is one hot.
0 Kudos
Reply