Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Detecting a pattern in a parallel bus random start bit

Status
Not open for further replies.
If the interface is sending FFs after the sync pattern until it actually has the message data, then the sync pattern will show up again. So now while you've already detected the sync pattern and have been "guaranteed that the next data msg detected is the first byte of that of the data packet" you've also just received another sync pattern which seems to have shot that guarantee you mentioned all to shreds. Sounds like either you're not describing the protocol correctly, or it is a protocol that needs some more thought put into it.

You're right, the protocol is to send the sync after so many data packets. Otherwise, if no data packets, 0xFFFF_FFFF is sent.

- - - Updated - - -

Kevin, I think you are over analyzing this. I get the impression the 0xFFFF_FFFF is the sync pattern being searched for, once found the input logic starts looking for the start of data which starts at the first byte (32-bit aligned) that is not 0xFF. I'm assuming there is either some header or a constant length that is used for the packet payload that is sent. The input logic will therefore work similarly to the synchronization of a Ethernet link where it synchronizes to the preamble but doesn't care if the payload has the preamble sequence embedded in it.

The sync is 0x7FFF_FFFF (bit 31 should be zero)

Once the data packet is detected, the numbers of bytes to follow is known for that source (type) .

My difficulty is basically that the sync pattern or data packets are not aligned to the 32-bit data bus where the start of either one can start on any bit position of the parallel bus (and it can divided between the previous and present word).
 

Hi,

it seems this is a kind of deserializer.

Instead of sending 0xFFFFFFFF when there is no data, you should consider to send 0x7FFFFFFF. Then the receiver is able to synchronize continously.
Then the start could be identified as 0xFFFFFFFF.

Doesn´t this make more sense?

Sometimes reciever (LVDS or RS485 or so) have fail safe output of "1".
With your 0xFFFFFFFF as idle signal the receiver can´t recognize if there is a valid transmitter or if there is a disconnected line.
With an idle pattern of 0x7FFFFFFF the receiver is able to detect an active transmitter (and sync).

In my eyes the deserializer (before there are 32 bit parallel data) should ensure syncing and should ensure correct data alignment in the 32 bit parallel value.

If you do the complete serializer-deserializer chain on your own, I recommend to read how LVDS serializer/deserializers work. This could give you ideas for your project.

Klaus
 

Instead of sending 0xFFFFFFFF when there is no data, you should consider to send 0x7FFFFFFF. Then the receiver is able to synchronize continously.
Then the start could be identified as 0xFFFFFFFF.

I am receiving this data on a parallel bus at the input of the FPGA (single ended). I am the receiver of this sync and data packets. The parallel bus is sent with a single ended clock (TTL levels). I need to decode the data packet and then send it to another module for decompression. Once I extract the data , I send the source and data for each type with a valid bit to the next module.
 

My difficulty is basically that the sync pattern or data packets are not aligned to the 32-bit data bus where the start of either one can start on any bit position of the parallel bus (and it can divided between the previous and present word).
Are you having difficulty understanding or implementing what I posted for determining the number of bits to shift and how to implement the shifter? If so, what exactly is the difficulty?

Kevin
 

Are you having difficulty understanding or implementing what I posted for determining the number of bits to shift and how to implement the shifter? If so, what exactly is the difficulty?

I will get back to you .. I need time to digest the information as the experience with VHDL is also a learning curve in addition to the interface.
I am going to try to implement something and simulate it.



thanks
 

The understanding should have nothing to do with VHDL it should be on what you are trying to design (the architecture) to do this "deserializer" type interface.

If you know the architecture of the design translating it to VHDL should be straightforward conversion of hardware blocks to the corresponding VHDL description of that block (e.g. FFs, multiplexers, comparators, etc.).

First and foremost you need to have a block diagram and architectural details for this design before coding it in VHDL. You seem to be jumping directly from a specification straight to a VHDL implementation, without having done any design.
 

Updated code to avoid confusion:
Code:
function createEqualityVector(x : std_logic_vector) return std_logic_vector is
  const kPattern : std_logic_vector(31 downto 0) := x"7FFFFFFF";
  variable xNml : std_logic_vector(x'length-1 downto 0);
  variable result : std_logic_vector(x'length-kPattern'length-1 downto 0) := (others => '0');
begin
  xNml := x;
  for i in result'range loop
    if xNml(xNml'high-i downto xNml'high-(kPattern'length-1)-i) = kPattern then
      result(result'high-i) := '1';
    end if;
  end loop;
  return result;
end function;

The problem sounds very similar to an MIIM/MDIO receiver.

To construct the solution, you would need a shift register as previously mentioned. There are two possible shift directions, one that works and one that does not. (this should be 32 additional registers over the registered input. Ideally, the input would come from FPGA registers instead of IO Registers. Thus this might be 64 registers total.)

The shift register is the input to the "createEqualityVector" function. This will likely be implemented as 32 32b compare-equals.
(This will output either all 0's, or a single 1. I will prefer to keep the vector in this order for simulation purposes)
(If this is too large, I think there is an adder-trick + adder-tree version that might be smaller, but nearly unreadable)

This is fed to the the or-reduce logic to generate a "sync-found" signal. This might be a 32-input or.
(the reason for this should be obvious)

It is also fed to the encoder -- more specifically, it is bit-reversed first. This is five 16 input or.
(this is a well known circuit, and because the input has at most a single bit set, this becomes a priority encoder. Just without extra priority logic that wouldn't be used.)

The original input is fed to a barrel shifter. The selector is the output of the encoder. This is 32 32:1 muxes.
(if the '0' is found in the msb (31), then 0 shift-lefts are required. if found in the lsb(0), then 31 shift-lefts are required. There are several ways to flip the indexing. Bit reversal, changing the encoder constants, etc...)

Now you will have output registers and whatever logic is required for marking outputs as valid. The lock signal will be aligned to the sync word. eg, lock='1' implies dataOut = x"7FFFFFFF".

You are mostly free to add registers to the design without significant area impacts. At 50MHz this has a good chance of meeting timing. Barrel shifts are not ideal for timing, but are not that bad when all inputs are local. Modern FPGAs also have better resources for implementing fast muxes. The other circuits are simple.
(make sure to delay the data by the correct amount as well. I suggest a baseline implementation that you can simulate first.)
 

For the "unreadable" implementation using adder-tricks. The idea is to generate a vector like '0' & x"0000FFFF" & x"FFFF8000" for an input of x"FFFF7FFF"&x"FFFF8777". This is then bit-counted to see if it's (the generated vector) weight (number of 1's) is >= 32. Basically the number of 1's to the left and right of bit 32, where bit 32 is treated as '1' no matter what. The location of the first 0 is again used in the same manner as before for muxing.

the input shift register is treated as a 65 bit value, where bit 64 = '0'.

The first adder-trick is done on bits 64:32. It is (-x&x), but with ~x because the problem looks for the rightmost 0. eg (-(~x) & (~x)). (-x&x) finds the rightmost '1' in a vector and returns a vector with either 0 or 1 bits set. The msb (64) is used to determine if there are any 0's in this vector. This could also be done using a normal compare.
Code:
(-x & x)
10011 = ~x
01100 = x
10100 = -x
00100 = (-x & x) // the rightmost 1 is set, no other bits are set.
// if you replace x with ~x, then the rightmost 0 is set by isometry.

The second adder-trick is (-(~x) ^ x), applied on (63:32). This one returns 1's up to, and including the first '0'. The -(~x) term is common, making the use in the comparison above justified.
Code:
00100 = ~x
11011 = x
11100 = -~x
00111 = (-(~x) ^ x) // bits before and including the first 0 are set.  (bits before the first 0 start with '1')

The third adder-trick uses the bit-reverse of bits [31:1]. It is ~(-(~y)|(~y)). This gives all 1's up to, but not including the first '0'. because the input is bit-reversed, this finds the leftmost '0'. (bit 0 is not used)
Code:
(assume the input was bit reversed so right becomes left.  I will display the carry from the right in the example.)
11011 = y
00100 = ~y
11100 = -~y
00011 = ~(-(~y)|(~y)) // bit before and including the first 1 are set.  (bits before the first 1 start with '0')

These are combined to form a 63 bit vector (+forward disable). It will be a 64 bit vector with some number of consecutive 1's expanding from bit 32.

An adder-tree is then used to see if the number of 1's is >= 32. This is the cumulative enable. If the forward disable is false and the cumulative enable is true, then the result is valid.

Also, I'm not giving the exact code for this. It is a horrible way to write code unless it can actually be justified. Also, if you choose to do this you must add commentary. This misuses language constructs heavily. Experienced developers will not think you are smarter than they are simply because you can't comment intentionally confusing code.

(also, this assumes adder-tree and the above adder-tricks are area/performance efficient. at 50MHz they likely are fine.)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top