StanislavF 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Здравствуйте, Прошиваю два Spartan3 с помощью AVR Atmega2561, последовательно, один за другим. Использую WinAVR 2010****. Прошивки для обеих ПЛИС компоную с прошивкой для ATmega. НО прошивки для ПЛИС со временем стали довольно большими и не влезают в 256 Кб для ATmega. Битовое сжатие не помогает. Придёться сжимать и распаковывать их потом с помощью самого ATmega при программировании ПЛИС. Существуюит ли алгоритмы распаковки zip для ATmega или какие-то другие решения этой проблемы? То, что я находил в сети работет с файлами, а в ATmega файлов по сути никаких и нет. Буду благодарен за любую предоставленную помощь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Ещё 10 лет назад статьи видел, про сжатие прошивок конфигураций для ПЛИС. И необязательно zip, ввиду специфики заливаемого массива можно применять простейшие методы (например, кодировать повторяющиеся серии нулей или единиц). Тогда это было связано с дороговизной флеши. А теперь? Что мешает поставить сбоку флешку и лить из неё? Кстати, файл - это всего лишь массив данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Да, 10+ лет назад это интенивно обсуждалось в PVT.HARDW.MAX2PLUS. Не знаю, как у xilinx, у альтеры прошивки в HEX выглядят как «много нулей, проскакивают ненули». Весьма неплохо жмутся простейшими алгоритамми типа модифицированного packbits (повторяться массово может только 0, поэтому его не нужно сохранять). Для распаковки: «если старший бит байта 0, то скопировать столько байт со входа на выход, иначе выдать на выход столько нулей, сколько записано в младших семи битах» Или с битовой картой - берём со входа байт, идём по его битам. Если 0 — выдаём на выход нулевой байт, если 1 — копируем на выход байт со входа (© Ivan Mak). Жмут они похуже ZIP-а, но распаковщик занимает настолько меньше места, что для меги256 может оказаться по сумме выгоднее zip. Cyclone альтеровские уже в себе имеют распаковщик какого-то RLE и Quartus при соответствующей галке генерирует сжатый поток, у спартана3 такого нет? Впрочем, кажется, какой-то из алгоритмов для первого циклона жал лучше, чем штатный квартусовский. Зато тот можно в конфиг eeprom записать и циклон сам поймёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба У нас в похожей ситуации используется сжатие RLE, которое тут уже упоминалось. Альтернативным решением м.б использование другого (более простого/дешевого) МК и SPI Flash. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
StanislavF 0 8 ноября, 2010 Опубликовано 8 ноября, 2010 · Жалоба Спасибо за ответы. Что мешает поставить сбоку флешку и лить из неё? То, что аппаратура уже какая есть. Cyclone альтеровские уже в себе имеют распаковщик какого-то RLE и Quartus при соответствующей галке генерирует сжатый поток, у спартана3 такого нет? В Spartran 3 есть сжатие битового потока, есть сжатие z для многоблочных PROM Xilinx. У меня стоит больше задача распаковать это на стороне ATmega. Буду благодарен на ссылки с алгоритмами. На счёт первого бита в байте не совсем понял -- что если он на чамом деел уже такой есть (не искуственно созданный). У нас в похожей ситуации используется сжатие RLE, которое тут уже упоминалось. Альтернативным решением м.б использование другого (более простого/дешевого) МК и SPI Flash. Другие МК уже не поставить. RLE попробую посмотреть. Если вспомните полезные ссылки и прочее для кода на C, буду благодарен. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 8 ноября, 2010 Опубликовано 8 ноября, 2010 · Жалоба О первом бите — ну так мы его так сгенерировали. Пример: Вход на упаковку FA AC 11 00 00 00 00 00 00 00 04 18 21 E7 00 00 00 00 00 00 00 00 00 00 22 00 44 55 00 00 00 00 00 00 00 01 Выход упаковщика 03 FA AC 11 87 04 04 18 21 E7 8A 04 22 00 44 55 87 01 01 Оиночный 00, выдленный курсивом, не было смысла пускать как ноль. До двух нулей смысла нет. Распаковщик 03 FA AC 11 — копируем три байта со входа на выход 87 — пишем на выход семь нулей 04 04 18 21 E7 — копируем четыре байта со входа на выход 8A — пишем на выход десять нулей 04 22 00 44 55 — копируем четыре байта со входа на выход 87 — пишем на выход семь нулей 01 01 — копируем один байт со входа на выход Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
StanislavF 0 23 ноября, 2010 Опубликовано 23 ноября, 2010 · Жалоба Использую PackBits. На машине упаковка и распаковка работают нормально. При программировании AVR, тестовый у ПЛИС светодиод не мигает, т.е. ПЛИС программируется неправильно. В чём может быть дело? Процедура программирования ПЛИС несжатой прошивкой. void FPGA_sendfile(uint_farptr_t buf, uint32_t buf_len) { unsigned char i; uint32_t l; uint8_t c; for (l = 0; l < buf_len; l ++) // buf_len-1 { c = pgm_read_byte_far(buf + l); for (i = 0;i < 8;i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c<<=1; SET_XSP_CLK; } } SET_XSP_DIN; } Процедура программирования ПЛИС сжатой прошивкой. void FPGA_sendpackedfile(uint_farptr_t buf, uint32_t buf_len) { unsigned char i; uint32_t L; // uint8_t c; int32_t countChar; /* run/copy count */ uint8_t c; /* current character */ L = - 1; while(L <= buf_len - 1) // - 2? { L += 1; countChar = (int32_t) pgm_read_byte_far(buf + L); if (countChar < 0) { /* we have a run write out 2 - countChar copies */ countChar = (MIN_RUN - 1) - countChar; L += 1; while (countChar > 0) { c = pgm_read_byte_far(buf + L); for (i = 0;i < 8;i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c <<= 1; SET_XSP_CLK; } countChar--; } } else { /* we have a block of countChar + 1 symbols to copy */ for (countChar++; countChar > 0; countChar--) { L += 1; c = pgm_read_byte_far(buf + L); for (i = 0; i < 8; i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c <<= 1; SET_XSP_CLK; } } } } SET_XSP_DIN; } Не пойму, где тут мог намудрить. Я прикрепил проект для тестирования упаковки/распаковки на инструментальной системе и проект для программирования целевой. Буду благодарен за советы и помощь. packbits.zip sp_control.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 23 ноября, 2010 Опубликовано 23 ноября, 2010 · Жалоба Можно делать и прямую распаковку. Там тоже ничего сложного нет, но вам понадобится довольно много озу, для формирования словаря. Иногда делают с предустановленным фиксированным словарём, тогда эффективность несколько ниже, но приведенные последовательности исключительно хорошо будет сжимать/разжимать. Прямой метод LZH даст эффективность ~ 80-90% от ZIP сжатия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 24 ноября, 2010 Опубликовано 24 ноября, 2010 · Жалоба int32_t countChar; Зачем 32 бита? У вас максимальный счетчик - 128 countChar = (int32_t) pgm_read_byte_far(buf + L); if (countChar < 0) Если pgm_read_byte_far возвращает беззнаковый char то работать не будет countChar = (MIN_RUN - 1) - countChar; Это вообще не понял - там счетчик в чистом виде: countChar &= 0x7F; while (countChar > 0) { c = pgm_read_byte_far(buf + L); А вот это ошибка - мы 0 должны выводить, а не содержимое следующего байта флеша: while (countChar > 0) { c = 0; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 ноября, 2010 Опубликовано 24 ноября, 2010 · Жалоба Я делал сжатие несколько иначе - последовательность нулевых байтов заменялась одним нулевым байтом и следующим байтом, задающим количество нулевых байтов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
StanislavF 0 12 января, 2011 Опубликовано 12 января, 2011 · Жалоба int32_t countChar; Зачем 32 бита? У вас максимальный счетчик - 128 На самом деле 129. Можно обойтись и 16-тью. countChar = (int32_t) pgm_read_byte_far(buf + L); if (countChar < 0) Если pgm_read_byte_far возвращает беззнаковый char то работать не будет Как тогда быть? Что использовать вместо pgm_read_byte_far? countChar = (MIN_RUN - 1) - countChar; Это вообще не понял - там счетчик в чистом виде: countChar &= 0x7F; while (countChar > 0) { c = pgm_read_byte_far(buf + L); А вот это ошибка - мы 0 должны выводить, а не содержимое следующего байта флеша: while (countChar > 0) { c = 0; Я брал код отсюда (PackBits Variant): http://michael.dipperstein.com/rle/index.html На инструментальной системе всё работает, поэтому на сам алгоритм я не особо грешу, а вот на реалтзацию для avr... Надеюсь на вашу дальнейшую помощь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 12 января, 2011 Опубликовано 12 января, 2011 · Жалоба Как тогда быть? Что использовать вместо pgm_read_byte_far?Его и использовать. Приведение типа неправильное, должно быть countChar = (unsigned char) pgm_read_byte_far(buf + L); Я брал код отсюда (PackBits Variant)Пардон, я думал, что вы реализовали алгоритм от ReAl (он сюда подходит гораздо лучше) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 12 января, 2011 Опубликовано 12 января, 2011 · Жалоба Приведение типа неправильное, должно быть countChar = (unsigned char) pgm_read_byte_far(buf + L); pgm_read_byte и так по умолчанию uint8_t возвращает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 12 января, 2011 Опубликовано 12 января, 2011 · Жалоба Пардон, я думал, что вы реализовали алгоритм от ReAl (он сюда подходит гораздо лучше) Я на ACEX1K30..1K50 когда-то давно сверял, c битовой картой © Ivan Mak вроде бы чуть лучше работал. А я просто по быстрячку Macintosh PackBits модифицировал под случай, когда массово повторяться может только 0, поэтому его нет смысла и писать в выходной поток. Как тогда быть? Что использовать вместо pgm_read_byte_far?У Вас в массиве во флеше записаны знаковые байты. Значит, нужно возврат pgm_read_byte_far приводить к знаковому байту. int8_t counter; counter = (int8_t)pgm_read_byte_far( ptr ); Я пользовался не знаковым числом, а флагом в старшем бите беззнакового 8-битного числа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 января, 2011 Опубликовано 12 января, 2011 · Жалоба Я на ACEX1K30..1K50 когда-то давно сверял, c битовой картой © Ivan Mak вроде бы чуть лучше работал. Не могли бы вы показать, во что превратится код из примера в сообщении №6, закодированный © Ivan Mak, а то из вашего описания я не понял, как он работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться