title: Q : Serializer/Deserializer problems
body: <p>I want to implement a Serializer/Deserializer (SerDes) in VHDL. Actually, it is more like a simple Shift register. The shift register store a value and shifts to convert information from parallel to serial.The output of the register is 16 bits. It has an 16-bit Parallel input, which allows us to load the register with a new value. The load input allows to load a new value when a falling edge of the clock arrives. </p>
  
  <p>Moreover, I also made a testBench with two SerDes component connected together to implement a sort of loop/ring. Unfortunately, I don't know why when I send a data with the value "1234" from the parallel input I receive "3412" in my parallel output : <a href="https://i.stack.imgur.com/nmhAP.png" rel="nofollow noreferrer">waveform testBench</a>.</p>
  
  <p>Below my code : </p>
  
  <p>SerDes.vhd : </p>
  
  <pre><code>library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  use IEEE.NUMERIC_STD.ALL;
  
  entity SerDes is
      generic ( 
          Dbits : integer := 16
             );   
      Port (
             serial_clk : in STD_LOGIC;
             clk        : in STD_LOGIC;
             rstn       : in STD_LOGIC;
             load : in STD_LOGIC;
             enable : in STD_LOGIC;
             serial_in : in STD_LOGIC;
             parallel_in : in STD_LOGIC_VECTOR(Dbits-1 downto 0);
             dout : out STD_LOGIC;
             parallel_out : out STD_LOGIC_VECTOR(Dbits-1 downto 0)
            );
  end SerDes;
  
  architecture Behavioral of SerDes is
  
  signal rx_counter         : integer   := 0 ;
  signal shift_reg : STD_LOGIC_VECTOR(Dbits-1 downto 0);
  type   TYPE_STATE is (Idle,ShiftIn); 
  signal CURRENT_STATE      : TYPE_STATE := Idle;
  signal serial_clock_D : STD_LOGIC := '0';
  
  begin
  
  serialization : process(serial_clk,rstn)  --Envoyer une donnée parallèle et la récupérer sur la sortie série
  
  begin 
  
      if (rstn = '0') then
          shift_reg &lt;= (others =&gt; '0');
          rx_counter &lt;= 0;
          serial_clock_D &lt;= '0';
          CURRENT_STATE &lt;= Idle;
  
      elsif (clk = '1' and clk'event) then     
              case CURRENT_STATE is 
  
                  when Idle =&gt;
                      if (enable = '1') then
                          CURRENT_STATE &lt;= ShiftIn;
                      else
                          CURRENT_STATE &lt;= Idle;     
                      end if;
                      if (load = '1') then
                          shift_reg &lt;= parallel_in;
                      end if;
                      parallel_out &lt;=  shift_reg;
                      rx_counter &lt;= 0;
  
                  when ShiftIn =&gt;       
                        if(serial_clk = '1' and serial_clock_D = '0') then  
                          shift_reg &lt;=  shift_reg(14 downto 0) &amp; serial_in;                            
                        end if;
                         if (rx_counter = Dbits-1) then
                              CURRENT_STATE &lt;= Idle;
                         else 
                              rx_counter &lt;= rx_counter + 1;
                         end if;
              end case;
      end if;
  end process;
  
  dout &lt;= shift_reg(15); 
  
  end Behavioral;
  </code></pre>
  
  <p>SERDESTestbench.vhd : </p>
  
  <pre><code>library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  
  
  entity SERDES_Testbench is
  --  Port ( );
  end SERDES_Testbench;
  
  architecture Behavioral of SERDES_Testbench is
  constant Dbits : integer := 16;
  
  component SerDes is
      generic ( 
          Dbits : integer := 16
             );   
      Port (
             serial_clk : in STD_LOGIC;
             clk        : in STD_LOGIC;
             rstn       : in STD_LOGIC;
             load : in STD_LOGIC;
             enable : in STD_LOGIC;
             serial_in : in STD_LOGIC;
             parallel_in : in STD_LOGIC_VECTOR(Dbits-1 downto 0);
             dout : out STD_LOGIC;
             parallel_out : out STD_LOGIC_VECTOR(Dbits-1 downto 0)
            );
  end component;
  
  signal   serial_clk : STD_LOGIC := '0';
  signal   clk        : STD_LOGIC := '0';
  signal   rstn       : STD_LOGIC;
  signal   load :  STD_LOGIC := '1';
  signal   enable :  STD_LOGIC := '0';
  signal   serial_in :  STD_LOGIC;
  signal   parallel_in :  STD_LOGIC_VECTOR(Dbits-1 downto 0) := (others =&gt; '0');
  signal   dout :  STD_LOGIC;
  signal   parallel_out :  STD_LOGIC_VECTOR(Dbits-1 downto 0);
  signal   dout2 :  STD_LOGIC;
  signal   parallel_out2 :  STD_LOGIC_VECTOR(Dbits-1 downto 0);
  
  signal end_of_simu : STD_LOGIC := '0';
  
  begin
  
  SR1 : SerDes 
      generic map( 
          Dbits =&gt; Dbits
             )  
      Port map(
             serial_clk    =&gt; serial_clk,
             clk           =&gt; clk,
             rstn          =&gt; rstn,
             load          =&gt; load,
             enable        =&gt; enable,
             serial_in     =&gt; dout2,
             parallel_in   =&gt; parallel_in,
             dout          =&gt; dout,
             parallel_out  =&gt; parallel_out
            );
  
   SR2 : SerDes 
        generic map( 
            Dbits =&gt; Dbits
               )  
        Port map(
               serial_clk    =&gt; serial_clk,
               clk           =&gt; clk,
               rstn          =&gt; rstn,
               load          =&gt; load,
               enable        =&gt; enable,
               serial_in     =&gt; dout,
               parallel_in   =&gt; parallel_in,
               dout          =&gt; dout2,
               parallel_out  =&gt; parallel_out2
              );
  
  
  stimulus : process
    begin
        rstn &lt;= '0';
        wait for 100 ns;
        rstn &lt;= '1';
        wait for 100 ns;
        parallel_in &lt;= X"1234";
        enable &lt;= '1';
        wait;
  end process;
  
  
  clocking : process
  
  begin
    IF end_of_simu /= '1' THEN
        clk &lt;= not clk;
        wait for 5 ns;
    ELSE
        assert false report "end of test" severity note;
        WAIT;
    END IF;
  end process;
  
  
  sclk_gen : process
  
  begin
    IF end_of_simu /= '1' THEN
        serial_clk &lt;= not serial_clk;
        wait for 100 ns;
    ELSE
        assert false report "end of test" severity note;
        WAIT;
    END IF;
  end process;
  
  end Behavioral;
  </code></pre>