You are on page 1of 10

Berkeley Wireless Research Center Electrical Engineering and Computer Science Department University of California, Berkeley

December 31, 2009

Technical Report

Manchester Decoder and Clock Recovery Module for FPGA Prototype of Active RFID Tag

Anton Ageev

Abstract This report describes the development and testing of the Manchester decoder and clock recovery module for FPGA prototype of active RFID tag. At the core of module operation is the measurement of time between consecutive edges of a Manchester encoded signal, which is performed using two counters clocked by an available device clock. The measured time is used to compute the Manchester half-cycle duration, which is in turn used to recover the clock signals. The developed module receives a Manchester encoded signal and generates three signals: two clock signals one of the same frequency as the input Manchester signal, the other one of a doubled frequency, and a sequence of decoded data bits. The module has been written in VHDL programming language, simulated in Xilinx ISE simulator and tested using Xilinx Virtex-II Pro FPGA.

1. Introduction
One of the components of the active RFID tag is the clock recovery module, which derives a clock signal from an incoming radio signal. Assuming that the incoming radio signal is already demodulated and represented in digital form (such as signal encoded using Manchester code), the clock recovery module can be purely digital. In this case, decoding is done together with clock recovery and the clock signal is used to properly receive decoded data bits by some other module. As for the FPGA-based prototype of the tag, decoding and clock recovery functions can be performed by an HDL module. The rest of this report describes the developed Manchester decoder and clock recovery module, written in VHDL programming language, its verification by simulations and experiments.

2. Manchester decoder and clock recovery module


The module mydecoder.vhd (see Appendix) has been designed to receive a Manchester encoded signal, to give out two clock signals one of the same frequency as the Manchester signal (SYNC), the other one of a doubled frequency (DBL_BSB), and to provide decoded data bits serially. Also, the module uses another two input signals: the clock signal CLK supplied by the FPGA clock (emulating the clock oscillator of a real RFID tag) and reset signal RST. Schematic representation of the module is shown in figure 1. CLK mydecoder.vhd RST Manchester decoder and clock recovery module DBL_BSB SYNC

MANCH

SERIALDATA

Fig. 1. Schematic representation of the Manchester decoder and clock recovery module Each data bit in a Manchester encoded signal is represented by a transition, which should happen during a certain time interval (cycle), as shown in figure 2. Ideally, the cycle duration is constant and the transition happens exactly in the middle of the cycle. The recovered clock period should be equal to the cycle of the Manchester signal. Transitions (edges) of the Manchester signal can be significant, i.e. representing some data bit, or they can happen at the boundary between consecutive cycles. Significant edges take place in the middle of every cycle, while "boundary edges" do not happen between those consecutive cycles, which have different data bits (e.g. 0 and then 1 or vice versa). This means that the time between each two consecutive edges of the Manchester signal can be equal to either its one or two half-cycles.

encoded bit

pos_counter 0 MANCH neg_counter

halfcycle1

2*halfcycle1

halfcycle2

2* halfcycle2

SYNC

DBL_BSB

SERIALDATA

Fig. 2. Ideal waveforms applied to and generated by the Manchester decoder and clock recovery module The counter pos_counter is reset on a positive edge, the counter neg_counter on a negative edge of the Manchester signal. Thus, whenever a positive edge happens, the value of neg_counter indicates the time elapsed from the last negative edge, i.e. the time interval between the two resent edges. This value is stored as the half-cycle duration halfcycle1 if it lies within [halfcycle2 jitter; halfcycle2 + jitter], where halfcycle2 is the half-cycle duration computed previously (i.e. on the last negative edge) and jitter equals to some jitter value. If the neg_counter value is within [2*(halfcycle2 jitter); 2*(halfcycle2 + jitter)], it is divided by two and the result is stored as the half-cycle duration halfcycle1. Similarly, the half-cycle duration halfcycle2 is computed on a negative edge, using the value of pos_counter. If the half-cycle duration is not known before the decoding process, it must be computed using the two first edges of the incoming Manchester signal. In this case the first two data bits must be the same (either two zeros or ones) in order to correctly compute the half-cycle duration. Alternatively, if it is known in advance that the first two bits are different, the time interval between the first two edges equals to two half-cycles, and the half-cycle duration can be derived by dividing that time interval by two. The described clock recovery module assumes that the the first two data bits are the same. A special process controls both counters (increases and resets them), and two other processes compute the half-cycle duration: one on positive edges, another on negative edges. The jitter value is assumed to be equal to one eighth of the half-cycle duration and it is also recomputed on every edge. Clock recovery is based on the fact that the recovered clock signal should be inverted on any Manchester edge. Also it should be inverted at the boundary between adjacent Manchester cycles when an edge is not present (this happens when two consecutive data bits are different). This inversion is performed in a process that tracks the values of the two counters mentioned above. When any of the counters equals to zero, which happens just after some Manchester edge, the recovered clock signal sync_signal, and the doubled frequency signal doubled_baseband are

inverted. When there is no Manchester edge, the process checks whether the last observed edge was positive (this is true when pos_counter < neg_counter). If so, the process checks whether the pos_counter value is equal to halfcycle1 + jitter. If it is true, this means that no Manchester edge was detected and one half-cycle interval has already passed since the last positive edge. This corresponds to the boundary between adjacent Manchester periods and both sync_signal and doubled_baseband must be inverted. Besides, when pos_counter counts one or three quarters of Manchester period, the doubled_baseband should be inverted. When there is no Manchester edge and the last observed edge was negative, the clock signals are recovered in an analogous way. Decoding is based on the fact that each positive edge of sync_signal (recovered clock) happens just after a significant Manchester edge (i.e. after a transition representing some data bit). This takes place already in the second half of the Manchester period and the respective data bit equals to the inverted value of the Manchester signal at that moment, if G. E. Thomas convention is used (pos. transition corresponds to zero, neg. to one). A special process assigns that value to current_bit signal (connected to SERIALDATA output of the module) on a positive edge of sync_signal. The other module (which uses decoded data) can receive the bit on the following negative edge of sync_signal (which is connected to SYNC output of the module). Notice, that the first received edge of an incoming Manchester signal is taken as a significant one. The presented module uses G. E. Thomas convention, but this can be easily changed to IEEE 802.3 convention (where neg. transition corresponds to zero, pos. to one) by assigning Manchester signal value to current_bit on positive edges of sync_signal in the aforementioned process.

3. Simulations
The module operation was verified using Xilinx ISE simulator. A test bench waveform was created, which is shown in figure 3.

Fig. 3. Test bench waveform used to verify the module operation in Xilinx ISE simulator The frequency of CLK signal was set to 20 MHz. First, a positive pulse appears on RST input of the module, and then MANCH input is supplied with a square pulse signal representing the Manchester encoded data bit sequence "00110101010000000111". The result of the corresponding behavioral simulation is shown in figure 4.

Fig. 4. Simulation of the module operation in Xilinx ISE simulator

The recovered clock signal is generated correctly on the SYNC output starting from the very first Manchester edge (which is assumed to be a significant edge), despite of the fact that the half-cycle duration is not yet known (it is computed when at least two edges have already happened). This is because the recovered clock signal is inverted on any Manchester edge and the two first data bits are the same (which is necessary to correctly initialize the half-cycle value). The doubled baseband frequency signal, generated on the DBL_BSB output, is valid starting from the second half of the first Manchester period, since it requires the knowledge of half-cycle duration. The valid decoded data bits appear on the SERIALDATA output starting from the first Manchester edge. Notice that the positive pulses of SYNC and DBL_BSB signals are wider than normal when two adjacent bits differ. This is because the signal values are inverted later due to the absence of a Manchester edge, as it is explained above.

4. Experiments
In order to verify its operation experimentally, the module was used as a part of the hierarchical VHDL design (withdcm.vhd), whose simplified block diagram is shown in figure 5. Apart from mydecoder.vhd, this design includes the following functional blocks: AD1RefComp.vhd which controls the operation of Digilent PmodAD1 Analog To Digital Module Converter Board (containing two ADCs ADCS7476 with anti-aliasing filters), dcm_module a Digital Clock Manager module, which generates 40 MHz clock, frequency divider (a process in the top-level module withdcm.vhd) which divides by 2 the 40 MHz clock signal generated by dcm_module to provide 20 MHz CLK signal for AD1RefComp.vhd and mydecoder.vhd modules, demodulator (a process in the top-level module withdcm.vhd) which performs the demodulation of the signal received from AD1RefComp.vhd and forwards Manchester encoded signal to the mydecoder.vhd module. withdcm.vhd
ADC data RST AD1RefComp.vhd signal demodulator CLK 20 MHz divider CLK RST mydecoder.vhd MANCH SYNC DBL_BSB SERIALDATA

/2
40 MHz 100 MHz dcm_module

FPGA system clock

reset

Fig. 5. Hierarchical VHDL design used to experimentally verify the module operation

The detailed description of these modules operation is omitted here, since it is out of the scope of this report. In this design, SYNC, DBL_BSB and SERIALDATA outputs of the mydecoder.vhd module have been wired to the FPGA outputs, connected to expansion connector pins. This was done to test the module operation using an oscilloscope. The design has been used to configure XUP Virtex-II Pro board, containing Xilinx Virtex-II Pro FPGA. The Digilent PmodAD1 board outputs have been connected to FPGA outputs using an expansion connector. Analog input of PmodAD1 has been connected to the output of a pulse generator Philips PM5716. The FPGA outputs, on which the recovered clock signals and data signal should appear, have been in turn connected to the channels of Agilent MSO6052A oscilloscope.

signal measured on SYNC output

10 kHz test signal

Fig. 6. An oscilloscope screen shot showing the 10 kHz signal applied to ADC board and one of the module output signals SYNC During experiments, various square pulse signals have been generated and applied to analog inputs of PmodAD1, with the 3V amplitude and the frequency ranging from some Hertz to some tens of kilo-Hertz. These signals imitated the Manchester encoded signal representing the same data bits (all zeros). The signal was not modulated for simplicity. In the mentioned above range, the correct operation of the module was proved by the valid SYNC, DBL_BSB and SERIALDATA signals measured with the oscilloscope (the oscilloscope screen shot shown in figure 6 corresponds to 10 kHz input signal). Due to the described above jitter re-computation, the output signals were generated correctly even when the frequency of the test signal was varying slowly. These output signals were not stable, when higher frequency input signals were applied. This was due to some imperfections of the demodulator operation.

5. Conclusions
A simple VHDL module, which performs Manchester decoding and clock recovery, has been developed. The main function of the module is to receive a Manchester encoded signal, decode it and extract clock signal from it. The module generates two clock signals one of the same frequency as the input Manchester signal, the other one of a doubled frequency. Also, the module provides decoded data bits in series on one of its outputs. Each of the data bits can be received by some other module on the falling edges of the generated clock signal. The module, whose operation has been simulated in Xilinx ISE simulator and tested experimentally using Xilinx Virtex-II Pro FPGA, can be used in the FPGA-based prototype of the active RFID tag.

Appendix
Manchester decoder and clock recovery module mydecoder.vhd
----------------------------------------------------------------------------------- Company: BWRC -- Engineers: Anton Ageev, Wenting Zhou --- Create Date: 18:14:06 12/07/2009 -- Design Name: -- Module Name: mydecoder - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: Manchester decoder and clock recovery module --- Dependencies: --- Revision: -- Revision 0.01 - File Created -- Additional Comments: ----------------------------------------------------------------------------------library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity mydecoder is generic (JITTER_COEF: integer := 3); --jitter is halfcycle/(2^JITTER_COEF) Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; MANCH : in STD_LOGIC; -- Manchester signal SYNC : out STD_LOGIC; -- recovered clock SERIALDATA : out STD_LOGIC; -- decoded data DBL_BSB : out STD_LOGIC -- recovered clock of a doubled frequency ); end mydecoder; architecture Behavioral of mydecoder is signal pos_counter : std_logic_vector (31 downto 0) := (others=>'0');-- time since last positive edge of Manchester signal signal neg_counter : std_logic_vector (31 downto 0) := (others=>'0');-- time since last negative edge of Manchester signal signal half_cycle1 : std_logic_vector (31 downto 0) := (others=>'0');-- halfcycle of Manchester clock, computed on pos. edges signal half_cycle2 : std_logic_vector (31 downto 0) := (others=>'0');-- halfcycle of Manchester clock, computed on neg. edges signal start_pos_count : std_logic := '1';-- resets pos_counter signal start_neg_count : std_logic := '1';-- resets neg_counter signal first_pos_transition : std_logic :='1';-- indicates whether the first pos. edge is expected signal first_neg_transition : std_logic :='1';-- indicates whether the first neg. edge is expected signal sync_signal : std_logic :='0';-- clock signal recovered from Manchester signal (Manchester clock) signal current_bit : std_logic := '0';-- data bit decoded from Manchester signal signal doubled_baseband : std_logic := '0'; -- doubled frequency clock signal recovered from Manchester signal begin SERIALDATA <= current_bit; SYNC <= sync_signal; -- this process resets and increases the counters which measure the time between Manchester edges: process (CLK,pos_counter,neg_counter,MANCH,start_pos_count,start_neg_count,RST)

begin if (RST = '1') then pos_counter <= (others=>'0'); neg_counter <= (others=>'0'); start_pos_count<='1'; start_neg_count<='1'; elsif (CLK'event and CLK = '1') then if(MANCH='1')then -- if the last edge was positive if(start_pos_count='1')then pos_counter <= (others=>'0'); -- reset the counter start_pos_count<='0'; -- to reset it just once start_neg_count<='1'; -- to reset neg. counter on the next neg. edge else pos_counter <= pos_counter + 1; end if; -- keep increasing neg. counter to be able to compute the difference between two counters: neg_counter <= neg_counter + 1; else -- if the last edge was negative if(start_neg_count='1')then neg_counter <= (others=>'0'); -- reset the counter start_neg_count<='0'; -- to reset it just once start_pos_count<='1'; -- to reset pos. counter on the next pos. edge else neg_counter <= neg_counter + 1; end if; -- keep increasing pos. counter to be able to compute the difference between two counters: pos_counter <= pos_counter + 1; end if; end if; end process; -- this process decodes Manchester signal: process (sync_signal,MANCH,RST) begin if (RST = '1') then current_bit <= '0'; elsif (sync_signal'event AND sync_signal = '1') then -- pos. clock edge -- Manchester data (G. E. Thomas convention: _/ 0 \_ 1 ): current_bit<=NOT MANCH; end if; end process; -- this process derives clock signal from Manchester signal: process (CLK, sync_signal, doubled_baseband, half_cycle1, half_cycle2, pos_counter, neg_counter, RST) begin if (RST = '1') then sync_signal <= '0'; doubled_baseband <= '0'; elsif (CLK'event AND CLK = '1') then if(pos_counter = 0) then -- when a positive edge happens sync_signal <= NOT sync_signal; doubled_baseband <= NOT doubled_baseband; else if (neg_counter = 0) then -- when a negative edge happens sync_signal <= NOT sync_signal; doubled_baseband <= NOT doubled_baseband; else if(pos_counter < neg_counter)then -- after the last positive Manchester edge if(pos_counter = half_cycle1 + half_cycle1(31 downto JITTER_COEF))then sync_signal <= NOT sync_signal; doubled_baseband <= NOT doubled_baseband; elsif (pos_counter = ('0' & half_cycle1(31 downto 1)) OR pos_counter = half_cycle1 + ('0' & half_cycle1(31 downto 1)))then doubled_baseband <= NOT doubled_baseband; end if; else -- after the last negative Manchester edge if(neg_counter = half_cycle2 + half_cycle2(31 downto JITTER_COEF))then sync_signal <= NOT sync_signal; doubled_baseband <= NOT doubled_baseband; elsif (neg_counter = ('0' & half_cycle2(31 downto 1)) OR neg_counter = half_cycle2 + ('0' & half_cycle2(31

downto 1)))then doubled_baseband <= NOT doubled_baseband; end if; end if; end if; end if; end if; end process; DBL_BSB <= doubled_baseband; -- this process computes duration of halfcycles on positive edges of Manchester signal: process (MANCH,first_pos_transition,first_neg_transition,neg_counter,half_cycle2,RST) begin if (RST = '1') then first_pos_transition <= '1'; half_cycle1<=(others=>'0'); else if MANCH'event and MANCH = '1' then -- only for the first positive edge: if (first_pos_transition = '1') then first_pos_transition <= '0'; -- if a negative edge already happend: if(first_neg_transition='0')then -- half cycle duration just equals to the time passed since the last negative edge: half_cycle1<=neg_counter; end if; else -- for all consecutive positive edges -- if the time passed since last neg. edge is approximately one halfcycle, use it as a new half cycle value for clock signal (jitter equals to an eighth of a halfcycle): if (neg_counter > (half_cycle2-half_cycle2(31 downto JITTER_COEF)) AND neg_counter < (half_cycle2+half_cycle2(31 downto JITTER_COEF))) then -- half cycle duration just equals to the time passed since the last negative edge: half_cycle1<=neg_counter; -- otherwise, check whether the time passed since last neg. edge is approximately two halfcycles (jitter equals to a quarter of a halfcycle); if so, new value equals to neg. counter value divided by 2: else if (neg_counter > (half_cycle2+half_cycle2-half_cycle2(31 downto (JITTER_COEF-1))) AND neg_counter < (half_cycle2+half_cycle2+half_cycle2(31 downto (JITTER_COEF-1)))) then half_cycle1 <= '0' & neg_counter(31 downto 1);--divide by 2 end if; end if; end if; end if; end if; end process; -- this process computes duration of halfcycles on negative edges of Manchester signal: process (MANCH,first_neg_transition,first_pos_transition,pos_counter,half_cycle1,RST) begin if (RST = '1') then first_neg_transition <= '1'; half_cycle2<=(others=>'0'); else if MANCH'event and MANCH = '0' then if (first_neg_transition = '1') then -- only for the first negative edge first_neg_transition <= '0'; if(first_pos_transition='0')then -- if a positive edge already happened -- half cycle duration just equals to the time passed since the last positive edge: half_cycle2 <= pos_counter; end if; else -- for all consecutive negative edges -- if the time passed since last pos. edge is approximately one halfcycle, use it as a new half cycle value for clock signal (jitter equals to an eighth of a halfcycle): if (pos_counter > (half_cycle1-half_cycle1(31 downto JITTER_COEF)) AND pos_counter < (half_cycle1+half_cycle1(31 downto JITTER_COEF))) then -- half cycle duration just equals to the time passed since the last positive edge: half_cycle2 <= pos_counter; -- otherwise, check whether the time passed since last pos. edge is approximately two halfcycles (jitter equals to a quarter of a halfcycle); if so, new value equals to pos. counter value divided by 2: else

if (pos_counter > (half_cycle1+half_cycle1-half_cycle1(31 downto (JITTER_COEF-1))) AND pos_counter < (half_cycle1+half_cycle1+half_cycle1(31 downto (JITTER_COEF-1)))) then half_cycle2 <= '0'& pos_counter(31 downto 1); -- divide by 2 end if; end if; end if; end if; end if; end process; end Behavioral;

You might also like