February 1, 2018

a Hardware Design for XOR gates using sequential logic in VHDL

XOR logic gates are a fundamental component in cryptography. Many of the common stream and block ciphers use XOR gates. A few of these ciphers are ChaCha (stream cipher), AES (block cipher), and RSA (block cipher).

While many of the compiled and interpreted languages support bitwise operations such as XOR, the software implementation of both block and stream ciphers is computationally inefficient compared to FPGA and ASIC implementations.

Hybrid FPGA boards integrate FPGAs with multicore ARM and Intel application processors over high speed buses.  The ARM and Intel processors are general purpose processors. On a hybrid board, the ARM or Intel processor is termed the hard processor system or HPS. Writing to the FPGA from the HPS is typically performed via C from an embedded Linux build (yocto or buildroot) running on the ARM or Intel core.  For a hybrid ARM configuration, a simple bitstream can also be loaded into the FPGA fabric without using any ARM design blocks or functionality in the ARM core.

The following is a simple hardware design that I wrote in VHDL and simulated in ModelSim. The image contains the waveform output of a simulation in ModelSim. The HPS is not used. The bitstream is loaded into the FPGA fabric on boot. VHDL components are utilized and a testbench is defined for testing the design.  The entity and architecture VHDL design units are below.

ModelSim Full Window view with wave form output of xor simulation. ModelSim-Intel FPGA Starter Edition © Intel

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
- --three input xnor gate entity declaration - external interface to design entity
entity xnorgate is
port (
    a,b,c : in std_logic;
    q : out std_logic);
end xnorgate;

architecture xng of xnorgate is
begin
    q <= a xnor b xnor c;
end xng;

- --chain of xor / xnor gates using components and sequential logic
entity xorchain is
port (
    A,B,C,D,E,F : in std_logic;
    Av,Bv       : in std_logic_vector(31 downto 0);
    CLOCK_50    : in std_logic;
    Q           : out std_logic;
    Qv          : out std_logic_vector(31 downto 0));
end xorchain;

architecture rtl of xorchain is
component xorgate is
port (
    a,b  : in std_logic;
    q    : out std_logic);
end component;

component xnorgate is
port (
    a,b,c  : in std_logic;
    q      : out std_logic);
end component;

component xorsgate is
port (
    av : in std_logic_vector(31 downto 0);
    bv : in std_logic_vector(31 downto 0);
    qv : out std_logic_vector(31 downto 0));
end component;

signal a_in, b_in, c_in, d_in, e_in, f_in : std_logic;
signal av_in, bv_in : std_logic_vector(31 downto 0); 

signal conn1, conn2, conn3 : std_logic;

begin
    xorgt1  : xorgate port map(a => a_in, b => b_in, q => conn1); 
    xorgt2  : xorgate port map(a => c_in, b => d_in, q => conn2);
    xorgt3  : xorgate port map(a => e_in, b => f_in, q => conn3); 
    xnorgt1 : xnorgate port map(conn1, conn2, conn3, Q);
    xorsgt1 : xorsgate port map(av => av_in, bv => bv_in, qv => Qv);

   process(CLOCK_50)
   begin
       if rising_edge(CLOCK_50) then --assign inputs on rising clock edge
           a_in <= A;
           b_in <= B;
           c_in <= C;
           d_in <= D;
           e_in <= E;
           f_in <= F;
           av_in(31 downto 0) <= Av(31 downto 0);
           bv_in(31 downto 0) <= Bv(31 downto 0);
       end if;
    end process;
end rtl;

entity xorchain_tb is
end xorchain_tb;

architecture xorchain_tb_arch of xorchain_tb is
    signal A_in,B_in,C_in,D_in,E_in,F_in : std_logic := '0';
    signal Av_in                         : std_logic_vector(31 downto 0);
    signal Bv_in                         : std_logic_vector(31 downto 0);
    signal CLOCK_50_in                   : std_logic;
    signal BRK                           : boolean := FALSE;
    signal Q_out                         : std_logic;
    signal Qv_out                        : std_logic_vector(31 downto 0);

component xorchain
port (
    A,B,C,D,E,F      : in std_logic;
    Av               : in std_logic_vector(31 downto 0);
    Bv               : in std_logic_vector(31 downto 0);
    CLOCK_50         : in std_logic;
    Q                : out std_logic;
    Qv               : out std_logic_vector(31 downto 0));
end component;

begin
    xorchain_instance: xorchain port map (A => A_in,B => B_in, C => C_in, 
                                          D => D_in, E => E_in, F => F_in, Av => Av_in,
                                          Bv => Bv_in, CLOCK_50 => CLOCK_50_in, Q => Q_out,
                                          Qv => Qv_out);
clockprocess: process
    begin
        while not BRK loop
            CLOCK_50_in <= '0';
                wait for 20 ns;
                CLOCK_50_in <= '1';
                wait for 20 ns;
        end loop;
    wait;
end process clockprocess;
  
testprocess : process
    begin
        A_in <= '1';
        B_in <= '0';
        C_in <= '1';
        D_in <= '0';
        E_in <= '1';
        F_in <= '1';
        wait for 40 ns;
        A_in <= '1';
        B_in <= '0';
        C_in <= '1';
        D_in <= '0';
        E_in <= '1';
        F_in <= '0';
        wait for 20 ns;
        A_in <= '0';
        B_in <= '0';
        C_in <= '1';
        D_in <= '0';
        E_in <= '1';
        F_in <= '0';
        wait for 40 ns;
        BRK <= TRUE;
        wait;
    end process testprocess;
end xorchain_tb_arch;

entity xorgate is
port (
    a,b : in std_logic;
    q   : out std_logic);
end xorgate;

architecture xg of xorgate is
begin
    q <= a xor b;
end xg;

entity xorsgate is
port (
    av : in std_logic_vector(31 downto 0);
    bv : in std_logic_vector(31 downto 0);
    qv : out std_logic_vector(31 downto 0));
end xorsgate;

architecture xsg of xorsgate is
begin
    qv <= av xor bv;
end xsg;