Stupid Newby Question: VHDL/CPLD Shift Register Reset Problem

D

dhudson01

Let's say I'm building a simple 8-bit shift register (serial in,
parallel out) for a Xilinx XC2C256 CoolRunner-II CPLD. I am using the
Xilinx Webpack 8.1.03 running under Win XP Pro.

I have the 1.842 MHz system oscillator on my development board
disconnected from the CPLD. That is, no clock signal is running to the
IO_GCK2 clock input of the CPLD.

Is it okay to bring an external 125 kHz clock signal in on a general
purpose I/O line of the CPLD? This is the input that I am using to
clock my shift register.

The reason I'm asking is because I am having some reset problems when
shifting data on the falling edge of my 125 kHz clock. No reset
problems at all if I change a single line of code to shift from falling
edge to rising edge (see code below).

Someone told me (a Verilog guy, not a VHDL expert) that the problem
could be because I'm not using the "real" system clock as the clock for
my shift register. I could find no other reference that supported that
view. Any thoughts?

For anyone still reading, the details of my "reset problem" are as
follows:
Following a power cycle, I assert the Reset signal. I then clock in 8
bits of serial data at 125 kHz. The DataReady output signal is
asserted 1 cycle too soon (i.e. it is as if the Count variable is
initialized to '1' instead of '0' at Reset) and my DataOut is off by 1
bit position.

If the Reset signal is asserted again and data is clocked in, the
output is correct. Subsequent data clockings work as expected. The
problem only occurs after power cycling. It is as if I have to clock
in some data before the Reset works correctly after power cycling.

Interestingly, if I change the code to shift on the rising edge,
everything works correctly!

What am I doing wrong? Thanks in advance for any help!

Regards,
Doug

============
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity SerialToParallel is
generic(DATA_WIDTH: natural := 8);
Port ( Clock : in STD_LOGIC; -- 125 kHz shift
clock
SerialDataIn : in STD_LOGIC;
Reset : in STD_LOGIC;
DataReady : out STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (7 downto 0);
TestOut : out STD_LOGIC);
end SerialToParallel;

architecture Behavioral of SerialToParallel is
begin
process(Clock, Reset)
variable DataReg : STD_LOGIC_VECTOR (7 downto 0);
variable Count : integer range 0 to DATA_WIDTH;
begin
if (Reset = '1') then
DataReg := (others => '0');
Count := 0;
DataOut <= (others => '0');
DataReady <= '1';
TestOut <= '1';
-- elsif (rising_edge(Clock)) then
elsif (falling_edge(Clock)) then
DataReg := DataReg((DATA_WIDTH - 2) downto 0) & SerialDataIn;

Count := Count + 1;
if (Count = DATA_WIDTH) then
DataOut <= DataReg;
Count := 0;
DataReady <= '1';
TestOut <= '1';
else
DataReady <= '0';
TestOut <= '0';
end if;
end if;
end process;
end Behavioral;
 
K

KJ

Is it okay to bring an external 125 kHz clock signal in on a general
purpose I/O line of the CPLD? This is the input that I am using to
clock my shift register.

Don't think this should be an issue.
The reason I'm asking is because I am having some reset problems when
shifting data on the falling edge of my 125 kHz clock. No reset
problems at all if I change a single line of code to shift from falling
edge to rising edge (see code below).

Someone told me (a Verilog guy, not a VHDL expert) that the problem
could be because I'm not using the "real" system clock as the clock for
my shift register. I could find no other reference that supported that
view. Any thoughts?

Those Verilog guys....snicker
For anyone still reading, the details of my "reset problem" are as
follows:
Following a power cycle, I assert the Reset signal. I then clock in 8
bits of serial data at 125 kHz. The DataReady output signal is
asserted 1 cycle too soon (i.e. it is as if the Count variable is
initialized to '1' instead of '0' at Reset) and my DataOut is off by 1
bit position.

If the Reset signal is asserted again and data is clocked in, the
output is correct. Subsequent data clockings work as expected. The
problem only occurs after power cycling. It is as if I have to clock
in some data before the Reset works correctly after power cycling.

Interestingly, if I change the code to shift on the rising edge,
everything works correctly!

What am I doing wrong? Thanks in advance for any help!
Check the timing from when Reset switches from high to low for the
first time after power cycling and see where it is relative to the
clock and verify that it is meeting the setup time of both the rising
and falling edges of your clock....actually only the edge that you're
using at a given time is important but since you're reprogramming the
CPLD to switch clock sampling edges it needs to be far enough away from
both edges for it to work. I'm guessing that with a 125 KHz clock
though that this probably isn't the problem but worth checking.

Next look to see when that first falling edge after power up really is
occurring. The most likely explanation is that after reset has been
de-asserted (with the above mentioned appropriate setup time) that
you're getting a falling edge on your clock at a time when you're not
quite expecting. That would generate exactly the symptoms that you're
seeing. Also remember that any sort of glitch that can be interpreted
as a falling edge (i.e. something going from >2V to less than ~1.5 V)
can be causing the clocking.

Lastly, look at the signal quality on your clock and make sure that
both rising and falling edges are monotonic. Any sort hiccups in the
'gray zone' (i.e. 0.8 - 2.0 V....I'm assuming TTL logic levels on all
of this by the way) can cause unexpected clocking

KJ
 
D

dhudson01

KJ said:
Check the timing from when Reset switches from high to low for the
first time after power cycling and see where it is relative to the
clock and verify that it is meeting the setup time of both the rising
and falling edges of your clock....

Some background might be helpful. I'm trying to implement a Serial
Peripheral Interface (SPI) slave that would run on a CPLD and
communicate with a microcontroller. For testing, I have replaced the
micro with a SPI simulator tool that allows me transmit/receive SPI
data. Since I was having problems with the receive portion of my SPI
slave, I pulled out the serial to parallel shift register that was the
problem child and began focusing on it.

My Reset is asynchronous to my clock. I am manually resetting by
pressing a debounced button on my dev board. The serial clock isn't
running when I press the reset. The clock only generates 8 pulses when
I transmit with my SPI simulator tool. So the sequence is:

Power Up
Press Reset
Clock Data
Hit desk in frustration

Since I have both the clock and the reset in the process sensitivity
list, can the reset be asynchronous to the clock? Is that legal?

Thanks for your insights!

Doug
 
K

KJ

My Reset is asynchronous to my clock. I am manually resetting by
pressing a debounced button on my dev board. The serial clock isn't
running when I press the reset.

Then that would rule out a timing problem between reset being de-asserted
and either edge of the clock as the culprit. That leaves the case that
there is an unexpected falling edge/glitch on the clock as the likely
culprit.
The clock only generates 8 pulses when
I transmit with my SPI simulator tool.

Try modifying your source code to bring 'Count' out to observable pins.
Then you should be able to home in on just exactly where 'Count' is getting
set to 1 when you think it should be 0. Presumably at that point you'll
also see a falling edge or glitch on clock which caused the problem. If
not, then perhaps you have a bum part....but I'm leaning more towards the
clock falling.
Since I have both the clock and the reset in the process sensitivity
list, can the reset be asynchronous to the clock? Is that legal?
Yes, it's legal. The code you wrote looks fine.

KJ
 
B

Benjamin Todd

I'm interested in what was the cause of this problem...

- does the "default power up value of registers" value in ISE change the
function? (if it can be programmed for the XC2C)

- does the synthesiser complain about gated clocks, or the fact that you're
using a non dedicated clock net?

- do you have any wrapper around the component you posted or is that the top
level?

- is the delay from you releasing the push-button to the startup long enough
to be sure that there's no debounce issue?

personally i'd go for a different approach, but it would avoid the problem
rather than understand it: use the fast quartz clock, and detect rising
edges on your input signal.

detect_edges: process (clock, reset)
-- make a 2-bit shift register of sampled values of the 25kHz clock
blah

re125k <= delayed2 AND NOT delayed1;
use this as an enable.

Let us know how you get on.
Ben
 
D

dhudson01

Follow up:

I submitted a WebCase to Xilinx describing my problem and worked with
some others as well trying to resolve this issue. I ran behavioral and
post-fix simulations and they showed that the code should work as
intended. I modified the pin out so that instead of general I/O pins,
my clock and reset signals were connected to the GCK2 and GSR pins,
respectively, of the CPLD. Nothing seemed to help.

As I was running out of options, I decided to replace the board that I
was using as a SPI master with an Atmel AVR dev board that I had laying
around. I wrote a quick program that configured the AVR as the SPI
master and transmitted a byte of data. I connected the AVR board to my
Xilinx board and everything worked perfectly!

I have no idea why my original SPI master board didn't play nice. The
clock and data lines looked clean on the scope. Due to my project
schedule, I seriously doubt that I will have time to find out.

Thanks for taking the time to help me out on this problem.

Later,
Doug
 
D

Dave Higton

In message <[email protected]>
Follow up:

I submitted a WebCase to Xilinx describing my problem and worked with
some others as well trying to resolve this issue. I ran behavioral and
post-fix simulations and they showed that the code should work as
intended. I modified the pin out so that instead of general I/O pins,
my clock and reset signals were connected to the GCK2 and GSR pins,
respectively, of the CPLD. Nothing seemed to help.

As I was running out of options, I decided to replace the board that I
was using as a SPI master with an Atmel AVR dev board that I had laying
around. I wrote a quick program that configured the AVR as the SPI
master and transmitted a byte of data. I connected the AVR board to my
Xilinx board and everything worked perfectly!

I have no idea why my original SPI master board didn't play nice. The
clock and data lines looked clean on the scope. Due to my project
schedule, I seriously doubt that I will have time to find out.

You have to use a scope /and/ /probe/ system of sufficient bandwidth.
I often use a 400 megasamples per second 'scope to look at clock
waveforms, but it only shows up real problems when it's used in
equivalent time sampling mode, where the effective sample rate is
much higher. You really need to be looking with a bandwidth of at
least 1 GHz. And that's for devices that are still some way behind
the leading edge of technology.

For a probe, I usually use a 5k1 surface mount resistor on a 50 ohm
cable to the 'scope (which has 50 ohm termination turned on, of
course), with the earth braid kept to less than 1 cm.

If you use an observation system like that, you may discover all
sorts of overshoots, undershoots and multiple transitions. An all
too frequent problem is the clock signal reaching about 1.2 volts,
then changing direction momentarily (under 1 ns) before continuing
to complete its transition. The logic device has enough bandwidth
to see two transitions, in many cases - but, worst of all, you
can't guarantee that all the flip flops in the device will see
them.

If you use an observation system of too low a bandwidth, all this
detail is filtered out.

I exhort everybody to learn and understand transmission line
theory. Once you do, and apply all the remedies whose need then
becomes obvious, development life gets a whole lot easier.

Dave
 

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,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top