Q: Проблемы с сериализатором / десериализатором - PullRequest
0 голосов
/ 12 октября 2018

Я хочу реализовать сериализатор / десериализатор (SerDes) в VHDL.На самом деле, это больше похоже на простой регистр Shift.Сдвиговый регистр хранит значение и сдвигает для преобразования информации из параллельной в последовательную. Выходной регистр составляет 16 бит.Он имеет 16-битный параллельный вход, что позволяет нам загружать регистр с новым значением.Вход загрузки позволяет загрузить новое значение, когда наступает задний фронт часов.

Более того, я также создал testBench с двумя компонентами SerDes, соединенными вместе для реализации своего рода цикла / кольца.К сожалению, я не знаю, почему, когда я отправляю данные со значением «1234» с параллельного входа, я получаю «3412» на моем параллельном выходе: waveform testBench .

Ниже моегокод:

SerDes.vhd:

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 <= (others => '0');
        rx_counter <= 0;
        serial_clock_D <= '0';
        CURRENT_STATE <= Idle;

    elsif (clk = '1' and clk'event) then     
            case CURRENT_STATE is 

                when Idle =>
                    if (enable = '1') then
                        CURRENT_STATE <= ShiftIn;
                    else
                        CURRENT_STATE <= Idle;     
                    end if;
                    if (load = '1') then
                        shift_reg <= parallel_in;
                    end if;
                    parallel_out <=  shift_reg;
                    rx_counter <= 0;

                when ShiftIn =>       
                      if(serial_clk = '1' and serial_clock_D = '0') then  
                        shift_reg <=  shift_reg(14 downto 0) & serial_in;                            
                      end if;
                       if (rx_counter = Dbits-1) then
                            CURRENT_STATE <= Idle;
                       else 
                            rx_counter <= rx_counter + 1;
                       end if;
            end case;
    end if;
end process;

dout <= shift_reg(15); 

end Behavioral;

SERDESTestbench.vhd:

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 => '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 => Dbits
           )  
    Port map(
           serial_clk    => serial_clk,
           clk           => clk,
           rstn          => rstn,
           load          => load,
           enable        => enable,
           serial_in     => dout2,
           parallel_in   => parallel_in,
           dout          => dout,
           parallel_out  => parallel_out
          );

 SR2 : SerDes 
      generic map( 
          Dbits => Dbits
             )  
      Port map(
             serial_clk    => serial_clk,
             clk           => clk,
             rstn          => rstn,
             load          => load,
             enable        => enable,
             serial_in     => dout,
             parallel_in   => parallel_in,
             dout          => dout2,
             parallel_out  => parallel_out2
            );


stimulus : process
  begin
      rstn <= '0';
      wait for 100 ns;
      rstn <= '1';
      wait for 100 ns;
      parallel_in <= X"1234";
      enable <= '1';
      wait;
end process;


clocking : process

begin
  IF end_of_simu /= '1' THEN
      clk <= 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 <= not serial_clk;
      wait for 100 ns;
  ELSE
      assert false report "end of test" severity note;
      WAIT;
  END IF;
end process;

end Behavioral;
...