Перейти к содержанию
    

Обращаюсь к знатокам VHDL

Потихоньку начинаю понимать, что сотворил. Получается циклы лучше не использовать в VHDL? В каких случаях их нужно использовать?

 

Вы этот цикл вручную "синтезируйте", на бумажке, из логических вентилей. Рисуя схему, соответствующую каждой итерации цикла, и соединяя их друг с другом... И тогда все сразу и в полном объеме поймете. Это у Вас классическая проблема новичка, не изучившего построение цифровых логических схем.

 

Попробуйте пойти от обратного - нарисуйте блок-схему устройства для подсчета CRC из логики и регистров-триггеров, и потом опишите ее на VHDL. Получится куда более маленькая (по ресурсам) конструкция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы этот цикл вручную "синтезируйте", на бумажке, из логических вентилей. Рисуя схему, соответствующую каждой итерации цикла, и соединяя их друг с другом... И тогда все сразу и в полном объеме поймете. Это у Вас классическая проблема новичка, не изучившего построение цифровых логических схем.

 

Попробуйте пойти от обратного - нарисуйте блок-схему устройства для подсчета CRC из логики и регистров-триггеров, и потом опишите ее на VHDL. Получится куда более маленькая (по ресурсам) конструкция.

 

Вооот! теперь все на свои места встало, SM предложил рисовать схему, значит мне пора сказать что

 

в ПЛИС все выполняется одновременно, и цикл в плис ни что иное как сокращенная запись, то есть (пишу условно не привязываясь к языку, надеюсь будет понятно)

for(i=0;i<3; i= i+1)

out <= in[2*i];

ничто иное как запись

out[0] <= in[0];

out[1] <= in[2];

out[2] <= in[4];

то есть в ПЛИСах (тут я тоже имею ввиду описание железа в целом) циклы нужны для улучшения читабельности кода, и избавления автора от рутины, но ими нельзя делать итерации.

 

Все последовательное (итерации) в ПЛИС делается конечными автоматами, и типичный цикл for выглядит как автомат

 

1 состояние: инициализация i=0;

2 состояние: проверка i<3 (переход в 3 если верно, или в 4 если нет)

3 состояние: тело цикла + увеличение i = i + 1; переход в 2

4 состояние: завершение цикла

 

остается добавить тактовый сигнал и будет цикл.

Насчет CRC - это поточная контрольная сумма, которая затачивалась на изменение с каждым пришедшим разрядом, в процах применяют табличный метод рассчета, который сводиться к тому что из таблицы берут результат обработки 8 бит. То есть в таблице перечислены все результаты для каждого вида байта, и вместо того чтобы 8 раз обрабатывать один бит, берут сразу результат обработки 8 бит. Но это актуально для процов, потому что там пока считаете одно, все остальное стоит.

В плис же все идет в параллель, и блок расчета CRC по ходу приема не задержит ни один другой блок, и в ней нет смысла терять память на таблицы и городить огромные мультиплексоры выбора из памяти (ну или что там городиться), достаточно правильно реализовать сдвиговый регистр с обратными связями и все!

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем большое спасибо! Теперь я понял где был не прав.

то есть в ПЛИСах (тут я тоже имею ввиду описание железа в целом) циклы нужны для улучшения читабельности кода, и избавления автора от рутины, но ими нельзя делать итерации

Как то даже и не догадывался об этом!

 

Сейчас попробую написать код правильно.

 

Я еще хотел уточнить можно в process, как в моем случае, использовать большое количество последовательных операторов? Ведь все последовательные операторы должны выполняться за один такт clk, а выполнение каждого оператора происходит не мгновенно а с задержкой (дельта)! Проконсультируйте меня пожалуйста по данному вопросу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

там вообще нет последовательных операторов, все они параллельны! И их может быть не ограничено, в этом прелесть ПЛИС, сделал блок. отладил, потом скопировал его миллион раз, и у получил миллион блоков работающих без задержек.

 

каждую строчку, что вы написали надо рассматривать как отдельную от всех других, даже когда вы пишите блокирующие присвоения типа

 

A=A +1;

B=A + 2;

C=B +3;

 

где казалось бы нижняя строчка зависит от верхних, то это все на уровне записи, чтобы было удобно читать человеку, плис же для себя сделает

 

A <= A+1;

B <= (A+1)+2;

C <= ((A+1)+2)+3;

 

которые все выполнятся в параллель

 

правильно мыслить идеальной ситуаций, что у вас до фронта клока ((clk'event & clk == 1) или как там в VHDL,уже забыл) все сигналы имеют одно значение, а сразу после все имеют новое, заданное значение, и все значения применяться независимо и одновременно. В реальности потом окажется что какие то сигналы станут верными чуть раньше, какие то чуть позже, но правильно думать что до след сигнала фронта клока все уже будет правильно установлено. Проблемы возникают когда у вас 2 клока не связанных друг с другом, но это уже другая история, на будущее так сказать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем добрый день! Появились проблемы при разработке протокола Modbus для slave на VHDL, ПЛИС фирмы Xilinx XC6SLX9. Сам код:

 

Может быть есть более простые варианты решения данной задачи?

А еще есть и вот такой взгляд...

Вы принимаете данные в ПЛИС байтами, а это значит, что не сильно быстро. Потому как синхрочастота внутри ПЛИС может быть на порядок быстрее, чем частота приема байтов. А это значит, что обработка может быть сделана последовательным кодом по-битно...

Не успеваете по 1 биту, обрабатывайте по 2 бита, или по 4...

Чем меньше комбинационной логики, тем быстрее можно сделать обработку внутри ПЛИС.

 

В том числе и CRC... А это даст довольно большую экономию ресурса. Только надо уметь сопрячь частоту приема с частотой обработки...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

насчет CRC - посмотрите как делается и разберитесь что и как (Вам этот ресурс ранее рекомендовали).

Попробуйте разобраться, просимулировать и проверить работу для начала...

 

Потом опишите FSM по рекомендациям Golikov A. вместо цикла...

 

Затем вставите логику для синхронизации при пересечении клоковых доменов, о чем Вам написал iosifk

 

PS совет: оформите CRC как функцию - проще будет использование в FSM

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

там вообще нет последовательных операторов, все они параллельны!

Как это? Ведь внутри process команды выполняются последовательно. А можем задать очередность выполнения команд?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как это? Ведь внутри process команды выполняются последовательно. А можем задать очередность выполнения команд?

 

Мы сейчас не говорим о тестбенче.

Это не "команды", это "описание железа"... Ну, представьте схему на которой изображены 3 триггера. Имеет ли значение, в каком углу схемы нарисован триггер?

А если не верите, то перенесите эти "команды" немного "вверх" и запустите симуляцию...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можем задать очередность выполнения команд?

можем, но только через конечный автомат:)...

 

все что написано - параллельно

все что хотим последовательно - через автомат.

 

Тут есть один момент, тестбенчь - это совершенно другая сущность, она просто написана на том же языке, просто для удобства разработчиков. Но строго говоря надо различать тестбенчь и описание железа, они работают по похожим, но все же разным правилам, так будет правильнее для понимания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можем, но только через конечный автомат...

 

все что написано - параллельно

все что хотим последовательно - через автомат.

Что же это получается, что даже внутри process команды выполняются параллельно! А в литературе пышут про последовательное выполнение команд. Получается, что в process можно поменять команды местами и ни чего не изменится? Или нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же это получается, что даже внутри process команды выполняются параллельно!

А мое письмо пришло?

Если нет, то в личной карточке участника есть адрес или через сайт...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же это получается, что даже внутри process команды выполняются параллельно! А в литературе пышут про последовательное выполнение команд. Получается, что в process можно поменять команды местами и ни чего не изменится? Или нет

А почему не почитать миинимум литературы, Вы задаете вопросы которые разъясняются во втором параграфе ЛЮБОЙ книги по VHDL.

Изменено пользователем silantis

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему не почитать миинимум литературы, Вы задаете вопросы которые разъясняются во втором параграфе ЛЮБОЙ книги по VHDL.

потому что так быстрее если есть кому ответить....

 

Получается, что в process можно поменять команды местами и ни чего не изменится? Или нет

 

да можно поменять, но надо учитывать 2 момента.

 

1. есть блокирующие и не блокирующие присвоения

 

то есть

A<= B;

B<= C;

 

это не блокирующие они выполняются параллельно, и запись

 

A <= B;

B <= C;

 

равносильна

B <= C;

A <= B;

 

но есть блокирующие

 

A = A+1;

B = A+1;

 

эти выполняются тоже параллельно, то есть и А и В поменяют свои значения мгновенно, но для синтезатора они выглядят как

A <= A+1;

B <= (A+1) + 1; === B <= A+2;

 

 

а вот если записать в обратной последовательности

B = A+1;

A = A+1;

то синтезатор из воспримет как

B<= A+1;

A<=A+1;

 

то есть в этом случае порядок важен, но влияет лишь на интерпритацию записанного, но никак не на время между присвоениями...

 

 

2. Момент это последовательность одинаковых присвоений (вот тут я что-то стал сомневаться так ли это в VHDL, или это только для верилога)

 

под одним клоком если написать

 

A<= 2;

 

if(C == 5)

A <= 3;

 

то в случае С == 5

мы имеем запись вида

A<=2;

A<=3;

в этом случае, синтезатор выкидывает все записи кроме последней, то есть

А<=3;

а если же С !=5

то остается только А<=2;

 

соответственно для варианта

if(C == 5)

A <= 3;

A<= 2;

 

всегда будет оставаться только А<=2, как последние записанное, не зависимо от значения С

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. есть блокирующие и не блокирующие присвоения
Молодой человек, тема про VHDL. Что вы лезете со своим Верилогом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо! И огромное спасибо Golikov A.!!

 

Учитывая все замечания я написал код расчета CRC16. Выглядит так:

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CRCMod is
port (clk : in std_logic;
        crc : out std_logic_vector(15 downto 0));
end CRCMod;

architecture Behavioral of CRCMod is

type ram_type is array (0 to 7) of std_logic_vector(7 downto 0);
type state_type is (st1,st2,st3,st4);

signal dat     : ram_type;
signal state: state_type:=st1;
signal flag    : std_logic;
signal reg     : std_logic_vector(15 downto 0):=x"ffff";
signal i     : std_logic_vector(2 downto 0):=(others => '0');--счетчик бит
signal j     : std_logic_vector(7 downto 0):=(others => '0');--счетчик байт
signal n     : std_logic_vector(7 downto 0):=(others => '0');--количество байт

begin
--dat<=(x"11",x"06",x"00",x"01",x"00",x"03",x"9a",x"9b");
dat<=(x"11",x"03",x"00",x"6b",x"00",x"03",x"76",x"87");
n<=x"05";
p_crc:process(clk)
    begin
        if clk'event and clk='1' then
            case state is
                when st1 => 
                    reg(7 downto 0) <= reg(7 downto 0) xor dat(conv_integer(j));
                    state <= st2;
                when st2 => 
                    flag <= reg(0);
                    reg <= '0' & reg(15 downto 1);
                    state <= st3;
                when st3 =>
                    if flag = '1' then
                        reg <= reg xor x"a001"; 
                    end if;
                    if i=7 then
                        state <= st1;
                        i<=conv_std_logic_vector(0,3);
                        if j=n then state <= st4;
                            else j<=j+1;
                        end if;
                        else 
                        i<=i+1;
                        state <= st2;
                    end if;
                when others => null;
            end case;
        end if;
    end process p_crc;
    crc <= reg(7 downto 0)&reg(15 downto 8);
end Behavioral;

 

Рассчитывает контрольную сумму для 5 байт.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...