Complex (bad) Behavior from Simple Shifter .. Need Help.

T

Tom Poliquin

Guest
Just when I think I am able to write a little
Verilog code, I get a wakeup call telling me
I don't know anything ..

I'm hoping that someone can tell me what I'm
doing wrong.

Overview
--------

I'm trying to get a small CPLD to read a FLASH
connected to it.

The address to read is clocked out serially from
a PC, via the parallel port to the CPLD.

The data at the specified address is clocked in,
again serially, via the parallel port, to the PC.

We are using a simple "rdN/wrN" protocol and 4 lines
on the PC parallel port, 1 for addresses out, 1 for
data in from the FLASH, and two handshakes (rdN, wrN).

It all works in the behavioral simulation and post-route
simulation but the shift register clocking out the data
fails on on the real hardware. The shift register for
the address works fine.

The scope says the outside world signals are not
particularly dirty.

The logic analyzer shows (when we pull out the
least significant 8 bits of the data shift register)
glitching and weirdness.

The failure mode totally consistent, quite compex,
yet elegant. It appears to validly read the byte from
FLASH and 'converts' it to another byte value as it gets
shifted out.

Examples:

Byte in Flash Reconstructed
Byte Read
at Pc

0xACCE 0x0F6E
0x0090 0x0050

Pardon my anthropomorphization but here's the algorithn
it appears to be following ..

1) Start at the rightmost bit and scan leftward for the first
'1' bit, leaving that bit and all the bits to the right intact.

2) Scan left again for the next '1' bit. When found
shift that '1' bit and all the bits to the left of it
right one.

3) Repeat step 3 until bit 15 is reached.


We have no system clock since the purpose of this
device is to read FLASHes from dead boards.

Ok, enough overview.


The Shift Register Verilog Code
-------------------------------


always @ (posedge data_rdN or posedge reset) begin
if (reset)
data_buffer[15:0] <= 16'b0;
else if (data_wrN == 1'b1)
data_buffer[15:0] <= flash_data_in[15:0];
else
data_buffer <= data_buffer >> 1;
end


Test Bench Fragment
-------------------



// wrN indicates the function of rdN
// if wrN==1, rdN posedge will latch the FLASH data
// if wrN==0, rdN posedge will shift the data right one

// latch the data from the FLASH

#(NORMAL_DELAY) data_wrN = 1'b1; // high forces rdn to latch
#(NORMAL_DELAY) flash_data_in = 16'h9876; // simulates the data in flash
#(NORMAL_DELAY) data_rdN = 1'b0;
#(NORMAL_DELAY) data_rdN = 1'b1; // this latches the data from the flash


// now drop data_wrN to show that data_rdN toggling should shift

#(NORMAL_DELAY) data_wrN = 1'b0; // low makes rdN edges shift data
#(NORMAL_DELAY) data_read_from_flash = 16'b0; // builds data from flash

i = 0;
repeat (16) begin

data_read_from_flash = data_out;

#(NORMAL_DELAY) data_rdN = 1'b0; // force a shift
#(NORMAL_DELAY) data_rdN = 1'b1;
i = i + 1;

end


Hopefully someone can tell me where I'm screwing up, and
include perhaps, some information on land prices in Idaho so I
can start potato farming.

Thanks in advance,

Tom
 
nospam <nospam@nospam.invalid> wrote in message news:<blb2ivo188ht72i7ccppithrcvo8lgdilo@4ax.com>...
poliquin@softcomp.com (Tom Poliquin) wrote:

The failure mode totally consistent, quite compex,
yet elegant. It appears to validly read the byte from
FLASH and 'converts' it to another byte value as it gets
shifted out.

Examples:

Byte in Flash Reconstructed
Byte Read
at Pc

0xACCE 0x0F6E
0x0090 0x0050

Pardon my anthropomorphization but here's the algorithn
it appears to be following ..

1) Start at the rightmost bit and scan leftward for the first
'1' bit, leaving that bit and all the bits to the right intact.

2) Scan left again for the next '1' bit. When found
shift that '1' bit and all the bits to the left of it
right one.

3) Repeat step 3 until bit 15 is reached.

Putting that another way for every 1 to 0 transition of the shift register
output insert an extra shift register clock?

I would guess in hardware you are coupling a spike from the shift register
data output to the shift register clock.
Thanks for the clarity ....

This was it.

We added some termination (2K pullup) on the rdN line
(shift register clock) and that fixed it. This is just a quick band
aid because when we looked closely (we need a better scope) we've got
some nasty undershoot on the data_out line out line too ..

We're on the road again ..

Thanks a lot!

Tom
 

Welcome to EDABoard.com

Sponsor

Back
Top