CycloneIV registers - infer use of both clock ENA and synch clear SCLR - Page 1
Forum section: electronics / general

author: voltsandjolts
author_rank: Unknown
timestamp: November 28, 2021, 03:24:45 pm
content: Hmm, stuck on the basics here!Just a simple 16bit register.First picture shows almost what I want, just need to connect i_rst to SCLR...but I can't get there.The second picture is functional but not what I expected ...and less efficient since it's not using available hardware?Tried different ways of structuring the code but no luck.What do I need to do in VHDL to infer the use of both ENA and SCLR?Code:library ieee;use ieee.std_logic_1164.all;entity dtype isport (i_clk, i_clk_en : in std_logic;i_rst : in std_logic;i : in std_logic_vector(15 downto 0);q : out std_logic_vector(15 downto 0));end dtype;architecture rtl of dtype isbeginprocess (i_clk)begin-- this produces 16bit register and uses ENA for clock enable. All as expected.-- if rising_edge(i_clk) then-- if (i_clk_en = '1') then-- q <= i;-- end if;-- end if;-- end process;-- this doesn't use ENA or SCLR, why not?if rising_edge(i_clk) thenif (i_rst = '1') thenq <= (others => '0');elsif (i_clk_en = '1') thenq <= i;end if;end if;end process;end architecture;

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 28, 2021, 05:11:25 pm
content: Regarding the use of SCLR itself, you probably have an answer there:https://www.intel.com/content/www/us/en/support/programmable/articles/000075977.htmlAs to the second version not even using ENA, you need to take a look at the schematic you got. It's more "severe" than just not using ENA. As you can see, the result *looks* very inefficient, with the output of the register fed back to an input MUX, and an additional MUX to deal with the synchronous clear. While it's not "pretty" to look at, it may actually not make a difference. The reason for the first point (synthesis not necessarily using SCLR) is an optimization one. In FPGAs, you don't deal with fully independent logic structures as shown on schematics, you deal with logic blocks, and their efficient use is something that often eludes us poor humans. So you may think it didn't do a good job, while actually the end result is everything as good, if not better.Now the last point here regarding your second version is the use of both a clock enable and a synchronous clear. One thing to check in Intel's docs is whether the synchronous clear signal of registers is subject to the clock enable signal or not. In the code you posted, you are assuming it's not. I am not sure.

author: voltsandjolts
author_rank: Unknown
timestamp: November 28, 2021, 07:13:21 pm
content: Quote from: SiliconWizard on November 28, 2021, 05:11:25 pmI had guessed that might be the case, hence sized the register to use a whole LAB.Resorting to primitives fixes it, but that's not ideal.Code:library ieee;use ieee.std_logic_1164.all;library altera;use altera.altera_primitives_components.all;entity dtype isgeneric (USE_PRIMITIVE_DFFEAS : natural := 1);port (i_clk, i_clk_en : in std_logic;i_rst : in std_logic;d : in std_logic_vector(15 downto 0);q : out std_logic_vector(15 downto 0));end dtype;architecture rtl of dtype iscomponent DFFEASport (d : in STD_LOGIC;clk : in STD_LOGIC;clrn : in STD_LOGIC;prn : in STD_LOGIC;ena : in STD_LOGIC;asdata : in STD_LOGIC;aload : in STD_LOGIC;sclr : in STD_LOGIC;sload : in STD_LOGIC;q : out STD_LOGIC);end component;begintest_infer : if USE_PRIMITIVE_DFFEAS = 0 generateprocess (i_clk)begin-- this produces 16bit register and uses ENA for clock enable. All as expected.-- if rising_edge(i_clk) then-- if (i_clk_en = '1') then-- q <= i;-- end if;-- end if;-- end process;-- this doesn't use ENA or SCLR, why not?if rising_edge(i_clk) thenif (i_rst = '1') thenq <= (others => '0');elsif (i_clk_en = '1') thenq <= d;end if;end if;end process;end generate test_infer;test_prim : if USE_PRIMITIVE_DFFEAS = 1 generateGEN_REG :for I in 0 to 15 generateREGX : DFFEASport map(d => d(I),clk => i_clk,clrn => '1',prn => '1',ena => i_clk_en,asdata => '0',aload => '0',sclr => i_rst,sload => '0',q => q(I));end generate GEN_REG;end generate test_prim;end architecture;

author: Someone
author_rank: Super Contributor
timestamp: November 28, 2021, 09:27:48 pm
content: Quote from: voltsandjolts on November 28, 2021, 07:13:21 pmThat has also changed the functionality and is not equivalent to the HDL code you wrote, as SiliconWizard discussed.Quote from: SiliconWizard on November 28, 2021, 05:11:25 pmLead a horse to water and all that....

author: voltsandjolts
author_rank: Unknown
timestamp: November 29, 2021, 09:58:59 am
content: Thanks. In my OP I did say that I tried different ways of structuring the code, including this, which also doesn't work:Code:-- this doesn't use SCLR, why not?if rising_edge(i_clk) thenif (i_clk_en = '1') thenif (i_rst = '1') thenq <= (others => '0');elseq <= d;end if;end if;end if;Any more clues on the direction of nearest water for this thoroughbred?

author: Bassman59
author_rank: Super Contributor
timestamp: November 29, 2021, 04:52:43 pm
content: Quote from: voltsandjolts on November 28, 2021, 03:24:45 pmSynthesis tools are smart, and sometimes their logic minimization does things which are unexpected because the results are better than an "obvious" solution. I've seen many cases where what I thought was a simple clock enable not get synthesized as such: both the D and the ENA inputs got driven by a CLB with a interesting logic function. That's because the tool looks at everything which drives the flip-flop's inputs. Those inputs are D, ENA, SCLR/SPRE, and so it may end up deciding that some combination of those inputs, based on the logic design, give superior results.All of which is to say: design your logic in a manner that expresses the desired functionality and let the synthesizer do the hard work of optimization.(edit: slight change to "inputs got driven ...")

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 29, 2021, 05:45:48 pm
content: Quote from: voltsandjolts on November 29, 2021, 09:58:59 amNow it uses ENA as expected. But still not SCLR, for the reason explained above. Synthesis just considers it's not worth it for just ONE register.Unless you have specific timing issues with real designs (and not just small pieces of code), you should usually not even bother trying to optimize this, as what is more efficient is again pretty hard to figure out for us mere humans. If synthesis decides not to use SCLR, that's for a reason.

author: voltsandjolts
author_rank: Unknown
timestamp: November 29, 2021, 05:58:29 pm
content: OK, I'll keep calm and carry on, leaving the synthesis to do it's job.Thank you for taking the time to explain.