Original document: Quadrature Encoder Receiver Module : An Implementation on FPGA (.pdf)

In the original document cited above, we discussed some designs of quadrature encoder receiver module where Verilog code listings were included. This supplementary article provides the same implementations using VHDL. The development flows remain the same for both design A and B, so we basically list the codes and show simulation results here without repeating the design details.

### Design A

For Design A, the receiver module generates pulses at output pin U (up) or D (down), corresponding to whether A leads B, or A lags B, respectively (*). We showed the design process using STG (State Transition Graph) that yielded the results in equation (1) – (4) . The VHDL code for this implementation is in Listing 1 with simulation result shown in Figure 1. (The synthesis and behavioral simulation was performed using Xilinx Webpack 13.4 and Isim simulation, which could be downloaded from Xilinx website.

(*) It turns out that in the original document, the Karnaugh map for output U and D shuffles, so as the resulting equations (3) and (4). You could verify from the simulation in Figure 9. If this gives the wrong sense for your motor setup, simply switch equation (3) and (4). We do so in the VHDL code below.

```library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity x4enc1 is
Port ( A,B,Clk : in  STD_LOGIC;
U,D : out  STD_LOGIC);
end x4enc1;
architecture Behavioral of x4enc1 is
signal Q0, Q1 : STD_LOGIC;
begin
process (Clk)
begin
if (Clk'event and Clk='1') then
Q0 <= A xor B;
Q1 <= B;
end if;
end process;
U <= (not A and not B and Q1) or (not A and Q1 and not Q0)
or (A and not Q1 and not Q0) or (A and B and not Q1);
D <= (not A and B and not Q1) or (not A and not Q1 and Q0)
or (A and Q1 and Q0) or (A and not B and Q1);
end Behavioral;
```

Listing 1: VHDL code for X4 receiver module (Design A, STG method) Figure 1: Simulation result for X4 receiver module (Design A, STG method)

Manually solving for logic equations using STG might be fun for simple problem, though it’s quite easy to make mistakes (as you can see). Such implementation is often referred to as “structural model.” With the advancement of computer technology and software, it’s preferred that we benefit from development tools as much as possible. For the receiver module design A, we can draw an ASM (Algorithmic State Machine) chart like it Figure 2 and write VHDL code from it directly, such as in Listing 2. This approach is named “behavioral model,” since we just describe what the model must do and leave the low-level synthesis to the software. The simulation result in Figure 3 confirms that the module has similar behavior as the STG design version, with much less human effort in the design process. Figure 2: ASM chart for X4 receiver module (design A)

```library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity x4enc2 is
Port ( AB : in  STD_LOGIC_VECTOR (1 downto 0);
Clk : in  STD_LOGIC;
UD : out  STD_LOGIC_VECTOR (1 downto 0));
end x4enc2;

architecture Behavioral of x4enc2 is
signal State: STD_LOGIC_VECTOR (1 downto 0) := "00";
-- State 0 = "00", State 1 = "01",
-- State 2 = "10", State 3 = "11"
begin
process (CLk)
begin
if (Clk'event and Clk='1') then
case State is
when "00" => -- State 0
case AB is
when "00" => UD  UD <= "01"; State  UD <= "10"; State  UD   -- State 1
case AB is
when "00" => UD <= "01"; State  UD  UD <= "10"; State  UD  -- State 2
case AB is
when "01" => UD <= "10"; State  UD <= "01"; State  UD  UD  -- State 3
case AB is
when "00" => UD <= "10"; State  UD  UD <= "01"; State  UD  null;
end case;
end if;
end process;

end Behavioral;

```

Listing 2: VHDL code for X4 receiver module (Design A, ASM method ) Figure 3: Simulation result for X4 receiver module (Design A, ASM method)

### Design B

Design B in the original document refers to the X4 encoder receiver module intended to be used with a counter that accepts pulse and direction inputs. So the module must provide output P (pulse) and DIR (direction). Following the same discussion there, the resulting VHDL code is as in Listing 3, with simulation result shown in Figure 4.

```library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity x4enc3 is
Port ( A,B, Clk : in  STD_LOGIC;
P,Dir : out  STD_LOGIC);
end x4enc3;

architecture Behavioral of x4enc3 is
signal Ar, Br : STD_LOGIC_VECTOR (1 downto 0) := "00";
begin
process (Clk,A,B)
begin
if (Clk'event and Clk='1') then
Ar <= (Ar(0)&A);
Br <= (Br(0)&B);
if (Ar = "01") then -- rising edge of A
P <= '1';
if (B = '0') then Dir <= '1'; -- A leads B
else Dir <= '0';					-- B leads A
end if;
elsif (Ar = "10") then -- falling edge of A
P <= '1';
if (B = '1') then Dir <= '1'; -- A leads B
else Dir <= '0';					-- B leads A
end if;
elsif (Br = "01") then -- positive edge of B
P <= '1';
if (A = '1') then Dir <= '1'; -- A leads B
else Dir <= '0';					-- B leads A
end if;
elsif (Br = "10") then -- positive edge of B
P <= '1';
if (A = '0') then Dir <= '1'; -- A leads B
else Dir <= '0';					-- B leads A
end if;
else P <= '0';
end if;
end if;

end process;
end Behavioral;

```

Listing 3: VHDL code for X4 receiver module (Design B) Figure 4: Simulation result for X4 receiver module (Design B)