Я вижу, что у вас мало ответов ... Вы опубликовали много кода, чтобы ожидать, что потенциальные ответчики пройдут! Я думаю, тебе придется немного разобраться, прежде чем ты получишь гораздо больше помощи. (И привести в порядок - например, удалить все закомментированные части, пожалуйста.)
Чтобы отладить себя, я бы посоветовал сначала настроить отдельный канал на отдельную сущность. Если у вас все еще есть проблемы, отредактируйте свой вопрос, указав, что вы пробовали, а что не сработало.
Как только работает один канал, вы можете создать 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
для инкапсуляции повторяющегося кода.