-
Постов
12 216 -
Зарегистрирован
Весь контент ViKo
-
Я в Quartus 9.1 работаю. Там не нашел визарда.
-
Отвечаю себе и заглянувшим в тему. Была недавно ссылка. Там написано, как надо. Настоятельно рекомендую. http://electronix.ru/redirect.php?http://w...uest_User_Guide Действительно, редактируется в Quartus'e. Там есть команда Edit -> Insert Constraint. И еще интереснее Edit -> Insert Template. А там уж есть всё, что пожелаешь.
-
Синхронизатор
ViKo ответил AlphaMil тема в Работаем с ПЛИС, области применения, выбор
Конечно. Это мы обсуждали год назад :) Это рисунок 8, на который ссылается Мур. Думаю, часть темы стоит посвятить этой картинке. Я сейчас смотрю в TimeQuest (пришло время), и прихожу к выводу, что по ПЛИС такты приходят на триггера совсем не одновременно. P.S. Отстаивая честь Quartus'а, скомпилировал следующий код. always @(posedge clkin, posedge din) if (din) dout[4] <= din; else dout[4] <= 0; Для Циклона-2 получил триггер с ADATA и ALOAD, подключенными к din, тактовым сигналом на clkin, и нулем на входе данных. Спасен! -
Синхронизатор
ViKo ответил AlphaMil тема в Работаем с ПЛИС, области применения, выбор
Про эту картинку речь идет? Пусть висит. Если на входе Data будет импульс в 3 такта Clock1, на Output появится 2 импульса длительностью Clock2. И без всякой метастабильности. В метастабильном состоянии триггер может висеть "между небом и землей" сколь угодно долго, в идеальном случае. До следующего такта. А если в следующем такте вход неопределен, то все продолжится. Если вдруг почему-то Clock1 отстанет от Data, доберется до "желтого" триггера чуть позже, триггер влетит в метастабильное состояние. Это я не к тому, что схема плохая или неправильная, а к тому, что идеального в мире ничего нет. Нужно смотреть внимательно. -
Кое в чем разобрался. Но, похоже, увидеть файл *.sdc целиком можно только во внешнем редакторе (или в Quartus). А как же строки редактировать, если что-то не так задал? :05:
-
Синхронизатор
ViKo ответил AlphaMil тема в Работаем с ПЛИС, области применения, выбор
Вы показали картинку, и написали, что на такое Quartus ругается. Я показал картинку, на которую Quartus "не ругается". Они что, сильно отличаются? Поясните, что вы хотели сказать в первом случае, и только что. Как это не его? Скопировал. Создал файл *.vhd. Скомпилировал. Картинку извлек. В сообщение забросил. -
Синхронизатор
ViKo ответил AlphaMil тема в Работаем с ПЛИС, области применения, выбор
Вот и я, из любопытства скомпилировал код Oldring и показал картинку. -
Quartus TimeQuest Timing Analyzer
ViKo опубликовал тема в Среды разработки - обсуждаем САПРы
Догадываюсь, что можно с помощью команд в панели Tasks и в меню Constraints. Но как увидеть сам файл? В Quartus открывать, что ли? И имя при сохранении норовит изменить на *.out.sdc. Написать в любом текстовом редакторе - вопрос не об этом. -
74dB это все-таки чуть больше, чем 12 разрядов. Так что сысл в 13-м есть. Но вопрос, как такое слово хранить, передавать. 12 битов можно компактнее упаковать.
-
С этим согласен. Есть еще команды исключительного доступа. С ними пока серьезно не разбирался. Думаю, они помогли бы в описанном случае. Ну, и те самые регистры - сбросить бит порта, установить бит порта. С истинной атомарностью. И голова не болит.
-
Синхронизатор
ViKo ответил AlphaMil тема в Работаем с ПЛИС, области применения, выбор
-
В результате, для инвертирования бита через бит-бэнд, по сравнению с обычным xor регистра ODR: - Настоящей атомарности нет, - Размер кода такой же, - Время выполнения такое же.
-
Добавлю еще, что инвертировать бит везде, кроме рабочих регистров процессора ARM или Cortex - это не атомарная операция. Независимо от способа, "напрямую" или через bit-band. Потому, что сначала этот бит нужно прочитать, в виде целого слова, или как отдельный бит через bit-band alias. Нужно выполнить те самые неоднократно показанные три команды. Но после чтения может случиться что угодно до того, как измененный бит будет записан обратно. Атомарными будут только сброс или установка бита через bit-band. Потому, что это одна команда. А чтение-модификация-запись слова, содержащего нужный бит, делается аппаратно. Также атомарными будут команды сброса или установки порта ввода-вывода через BSRR и BRR. Потому что в этом случае не происходит чтение-модификация-запись. Не так уж и много. Если команда 4-байтовая, вот она половину одного регистра и забрала. Т.е., всего в два регистра влазит от 4-х до 8-ми команд. Вот последний показанный мой код влезет в два регистра. А как остальное, не знаю.
-
:bb-offtopic: Извиняюсь за офтопик, но, натыкаясь на эту тему воспринимаю информацию как "Освобождение из СИЗО условно-досрочно!" P.S. А почему последним писателем висит rezident? С этим разобрался. Из-за переноса темы.
-
Практика - критерий истины. Проверил на STM32VLDISCOVERY, на частоте 24MHz, код выполнялся из flash с 0 циклов ожидания (естественно). Все три мои варианта (назовем P ^= 1UL<<8; BB ^= 0x1; BB = ~BB) работают одинаково. Цикл выполняется за 15 тактов, а период полученной частоты, понятно, в 2 раза больше. Итого 24MHz/30 = 800kHz. Удивительно, что получилось именно 15, а не 16 тактов! Чудо. Для проверки добавил код, разрешающий вывод через MCO 8MHz от кварцевого генератора HSE. Убедился, что 8MHz есть. Период же исследуемого сигнала стал 32 такта (16+16). Как и ожидалось изначально. Добавил _nop();, ставил и перед изменением регистра, и после ставил. Период сигнала стал 34 такта (17+17). Как видите, NOP работает. Примечательно, что размер кода при этом увеличился на 4 байта, а не на 2. В-общем, работа компилятора - потемки. Похоже, никаких лишних тактов обращение к bit-band alias не требует. Несомненно, используется некий аппаратный способ. Команда NOP может работать, как надо. Кроме шины AHB еще есть буфер предвыборки flash, который путает всю временную картину. Он состоит из 2-х 64-битовых регистров. Как туда лягут команды цикла - тайна, покрытая мраком. Ради интереса попробовал работу с портом через BSRR, BRR. Вот такой код выдает на ножке 4MHz со скважностью 50%, 3 такта - 0, 3 такта - 1. Может быть, при другом раскладе кода будет иначе. while (1) { GPIOC->BRR = 0x00000100; __nop(); __nop(); GPIOC->BSRR = 0x00000100; } Сравните с 800kHz через инверсию. Понятно, вещи разные. Но для меня, как не было нужды инвертировать бит, так и не появилось желания. Одно удобно - при инвертировании скважность частоты будет точно 50%. Вот такой вам ответ от DISCOVERY и Осциллографа с Симулятором. :)
-
я забыл, перепутал Для манипуляций с битами ODR - и там, и там используется RMW, читаем-меняем-записываем. Аналогично для регистров BSRR и BRR - и там, и там используется просто запись. Разница между обычным доступом и bit-band только в том, что обращаемся к целому слову или к одному биту. Вот она и "атомарность". На 100% достоверность не претендую. Однако симулятор показывает... Надо знать само устройство этого bit-band. Аналогично. добавил __nop(); получил на такт длительнее цикл, 17 тактов. А разве должно было быть иначе? P.S. Чтобы разобраться до конца, попробую запустить свои варианты из flash, из RAM и посмотрю осциллографом. Доложу, когда сделаю.
-
Вот как компилирует Keil. Почему так, не знаю. Но уже замечал, что в IAR получается компактнее. ;;;30 ALIAS_PTR(GPIOC->ODR,8) = ~ALIAS_PTR(GPIOC->ODR,8); 000002 6801 LDR r1,[r0,#0] 000004 ea6f0101 MVN r1,r1 000008 6001 STR r1,[r0,#0] Если, как видите, команды для обычной пересылки и пересылки в bit-band, практически, одни и те же (а по тактам полностью одинаковые, EOR и MVN выполняются за одну команду), то с чего бы второй вариант был быстрее? Осциллограф показывает работу кода из flash. Попробуйте запустить из ОЗУ. Я делал, но точные цифры сейчас вряд ли найду. P.S. У вас MVNS - с обновлением флагов, у меня MVN - без обновления. Кто здесь "правильнее" подошел, Keil или GCC, не могу сказать. С одной стороны, лишний раз флаги "портить" не желательно, вдруг они потом используются. С другой, с "порчей" флагов компактнее. В любом случае, это особенности компиляторов, а не достоинства bit-band. Я, все же, останусь при своей точке зрения. Bit-band для манипуляции битами порта использовать не буду.
-
#include "stm32f10x.h" #define ALIAS_PTR(VarPtr,BitNum) \ *((__IO uint32_t *) (((uint32_t) &(VarPtr) & 0xf0000000) | 0x02000000 \ + (((uint32_t) &(VarPtr) & 0xfffff)<<5) | (BitNum<<2))) void Bit_toggle(void); int32_t main(void) { while (1) { Bit_toggle(); } } void Bit_toggle() { // GPIOC->ODR ^= 1UL<<8; // ALIAS_PTR(GPIOC->ODR,8) ^= 1; // ALIAS_PTR(GPIOC->ODR,8) = ~ALIAS_PTR(GPIOC->ODR,8); } Предлагаю всем желающим скомпилировать показанный код, раскомментировав одну из трех строк, и самостоятельно убедиться, что все три варианта дают одинаковое количество байтов, и одинаковое количество тактов. А именно, для Keil 4.12 при оптимизации default программа занимает 18 байтов, плюс 4 байта константа адреса. Основной цикл while выполняется за 16 тактов в симуляторе. Вот листинг для одного из вариантов. Для других картина аналогичная. ; generated by ARM C/C++ Compiler, 4.1 [Build 481] ; commandline ArmCC [--debug -c --asm --interleave -o.\objects\bit_toggle.o --depend=.\objects\bit_toggle.d --cpu=Cortex-M3 --apcs=interwork -O3 -IC:\Programs\Keil\ARM\INC -IC:\Programs\Keil\ARM\INC\ST\STM32F10x -DSTM32F10X_HD --omf_browse=.\objects\bit_toggle.crf Source\Bit_toggle.c] THUMB AREA ||.text||, CODE, READONLY, ALIGN=2 Bit_toggle PROC ;;;25 ;;;26 void Bit_toggle() 000000 4804 LDR r0,|L1.20| ;;;27 { ;;;28 GPIOC->ODR ^= 1UL<<8; 000002 68c1 LDR r1,[r0,#0xc] 000004 f4817180 EOR r1,r1,#0x100 000008 60c1 STR r1,[r0,#0xc] ;;;29 // ALIAS_PTR(GPIOC->ODR,8) ^= 1; ;;;30 // ALIAS_PTR(GPIOC->ODR,8) = ~ALIAS_PTR(GPIOC->ODR,8); ;;;31 } 00000a 4770 BX lr ENDP main PROC |L1.12| ;;;18 ;;;19 int32_t main(void) 00000c f7fffffe BL Bit_toggle ;;;20 { ;;;21 while (1) { ;;;22 Bit_toggle(); 000010 e7fc B |L1.12| ;;;23 } ;;;24 } ;;;25 ENDP 000012 0000 DCW 0x0000 |L1.20| DCD 0x40011000 __ARM_use_no_argv EQU 0
-
Отвечу вопросом на вопрос - а разве я такое где-то сказал? Я сказал, что при манипуляции битами портов от bit-band пользы мало. Даже если и выиграешь пару байтов, по сравнению с общим количеством кода это пустое. Хотя, я тоже стремлюсь использовать "совершенный" код. И применяю, например, такие конструкции: typedef struct { int HelpEna : 1; // Индикация помощи int Lang : 2; // Язык int Vect : 1; // Точки / Вектора int Wide : 1; // WorkArea Wide int Scale : 2; // Work Scale Form int dummy : 1; } DPY_t __attribute__((bitband)); Работа с такими переменными компилируется в команды с использованием bit-band. Bit-band манипуляции полезны, в первую очередь, своей атомарностью. Но при работе с портами ее (атомарность) можно получить и иными способами. А такты-байтики считать - не главное. IMHO. P.S. В моем сообщении №99 нужно переставить местами bit-band alias и bit-band. Bit-band - это область в 1MB, а bit-band alias - это то, что имеет размер 32MB, и отражается на bit-band. Поправить сообщение уже не могу. P.P.S. А есть ли у кого мысли, как этот bit-band реализован физически? Теряюсь в смутных догадках...
-
И сильно "стадали"? Рожали в муках, наверное? (вот это - легкий сарказм). Дело в том, что я тоже поначалу загорелся этим bit-band, но попробовав, пришел к выводу, что для управления битами порта это не нужно, благодаря куче специально предназначенных регистров. И эту работу я провел не походя, и не вчера. Во всех случаях, кроме инверсии бита, работа через bit-band не дает ничего. А инверсия мне не нужна (может, именно поэтому и не нужна). Хотите, "пострадаем" и "выберем после многих тестов" еще раз, вместе? Начнем со сброса бита? Я же и говорю, что трудно посчитать объективно.
-
Дома у себя не держу, как оказалось. Если до понедельника не возьмете там, где все, пришлю. Но объем файла большой. (Об этом можно было и в частном порядке спросить) Not at all!
-
VHDL or Verilog
ViKo ответил D-Luxe тема в Языки проектирования на ПЛИС (FPGA)
1. entity (Computer En-Ru) сущность, объект. Логически целостный элемент предметной области, информация о котором хранится в базе данных. (regular entity, weak entity). 2. entity ['entItI] (Mueller En-Ru) n. 1) филос. бытие 2) сущность, существо 3) нечто реально существующее 4) существо, организм; организация; political entity политическая организация; legal entity юридическое лицо 5) разг. вещь, объект Мое мнение - вполне подходит "вещь", остальные "сущности", вроде "объект", "элемент" - уже разобраны. -
Вообще-то, я не вам предлагал считать. Тот код, что я показал, содержит все строки исходного кода. Кому интересно, может скомпилировать и изучить самостоятельно. ALIAS_PTR(), например, кому-нибудь может пригодиться. А что, байты посчитать тяжелая задача? P.S. А грубить зачем? P.P.S. А про инверсию бита я уже сказал - обхожусь без инверсии, задаю то, что мне нужно через BSRR и BRR.
-
Пусть бы ReAl показал результат не для ---- через GPIOx->BSRR = Latched() ? mask << 16 : mask; а if (Latched()) GPIOx->BSRR = mask; else GPIOx->BRR = mask; Впрочем, для инверсии бита, наверное, вывод ReAl верный. Зато через регистр BSRR можно зараз сбросить-установить кучу битов. Покажу результат своих только что проделанных экспериментов. Считайте сами, не забудьте константы в конце кода. Bit_change1 PROC ;;;68 ;;;69 void Bit_change1(bool set) 000004 b118 CBZ r0,|L1.14| ;;;70 { ;;;71 if (set) GPIOB->BSRR = 0x0002; 000006 2102 MOVS r1,#2 000008 4a0f LDR r2,|L1.72| 00000a 6011 STR r1,[r2,#0] 00000c e002 B |L1.20| |L1.14| ;;;72 else GPIOB->BRR = 0x0002; 00000e 2102 MOVS r1,#2 000010 4a0e LDR r2,|L1.76| 000012 6011 STR r1,[r2,#0] |L1.20| ;;;73 } 000014 4770 BX lr ;;;74 ENDP Bit_change2 PROC ;;;75 void Bit_change2(bool set) 000016 b108 CBZ r0,|L1.28| ;;;76 { ;;;77 GPIOB->BSRR = 0x0002<<(set ? 0 : 16); 000018 2200 MOVS r2,#0 00001a e000 B |L1.30| |L1.28| 00001c 2210 MOVS r2,#0x10 |L1.30| 00001e 2102 MOVS r1,#2 000020 4091 LSLS r1,r1,r2 000022 4a09 LDR r2,|L1.72| 000024 6011 STR r1,[r2,#0] ;;;78 } 000026 4770 BX lr ;;;79 ENDP Bit_change3 PROC ;;;80 void Bit_change3(bool set) 000028 b108 CBZ r0,|L1.46| ;;;81 { ;;;82 GPIOB->BSRR = set ? 0x0002 : 0x0002<<16; 00002a 2102 MOVS r1,#2 00002c e001 B |L1.50| |L1.46| 00002e f44f3100 MOV r1,#0x20000 |L1.50| 000032 4a05 LDR r2,|L1.72| 000034 6011 STR r1,[r2,#0] ;;;83 } 000036 4770 BX lr ;;;84 ENDP Bit_change4 PROC ;;;91 ;;;92 void Bit_change4() 000038 4905 LDR r1,|L1.80| ;;;93 { ;;;94 #define ALIAS_PTR(VarPtr,BitNum) \ ;;;95 *((__IO uint32_t *) (((uint32_t) &(VarPtr) & 0xf0000000) | 0x02000000 \ ;;;96 + (((uint32_t) &(VarPtr) & 0xfffff) <<5) | (BitNum <<2))) ;;;97 ;;;98 uint32_t bit = ALIAS_PTR(GPIOB->ODR,1); 00003a 6808 LDR r0,[r1,#0] ;;;99 bit = !bit; 00003c b908 CBNZ r0,|L1.66| 00003e 2101 MOVS r1,#1 000040 e000 B |L1.68| |L1.66| 000042 2100 MOVS r1,#0 |L1.68| 000044 4608 MOV r0,r1 ;;;100 } 000046 4770 BX lr ;;;101 ENDP |L1.72| DCD 0x40010c10 |L1.76| DCD 0x40010c14 |L1.80| DCD 0x42218184
-
Думаю, да. А для чтения-модификации бита можете и ODR регистр использовать. Мне не было необходимости делать именно инверсию бита. Просто задаю то состояние, что нужно. Трудно сравнивать объективно, потому что слова для записи и адреса еще нужно подготовить. Вот листинг того кода, что я показал. ;;;370 void LED_Blink(void) { 000386 482e LDR r0,|L1.1088| ;;;371 while (1) { ;;;372 GPIOB->BSRR = 0x0002; 000388 f04f0102 MOV r1,#2 |L1.908| 00038c f8c01c10 STR r1,[r0,#0xc10] ;;;373 // __nop(), __nop(), __nop(); // from Flash 12 clock states ;;;374 // __nop(), __nop(); // from RAM 14 clock states ;;;375 GPIOB->BRR = 0x0002; 000390 f8c01c14 STR r1,[r0,#0xc14] 000394 e7fa B |L1.908| ;;;376 } ;;;377 } Пара регистров BSRR, BRR тем и хороша, что одним и тем же словом можно установить или сбросить бит. Как в этом коде - оно хранится в R1. И адрес структуры один - в R0. А смещение внутри команды задается. Я пробовал и с bit-band, у меня получилось хуже.