FPGARelated.com
Forums

Driving PLL from general I/O in Altera Cyclone

Started by nfirtaps March 8, 2007
I am trying to deserialize a DDR signal in my Cyclone.  For reasons I
won't go into the DDR clock comes in off a general purpose I/O pin.  I
need a way of deserializing this signal, and want to increase the
frequency of the DDR clock by 2 so I can use rising edge flip-flops.

1.) Can I somehow drive a PLL with a general purpose I/O
2.) Is there another way of deserializing the DDR signal.

Currently I have a the DDR clock coming in my fpga and I not the clock
so I can sample the DDR signal on the rising egde.

Thanks

"nfirtaps" <lloyd.rochester@gmail.com> wrote in message 
news:1173383894.763347.110110@64g2000cwx.googlegroups.com...
> > 1.) Can I somehow drive a PLL with a general purpose I/O
I don't think so. I'm using Cyclone II at the moment and I'm 99.9% sure you can't feed the PLLs with anything except one of the 'clock input' pins. (These can also be general purpose input pins, so I would always recommend connecting anything vaguely 'clock-like' to one of those pins, even if you think you might not actually use it as a clock.)
> 2.) Is there another way of deserializing the DDR signal.
You don't say anything about frequency, but I'd be inclined just to sample on the falling edge as well, and then shift the two bits (+ve edge and -ve edge) into your shift register on the next +ve clock.
> Currently I have a the DDR clock coming in my fpga and I not the clock > so I can sample the DDR signal on the rising egde.
Is that giving you a problem? Will
The problem I am having maybe due to jitter. I am not sure.  I am
running under 35 MHz, althougth I am using LVDS.  I am sampling on the
rising and falling edge of the clock, and the deserializer needs to
take every 7 clocks (respective 14 bits) since it is DDR.  When I look
at the output clk/7 that I generate by a simple counter (when counter
= 1-4 clk is high, when counter = 4-7 clk is low), I see that the duty
cycle changes by about 1 clock.  It seems as though the counter misses
a beat or something of that nature.

What I expect to see is a newly generated clock where the rising edges
occur at the same place every time, although, I see a rising edges
"walk" with respect to my trigger on the scope.  I have no idea the
source of the problem, or how to fix it.

Regards

On Mar 8, 2:12 pm, "Will Dean" <w...@nospam.demon.co.uk> wrote:
> "nfirtaps" <lloyd.roches...@gmail.com> wrote in message > > news:1173383894.763347.110110@64g2000cwx.googlegroups.com... > > > > > 1.) Can I somehow drive aPLLwith a general purpose I/O > > I don't think so. I'm usingCycloneII at the moment and I'm 99.9% sure you > can't feed the PLLs with anything except one of the 'clock input' pins. > (These can also be general purpose input pins, so I would always recommend > connecting anything vaguely 'clock-like' to one of those pins, even if you > think you might not actually use it as a clock.) > > > 2.) Is there another way of deserializing the DDR signal. > > You don't say anything about frequency, but I'd be inclined just to sample > on the falling edge as well, and then shift the two bits (+ve edge and -ve > edge) into your shift register on the next +ve clock. > > > Currently I have a the DDR clock coming in my fpga and I not the clock > > so I can sample the DDR signal on the rising egde. > > Is that giving you a problem? > > Will
If your input clock is not on the global clock network you will be fighting 
with clock skew to the flops.  When your clock edges are happening with 
respect to the data at the flops becomes an utmost concern for you.

"nfirtaps" <lloyd.rochester@gmail.com> wrote in message 
news:1173383894.763347.110110@64g2000cwx.googlegroups.com...
>I am trying to deserialize a DDR signal in my Cyclone. For reasons I > won't go into the DDR clock comes in off a general purpose I/O pin. I > need a way of deserializing this signal, and want to increase the > frequency of the DDR clock by 2 so I can use rising edge flip-flops. > > 1.) Can I somehow drive a PLL with a general purpose I/O > 2.) Is there another way of deserializing the DDR signal. > > Currently I have a the DDR clock coming in my fpga and I not the clock > so I can sample the DDR signal on the rising egde. > > Thanks >
"nfirtaps" <lloyd.rochester@gmail.com> wrote in message 
news:1173403110.735187.326520@t69g2000cwt.googlegroups.com...
> The problem I am having maybe due to jitter. I am not sure. I am > running under 35 MHz, althougth I am using LVDS. I am sampling on the > rising and falling edge of the clock, and the deserializer needs to > take every 7 clocks (respective 14 bits) since it is DDR. When I look > at the output clk/7 that I generate by a simple counter (when counter > = 1-4 clk is high, when counter = 4-7 clk is low), I see that the duty > cycle changes by about 1 clock. It seems as though the counter misses > a beat or something of that nature.
If I understand what you're saying, it doesn't sound like it's anything to do with picking-up the falling-edges - surely your count-to-seven is only trigged off the positive edges anyway? Can you post some HDL for this? Will
Will here I have the entire serializer, it looks like a lot of code
but most all the lines are repeated. Just to clarify it desrialized 14
bits of a ddr signal. So every 7 clock cycles the 14-bit word is
latched.  Clk is the signal that is the clock that has a problem with
duty cycle, it is driven by toggler and toggler is driven by the
counter.  Thanks so much for you help. Having a group like this is
extremely valuable.

ENTITY ad9259deser IS
	-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
	PORT
	(
		dco : IN STD_LOGIC;
		fco : IN STD_LOGIC;
		sera : IN STD_LOGIC;
		serb : IN STD_LOGIC;
		serc : IN STD_LOGIC;
		serd : IN STD_LOGIC;
		cha : out STD_LOGIC_VECTOR(13 downto 0);
		chb : out STD_LOGIC_VECTOR(13 downto 0);
		chc : out STD_LOGIC_VECTOR(13 downto 0);
		chd : out STD_LOGIC_VECTOR(13 downto 0);
		clk : out STD_LOGIC
	);
	-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!

END ad9259deser;


--  Architecture Body

ARCHITECTURE ad9259deser_architecture OF ad9259deser IS

signal ba0,ba1,ba2,ba3,ba4,ba5,ba6,ba7,ba8,ba9,ba10,ba11,ba12,ba13 :
std_logic := '0';
signal
ba14,ba15,ba16,ba17,ba18,ba19,ba20,ba21,ba22,ba23,ba24,ba25,ba26,ba27 :
std_logic := '0';

signal bb0,bb1,bb2,bb3,bb4,bb5,bb6,bb7,bb8,bb9,bb10,bb11,bb12,bb13 :
std_logic := '0';
signal
bb14,bb15,bb16,bb17,bb18,bb19,bb20,bb21,bb22,bb23,bb24,bb25,bb26,bb27 :
std_logic := '0';

signal chat,chbt : std_logic_vector(13 downto 0);

signal count_dco : unsigned(4 downto 0) := (others=>'0');
signal count_fco : unsigned(4 downto 0) := (others=>'0');
signal toggler : std_logic := '0';
signal go : std_logic := '0';
signal test : std_logic;

BEGIN

process(fco)
begin
	if(fco'event and fco='1') then
		go <= '1';
	end if;
end process;

process(dco)
begin
	if (dco'event and dco = '1' and go = '1') then
		count_dco <= count_dco+1;
		chd <= "000000000" & std_logic_vector(count_dco);
		chc <= "000000000" & std_logic_vector(count_fco);
		clk <= toggler;
		if (count_dco = 13) then  -- every 14 cycles a new word is latched
			chat(13) <= ba27;
			chat(12) <= ba26;
			chat(11) <= ba25;
			chat(10) <= ba24;
			chat( 9) <= ba23;
			chat( 8) <= ba22;
			chat( 7) <= ba21;
			chat( 6) <= ba20;
			chat( 5) <= ba19;
			chat( 4) <= ba18;
			chat( 3) <= ba17;
			chat( 2) <= ba16;
			chat( 1) <= ba15;
			chat( 0) <= ba14;

			chbt(13) <= bb27;
			chbt(12) <= bb26;
			chbt(11) <= bb25;
			chbt(10) <= bb24;
			chbt( 9) <= bb23;
			chbt( 8) <= bb22;
			chbt( 7) <= bb21;
			chbt( 6) <= bb20;
			chbt( 5) <= bb19;
			chbt( 4) <= bb18;
			chbt( 3) <= bb17;
			chbt( 2) <= bb16;
			chbt( 1) <= bb15;
			chbt( 0) <= bb14;

			cha <= not chat(13) & chat(12 downto 0);
			chb <= not chbt(13) & chbt(12 downto 0);

			toggler <= '1';
			count_dco <= "00000";
		elsif (count_dco = 4) then
			toggler <= '0';
		end if;
	end if;
end process;

process(dco)
begin
	if(dco'event and dco = '1') then
		ba1  <= sera;
		ba3  <= ba1;
		ba5  <= ba3;
		ba7  <= ba5;
		ba9  <= ba7;
		ba11 <= ba9;
		ba13 <= ba11;
		ba15 <= ba13;
		ba17 <= ba15;
		ba19 <= ba17;
		ba21 <= ba19;
		ba23 <= ba21;
		ba25 <= ba23;
		ba27 <= ba25;

		bb1  <= serb;
		bb3  <= bb1;
		bb5  <= bb3;
		bb7  <= bb5;
		bb9  <= bb7;
		bb11 <= bb9;
		bb13 <= bb11;
		bb15 <= bb13;
		bb17 <= bb15;
		bb19 <= bb17;
		bb21 <= bb19;
		bb23 <= bb21;
		bb25 <= bb23;
		bb27 <= bb25;
	elsif(dco'event and dco = '0') then
		ba0  <= sera;
		ba2  <= ba0;
		ba4  <= ba2;
		ba6  <= ba4;
		ba8  <= ba6;
		ba10 <= ba8;
		ba12 <= ba10;
		ba14 <= ba12;
		ba16 <= ba14;
		ba18 <= ba16;
		ba20 <= ba18;
		ba22 <= ba20;
		ba24 <= ba22;
		ba26 <= ba24;

		bb0  <= serb;
		bb2  <= bb0;
		bb4  <= bb2;
		bb6  <= bb4;
		bb8  <= bb6;
		bb10 <= bb8;
		bb12 <= bb10;
		bb14 <= bb12;
		bb16 <= bb14;
		bb18 <= bb16;
		bb20 <= bb18;
		bb22 <= bb20;
		bb24 <= bb22;
		bb26 <= bb24;
	end if;
end process;

END ad9259deser_architecture;

On Mar 9, 5:55 am, "Will Dean" <w...@nospam.demon.co.uk> wrote:
> "nfirtaps" <lloyd.roches...@gmail.com> wrote in message > > news:1173403110.735187.326520@t69g2000cwt.googlegroups.com... > > > The problem I am having maybe due to jitter. I am not sure. I am > > running under 35 MHz, althougth I am using LVDS. I am sampling on the > > rising and falling edge of the clock, and the deserializer needs to > > take every 7 clocks (respective 14 bits) since it is DDR. When I look > > at the output clk/7 that I generate by a simple counter (when counter > > = 1-4 clk is high, when counter = 4-7 clk is low), I see that the duty > > cycle changes by about 1 clock. It seems as though the counter misses > > a beat or something of that nature. > > If I understand what you're saying, it doesn't sound like it's anything to > do with picking-up the falling-edges - surely your count-to-seven is only > trigged off the positive edges anyway? > > Can you post some HDL for this? > > Will
On Mar 8, 9:27 pm, "Rob" <robns...@frontiernet.net> wrote:
> If your input clock is not on the global clock network you will be fighting > with clock skew to the flops. When your clock edges are happening with > respect to the data at the flops becomes an utmost concern for you. > > "nfirtaps" <lloyd.roches...@gmail.com> wrote in message
> > news:1173383894.763347.110110@64g2000cwx.googlegroups.com... > > >I am trying to deserialize a DDR signal in my Cyclone. For reasons I > > won't go into the DDR clock comes in off a general purpose I/O pin. I > > need a way of deserializing this signal, and want to increase the > > frequency of the DDR clock by 2 so I can use rising edge flip-flops. > > > 1.) Can I somehow drive a PLL with a general purpose I/O > > 2.) Is there another way of deserializing the DDR signal. > > > Currently I have a the DDR clock coming in my fpga and I not the clock > > so I can sample the DDR signal on the rising egde. > > > Thanks
As for the clock not being part of the global clock network, Quartus gives me the following message "Info: Automatically promoted signal "dco" to use Global clock in PIN 29" so I guess my clock is put into the global network.
"nfirtaps" <lloyd.rochester@gmail.com> wrote in message 
news:1173456025.129640.67790@h3g2000cwc.googlegroups.com...

> Will here I have the entire serializer, it looks like a lot of code > but most all the lines are repeated. Just to clarify it desrialized 14 > bits of a ddr signal. So every 7 clock cycles the 14-bit word is > latched. Clk is the signal that is the clock that has a problem with > duty cycle, it is driven by toggler and toggler is driven by the > counter. Thanks so much for you help. Having a group like this is > extremely valuable.
It would be even more valuable if I was a VHDL person rather than a Verilog one, but it does appear that you're trying to count to 14, when I think I would be trying to count to 7, and dealing with two bits on every count. So you'd have one bit of code which just samples the data on the negative edge of the clock and stores it, and another bit which works on the positive edge of the block, samples one bit and stores BOTH bits into your shift register on each positive edge. Like I say, I'm not a VHDL person, but I suspect there is a rather neater way to write that code - hopefully someone else might offer some advice. You're also assigning to count_dco in two places when it's equal to 13 - I don't know how that gets synthesised in VHDL, but it's the kind of thing I avoid. Is this your original code or did you lift it from somewhere else? Have you tried a functional simulation of this? (In Modelsim or ActiveHDL, for example?) I don't really think you're doing anything terribly ambitious, and it's perhaps a bit early to be worrying about jitter and PLLs at this stage. (Don't be distracted by the efforts people make to get DDR266 interfaces working - that's a completely different type of problem.) Will
On Mar 9, 9:25 am, "Will Dean" <w...@nospam.demon.co.uk> wrote:
> "nfirtaps" <lloyd.roches...@gmail.com> wrote in message > > news:1173456025.129640.67790@h3g2000cwc.googlegroups.com... > > > Will here I have the entire serializer, it looks like a lot of code > > but most all the lines are repeated. Just to clarify it desrialized 14 > > bits of a ddr signal. So every 7 clock cycles the 14-bit word is > > latched. Clk is the signal that is the clock that has a problem with > > duty cycle, it is driven by toggler and toggler is driven by the > > counter. Thanks so much for you help. Having a group like this is > > extremely valuable. > > It would be even more valuable if I was a VHDL person rather than a Verilog > one, but it does appear that you're trying > to count to 14, when I think I would be trying to count to 7, and dealing > with two bits on every count. > > So you'd have one bit of code which just samples the data on the negative > edge of the clock and stores it, and another bit which works on the positive > edge of the block, samples one bit and stores BOTH bits into your shift > register on each positive edge. > > Like I say, I'm not a VHDL person, but I suspect there is a rather neater > way to write that code - hopefully someone else might offer some advice. > > You're also assigning to count_dco in two places when it's equal to 13 - I > don't know how that gets synthesised in VHDL, but it's the kind of thing I > avoid. > > Is this your original code or did you lift it from somewhere else? > > Have you tried a functional simulation of this? (In Modelsim or ActiveHDL, > for example?) > > I don't really think you're doing anything terribly ambitious, and it's > perhaps a bit early to be worrying about jitter and PLLs at this stage. > (Don't be distracted by the efforts people make to get DDR266 interfaces > working - that's a completely different type of problem.) > > Will
Will I did make a cleaner version with no counters: here it is. ENTITY ad9259deser IS -- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! PORT ( dco : IN STD_LOGIC; fco : IN STD_LOGIC; sera : IN STD_LOGIC; serb : IN STD_LOGIC; serc : IN STD_LOGIC; serd : IN STD_LOGIC; cha : out STD_LOGIC_VECTOR(13 downto 0); chb : out STD_LOGIC_VECTOR(13 downto 0); chc : out STD_LOGIC_VECTOR(13 downto 0); chd : out STD_LOGIC_VECTOR(13 downto 0); clk : out STD_LOGIC ); -- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! END ad9259deser; -- Architecture Body ARCHITECTURE ad9259deser_architecture OF ad9259deser IS signal dco_plus, dco_minus : std_logic; signal ba0,ba1,ba2,ba3,ba4,ba5,ba6,ba7,ba8,ba9,ba10,ba11,ba12,ba13 : std_logic := '0'; signal ba14,ba15,ba16,ba17,ba18,ba19,ba20,ba21,ba22,ba23,ba24,ba25,ba26,ba27 : std_logic := '0'; signal bb0,bb1,bb2,bb3,bb4,bb5,bb6,bb7,bb8,bb9,bb10,bb11,bb12,bb13 : std_logic := '0'; signal bb14,bb15,bb16,bb17,bb18,bb19,bb20,bb21,bb22,bb23,bb24,bb25,bb26,bb27 : std_logic := '0'; signal chat,chbt : std_logic_vector(13 downto 0); signal count_dco : unsigned(4 downto 0) := (others=>'0'); signal count_fco : unsigned(4 downto 0) := (others=>'0'); signal toggler : std_logic := '0'; signal go : std_logic := '0'; signal test : std_logic; BEGIN clk <= fco; process(fco) begin if (fco'event and fco = '1') then go <= '1'; chd <= "00000000000000"; chc <= "00000000000000"; chat(13) <= ba27; chat(12) <= ba26; chat(11) <= ba25; chat(10) <= ba24; chat( 9) <= ba23; chat( 8) <= ba22; chat( 7) <= ba21; chat( 6) <= ba20; chat( 5) <= ba19; chat( 4) <= ba18; chat( 3) <= ba17; chat( 2) <= ba16; chat( 1) <= ba15; chat( 0) <= ba14; chbt(13) <= bb27; chbt(12) <= bb26; chbt(11) <= bb25; chbt(10) <= bb24; chbt( 9) <= bb23; chbt( 8) <= bb22; chbt( 7) <= bb21; chbt( 6) <= bb20; chbt( 5) <= bb19; chbt( 4) <= bb18; chbt( 3) <= bb17; chbt( 2) <= bb16; chbt( 1) <= bb15; chbt( 0) <= bb14; cha <= not chat(13) & chat(12 downto 0); chb <= not chbt(13) & chbt(12 downto 0); end if; end process; process(dco) begin if(dco'event and dco = '1' and go = '1') then count_dco <= count_dco + 1; ba1 <= count_dco(3); ba3 <= ba1; ba5 <= ba3; ba7 <= ba5; ba9 <= ba7; ba11 <= ba9; ba13 <= ba11; ba15 <= ba13; ba17 <= ba15; ba19 <= ba17; ba21 <= ba19; ba23 <= ba21; ba25 <= ba23; ba27 <= ba25; bb1 <= serb; bb3 <= bb1; bb5 <= bb3; bb7 <= bb5; bb9 <= bb7; bb11 <= bb9; bb13 <= bb11; bb15 <= bb13; bb17 <= bb15; bb19 <= bb17; bb21 <= bb19; bb23 <= bb21; bb25 <= bb23; bb27 <= bb25; elsif(dco'event and dco = '0' and go = '1') then ba0 <= sera; ba2 <= ba0; ba4 <= ba2; ba6 <= ba4; ba8 <= ba6; ba10 <= ba8; ba12 <= ba10; ba14 <= ba12; ba16 <= ba14; ba18 <= ba16; ba20 <= ba18; ba22 <= ba20; ba24 <= ba22; ba26 <= ba24; bb0 <= serb; bb2 <= bb0; bb4 <= bb2; bb6 <= bb4; bb8 <= bb6; bb10 <= bb8; bb12 <= bb10; bb14 <= bb12; bb16 <= bb14; bb18 <= bb16; bb20 <= bb18; bb22 <= bb20; bb24 <= bb22; bb26 <= bb24; end if; end process; END ad9259deser_architecture;
Have you read chapter 10 in the Cyclone Device Handbook?  "Implementing 
Double Data Rate I/O Signaling Cyclone Devices" You are using a Cyclone and 
not Cyclone2, correct?


"nfirtaps" <lloyd.rochester@gmail.com> wrote in message 
news:1173457175.663323.155840@j27g2000cwj.googlegroups.com...
> On Mar 8, 9:27 pm, "Rob" <robns...@frontiernet.net> wrote: >> If your input clock is not on the global clock network you will be >> fighting >> with clock skew to the flops. When your clock edges are happening with >> respect to the data at the flops becomes an utmost concern for you. >> >> "nfirtaps" <lloyd.roches...@gmail.com> wrote in message > > > >> >> news:1173383894.763347.110110@64g2000cwx.googlegroups.com... >> >> >I am trying to deserialize a DDR signal in my Cyclone. For reasons I >> > won't go into the DDR clock comes in off a general purpose I/O pin. I >> > need a way of deserializing this signal, and want to increase the >> > frequency of the DDR clock by 2 so I can use rising edge flip-flops. >> >> > 1.) Can I somehow drive a PLL with a general purpose I/O >> > 2.) Is there another way of deserializing the DDR signal. >> >> > Currently I have a the DDR clock coming in my fpga and I not the clock >> > so I can sample the DDR signal on the rising egde. >> >> > Thanks > > As for the clock not being part of the global clock network, Quartus > gives me the following message "Info: Automatically promoted signal > "dco" to use Global clock in PIN 29" so I guess my clock is put into > the global network. >