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
Driving PLL from general I/O in Altera Cyclone
Started by ●March 8, 2007
Reply by ●March 8, 20072007-03-08
"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/OI 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
Reply by ●March 8, 20072007-03-08
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
Reply by ●March 9, 20072007-03-09
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 >
Reply by ●March 9, 20072007-03-09
"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
Reply by ●March 9, 20072007-03-09
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
Reply by ●March 9, 20072007-03-09
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. > > > ThanksAs 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.
Reply by ●March 9, 20072007-03-09
"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
Reply by ●March 9, 20072007-03-09
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.) > > WillWill 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;
Reply by ●March 10, 20072007-03-10
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. >