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
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