I'm trying to produce a square wave clock that is a fifth of the
frequency of a faster clock. This means that I must use both the falling
edge and rising of the clock. XST complains "Signal cnt cannot be
synthesized, bad synchronous description.", I have since learned that I
can only have one event per process.
How do I produce a counter that counts on both clock edges?
Regards
Andrew
entity div5 is
port (
clk : in std_logic;
q : out std_logic);
end div5;
architecture div5_arch of div5 is
signal cnt : std_logic_vector (2 downto 0) := "000";
begin
process (clk)
begin
if(clk'event and clk = '0')then
if(cnt = "110") then
cnt <= "000";
else
cnt <= cnt + 1;
end if;
end if;
if(clk'event and clk = '1')then
if(cnt = "010") then
cnt <= "100";
else
cnt <= cnt;
end if;
end if;
end process;
q <= cnt(2);
end div5_arch;
--
Spartan3 configuration JTAG download tool for GNU/Linux available from
http://www.rogerstech.co.uk/xc3sprog/
Counter counting on both clock edges.
Started by ●August 28, 2004
Reply by ●August 28, 20042004-08-28
Andrew Rogers wrote:> > I'm trying to produce a square wave clock that is a fifth of the > frequency of a faster clock. This means that I must use both the falling > edge and rising of the clock. XST complains "Signal cnt cannot be > synthesized, bad synchronous description.", I have since learned that I > can only have one event per process. > > How do I produce a counter that counts on both clock edges? > > Regards > Andrew > > entity div5 is > port ( > clk : in std_logic; > q : out std_logic); > end div5; > > architecture div5_arch of div5 is > signal cnt : std_logic_vector (2 downto 0) := "000"; > > begin > process (clk) > begin > if(clk'event and clk = '0')then > if(cnt = "110") then > cnt <= "000"; > else > cnt <= cnt + 1; > end if; > end if; > if(clk'event and clk = '1')then > if(cnt = "010") then > cnt <= "100"; > else > cnt <= cnt; > end if; > end if; > end process; > q <= cnt(2); > end div5_arch;This program is trying to describe something that can not be built using standard elements found inside an FPGA. Instead of trying to think in VHDL, try thinking in terms of the logic. Forget the code for a moment and figure out what logic would be generated to do what you want. I can think of three ways to do what you want. One is to use a clock that is twice the frequency (generated in a PLL/DLL in the FPGA). Your design is a bit unusual in that you do different things on the rising and falling edges of the original clock. You will need to reference this clock to distinguish the two actions. A second way is to use both a rising edge triggered register and a falling edge register, each a function of the other. Your logic will need to change from what you have above. The third is to use two registers, but one logic path with a MUX in the front to switch registers as required by your function definition. Since this is a very odd function to be implementing as part of a job, I assume it is a homework assignment. So I won't give any more details... But the main idea is to use VHDL to describe your logic... *AFTER* you have figured out what it must be. Don't try to code your problem without having a solution in mind. -- Rick "rickman" Collins rick.collins@XYarius.com Ignore the reply address. To email me use the above address with the XY removed. Arius - A Signal Processing Solutions Company Specializing in DSP and FPGA design URL http://www.arius.com 4 King Ave 301-682-7772 Voice Frederick, MD 21701-3110 301-682-7666 FAX
Reply by ●August 28, 20042004-08-28
Hi Andrew In real hardware the trick is to use a 5-stage shift register with an inverter between the output of the last stage and the input of the first stage. This should be easy to implement in VHDL. Mogens Pelle "Andrew Rogers" <andrew@_NO_SPAM_rogerstech.co.uk> skrev i en meddelelse news:4130963b$1_1@127.0.0.1...> I'm trying to produce a square wave clock that is a fifth of the > frequency of a faster clock. This means that I must use both the falling > edge and rising of the clock. XST complains "Signal cnt cannot be > synthesized, bad synchronous description.", I have since learned that I > can only have one event per process. > > How do I produce a counter that counts on both clock edges? > > Regards > Andrew > > > > entity div5 is > port ( > clk : in std_logic; > q : out std_logic); > end div5; > > architecture div5_arch of div5 is > signal cnt : std_logic_vector (2 downto 0) := "000"; > > begin > process (clk) > begin > if(clk'event and clk = '0')then > if(cnt = "110") then > cnt <= "000"; > else > cnt <= cnt + 1; > end if; > end if; > if(clk'event and clk = '1')then > if(cnt = "010") then > cnt <= "100"; > else > cnt <= cnt; > end if; > end if; > end process; > q <= cnt(2); > end div5_arch; > > -- > Spartan3 configuration JTAG download tool for GNU/Linux available from > http://www.rogerstech.co.uk/xc3sprog/ >
Reply by ●August 28, 20042004-08-28
rickman <spamgoeshere4@yahoo.com> wrote in message news:<4130AEF9.BF3AD39D@yahoo.com>...> Since this is a very odd function to be implementing as part of a job, I > assume it is a homework assignment. So I won't give any more > details...I see this sort of answer a lot on this forum and, while I agree that we don't need to be doing someone's homework, do we really need to make this sort of statement? It's condescending and really unnecessary. If you don't want to give details, just leave them out. Let's give folks the benefit of the doubt and maybe we won't scare people away. I -have- had to implement this sort of thing as part of a job (more than once, in fact). Another way to do this (depending on what you really need) is to construct a /10 signal, delay it by 2.5 cycles (using a neg-triggered FF) and XOR it with the undelayed version. If the freq. of the input is high enough to allow you to use the on-chip DLL (if you're using an FPGA with one), many DLLs will do a divide-by-5. Jake
Reply by ●August 28, 20042004-08-28
"mep" <mpe@metanic.dk> wrote in message news:4130c30c$0$287$edfadb0f@dread14.news.tele.dk...> Hi Andrew > In real hardware the trick is to use a 5-stage shift register with an > inverter between the output of the last stage and the input of the first > stage. This should be easy to implement in VHDL. > Mogens Pelle >Mogens - That gives you a /10, not /5 (assuming you start with all 5 FFs in the same state). But he could use your 5-stage shift register + inverter if he initialized it to "00011". Then delay the shift register output (any stage will work) 1/2 cycle and OR it with the undelayed output to create a 50% duty cycle /5 clock. Without a 2x clock I don't think there's any way to avoid a 1/2 cycle delay someplace plus a gate. Another poster (Jake) suggested a /10 signal delayed 2 1/2 cycles then XORed with the undelayed output. Same idea. RJS
Reply by ●August 29, 20042004-08-29
Thanks for all the suggestions, they are valuable ideas that I will use
for similar problems.
However, I needed a divide by 2.5 in the end. A divide by 5 is simple
once you have a divide by 2.5. I wrote the following code:
library IEEE;
use IEEE.std_logic_1164.all; -- defines std_logic types
use IEEE.std_logic_unsigned.all;
--- Divide by 2.5 counter ---
entity div2p5 is
port (
clk : in std_logic;
q : out std_logic);
end div2p5;
architecture div2p5_arch of div2p5 is
signal cnt0 : std_logic_vector (2 downto 0) := "000";
signal cnt1 : std_logic_vector (2 downto 0) := "000";
signal q0 : std_logic;
signal q1 : std_logic;
begin
q <= q0 and q1;
process (clk)
begin
if(clk'event and clk = '0')then
if(cnt1 = "000") then
q0 <= '1';
end if;
if(cnt1 = "100") then
cnt0 <= "000";
q0 <= '0';
else
cnt0 <= cnt1 + 1;
end if;
end if;
end process;
process (clk)
begin
if(clk'event and clk = '1')then
cnt1 <= cnt0;
if(cnt0 = "010")then
q1 <= '0';
elsif(cnt0 = "011")then
q1 <= '1';
end if;
end if;
end process;
end div2p5_arch;
----------------------------
I needed a 20MHz clock on the Xilinx Spartan3 kit which has a 50MHz crystal.
Regards
Andrew
--
Spartan3 configuration JTAG download tool for GNU/Linux available from
http://www.rogerstech.co.uk/xc3sprog/
Reply by ●August 29, 20042004-08-29
Robert Sefton wrote:> But he could use your 5-stage shift register + inverter if he initialized it > to "00011". Then delay the shift register output (any stage will work) 1/2 > cycle and OR it with the undelayed output to create a 50% duty cycle /5 > clock.The shift register gives you a /10 signal, right? I don't see how you generate the 50% duty cycle /5 clock from this by delaying 1/2 cycle and ORing it with undelayed output? Can you elaborate a bit? I think Jake's suggestion makes sense, you generate a /10 clock and delay it 2.5 cycles (in the faster domain) which corresponds to 2.5/10 = 1/4 cycle delay in the slower domain. By XORing two clocks with 1/4 cycle offset you get the double frequency with 50% duty cycle, in this case a /5 clock. -JS-
Reply by ●August 29, 20042004-08-29
Jake Janovetz wrote:> > rickman <spamgoeshere4@yahoo.com> wrote in message news:<4130AEF9.BF3AD39D@yahoo.com>... > > Since this is a very odd function to be implementing as part of a job, I > > assume it is a homework assignment. So I won't give any more > > details... > > I see this sort of answer a lot on this forum and, while I agree that > we don't need to be doing someone's homework, do we really need to > make this sort of statement? It's condescending and really > unnecessary. If you don't want to give details, just leave them out. > Let's give folks the benefit of the doubt and maybe we won't scare > people away.Condescending it may be, but if I don't explain why I am leaving out details, then he won't be able to correct me if I am wrong. -- Rick "rickman" Collins rick.collins@XYarius.com Ignore the reply address. To email me use the above address with the XY removed. Arius - A Signal Processing Solutions Company Specializing in DSP and FPGA design URL http://www.arius.com 4 King Ave 301-682-7772 Voice Frederick, MD 21701-3110 301-682-7666 FAX
Reply by ●August 29, 20042004-08-29
Logically, this will work. But you don't need two counters, just one will do. Like another someone suggested, this algorithm generates two waveforms, each a divide by five, with a 2.5 clock phase shift. The results are ANDed to produce a waveform which is a divide by 2.5. Remove cnt0, make everything a function of cnt1 and you will get the same results. Notice that the result will not be square (50%/50% duty cycle). I believe this is what was originally requested. Andrew Rogers wrote:> > Thanks for all the suggestions, they are valuable ideas that I will use > for similar problems. > > However, I needed a divide by 2.5 in the end. A divide by 5 is simple > once you have a divide by 2.5. I wrote the following code: > > library IEEE; > use IEEE.std_logic_1164.all; -- defines std_logic types > use IEEE.std_logic_unsigned.all; > > --- Divide by 2.5 counter --- > entity div2p5 is > port ( > clk : in std_logic; > q : out std_logic); > end div2p5; > > architecture div2p5_arch of div2p5 is > signal cnt0 : std_logic_vector (2 downto 0) := "000"; > signal cnt1 : std_logic_vector (2 downto 0) := "000"; > signal q0 : std_logic; > signal q1 : std_logic; > > begin > > q <= q0 and q1; > > process (clk) > begin > if(clk'event and clk = '0')then > if(cnt1 = "000") then > q0 <= '1'; > end if; > if(cnt1 = "100") then > cnt0 <= "000"; > q0 <= '0'; > else > cnt0 <= cnt1 + 1; > end if; > end if; > end process; > > process (clk) > begin > if(clk'event and clk = '1')then > cnt1 <= cnt0; > if(cnt0 = "010")then > q1 <= '0'; > elsif(cnt0 = "011")then > q1 <= '1'; > end if; > end if; > end process; > > end div2p5_arch; > ---------------------------- > > I needed a 20MHz clock on the Xilinx Spartan3 kit which has a 50MHz crystal. > > Regards > Andrew > -- > Spartan3 configuration JTAG download tool for GNU/Linux available from > http://www.rogerstech.co.uk/xc3sprog/-- Rick "rickman" Collins rick.collins@XYarius.com Ignore the reply address. To email me use the above address with the XY removed. Arius - A Signal Processing Solutions Company Specializing in DSP and FPGA design URL http://www.arius.com 4 King Ave 301-682-7772 Voice Frederick, MD 21701-3110 301-682-7666 FAX
Reply by ●August 29, 20042004-08-29
Andrew, To easiest way generate a 20 Mhz clock signal on the Spartan-3 starter kit from the 50 Mhz osc would be to use the DCM. Is there any reason you have not considered that? Shalin- Andrew Rogers wrote:> Thanks for all the suggestions, they are valuable ideas that I will use > for similar problems. > > However, I needed a divide by 2.5 in the end. A divide by 5 is simple > once you have a divide by 2.5. I wrote the following code: > > library IEEE; > use IEEE.std_logic_1164.all; -- defines std_logic types > use IEEE.std_logic_unsigned.all; > > --- Divide by 2.5 counter --- > entity div2p5 is > port ( > clk : in std_logic; > q : out std_logic); > end div2p5; > > architecture div2p5_arch of div2p5 is > signal cnt0 : std_logic_vector (2 downto 0) := "000"; > signal cnt1 : std_logic_vector (2 downto 0) := "000"; > signal q0 : std_logic; > signal q1 : std_logic; > > begin > > q <= q0 and q1; > > process (clk) > begin > if(clk'event and clk = '0')then > if(cnt1 = "000") then > q0 <= '1'; > end if; > if(cnt1 = "100") then > cnt0 <= "000"; > q0 <= '0'; > else > cnt0 <= cnt1 + 1; > end if; > end if; > end process; > > process (clk) > begin > if(clk'event and clk = '1')then > cnt1 <= cnt0; > if(cnt0 = "010")then > q1 <= '0'; > elsif(cnt0 = "011")then > q1 <= '1'; > end if; > end if; > end process; > > end div2p5_arch; > ---------------------------- > > I needed a 20MHz clock on the Xilinx Spartan3 kit which has a 50MHz > crystal. > > Regards > Andrew





