Counter Issue on FPGA and CPLD

B

BC

I am new to VHDL and I have a couple of boards that I am experimenting
with using Xilinx ISE 7.1

One is the Spartan-3 board from Digilent which has an XC3S200 FPGA on
it and 50MHz oscillator, the other is a board I made with a Xilinx
XC9572 84 pin CPLD on it and a 10MHz oscillator.

With either board I can successfuly create schematic based asynchronous
counters using D type flipflops to divide the clocks down. On the S3
board I can also write code such as this to create a divide by 10.

entity div10 is
Port ( clock_in : in std_logic;
clock_out : out std_logic);
end div10;

architecture Behavioral of div10 is
signal cnt: std_logic_vector(3 downto 0):="0001";
signal clktemp : std_logic:='0';
begin
process (clock_in) --sensitivity only to clock_in
begin
if (clock_in'event and clock_in = '1') then
cnt <= cnt + '1';
if (cnt = "0101") then
cnt <= "0001";
clktemp <= not clktemp;
end if;
end if;
end process;
clock_out <= clktemp;
end Behavioral;


HOWEVER, this code does not work on the CPLD board the output is close
to a divide by 2, but not completely regular. I have also tried a
schematic design for a synchronous divide by 10, however that doesnt
work in the CPLD either.

I'm sure its something obvious that I'm missing, something to do with
the clocks on the CPLD maybe???

Thanks
BC
NZ
 
J

Jonathan Bromley

I am new to VHDL and I have a couple of boards that I am experimenting
with using Xilinx ISE 7.1

One is the Spartan-3 board from Digilent which has an XC3S200 FPGA on
it and 50MHz oscillator, the other is a board I made with a Xilinx
XC9572 84 pin CPLD on it and a 10MHz oscillator.

With either board I can successfuly create schematic based asynchronous
counters using D type flipflops to divide the clocks down. On the S3
board I can also write code such as this to create a divide by 10. [...]

HOWEVER, this code does not work on the CPLD board the output is close
to a divide by 2, but not completely regular. I have also tried a
schematic design for a synchronous divide by 10, however that doesnt
work in the CPLD either.

I'm sure its something obvious that I'm missing, something to do with
the clocks on the CPLD maybe???

No guarantees of course, but in my experience this is usually caused
by one of two problems:

1) Check this first because it's easy to fix:
Is your clock input really going to one of the CPLD's dedicated clock
input pins? If not, you may have issues about the timing of clock
signal distribution that give rise to hold time violations. This
can easily make counters and other synchronous logic go
horribly wrong, even with a slow clock.

2) This one is more likely to be the problem, but more work to fix:
Your CPLD board is "home-made", yes? Then I suspect the
problem may be related to ground integrity ("ground bounce").
CPLD outputs are pretty brutal things; they can drive large amounts
of current with very rapid rising and falling edges. If these outputs
are driving something with significant capacitance (for example,
a cheap-and-nasty x1 'scope probe, or a long piece of wiring) then
the current pulse that flows in the GROUND pins of the CPLD as
the result of 1->0 output transitions can be very large and very
fast. The ground wiring, if it's not a solid ground plane on
a PCB, will have inductance; rapid current changes flowing
in this inductance will cause voltage spikes on the ground
pins of the CPLD. I have often seen this effect give rise to
spurious clocking of a device. It used to be a terrible problem
when students used CMOS GAL22V10 devices for experiments,
and they put them on stripboard. Combinatorial logic worked
beautifully, clocked logic was almost always broken.

The only truly reliable solution to (2) is a PCB with a
really good ground plane. However, you can go a long
way to fixing it by adding small resistors (50 to 100 ohm)
in series with each output pin of the CPLD, TAKING GREAT
CARE TO PUT THE RESISTORS AS CLOSE TO THE PIN
AS POSSIBLE. In this way, the currents flowing in each
output are limited - it's a crude way of restricting the
output slew rate and isolating the outputs from any
large capacitive load.

Please forgive me if this is a red herring!
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
P

Peter

BC skrev:
I am new to VHDL and I have a couple of boards that I am experimenting
with using Xilinx ISE 7.1

One is the Spartan-3 board from Digilent which has an XC3S200 FPGA on
it and 50MHz oscillator, the other is a board I made with a Xilinx
XC9572 84 pin CPLD on it and a 10MHz oscillator.

With either board I can successfuly create schematic based asynchronous
counters using D type flipflops to divide the clocks down. On the S3
board I can also write code such as this to create a divide by 10.

entity div10 is
Port ( clock_in : in std_logic;
clock_out : out std_logic);
end div10;

architecture Behavioral of div10 is
signal cnt: std_logic_vector(3 downto 0):="0001";
signal clktemp : std_logic:='0';
begin
process (clock_in) --sensitivity only to clock_in
begin
if (clock_in'event and clock_in = '1') then
cnt <= cnt + '1';
if (cnt = "0101") then
cnt <= "0001";
clktemp <= not clktemp;
end if;
end if;
end process;
clock_out <= clktemp;
end Behavioral;


HOWEVER, this code does not work on the CPLD board the output is close
to a divide by 2, but not completely regular. I have also tried a
schematic design for a synchronous divide by 10, however that doesnt
work in the CPLD either.

I'm sure its something obvious that I'm missing, something to do with
the clocks on the CPLD maybe???

Hi,

Your design needs a reset input to initialize the registers to a known
state.
The order in which you perform the test of the counter seems a bit
strange. Why not do it like the (untested) example below:

signal cnt : unsigned(2 downto 0); -- using ieee.numeric_std.all
.....
.....
cnt : process(clk_in,res) is

begin
if res = '1' then
cnt <= (others => '0');
clktemp <= '0';
elsif rising_edge(clk_in) then
if cnt = 4 then
cnt <= (others => '0');
clktemp <= not clktemp;
else
cnt <= cnt + 1;
end if;
end if;
end process;

/Peter
 
P

Peter

BC skrev:
I am new to VHDL and I have a couple of boards that I am experimenting
with using Xilinx ISE 7.1

One is the Spartan-3 board from Digilent which has an XC3S200 FPGA on
it and 50MHz oscillator, the other is a board I made with a Xilinx
XC9572 84 pin CPLD on it and a 10MHz oscillator.

With either board I can successfuly create schematic based asynchronous
counters using D type flipflops to divide the clocks down. On the S3
board I can also write code such as this to create a divide by 10.

entity div10 is
Port ( clock_in : in std_logic;
clock_out : out std_logic);
end div10;

architecture Behavioral of div10 is
signal cnt: std_logic_vector(3 downto 0):="0001";
signal clktemp : std_logic:='0';
begin
process (clock_in) --sensitivity only to clock_in
begin
if (clock_in'event and clock_in = '1') then
cnt <= cnt + '1';
if (cnt = "0101") then
cnt <= "0001";
clktemp <= not clktemp;
end if;
end if;
end process;
clock_out <= clktemp;
end Behavioral;


HOWEVER, this code does not work on the CPLD board the output is close
to a divide by 2, but not completely regular. I have also tried a
schematic design for a synchronous divide by 10, however that doesnt
work in the CPLD either.

I'm sure its something obvious that I'm missing, something to do with
the clocks on the CPLD maybe???

Hi,

Your design needs a reset input to initialize the registers to a known
state.
The order in which you perform the test of the counter seems a bit
strange. Why not do it like the (untested) example below:

signal cnt : unsigned(2 downto 0); -- using ieee.numeric_std.all
.....
.....
cnt : process(clk_in,res) is

begin
if res = '1' then
cnt <= (others => '0');
clktemp <= '0';
elsif rising_edge(clk_in) then
if cnt = 4 then
cnt <= (others => '0');
clktemp <= not clktemp;
else
cnt <= cnt + 1;
end if;
end if;
end process;

/Peter
 
R

Rtafas

Hello,

He has 2 concurrent statments: counter <= counter + '1' and when couter
reach it's compare value, it will be assigned again. Two assignments on
the same time. this is bogus. I cannot imagine what XST has implemented
on the working FPGA version.

Not using a reset is just a bad pratice, but it is not the source of
problem in this case (but simulator will disagree).

The use of std_logic_vector is ok. The problem is a classical error
about sequential and concurrent statement. A good reading about this
can be found with google.

Regards,

Ricardo

Peter escreveu:
 
J

Jonathan Bromley

Hello,

He has 2 concurrent statments: counter <= counter + '1' and when couter
reach it's compare value, it will be assigned again. Two assignments on
the same time. this is bogus.

Those statements aren't concurrent, they're sequential; the code
is fine (although, as has been pointed out, the lack of reset
is undesirable).

Gentle readers, take note: multiple assignments to a signal
in the same process are certainly NOT bogus; they're fine,
and allow you to describe various things much more
elegantly than you otherwise might.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
R

Rtafas

Hello,

IMHO, I disagree with that and I think that multiple assignments are
not good when using FPGAs (well, this is the "religion" field of design
pratices). I can't tell about the ASIC world.

This makes me question: when the counter reaches the compare value, it
is going to assign a value to counter OR increment it's actual value?
The sinthesizer will found what kind of digital logic to do this? The
tool may resolve that itself, and this may be not what he wants. This
case is singular because probably he wants to force a new value. I
think they wouldn't be concurrent within the same process if it was
something like:

Process(clk)
begin
if clk'event and clk = '1' then
if counter = "0101" then
counter <= "0001";
else
counter <= counter + '1';
end if;
end if;
end process;

Maybe the tool will find a logic and use the "preset". But I don't
think it is going to work all cases all the time.

Regards,
Ricardo

Jonathan Bromley escreveu:
 
R

Rtafas

In fact, XST implements it using a LOAD issue, according to "RTL
schematic tool", it is a counter with assynchronous logic to the load
input.


Rtafas escreveu:
 
R

Ralf Hildebrandt

Rtafas said:
IMHO, I disagree with that and I think that multiple assignments are
not good when using FPGAs (well, this is the "religion" field of design
pratices). I can't tell about the ASIC world.

It has nothing to do with FPGAs or ASICs. Multiple assignments are
independent from the target.

This makes me question: when the counter reaches the compare value, it
is going to assign a value to counter OR increment it's actual value?

It will updated with this value, what is the result of these multiple
assignments.
The sinthesizer will found what kind of digital logic to do this?

Yes, it will.

Multiple assignments are really helpful if you have a huge combinational
process where you want to avoid latches - e.g.:

process(s1,s2,s3,s4,s5,s6)
begin
out1<='0'; -- default to avoid latches
out2<='0'; -- default to avoid latches
if (s1='1' and s2='0') then
if (s6='0') then
out1<='1';
else
out1<=s3;
end if;
if (s4=s5) then
out2<='1';
end if;
end if;
end process;

As the if-branches grow the behavior becomes difficult to understand.
Default values makes it much easier to read.

For the synthesis tool this bunch of logic is a lookup-table with some
inputs and some outputs. It will simplify the logic equations (as you
have done with the Karnaugh table in your studies) and will output just
a bunch of gates. It will not build a multiplexer, that choses from the
default value and the other possible result.


And even during simulation the behavior is the same as if you would
avoid such multiple assignments. The simulator will assign a new value
to the signals when it processes the default statement. This value will
be assigned in the next delta delay. Then the simulator comes to a
deeper branch of the shown if-branches and assigns a new value to the
output. But the new assignment is done also in the next delta delay and
therefore at exactly the same time as the new default value would have
been assigned.
Remember - we talk about signals and not about variables / shared
variables or Verilog blocking assignments!


Ralf
 
R

Rtafas

Hello!

I got it. The "else" part of the IF is implemented this way. Never
tried it before. Must study more about it :p

Thnaks for your reply!

Regards

Ricardo


Ralf Hildebrandt escreveu:
 
P

Peter

Jonathan Bromley skrev:
No guarantees of course, but in my experience this is usually caused
by one of two problems:

1) Check this first because it's easy to fix:
Is your clock input really going to one of the CPLD's dedicated clock
input pins? > .....
2) This one is more likely to be the problem, but more work to fix:
Your CPLD board is "home-made", yes? Then I suspect the
problem may be related to ground integrity ("ground bounce").
.....
Jonathan Bromley, Consultant

Good comment. And dont forget decoupling...

/Peter
 
B

BC

Thank you all for your positive and helpful comments.
I rewrote the hdl to include a reset,
I added more decoupling under the board directly under the CPLD
and I soldered some heavier wires under the board from ground to the
ground pins,
it seems to be working very well now, all these contributed to my
problem
My next board will be double sided with decent ground plane!

With the reset t is just tied to '1' all the time in the VHDL so my
assumption is that having it causes the logic to power up in a stable
state even though it is never actually used????

I guess as I become more familiar with what is going on inside a
CPLD/FPGA I will understand what is happening with this.
thanks again
BC
NZ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top