Flip-fl0p 4 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба Приветствую вас. Возникло некоторое непонимание при написании простейшего счетчика. Приведу пример самого простейшего счетчика c синхронным сбросом на VHDL, которым я обычно пользуюсь: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY COUNTER_SCLR IS GENERIC ( WIDTH : INTEGER := 512 ); PORT ( CLK : IN STD_LOGIC; SCLR : IN STD_LOGIC; DATA_OUT : OUT INTEGER RANGE 0 TO WIDTH - 1 := 0 ); END ENTITY; ARCHITECTURE RTL OF COUNTER_SCLR IS SIGNAL COUNTER : INTEGER RANGE 0 TO WIDTH - 1 := 0; BEGIN COUNTER_PROC : PROCESS ( CLK ) BEGIN IF (RISING_EDGE(CLK)) THEN IF (COUNTER >= WIDTH - 1) THEN COUNTER <= 0; ELSE COUNTER <= COUNTER + 1; END IF; IF (SCLR = '1') THEN COUNTER <= 0; END IF; END IF; END PROCESS COUNTER_PROC; DATA_OUT <= COUNTER; END ARCHITECTURE; На RTL модели видно 2 ряда мультиплексоров, один ряд для синхронного сброса, другой ряд для сброса по условию: когда счетчик досчитал до условия сброса (в данном случае во всех разрядах единицы) то его сбросить. Логика понятная и правильная с точки зрения описания текста. Но вот если этот же счетчик описать так: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY COUNTER_SCLR IS PORT ( CLK : IN STD_LOGIC; SCLR : IN STD_LOGIC; DATA_OUT : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) ); END ENTITY; ARCHITECTURE RTL OF COUNTER_SCLR IS SIGNAL COUNTER : STD_LOGIC_VECTOR(8 DOWNTO 0); BEGIN COUNTER_PROC : PROCESS ( CLK ) BEGIN IF (RISING_EDGE(CLK)) THEN COUNTER <= STD_LOGIC_VECTOR(UNSIGNED(COUNTER) + 1); IF (SCLR = '1') THEN COUNTER <= (OTHERS => '0'); END IF; END IF; END PROCESS COUNTER_PROC; DATA_OUT <= COUNTER; END ARCHITECTURE; То видно, что ряд мультиплексоров и схема сравнения была убрана, поскольку мы это и не описывали. Казалось бы, поведение счетчиков абсолютно одинаковое, но т.к мы работаем не с INTEGER а c SLV, то счетчик автоматически обнуляется, при переполнении. Да и максимальная частота проекта выросла, что не может не радовать. На данный момент, у меня получилось мудрёное описание счетчика, который в зависимости от его максимального значения создает счетчик с условием обнуления или создает счётчик, который сам обнуляется при переполнении. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY COUNTER_SCLR IS GENERIC ( WIDTH : INTEGER := 511 ); PORT ( CLK : IN STD_LOGIC; SCLR : IN STD_LOGIC; DATA_OUT : OUT INTEGER RANGE 0 TO WIDTH-1 ); END ENTITY; ARCHITECTURE RTL OF COUNTER_SCLR IS SIGNAL COUNTER: INTEGER RANGE 0 TO WIDTH-1; BEGIN GENERATING_FULL_COUNTER : FOR I IN 1 TO 30 GENERATE GENERATING_COUNTER: IF (2**I = WIDTH) GENERATE COUNTER_PROC : PROCESS ( CLK ) VARIABLE COUNTER : STD_LOGIC_VECTOR(I-1 DOWNTO 0); BEGIN IF (RISING_EDGE(CLK)) THEN COUNTER := STD_LOGIC_VECTOR(UNSIGNED(COUNTER) + 1); IF (SCLR = '1') THEN COUNTER := (OTHERS => '0'); END IF; END IF; DATA_OUT <= TO_INTEGER(UNSIGNED(COUNTER)); END PROCESS COUNTER_PROC; END GENERATE; END GENERATE; GENERATING_SMALL_COUNTER: IF (WIDTH /= 2) AND (WIDTH /= 4) AND (WIDTH /= 8) AND (WIDTH /= 16) AND (WIDTH /= 32) AND (WIDTH /= 64) AND (WIDTH /= 128) AND (WIDTH /= 256) AND (WIDTH /= 512) AND (WIDTH /= 1024) AND (WIDTH /= 2048) GENERATE -- ИТД... COUNTER_PROC : PROCESS ( CLK ) BEGIN IF (RISING_EDGE(CLK)) THEN IF (COUNTER >= WIDTH-1) THEN COUNTER <= 0; ELSE COUNTER <= COUNTER + 1; END IF; IF (SCLR = '1') THEN COUNTER <= 0; END IF; END IF; END PROCESS COUNTER_PROC; DATA_OUT <= COUNTER; END GENERATE; END ARCHITECTURE; На альтеровское описание счетчика, которое есть в шаблонах, Modelsim орёт благим матом, поскольку там нет условия обнуления счетчика. А можно ли это как-то красивее сделать, чем я описал ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Inanity 1 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба Integer или SLV роли не играют. Лишний мультиплексор в первом примере появляется из-за лишней проверки. Если её убрать, то получится точно такая же схема как во втором примере. Разрядность переменной типа integer ограничена до 9 бит на этапе описания переменной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 20 апреля, 2017 Опубликовано 20 апреля, 2017 (изменено) · Жалоба Integer или SLV роли не играют. Лишний мультиплексор в первом примере появляется из-за лишней проверки. Если её убрать, то получится точно такая же схема как во втором примере. Разрядность переменной типа integer ограничена до 9 бит на этапе описания переменной. Именно. Вот только Modelsim откажется это симулировать... .# ** Fatal: (vsim-3421) Value 256 for DATA_OUT is out of range 0 to 255. # Time: 6450 ns Iteration: 3 Signal: /counter_sclr_vhd_tst/DATA_OUT File: Мне не жалко лишних ресурсов в ПЛИС. Это капля в море... Хотя может и пригодиться когда-нибудь сделать очень быстрый счетчик. Хотя там наверно надо будет делать ускоренный перенос. Изменено 20 апреля, 2017 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба проверка >= порождает вычитатель и схему сравнения, проверяйте на равенство и выиграете ресурсы, более того проверка на константу хуже чем проверка на нулевое значение или проверка на 1 в старшем разряде на этом тоже можно что-то выиграть. Вопрос только в том зачем это все? Более того смотреть надо не эту схему, а технологический вид, потому что в итоге это все ляжет в ЛУТы - Лешки и будет все совсем по другому, а может даже одинаково. Точно также изменится частота после мапинга на реальную схему. Правильно и изящно описывать то что вам надо по поведению, предоставив схему городить синтезатору и оптимизатору. Лично я стараюсь избегать в синтезируемых схемах интежеров и подобное, использую битовые вектора заданной разрядности, так мне кажется как-то правильнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба проверка >= порождает вычитатель и схему сравнения, проверяйте на равенство и выиграете ресурсы, более того проверка на константу хуже чем проверка на нулевое значение или проверка на 1 в старшем разряде на этом тоже можно что-то выиграть. Вопрос только в том зачем это все? Более того смотреть надо не эту схему, а технологический вид, потому что в итоге это все ляжет в ЛУТы - Лешки и будет все совсем по другому, а может даже одинаково. Точно также изменится частота после мапинга на реальную схему. Правильно и изящно описывать то что вам надо по поведению, предоставив схему городить синтезатору и оптимизатору. Лично я стараюсь избегать в синтезируемых схемах интежеров и подобное, использую битовые вектора заданной разрядности, так мне кажется как-то правильнее. Вопрос возник из-за разной максимальной частоты схемы, которую выдает TimeQuest. Вот и решил разобраться. Может я просто что-то неправильно понимаю. На технологическом виде схемы создаются разные, я проверял. А как тогда описывать по поведению ? А проверка нулевого значения это Вы имеете ввиду вычитающий счетчик ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
likeasm 0 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба А как тогда описывать по поведению ? Минимизировать описания, в данном случае ваше условие >= не имеет никакого смысла, оно лишь утяжеляет схему. А проверка нулевого значения это Вы имеете ввиду вычитающий счетчик ? Имеется ввиду логическая операция ИЛИ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 20 апреля, 2017 Опубликовано 20 апреля, 2017 (изменено) · Жалоба Минимизировать описания, в данном случае ваше условие >= не имеет никакого смысла, оно лишь утяжеляет схему. Имеется ввиду логическая операция ИЛИ. С этим согласен, схему несколько утяжеляет, это я подправлю. Но основная проблема в именно в том, что создав два разных описания счетчиков с одинаковым поведением, Quartus создает 2 совершенно одинаковые схемы (технологические карты), что вполне логично, поскольку это описания одного и того-же счетчика. Но вот одну схему Modelsim воспринимает нормально, выдав предупреждение о переполнении разрядов, что опять же вполне логично. А вот другую схему забраковывает, ругаясь на то, что INTEGER вышел за диапазон счета. Это несколько некорректное поведение симулятора... Конечно можно оставить как есть, и забить на это дело. В конце-концов фиг с ним, с лишним мультиплексором. Капля в море. У меня пока не встречалось задач, где счётчик считать не успевает. Пока не встречалось... Но в качестве самообразования хотелось бы знать, а как правильно делать. Изменено 20 апреля, 2017 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dimidrol 0 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба Именно. Вот только Modelsim откажется это симулировать... Ну дык зайти с другого фланга можно, или я что-то не понимаю. IF (COUNTER < WIDTH - 1) THEN COUNTER <= COUNTER + 1; ELSE COUNTER <= 0; END IF; А вообще нужно делом заниматься, а не счетчики через диапазоны целых объявлять. Причем лучше всего через типы пакета NUMERIC_STD. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 20 апреля, 2017 Опубликовано 20 апреля, 2017 · Жалоба Ну дык зайти с другого фланга можно, или я что-то не понимаю. IF (COUNTER < WIDTH - 1) THEN COUNTER <= COUNTER + 1; ELSE COUNTER <= 0; END IF; А вообще нужно делом заниматься, а не счетчики через диапазоны целых объявлять. Причем лучше всего через типы пакета NUMERIC_STD. А я и работаю только с пакетом NUMERIC_STD. А смысл в том, что такая конструкция вполне рабочая, прекрасно работает в Modelsim и синтезируется. IF (RISING_EDGE(CLK)) THEN COUNTER <= STD_LOGIC_VECTOR(UNSIGNED(COUNTER) + 1); IF (SCLR = '1') THEN COUNTER <= (OTHERS => '0'); END IF; END IF; Аналогичная конструкция, но объявленная через тип INTEGER, прекрасно синтезируется, моделируется в Quartus. Но Modelsim ругается благим матом на неё. IF (RISING_EDGE(CLK)) THEN COUNTER <= COUNTER + 1; IF (SCLR = '1') THEN COUNTER <= 0; END IF; END IF; Эти 2 конструкции одинаково ложатся в ячейки ПЛИС поскольку на технологических картах выглядят одинаково. Более того конструкция ,предложенная специалистами от Altera, которая находиться в шаблонах кода так-же взывает ругань у Modelsim. process (clk) variable cnt : integer range MIN_COUNT to MAX_COUNT; begin if (rising_edge(clk)) then if reset = '1' then -- Reset the counter to 0 cnt := 0; elsif enable = '1' then -- Increment the counter if counting is enabled cnt := cnt + 1; end if; end if; -- Output the current count q <= cnt; end process; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dimidrol 0 21 апреля, 2017 Опубликовано 21 апреля, 2017 · Жалоба На то он и симулятор, что- бы ругаться на такие дела. При описании моим спобом ругатся не будет, ибо счетчик сбросится до того, как нужно будет ругаться. Но компаратор останется в общем случае, конечно. Поэтому я и предлагают не заниматеться ерундой, и описывать все как есть, а не давать додумывать за себя бездуховной программе. Еще есть предположение, что у симулятора есть какой-нибудь ключик, типа -relax_integer_rage, который позволит обойти стороной эту ругань. зы. Шаблон альтеры позабавил. ззы. Тут народ ругается, что в ISIM по умолчанию проверка выключена. https://forums.xilinx.com/t5/Simulation-and...-p/368031#M7970 зззы. Нашел опцию для ModelSim: [-norangecheck] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
likeasm 0 21 апреля, 2017 Опубликовано 21 апреля, 2017 · Жалоба Какие-то странные костыли у вас с симулятором. Сам VHDL я не изучал, но читая форум складывается впечатление, что язык этот делает все, чтобы усложнить жизнь. Может быть вам лучше посмотреть в сторону Verilog? :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 21 апреля, 2017 Опубликовано 21 апреля, 2017 · Жалоба Какие-то странные костыли у вас с симулятором. Сам VHDL я не изучал, но читая форум складывается впечатление, что язык этот делает все, чтобы усложнить жизнь. Может быть вам лучше посмотреть в сторону Verilog? :rolleyes: Ну в VHDL есть такое что надо одно и тоже в нескольких местах писать, а как чуть не так и синтез с моделированием разошлись:) Вопрос возник из-за разной максимальной частоты схемы, которую выдает TimeQuest. Вот и решил разобраться. По мне это не верный подход. Так как синтезатор может сделать много места мало времени, и наоборот, и много средних вариантов. При этом оптимизация идет до тех пор, пока не уложится в ограничения. Так что оценивать что одна схема быстрее чем другая без ограничений не совсем верно. Просто так получилось что в одном случае так, в другом сяк, а в условиях ограничений они могли вообще выродиться в третью схему. Поэтому и оценка ресурсов в вакууме тоже не совсем верна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 21 апреля, 2017 Опубликовано 21 апреля, 2017 · Жалоба Ну в VHDL есть такое что надо одно и тоже в нескольких местах писать, а как чуть не так и синтез с моделированием разошлись :)Вы, кажется, на VHDL не пишете. Но мнение имеете. Я вот тоже имею мнение, что синтаксис Верилога делали под воздействием тяжёлых веществ, потому что в здравом уме такого кадавра придумать трудно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 21 апреля, 2017 Опубликовано 21 апреля, 2017 · Жалоба Вы, кажется, на VHDL не пишете. Но мнение имеете. Я вот тоже имею мнение, что синтаксис Верилога делали под воздействием тяжёлых веществ, потому что в здравом уме такого кадавра придумать трудно. Ну зачем что-то делать чтобы иметь мнение?:) Я достаточно плотно писал на VHDL в начале карьеры, потом перешел на Verilog так что я могу сравнивать. Синтаксис Verilog очень далек от совершенства, но в целом он удобнее чем VHDL. Синтаксис и организация кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться