4 FIFO и сериализация - PullRequest
       27

4 FIFO и сериализация

0 голосов
/ 27 июня 2011

Я реализовал очередь 4 FIFO и блок, который ищет индекс FIFO, и, если найденный FIFO, который не пустой, извлечет конец данных, он отправит его последовательно.

Это код:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Serialize is
       port
       (
           TX                                                                  : out std_logic_vector(1 downto 0);
           RESET, CLK, We1, We2, We3, We4                                      : in std_logic;
           --
           DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D                          : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
           fifo_full1, fifo_full2, fifo_full3, fifo_full4                      : out std_logic;
           --
           SendPackage                                                         : out std_logic
       );
end Serialize;

architecture rtl of Serialize is
     signal step, nr : integer:=0;
     signal enl : std_logic := '0';
     signal temp : std_logic_vector(31 downto 0);
     --signal txx  : std_logic_vector(1 downto 0);
     TYPE sr_length IS ARRAY (0 to 3) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
     SIGNAL queue, queue1, queue2, queue3 : sr_length;
     signal ptr, ptr1, ptr2, ptr3 : integer:= 0;
    -- signal tmp : std_logic_vector(1 downto 0);
     signal i_a, i_b : std_logic;
     signal q_a, q_b, q_c, q_d : std_logic_vector(31 downto 0);
     --signal nr : integer := 0;
begin

     process(CLK, RESET, We1, We2, We3, We4, DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D) is
          --variable step, nr : integer:=0;
          --variable enl : std_logic := '0';
          --variable temp : std_logic_vector(31 downto 0);
     begin
          if(RESET = '1') then
              SendPackage <= '0';
              TX<= "00";
             -- busy <= '0';
              --step:= 0;
              --temp := X"00000000";
              --enl := '0';
              step<= 1;
              temp <= X"00000000";
              enl <= '0';
               ptr <= 0;
               ptr1 <= 0;
               ptr2 <= 0;
               ptr3 <= 0;
               fifo_full1 <= '0';
               fifo_full2 <= '0';
               fifo_full3 <= '0';
               fifo_full4 <= '0';
               --nr := 0;
               nr <= 0;
               for i in 0 to 2 loop
                   queue(i)<=X"00000000";
                   queue1(i)<=X"00000000";
                   queue2(i)<=X"00000000";
                   queue3(i)<=X"00000000";
               end loop;
          end if;
          if(CLK'event) then
            if(CLK = '1')then
              --SendPackage <= '0';
            if(We1 = '1' or We2 = '1' or We3 = '1' or We4 = '1')then
               IF (We1 = '1' and ptr <= 3) THEN
                    for i in 0 to 2 loop
                        queue(i + 1) <= queue(i);
                    end loop;
                    queue(0) <= DATA_IN_A;
                    ptr <= ptr+ 1;
              END IF;
              IF (We2 = '1' and ptr1 <= 3) THEN
                    for i in 0 to 2 loop
                        queue1(i + 1) <= queue1(i);
                    end loop;
                    queue1(0) <= DATA_IN_B;
                    ptr1 <= ptr1+ 1;
              END IF;
              IF (We3 = '1' and ptr2 <= 3) THEN
                    for i in 0 to 2 loop
                        queue2(i + 1) <= queue2(i);
                    end loop;
                    queue2(0) <= DATA_IN_C;
                    ptr2 <= ptr2 + 1;
              END IF;
              IF (We4 = '1' and ptr3 <= 3) THEN
                    for i in 0 to 2 loop
                        queue3(i + 1) <= queue3(i);
                    end loop;
                    queue3(0) <= DATA_IN_D;
                   --if(ptr3<=3)then ptr3 <= ptr3 + 1;  end if;
                   ptr3 <= ptr3 + 1;
              END IF;
            elsif(enl = '1')then
                   SendPackage <= '0';
                   --if(step = 0) then step <= step + 1;   end if;
                   if(step = 1) then TX <= temp(1 downto 0); i_b <= '1'; step <= step + 1;   end if;
                   if(step = 2) then TX <= temp(3 downto 2);   i_b <= '0'; step <= step + 1;   end if;   --step <= step + 1;
                   if(step = 3) then TX <= temp(5 downto 4); step <= step + 1;   end if;
                   if(step = 4) then TX <= temp(7 downto 6); step <= step + 1;   end if;
                   if(step = 5) then TX <= temp(9 downto 8); step <= step + 1;   end if;
                   if(step = 6) then TX <= temp(11 downto 10); step <= step + 1;   end if;
                   if(step = 7) then TX <= temp(13 downto 12); step <= step + 1;   end if;
                   if(step = 8) then TX <= temp(15 downto 14); step <= step + 1;   end if;
                   if(step = 9) then TX <= temp(17 downto 16); step <= step + 1;   end if;
                   if(step = 10) then TX <= temp(19 downto 18); step <= step + 1;   end if;
                   if(step = 11) then TX <= temp(21 downto 20); step <= step + 1;   end if;
                   if(step = 12) then TX <= temp(23 downto 22); step <= step + 1;   end if;
                   if(step = 13) then TX <= temp(25 downto 24);  step <= step + 1;   end if;
                   if(step = 14) then TX <= temp(27 downto 26); step <= step + 1;   end if;
                   if(step = 15) then TX <= temp(29 downto 28); step <= step + 1;   end if;
                   if(step = 16) then--mai merg un pas pentru a putea transmite tot pachetul. Daca nu pierd 2 biti
                        TX <= temp(31 downto 30); step <= step + 1;   end if;
                   if(step = 17) then--dupa inca un pas initializez alta trasmitere
                        --step := 0;
                        --temp := X"00000000";
                        --enl := '0';
                        step <= 1;
                        temp <= X"00000000";
                        enl <= '0';
                        --step <= step + 1;
                   end if;
                   i_a <= '1';
                   --step <= step + 1;
            elsif(enl = '0')then
                if(nr = 0)then
                   if(ptr>=1)then
                        ptr <= ptr - 1;
                        --temp := queue(ptr-1);
                        temp <= queue(ptr-1);
                        q_a <= queue(ptr-1);
                        SendPackage <= '1';
                        enl <= '1';
                        step <= 1;
                        --enl := '1';
                        --step := 0;
                        TX <= "00";
                   end if;
                   nr <= nr + 1;
               end if;
               if(nr = 1)then
                   if(ptr1>=1)then
                        ptr1 <= ptr1 - 1;
                        temp <= queue1(ptr1-1);
                        q_b <= queue1(ptr1-1);
                        --temp := queue1(ptr1-1);
                        SendPackage <= '1';
                         enl <= '1';
                        step <= 1;
                        --enl := '1';
                        --step := 0;
                        TX <= "00";
                   end if;
                   nr <= nr + 1;
               end if;
               if(nr = 2)then
                   if(ptr2>=1)then
                        ptr2 <= ptr2 - 1;
                        --temp := queue2(ptr2-1);
                        temp <= queue2(ptr2-1);
                        q_c <= queue2(ptr2-1);
                        SendPackage <= '1';
                         enl <= '1';
                        step <= 1;
                        --enl := '1';
                        --step := 0;
                        TX <= "00";
                   end if;
                   nr <= nr + 1;
               end if;
               if(nr >= 3)then
                   if(ptr3>=1)then
                        ptr3 <= ptr3 - 1;
                        temp <= queue3(ptr3-1);
                        q_d <= queue3(ptr3-1);
                        --temp := queue3(ptr3-1);
                        SendPackage <= '1';
                         enl <= '1';
                        step <= 1;
                        nr <= nr  + 1;
                       -- nr := 0;
                        --enl := '1';
                        --step := 0;
                        TX <= "00";
                   end if;
                   nr <= 0;
                end if;
                --if(nr >= 3 )then nr <= 0; end if;
            end if;

          else
            SendPackage <= '0';
            i_a <= '0';
          end if;
         end if;
          if(ptr >= 4)then fifo_full1 <= '1'; else fifo_full1 <= '0'; end if;
          if(ptr1 >= 4)then fifo_full2 <= '1'; else fifo_full2 <= '0'; end if;
          if(ptr2 >= 4)then fifo_full3 <= '1'; else fifo_full3 <= '0'; end if;
          if(ptr3 >= 4)then fifo_full4 <= '1'; else fifo_full4 <= '0'; end if;
     end process;
end rtl;

Работает нормально, пока вы не захотите вставить данные в одну очередь, которая не заполнена, и передача запущена.Этот шаг опущен.Из-за этого передача не будет работать.Я хочу, чтобы он работал независимо.

ex:

step : 1       3   4   5   6   7   8   9   10  11  12 ... 17
           _
We   :____| |_____________________________________.....
       _   _   _   _   _   _   _   _   _   _   _   _    
CLK  :| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|..

Я работаю (симулирую и внедряю на fpga) с Altium Designer Winter 09

1 Ответ

6 голосов
/ 29 июня 2011

Я вижу, что у вас мало ответов ... Вы опубликовали много кода, чтобы ожидать, что потенциальные ответчики пройдут! Я думаю, тебе придется немного разобраться, прежде чем ты получишь гораздо больше помощи. (И привести в порядок - например, удалить все закомментированные части, пожалуйста.)

Чтобы отладить себя, я бы посоветовал сначала настроить отдельный канал на отдельную сущность. Если у вас все еще есть проблемы, отредактируйте свой вопрос, указав, что вы пробовали, а что не сработало.

Как только работает один канал, вы можете создать 4 из них с меньшим процессом управления, чтобы разобраться с загрузкой этих элементов и получить правильные выводы в нужных местах.

Создайте вещи небольшими этапами.

Некоторые комментарии к вашему стилю кодирования:

Примечание: они основаны исключительно на «анализе стиля», а не на попытке исправить (или даже воспроизвести) какую-либо функциональность!


Прежде всего, отбросьте эти два пункта

use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

Вы их не используете. Если вам нужно сделать арифметику для векторов, используйте ieee.numeric_std и используйте unsigned / signed типов.


В entity у вас есть 4 "версии" нескольких сигналов - почему бы не сделать их std_logic_vector с шириной векторов, управляемой generic? Вы могли бы сделать то же самое с ptr, ptr1 и т. Д. (Создать массив целых чисел - например, полные метки для использования integers и не пытаться заставить всю арифметику происходить на std_logic_vectors)


Список чувствительности слишком сложен:

process(CLK, RESET, We1, We2, We3, We4, DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D) is

Вы пишете синхронный процесс с асинхронным сбросом, поэтому вам нужно только CLK и RESET в списке чувствительности.


Ваши часы:

if (CLK'event) then
     if (CLK = '1') then

имеют более привычную идиому:

if rising_edge(clk) then

(и не требуется () для логического условия if. Это будет программирование на C:)


Эта петля

 for i in 0 to 2 loop
     queue(i + 1) <= queue(i);
 end loop;
 queue(0) <= DATA_IN_A;

можно сделать в одной строке:

queue <= data_in_a & queue(0 to sr_length'high-1);

Каждый раз, когда много кода копируется и вставляется, обычно есть лучший способ:

 if(step = 1) then TX <= temp(1 downto 0); i_b <= '1'; step <= step + 1;   end if;
 if(step = 2) then TX <= temp(3 downto 2);   i_b <= '0'; step <= step + 1;   end if;   
 if(step = 3) then TX <= temp(5 downto 4); step <= step + 1;   end if;

может стать например:

if (step < 17) then 
    TX <= temp((step-1)*2+1 downto (step-1)*2);
    step <= step + 1;
end if;
i_b <= '0';
if step = 1 then 
   i_b <= '1';
end if;

, что было бы еще более аккуратно, если бы шаг шел от 0 до 16, а не от 1 до 17!


Наконец, эти части:

if(nr = 0)then
  if(ptr>=1)then

можно сделать в цикле for, если ptr..., q_a, q_b и т. Д. Были массивами.

и аналогичная петля для

if(ptr >= 4)then fifo_full1 <= '1'; else fifo_full1 <= '0'; end if;

Каждый раз, когда вы копируете, вставляете, а затем настраиваете большие куски кода, посмотрите на loop или создайте function или procedure для инкапсуляции повторяющегося кода.

...