Раз PRU0.prg нет, то будем тестировать блок ШД на эмуляторе.
"enable" будем подавать через "fast IN1", а параметры "количество импульсов" и "частоту импульсов" будем подавать через память PRU.
На мой взгляд, эксперимент удался. Импульсы генерируются, указанная длительность соблюдается.
Хорошо бы, конечно, в железе проверить, но тут не решён вопрос по PRU0.prg.
Попробую "проверенный" способ: кто-нибудь может пошевелить/поспрашивать ОВЕН на предмет возможности генерации PRU0.prg/PRU1.prg файлов из внешних программ?
Собственно, программа обрабатывающая блок ЩД:
a1_main_program.png
Ничего хитрого.
Из нового -- блок WAIT_TICK, который делает так, чтобы наш блок ШД вызывался не чаще, чем указанный интервал.
LBCO -- команды, загружающие значения из "памяти PRU" в регистр. В эмуляторе берём и "пишем напрямую в память". Возможно, HOST_TO_PRU/PRU_TO_HOST немного по-другому будут работать, но на суть это не влияет.
В самом блоке WAIT_TICK использован метод УКП (универсального коэффициента подгона):
a2_wait_tick.png
Выглядит жутковато, но тесты проходит: https://github.com/vlsi/pru-emulator...BlockTest.java
В тестах проверяется, что "полезная работа" стартует ровно раз в заданное время в комбинациях "cycleTime от 20 до 100" и "длительность тела цикла от 0 до 5".
Собственно берём наш блок ШД и начинаем его испытывать. Заранее скажу, что предыдущая версия блока оказалась неправильной.
Вот исправления, после которых блок начал проходить тесты:
a3_gener_burst.png
Начинаем с одного импульса и задержки в "35 тактов", и затем после каждой пачки увеличиваем количество импульсов на 1 и длительность тоже на 1.
Т.е. сначала должен получиться 1 импульс длины 35, затем 2 импульса по 36, затем 3 импульса по 37 и так далее.
Для большего разнообразия, вход enable будем активировать после случайной задержки. Так сказать, попробуем застать блок ШД врасплох.
Собственно, результаты теста. Тут через _/‾ и ‾\_ схематично изображены фронты out сигнала.
_/‾33‾\_ означает, что на выходе out была единица 33 такта.
‾\_36_/‾ означает, что на выходе был ноль 36 тактов.
Самая первая цифра -- это задержка от перевода enable в true до фронта out (т.е. задержка того, пока цикл PRU докрутится и запустит генерацию).
Цифра в пределах ожидаемого
cycle: 35, quantity: 1. _15_/‾33‾\_
cycle: 36, quantity: 2. _46_/‾34‾\_36_/‾36‾\_
cycle: 37, quantity: 3. _27_/‾35‾\_37_/‾37‾\_37_/‾37‾\_
cycle: 38, quantity: 4. _22_/‾36‾\_38_/‾38‾\_38_/‾38‾\_38_/‾38‾\_
cycle: 39, quantity: 5. _30_/‾37‾\_39_/‾39‾\_39_/‾39‾\_39_/‾39‾\_39_/‾39‾\_
cycle: 40, quantity: 6. _17_/‾38‾\_40_/‾40‾\_40_/‾40‾\_40_/‾40‾\_40_/‾40‾\_40_/‾40‾\_
cycle: 41, quantity: 7. _26_/‾39‾\_41_/‾41‾\_41_/‾41‾\_41_/‾41‾\_41_/‾41‾\_41_/‾41‾\_41_/‾41‾\_
cycle: 42, quantity: 8. _48_/‾40‾\_42_/‾42‾\_42_/‾42‾\_42_/‾42‾\_42_/‾42‾\_42_/‾42‾\_42_/‾42‾\_42_/‾42‾\_
cycle: 43, quantity: 9. _50_/‾41‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_43_/‾43‾\_
cycle: 44, quantity: 10. _14_/‾42‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_44_/‾44‾\_
cycle: 45, quantity: 11. _38_/‾43‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_45_/‾45‾\_
cycle: 46, quantity: 12. _20_/‾44‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_46_/‾46‾\_
Если присмотреться, то можно заметить, что длина первого импульса почему-то на 2 такта меньше, чем заданная длительность.
Можно, конечно, раскуривать ассемблер и смотреть где там стоит добавить-убрать такт, но нужно ли? Кого реально парят 2 такта?
Минимально стабильная длина цикла для этой программы составляет 33 такта.
Частота PRU где-то 150-200 МГц, т.е. за одну микросекунду PRU выполняет ~200 команд.
Иными словами, данная программа может генерировать пачки импульсов частоты до 1МГц (выходы вряд ли смогут такое, но не суть).
PS Вот так на ассемблере выглядит финальная программа (на один экран не вместилось, поэтому 3 картинки):
a4_asm1.png
a5_asm2.png
a6_asm3.png




Ответить с цитированием