Clocking data into a shift register on positive AND negative edges

Hi, I'm trying to design a floppy disc 'raw reader' (to archive discs that have been written in unusual formats that PCs can't read). I've got a basically working data separator design that turns the MFM (or FM) data signal into a data output and a data window signal. This is how it looks on a logic analyser (note that the vertical : lines denote the bit cell boundaries):

__________ __________ DWIN __________| |__________| |__________ : : _ : _ _ : DATA __________________________| |_____| |_| |_____________ : : : :

clock-0 clock-1 clock-1 clock-0 (noisy)

Basically, a transition (either H-L or L-H) on the DWIN (Data Window) line denotes the start of a bit cell. If DATA is pulsed at least once within that bit cell, then a 1 should be clocked into a shift register (a 16-bit SR used to detect the synchronisation word). If there wasn't a pulse, then a zero should be clocked into the shift register.

Now the problem I have is that in Verilog (or at least Xilinx ISE8.1 Verilog) you can't trigger on both a positive and negative edge of a signal - the language allows it, but ISE complains that it can't find a matching 'FF or latch template' (error code Xst:899).

The idea I came up with was to have a D-type flip-flop wired with D=1, Q to the SR's data line, and CLK wired to a signal that pulses every time there's a DWIN edge. The problem I have is that I'm quite new to CPLDs, so I'm not sure how to go about creating the 'pulse every transition' signal.

Am I thinking along the right lines here, or is there an easier (or just another) way to do this?

Thanks.

--
Phil.                         |  (\_/)  This is Bunny. Copy and paste Bunny
usenet07@philpem.me.uk        | (='.'=) into your signature to help him gain
http://www.philpem.me.uk/     | (")_(") world domination.
If mail bounces, replace "07" with the last two digits of the current year.
Reply to
Philip Pemberton
Loading thread data ...

The "other way" is to use a clock that's much higher in speed (4x is very safe). Sample the clock and data values. If the values match for 2 consecutive cycles, the values are valid and usable otherwise they might be in the middle of changing and should be ignored until 2 cycles are consistent. If the dual-edge transition you're looking for has transitioned either way within that sampled data, you have your data.

By using a master clock and sampling the data *and* floppy clock with that master clock, you can divorce the algorithm needs (dual edge) from the hardware (single edge). One system clock is significantly easier to deal with than multiple clocks in one FPGA. If you can't come up with a single clock FPGA design because of the design requirements, fewer clocks are almost always better.

Reply to
John_H

Philip Pemberton schrieb:

If you really need both clock edges, think about a pseudo-dual-edge flipflop:

Ralf

Reply to
Ralf Hildebrandt

The FFs in most (all?) FPGAs/CPLDs can only operate on one edge. If you want to use both edges, you have to use two distinct sets - one for each edge polarity.

Since floppies are low-speed devices, an oversampling edge detection scheme would do the job: you sample your input 3-4X faster than your shortest event (pulse) and XOR the samples with the delayed previous sample to detect edges. This XOR's output can be used as the clock enable for the remaining logic. Unless you really know what you are doing, you should not use combinational or non-clock/glitchy signals to drive clocks.

Reply to
Daniel S.

Thanks for the suggestion, John (and Daniel and Ralf). I've already got an

8MHz master clock that's used to drive the data separator, and seeing as the maximum data rate is only 1Mbit/sec, I've used the 8MHz clock to drive an oversampling transition detector to pick up the data window transitions, and then used a shift register to pick up the sync word:

---------- start code

module syncdetect(clock, data, dwin, reset, sync); input clock; // sampling clock, min 4*f_DWIN input data; // data input input dwin; // data window input reset; // reset input output reg sync; // sync-detect output

////////// // DWIN transition detector

reg [1:0] detector; wire dwin_transition; // 1 = transition detected on DWIN always @(posedge clock or posedge reset) begin if (reset) begin detector

Reply to
Philip Pemberton

Philip,

See what happens with the second allways block specified as

always @(posedge clock or negedge reset)

The way you have it currently set with

always @(posedge dwin_transition or posedge data or posedge reset)

is confusing at best. When you detect a transition at the 8 MHz clock you want to execute the non-reset code. The always has the clock and the code has the transition conditional.

The last else isn't quite right. If there's no transition of dwin, you want to accumulate dar - dar> single clock FPGA design because of the design requirements, fewer clocks

Reply to
John_H

[...]
[...]

Yes. I've done something similar, and you don't need any double-edge clocking for that.

Put two FFs in series, clocked by a free-running oscillator (perhaps 25 MHz or higher). XOR the outputs together. Now you get a pulse one clock cycle wide every time the data line changes.

If you also have a free running counter on the same clock, you can use the "changed" signal as a clock enable for a register to record the time that the data line changed, or push it into a FIFO.

For a floppy (or an ST506/412 interface Winchester, or the like), you don't actually need both edges, as only the leading edge of the data pulse is related to the flux transition on the disk. (The floppy drive uses a one-shot to generate a pulse for each detected flux transition.) Therefore instead of an XOR, you can use an AND gate and an inverter to detect only transitions in the direction of interest.

Reply to
Eric Smith

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.