01-25-2018 06:13 AM
I am running Vivado 2017.3 for synthesis, and I get unexpected results.
My design contains several FSMs, each coded following suggestions from Xilinx UG901: a single clocked process, with synchronous reset and a single case statement where I decide the (next) state and the outputs according to current input and state.
However, none of them gets inferred as FSM. For some of them I get the following:
ROM "curr_state" won't be mapped to Block RAM because address size (2) smaller than threshold (5)
while for others:
ROM "curr_state" won't be mapped to RAM because it is too sparse
The Internet suggests a way to solve the first of these issues by setting the minimum number of states for an FSM to be inferred. However, nothing changes from the synthesis logs.
01-30-2018 05:38 AM
01-25-2018 01:26 PM
Two points / Questions.
1. I believe the tool is telling you that it DID infer the FSM - however it's NOT mapping the FSM to a Block RAM. Meaning it will still search / optimize through other State Machine encodings (i.e. one-hot, user, grey, etc...)
2. Why does it matter? In either case you'll still get a resulting netlist that matches your RTL description.
(The second question I wonder all the time for any State Machine related question on these forums....)
01-25-2018 02:03 PM
Actually, I take that back. Reviewing some of my own logs, it appears I'm reading (both your) and my log files too quickly.
Vivado's missing most of my state machines too. (some snippage from my own logs)
INFO: [Synth 8-802] inferred FSM for state register 'state_reg' in module 'axi_dma_wrdata_fsm' INFO: [Synth 8-5544] ROM "next_state" won't be mapped to Block RAM because address size (1) smaller than threshold (5)
I see the lines next to each other, and assume they're related. But maybe not. It's hard to tell from the messages within the log as the tool doens't give enough context.
My second question still applies - why should I (or the OP care)? I've mild curiosity why my state machines are (perhaps) no longer being recognized. But probably not sufficient curiosity to spend much time figuring it out. My quality of results is fine - I usually have registers to spare. I can't believe that FSM optimizations would optimize things all that much. The OP may have different designs / criteria however...
01-26-2018 12:28 AM
01-26-2018 04:39 AM
I cannot post complete code, but I can post a template of it, hoping it will help as well.
... my libraries ... entity fsm is ... my generics ... ... my ports ... end entity fsm; architecture behavioral of fsm is ... my components ... -- States define type fsm_state_t is ( ... ); signal curr_state : fsm_state_t; signal last_state : fsm_state_t; ... my signals ... begin ... top-level wiring ... ... some procs and combinational instances ... -- Single clocked process FSM_proc : process(clk_i) begin if(rising_edge(clk_i)) then if(rstn_i = '0') then curr_state <= RESET; last_state <= RESET; else ... defaults assignments ... case curr_state is when RESET => if( ... condition ... ) then ... do stuff ... end if; ... for every state ... when UNKNOWN => null; when others => curr_state <= UNKNOWN; last_state <= UNKNOWN; end case; end if; end if; end process FSM_proc; end architecture behavioral;
In the meanwhile I gave few trials, failing every time:
- User-defined states encoding attributes (in the VHDL code) and synthesis option -fsm_extraction user_encoding;
- fsm_style attribute set to "bram" in VHDL code on the curr_state signal.
01-29-2018 01:59 AM
I think the issue here is in the case statement where the states are not changing as per your requirement.
You may try like this:
case curr_state is
when RESET = >
if (....condition ....) then
... do stuff...
curr_state <= UNKNOWN
curr_state <= RESET
... do stuff...
You need to do the same with state UNKNOWN too.
For more info. You can have a look in to UG901 FSM Example with Single Sequential Block. (page 155 )
01-30-2018 05:38 AM