Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

down-counter with CARRY_SUM-primitives

Hi all,

Since about 3 days I'm trying to implement a down-counter that uses the carry-chain. Reason is, [EDIT : did a mistake, no reason anymore, I just want to know]

Device is Cyclone_II, Software is Quartus 7.2sp3

I'm able to implement an up-counter where the carry-chain is utilized, but as soon a I change the carry logic to make it a down-counter, the compiler ignores all of the CARRY-buffers! the only difference is a simple NOT (see below). As far as I understood, the LEs in my case work in arithmetic-mode where the LUT is split into two 3-input LUTs, one for the respective bit of the couter and one for the carry-logic. So I don't get what the problem with this simple NOT is, since the LUT should be able to implement any arbitrary 3-input function.

Here are the code-snippets :

(In reality, the counters are 32-bits wide, but I'm showing only the first 3 bits here)

[comments in square-brackets are not part of the code]

ARCHITECTURE cntr_dwn32_sLd_aClr_ena_arch of cntr_dwn32_sLd_aClr_ena IS

SIGNAL cntComb : STD_LOGIC_VECTOR (31 downto 0);

SIGNAL cntReg : STD_LOGIC_VECTOR (31 downto 0);

SIGNAL cntSout : STD_LOGIC_VECTOR (31 downto 0);

SIGNAL carryIn : STD_LOGIC_VECTOR (32 downto 1);

SIGNAL carryOut : STD_LOGIC_VECTOR (31 downto 0);

BEGIN

q <= cntSout;

[1.) up-counter, this one works]

carryOut(0) <= cntReg(0);

carryOut(1) <= cntReg(1) AND carryIn(1);

carryOut(2) <= cntReg(2) AND carryIn(2);

[...]

[2.) down-counter, this one works NOT]

carryOut(0) <= NOT(cntReg(0));

carryOut(1) <= NOT(cntReg(1)) AND carryIn(1);

carryOut(2) <= NOT(cntReg(2)) AND carryIn(2);

[...]

carr_00_01 : CARRY_SUM PORT MAP (cin => carryOut(0), cout => carryIn(1), sin => cntReg(0), sout => cntSout(0));

carr_01_02 : CARRY_SUM PORT MAP (cin => carryOut(1), cout => carryIn(2), sin => cntReg(1), sout => cntSout(1));

carr_02_03 : CARRY_SUM PORT MAP (cin => carryOut(2), cout => carryIn(3), sin => cntReg(2), sout => cntSout(2));

[...]

cntComb (0) <= NOT(cntReg(0));

cntComb (1) <= cntReg(1) XOR carryIn(1);

cntComb (2) <= cntReg(2) XOR carryIn(2);

[...]

reg00 : DFFEAS PORT MAP (d => cntComb(0), clk => clck, clrn => aClr, prn => '1', ena => ena, asdata => ldVal(0), aload => '0', sclr => '0', sload => sLd, q => cntReg(0));

reg01 : DFFEAS PORT MAP (d => cntComb(1), clk => clck, clrn => aClr, prn => '1', ena => ena, asdata => ldVal(1), aload => '0', sclr => '0', sload => sLd, q => cntReg(1));

reg02 : DFFEAS PORT MAP (d => cntComb(2), clk => clck, clrn => aClr, prn => '1', ena => ena, asdata => ldVal(2), aload => '0', sclr => '0', sload => sLd, q => cntReg(2));

[...]

END cntr_dwn32_sLd_aClr_ena_arch;

Does anyone have an Idea ? Attached you can find the whole vhdl-file.

Ah and I'm using quartus 7.2sp3. Maybe this old Version has a Bug ? Could not find a revision-history of the changes made since then. But I didn't want to install the actual 10GB-bloat.

P.S.:The LPM-Megafunction is able to implement uo- and down-counters with enable, async.-clear and syncLoad that utilize the carry-chain, so physically it is possible.

Thanks for your help

Dieter
No RepliesBe the first to reply