22
1 INTRODUCTION TO VLSI A PROJECT REPORT ON MICROPROCESSOR-COMPATIBLE QUADRATURE DECODER/COUNTER DESIGN ROHIT SINGH M.TECH VLSI SYSTEMS AND TECHNOLOGY DEPARTMENT OF ELECTRICAL ENGINEERING SHIV NADAR UNIVERSITY

Microprocessor-Compatible Quadrature Decoder/Counter Design

Embed Size (px)

DESCRIPTION

A microprocessor-compatible quadrature decoder/counter is used to interface an optical shaft encoder (OSE) to a microprocessor's system bus. Quadrature decoder/counter find application in digital data input subsystems and digital closed loop motion control systems.

Citation preview

Page 1: Microprocessor-Compatible Quadrature Decoder/Counter Design

1

INTRODUCTION TO VLSI

A PROJECT REPORT

ON

MICROPROCESSOR-COMPATIBLE

QUADRATURE

DECODER/COUNTER DESIGN

ROHIT SINGH

M.TECH

VLSI SYSTEMS AND TECHNOLOGY

DEPARTMENT OF ELECTRICAL ENGINEERING

SHIV NADAR UNIVERSITY

Page 2: Microprocessor-Compatible Quadrature Decoder/Counter Design

2

Contents

1. Introduction 03

2. Quadrature decoder/counter 03

3. Optical shaft encoder (OSE) 03

3.1 Introduction 03

3.2 Signals having a quadrature phase relationship 04

4. Optical shaft encoder interface approach 05

4.1 Approach 1 05

4.2 Approach 2 05

5. Features of quadrature decoder/counter 05

5.1 Input signal noise filter 05

5.2 Four times decode 06

5.3 12-bit counter 07

5.4 Registered outputs that are readable “on the fly” 07

5.4.1 Reading the count “On the fly” 07

5.4.2 Double buffer register 08

5.5 8-bit microprocessor bus interfaces 08

6. Quadrature decoder/counter partition 08

7. VHDL Code 09

7.1 VHDL Code No. 1 (filter) 09

7.2 VHDL Code No. 2 (fx_decode) 10

7.3 VHDL Code No.3 (binary_cntr) 14

7.4 VHDL Code No.4 (inhibit_fsm) 15

7.5 VHDL Code No.5 (double_buff) 18

7.6 VHDL Code No.6 (mux) 19

7.7 VHDL Code No.7 (quad_decode) 19

Page 3: Microprocessor-Compatible Quadrature Decoder/Counter Design

3

1. Introduction

A microprocessor-compatible quadrature decoder/counter is used to interface an optical shaft

encoder (OSE) to a microprocessor‟s system bus. Quadrature decoder/counter find application in

digital data input subsystems and digital closed loop motion control systems.

2. Quadrature decoder/counter

Quadrature decoder/counter is used to decode the two input signal which are 90 degrees out of

phase. These signals are decoded to produce a count up pulse or a count down pulse. For

decoding in software, the A & B outputs are read by software, either via an interrupt on any edge

or polling, and the below table is used to decode the direction. For example, if the last value was

00 and the current value is 01, the device has moved one half step in the clockwise direction.

Coding for

clockwise rotation

Phase A B

1 0 0

2 0 1

3 1 1

4 1 0

Coding for

counter-clockwise

rotation

Phase A B

1 1 0

2 1 1

3 0 1

4 0 0

3. Optical shaft encoder (OSE)

3.1 Introduction

An optical shaft encoder (OSE) converts rotary mechanical motion into a digital output. It does

this by first converting the rotary of its shaft into interruptions of a light beam. It then converts

these light beam interruptions into electrical pulses.

One common use of OSE is on the front panel of an electronics instrument where it allows an

operator to increment or decrement a displayed parameter. For example, clockwise (CW)

rotation might cause the parameter to be incremented and counter clockwise (CCW) rotation

cause it to be decremented.

Page 4: Microprocessor-Compatible Quadrature Decoder/Counter Design

4

3.2 Signals having a quadrature phase relationship

When its shaft is rotated, the OSE produces two digital output waveforms, designated channel A

and channel B. These waveforms have a quadrature phase relationship.

Page 5: Microprocessor-Compatible Quadrature Decoder/Counter Design

5

4. Optical shaft encoder interface approach

There are two common approaches to interface an OSE to a microprocessor system‟s bus.

4.1 Approach 1

In a software-intensive approach, the microprocessor repeatedly inputs signals A and B from

OSE through input port. A software subroutine compares the newly read values of A and B with

a copy of the previously read values saved in memory. Based on this comparison, the subroutine

determines whether to increment or decrement a count variable in the microprocessor‟s memory.

This simple software approach requires that the microprocessor constantly monitor the OSE‟s

outputs to detect each change in their values.

4.2 Approach 2

To improve the performance of a system incorporating an OSE, the time-intensive

quadrature/decoder functions can be implemented in hardware. In this approach hardware

converts changes in A and B to a count that is stored in a register. A microprocessor-compatible

quadrature decoder/counter includes a bus interface that allows its count register to be read by a

microprocessor at any time.

5. Features of quadrature decoder/counter

Some features that quadrature decoder/counter IC might provide is:

1. Input signal noise filter

2. 4X decoder

3. 12-bit counter

4. Registered outputs that are readable “on the fly “

5. 8-bit microprocessor bus interface

5.1 Input signal noise filter

In an application environment, inputs A and B to the quadrature decoder/counter may be subject

to electrical noise. The quadrature decoder/counter must include features to minimize the effect

of both metastability from the asynchronous nature of inputs A and B and noise spikes of short

duration that might appear on these inputs.

Each input channel (A and B) is filtered by a separate copy of the digital noise filter (Shift

Register Digital Noise Filter).

Page 6: Microprocessor-Compatible Quadrature Decoder/Counter Design

6

Figure below shows a logic representation of a digital noise filter. The purpose of this filter is to

reject short duration noise spikes at its input cx. The filter‟s output y can change only after its

input has had the same value at three consecutive triggering clock edges. Input changes that have

duration of two or fewer clock cycles are rejected. Examination of the logic diagram indicates

that a valid input changes is delayed by five clock periods, one for each flip-flop, before it is seen

at the output.

A description of a functionally equivalent system is given in VHDL Code No. 1.

This code describes the functionality of the 4-bit shift register and J-K flip flop with gated inputs.

The first flip-flop of the shift register is used to reduce the chances of a metastable event if the

input data is asynchronous.

The filtered output is computed from the rightmost 3 bits of the shift register. If all three bits are

zeros “000”, then output Y is assigned a „0‟. If all three of these bits are ones “111”, then Y is

assigned a „1‟. For any other combination of these 3 bits, Y remains unchanged.

5.2 Four times decode

Since output signals A and B from the OSE have a quadrature relationship, if the counter in the

quadrature decoder/counter is enabled to count once for each quadrature of period of A, as

defined by its relationship with B, the effective resolution of the OSE is increased by a factor of

four.

The four times decode subsystem is a state machine that uses the system clock to detect each

time the combination of output values A and B changes. When this state machine detects such a

change, it asserts its count enable output (cnten) until the next triggering clock edge. A counter

enabled by cnten counts at the next triggering clock edge. The count enable output is

unasserted on this same clock edge. This finite state machine is described below.

Page 7: Microprocessor-Compatible Quadrature Decoder/Counter Design

7

5.3 12-bit counter

A counter enable input can also be added to a counter, so the counter only counts at a triggering

clock edge when it is enabled. If the counter is not enabled, its count remains the same at the

triggering clock edge.

A 12-bit binary up/down counter with a count enable input and a synchronous reset is described

in VHDL code No. 3. This counter‟s count direction can be reversed at any point in its count

sequence..

If an event on clk is positive edge, the inner if statement determines if the counter should be

reset. If not, the count enable signal cnten is checked to determine whether the counter is

enabled to count. If so, a case statement determines whether to count up or down. If the counter

is not enabled to count, its value remains unchanged.

5.4 Registered outputs that are readable “on the fly”

5.4.1 Reading the count “On the fly”

A problem can arise if a microprocessor directly reads the contents of a counter at the same time

the counter is being incremented (reads “on the fly”). The value read can be incorrect, containing

some bits from the old cont values that have not yet changed and some bits from the new count

value.

This problem is exacerbated in this application because the counter being read is wider than the

microprocessor‟s data bus. The counter is 12 bits and the microprocessor‟s data bus is only 8 bit

wide. This requires that the 12-bit data value be read as two different bytes, one containing the

most significant 4 bits of the count and the other containing the least significant 8 bits. Reading 2

bytes requires that the microprocessor execute two read bus cycles. The increased time period

Page 8: Microprocessor-Compatible Quadrature Decoder/Counter Design

8

over which the count is read increases the probability that the count might change while being

read.

5.4.2 Double buffer register

A double buffer register provides the solution to the problem of reading a counter “on the fly.”

The double buffer register is connected to the counter‟s output. While its inhibit input is „0‟, the

double buffer register stores a copy of the counter‟s output on each triggering clock edge.

However, when its inhibit input is a „1‟, the double buffer register leaves its stored value

unchanged.

A FSM is required to generate the inhibit signal. The FSM makes inhibit a „1‟ as soon as the

microprocessor starts to read the contents of the double buffer register, and returns inhibit to a

„0‟ after both bytes have been read.

5.5 8-bit microprocessor bus interfaces

Finally, a multiplexer is required to multiplex the 12-bit output of the double buffer register to

the 8-bit data bus output. The sel signal determines whether the high byte or low byte appears

on the multiplexer‟s outputs when oe_bar is asserted.

6. Quadrature decoder/counter partition

A block diagram of the first level partition of the quadrature decoder/counter‟s functions is

represented in figure below. There are seven components.

U0: shift register digital noise filter

U1: shift register digital noise filter

U2: four times decoder

U3: 12-bit counter

U4: double buffer

U5: inhibit FSM

U6: MUX

Page 9: Microprocessor-Compatible Quadrature Decoder/Counter Design

9

7. VHDL Code

7.1 VHDL Code No. 1 (filter)

library ieee;

use ieee.std_logic_1164.all;

entity filter is

port (cx, clk, rst_bar : in std_logic;

y : out std_logic) ;

end;

architecture behavior of filter is

begin

synch: process (clk)

variable q : std_logic_vector (3 downto 0) ;

begin

Page 10: Microprocessor-Compatible Quadrature Decoder/Counter Design

10

if rising_edge (clk) then

if rst_bar = '0' then

q := "0000";

y <= '0' ;

else

if q(2 downto 0 ) = "111" then --- filter

y <= '1' ;

elsif q(2 downto 0) = "000" then

y <= '0';

else

null ;

end if ;

q := cx & q (3 downto 1) ; -- right shift

end if ;

end if ;

end process ;

end behavior ;

7.2 VHDL Code No. 2 (fx_decode)

library ieee ;

use ieee.std_logic_1164.all ;

entity fx_decode is

port ( a, b, clk, rst_bar : in std_logic ;

cnten, up : out std_logic ) ;

end fx_decode ;

Page 11: Microprocessor-Compatible Quadrature Decoder/Counter Design

11

architecture behavior of fx_decode is

subtype state is std_logic_vector ( 1 downto 0) ;

signal present_state, next_state : state ;

constant state_p : state := "00" ;

constant state_q : state := "01" ;

constant state_r : state := "11" ;

constant state_s : state := "10" ;

begin

state_reg: process (clk)

begin

if rising_edge (clk ) then

if (rst_bar = '0' ) then

present_state <= (b, a);

else

present_state <= next_state ;

end if ;

end if ;

end process state_reg ;

outputs : process (a, b, present_state )

variable input : std_logic_vector (1 downto 0);

begin

input := (b, a) ;

case present_state is

Page 12: Microprocessor-Compatible Quadrature Decoder/Counter Design

12

when state_p =>

if input = "01" then up <= '1' ; cnten <= '1' ;

elsif input = "10" then up <= '0' ; cnten <= '1' ;

else up <= '-' ; cnten <= '0' ;

end if ;

when state_q =>

if input = "11" then up <= '1' ; cnten <= '1' ;

elsif input = "00" then up <= '0' ; cnten <= '1' ;

else up <= '-' ; cnten <= '0' ;

end if ;

when state_r =>

if input = "10" then up <= '1' ; cnten <= '1' ;

elsif input = "01" then up <= '0' ; cnten <= '1' ;

else up <= '-' ; cnten <= '0' ;

end if ;

when state_s =>

if input = "00" then up <= '1' ; cnten <= '1' ;

elsif input = "11" then up <= '0' ; cnten <= '1' ;

else up <= '-' ; cnten <= '0' ;

end if ;

Page 13: Microprocessor-Compatible Quadrature Decoder/Counter Design

13

when others => null ;

end case ;

end process ;

nxt_state: process (a, b, present_state)

variable input : std_logic_vector (1 downto 0);

begin

input := (b, a) ;

case present_state is

when state_p =>

if input = "01" then next_state <= state_q ;

elsif input = "10" then next_state <= state_s ;

else next_state <= state_p ;

end if ;

when state_q =>

if input = "11" then next_state <= state_r ;

elsif input = "00" then next_state <= state_p ;

else next_state <= state_q ;

end if ;

when state_r =>

if input = "10" then next_state <= state_s ;

Page 14: Microprocessor-Compatible Quadrature Decoder/Counter Design

14

elsif input = "01" then next_state <= state_q ;

else next_state <= state_r ;

end if ;

when state_s =>

if input = "00" then next_state <= state_p ;

elsif input = "11" then next_state <= state_r ;

else next_state <= state_s ;

end if ;

when others => null ;

end case ;

end process ;

end behavior ;

7.3 VHDL Code No.3 (binary_cntr)

library ieee ;

use ieee.std_logic_1164.all ;

use ieee.numeric_std.all ;

entity binary_cntr is

port (clk, cnten, up, rst_bar : in std_logic;

q : out std_logic_vector (11 downto 0)) ;

end binary_cntr ;

architecture behavioral of binary_cntr is

begin

Page 15: Microprocessor-Compatible Quadrature Decoder/Counter Design

15

cntr: process (clk)

variable count_v : unsigned (11 downto 0) ;

begin

if rising_edge (clk) then

if rst_bar = '0' then

count_v := (others => '0' ) ;

elsif cnten = '1' then

case up is

when '1' => count_v := count_v + 1 ;

when others => count_v := count_v - 1 ;

end case ;

end if ;

end if ;

q <= std_logic_vector (count_v) ;

end process ;

end behavioral ;

7.4 VHDL Code No.4 (inhibit_fsm)

library ieee ;

use ieee.std_logic_1164.all ;

entity inhibit_fsm is

port ( rst_bar : in std_logic ;

clk, sel, oe_bar : in std_logic ;

inhibit : out std_logic );

end inhibit_fsm ;

Page 16: Microprocessor-Compatible Quadrature Decoder/Counter Design

16

architecture behav of inhibit_fsm is

type inhib_state is ( idle, byte1, byte2) ;

signal present_state, next_state : inhib_state;

begin

inhib_sreg: process (clk)

begin

if rising_edge (clk) then

if rst_bar = '0' then

present_state <= idle;

else

present_state <= next_state ;

end if ;

end if ;

end process ;

inhib_output: process (present_state)

begin

case present_state is

when byte1 | byte2 =>

inhibit <= '1' ;

when others =>

inhibit <= '0' ;

end case ;

end process ;

inhib_nxt_state: process (present_state, sel, oe_bar)

begin

Page 17: Microprocessor-Compatible Quadrature Decoder/Counter Design

17

case present_state is

when idle =>

if sel = '0' and oe_bar = '0' then

next_state <= byte1 ;

else

next_state <= idle ;

end if ;

when byte1 =>

if sel = '1' and oe_bar = '0' then

next_state <= byte2 ;

else

next_state <= byte1 ;

end if ;

when byte2 =>

if oe_bar ='1' then

next_state <= idle ;

elsif sel = '0' and oe_bar = '0' then

next_state <= byte1 ;

else

next_state <= byte2 ;

end if ;

end case ;

end process ;

end behav ;

Page 18: Microprocessor-Compatible Quadrature Decoder/Counter Design

18

7.5 VHDL Code No.5 (double_buff)

library ieee ;

use ieee.std_logic_1164.all ;

entity double_buff is

port (din : in std_logic_vector (11 downto 0) ;

rst_bar : in std_logic ;

clk : in std_logic ;

inhibit : in std_logic ;

dout : out std_logic_vector (11 downto 0)) ;

end double_buff ;

architecture behav of double_buff is

begin

freeze : process (clk)

begin

if rising_edge (clk) then

if rst_bar = '0' then

dout <= x"000" ;

elsif inhibit = '0' then

dout <= din ;

end if ;

end if ;

end process ;

end behav ;

Page 19: Microprocessor-Compatible Quadrature Decoder/Counter Design

19

7.6 VHDL Code No.6 (mux)

ibrary ieee ;

use ieee.std_logic_1164.all ;

entity mux is

port ( din : in std_logic_vector (11 downto 0);

sel : in std_logic ;

oe_bar : in std_logic ;

dout : out std_logic_vector (7 downto 0));

end mux ;

architecture behav of mux is

begin

dout <= "0000" & din (11 downto 8) when oe_bar = '0' and sel =

'0' else

din (7 downto 0) when oe_bar = '0' and sel = '1' else

(others => 'Z' );

end behav ;

7.7 VHDL Code No.7 (quad_decode)

Top-level structural description of quadrature decoder/counter

library ieee ;

use ieee.std_logic_1164.all ;

entity quad_decode is

port ( ch_a, ch_b, rst_bar : in std_logic ;

clk, sel, oe_bar : in std_logic ;

d : out std_logic_vector (7 downto 0 )) ;

end quad_decode ;

Page 20: Microprocessor-Compatible Quadrature Decoder/Counter Design

20

architecture structure of quad_decode is

component filter

port ( cx, clk, rst_bar : std_logic ;

y : out std_logic );

end component ;

component fx_decode

port (a, b, clk, rst_bar : in std_logic ;

cnten, up : out std_logic );

end component ;

component binary_cntr

port ( clk, cnten, up, rst_bar : in std_logic ;

q : out std_logic_vector (11 downto 0 ) );

end component ;

component double_buff

port (din : in std_logic_vector (11 downto 0) ;

rst_bar : in std_logic ;

clk : in std_logic ;

inhibit : in std_logic ;

dout : out std_logic_vector (11 downto 0) );

end component ;

component inhibit_fsm

Page 21: Microprocessor-Compatible Quadrature Decoder/Counter Design

21

port ( rst_bar : in std_logic ;

clk : in std_logic ;

sel : in std_logic ;

inhibit : out std_logic ;

oe_bar : in std_logic );

end component ;

component mux

port (din : in std_logic_vector (11 downto 0);

sel : in std_logic ;

oe_bar : in std_logic ;

dout : out std_logic_vector (7 downto 0));

end component ;

signal ch_a_sig, ch_b_sig, cnten_sig, up_sig : std_logic;

signal count_sig : std_logic_vector (11 downto 0);

signal dbl_buff_sig : std_logic_vector (11 downto 0) ;

signal inhibit_sig : std_logic ;

begin

u0 : filter port map

( cx => ch_a , clk => clk, rst_bar => rst_bar, y => ch_a_sig );

u1 : filter port map (

cx => ch_b, clk =>clk, rst_bar => rst_bar, y => ch_b_sig );

Page 22: Microprocessor-Compatible Quadrature Decoder/Counter Design

22

u2 : fx_decode port map (

a => ch_a_sig, b => ch_b_sig, clk => clk, rst_bar => rst_bar,

cnten => cnten_sig, up => up_sig );

u3 : binary_cntr port map (

clk => clk, cnten => cnten_sig, up => up_sig, rst_bar =>

rst_bar,

q => count_sig );

u4 : double_buff port map (

din => count_sig, rst_bar => rst_bar, clk => clk, inhibit =>

inhibit_sig,

dout => dbl_buff_sig );

u5 : inhibit_fsm port map (

rst_bar => rst_bar, clk => clk, sel => sel, inhibit =>

inhibit_sig,

oe_bar => oe_bar );

u6 : mux port map (

din => dbl_buff_sig, sel => sel, oe_bar => oe_bar , dout => d );

end structure ;