|
|
  |
Вычисляемый GOTO на pic18f45j10, максимальное быстродействие |
|
|
|
May 19 2008, 15:31
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Понадобилось написать на ассемблере вычисляемый GOTO, аналог switch k на си, с максимально возможным быстодействием. Пока дошёл до такого кода Код movlw HIGH v8goto movwf PCLATH movf k,w addwf k,w addwf PCL,1 v8goto bra v8mf0 ;k=00 bra v8mf1 ;k=01 bra v8mf0 ;k=02-MF2(cylinder 1 & 5) bra v8mf0 ;k=03 bra v8mf0 ;k=04 и т.д. Проблема состоит в размещении кода в любом месте программы. После компиляции смотрю, где лежит таблица переходов, если не пересекает 256-байтную границу, то всё в порядке. Интересно бы посмотреть, как кто делает.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
May 21 2008, 06:44
|

Частый гость
 
Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344

|
Цитата(=GM= @ May 19 2008, 18:31)  Понадобилось написать на ассемблере вычисляемый GOTO, аналог switch k на си, с максимально возможным быстодействием. Пока дошёл до такого кода Код movlw HIGH v8goto movwf PCLATH movf k,w addwf k,w addwf PCL,1 v8goto bra v8mf0 ;k=00 bra v8mf1 ;k=01 bra v8mf0 ;k=02-MF2(cylinder 1 & 5) bra v8mf0 ;k=03 bra v8mf0 ;k=04 и т.д. Проблема состоит в размещении кода в любом месте программы. После компиляции смотрю, где лежит таблица переходов, если не пересекает 256-байтную границу, то всё в порядке. Интересно бы посмотреть, как кто делает. Попробуйте иначе: Код movlw HIGH v8goto movwf PCLATH movlw LOW v8goto addwf k,w addwf k,w btfsc STATUS, C incf PCTATH, f movwf PCL v8goto bra v8mf0 ;k=00 bra v8mf1 ;k=01 bra v8mf0 ;k=02-MF2(cylinder 1 & 5) bra v8mf0 ;k=03 bra v8mf0 ;k=04 и т.д. теперь граница = 0xffff если больше то PCLATH-UP добавить.
--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть" "Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
|
|
|
|
|
May 21 2008, 10:23
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(volodya @ May 21 2008, 05:44)  Попробуйте иначе: Код movlw LOW v8goto addwf k,w addwf k,w btfsc STATUS, C incf PCTATH, f movwf PCL теперь граница = 0xffff если больше то PCLATH-UP добавить. Вы считаете, что после первого сложения переноса никогда не будет, а может быть только после второго? Пусть например, LOW v8goto=0xFF, а k=2, тогда после первого сложения будет перенос, а у вас он не учитывается.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
May 22 2008, 12:13
|

Частый гость
 
Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344

|
Цитата(=GM= @ May 21 2008, 13:23)  Вы считаете, что после первого сложения переноса никогда не будет, а может быть только после второго? Пусть например, LOW v8goto=0xFF, а k=2, тогда после первого сложения будет перенос, а у вас он не учитывается. LOW adr_ROM для команды всегда четный - поскольку команды P18 16(32)бит, в первом сложении перенос исключен.
--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть" "Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
|
|
|
|
|
May 22 2008, 13:03
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(volodya @ May 22 2008, 11:13)  LOW adr_ROM для команды всегда чётный - поскольку команды P18 16(32)бит, в первом сложении перенос исключен Выше был выбран неудачный пример, пусть LOW v8goto=0xF0, а k=19, вполне реальные числа, у меня три таких вычисляемых GOTO с Кмах=36, 36 и 60. Как видите, адрес чётный и есть перенос при первом сложении. Не скажу, что я не вижу способов решения задачи, они есть, но все они какие-то громоздкие, крокозябистые...или у меня руки кривые, или это следствие корявой архитектуры и системы команд для пиков, одно из двух (:-). Опять же, для расчёта количества оборотов двигателя в минуту написал программу деления двух 32-битных чисел, еле поместился в 900 с лишком машинных циклов, ну можно скинуть сотню-другую циклов, но...как-то некрасиво всё выходит (:-(.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
May 23 2008, 04:59
|

Частый гость
 
Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344

|
Цитата(=GM= @ May 22 2008, 16:03)  Выше был выбран неудачный пример, пусть LOW v8goto=0xF0, а k=19, вполне реальные числа, у меня три таких вычисляемых GOTO с Кмах=36, 36 и 60. Как видите, адрес чётный и есть перенос при первом сложении.
Не скажу, что я не вижу способов решения задачи, они есть, но все они какие-то громоздкие, крокозябистые...или у меня руки кривые, или это следствие корявой архитектуры и системы команд для пиков, одно из двух (:-).
Опять же, для расчёта количества оборотов двигателя в минуту написал программу деления двух 32-битных чисел, еле поместился в 900 с лишком машинных циклов, ну можно скинуть сотню-другую циклов, но...как-то некрасиво всё выходит (:-(. Да ВЫ правы корректнее Код movlw HIGH v8goto movwf PCLATH bcf STATUS, C rlcf k, w btfsc STATUS, C incf PCTATH, f addlw LOW v8goto btfsc STATUS, C incf PCTATH, f movwf PCL TablJMP code 0xYYY00 ;для принудительного расположения в ПЗУ программ ;переносы можно упустить при к < 128 v8goto bra v8mf0 ;k=00 bra v8mf1 ;k=01 bra v8mf0 ;k=02-MF2(cylinder 1 & 5) bra v8mf0 ;k=03 bra v8mf0 ;k=04 и т.д. Лучше стараться поместится в страницу 128 переодов и распологать принудительно внутри страници ПЗУ - тогда можно не принимать во внимение перенос - экономить такты и восплользоваться Вашим первым вариантом кода. Архитектура имеет свои плюсы и минусы. Думаю спор о приемуществах и недостатках приведет к  . Хотя согласен с Вами - математика большой производительностью не блещет. Деление занимет много времени. - ограничение ситемы команд. Тут наверное или мириться или менять CPU. Удачи!
Сообщение отредактировал volodya - May 23 2008, 05:39
--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть" "Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
|
|
|
|
|
May 23 2008, 15:10
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(volodya @ May 23 2008, 03:59)  Лучше стараться поместить в страницу 128 переходов и располагать принудительно внутри страницы ПЗУ - тогда можно не принимать во внимание перенос - экономить такты и воспользоваться Вашим первым вариантом кода Пожалуй, воспользуюсь я вашим советом и размещу три таблицы в начале трёх страниц. С учётом того, что пока k<61 (а в обозримом будущем вряд ли будет больше) код получится более-менее приличный Код movlw HIGH v8goto movwf PCLATH bcf STATUS,C rlcf k,w ;k<128, no carry movwf PCL,f
v8goto bra v8mf0 ;k=00 bra v8mf1 ;k=01 bra v8mf0 ;k=02-MF2(cylinder 1 & 5) bra v8mf0 ;k=03 bra v8mf0 ;k=04 и т.д. Так лучше, чем мой первоначальный код, потому что здесь код вычисления перехода не обязательно размещать прямо перед таблицей. А в том коде ещё одна проблема возникнет с вычислением адреса перехода, если таблица займёт целую страницу (для k=128).
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
May 26 2008, 09:53
|

Частый гость
 
Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344

|
Цитата(=GM= @ May 23 2008, 18:10)  Пожалуй, воспользуюсь я вашим советом и размещу три таблицы в начале трёх страниц. С учётом того, что пока k<61 (а в обозримом будущем вряд ли будет больше) код получится более-менее приличный Код movlw HIGH v8goto movwf PCLATH bcf STATUS,C rlcf k,w ;k<128, no carry movwf PCL,f
v8goto bra v8mf0;k=00 bra v8mf1;k=01 bra v8mf0;k=02-MF2(cylinder 1 & 5) bra v8mf0;k=03 bra v8mf0;k=04 и т.д. Так лучше, чем мой первоначальный код, потому что здесь код вычисления перехода не обязательно размещать прямо перед таблицей. А в том коде ещё одна проблема возникнет с вычислением адреса перехода, если таблица займёт целую страницу (для k=128). Может Вы спешили(и я зря повторюсь  ) - но перед меткой пропущен оператор : Код TablJMP code 0xYYY00;для принудительного расположения в ПЗУ программ
v8goto: для линкера. Иначе фокус не прйдет.
Сообщение отредактировал volodya - May 26 2008, 09:54
--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть" "Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
|
|
|
|
|
May 26 2008, 23:00
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(volodya @ May 26 2008, 08:53)  Может Вы спешили (и я зря повторяюсь) - но перед меткой пропущен оператор : TablJMP code 0xYYY00;для принудительного расположения в ПЗУ программ для линкера. Иначе фокус не пройдет. Всё нормально, спасибо. Просто там должно быть три таблицы, не хотел их все три писать, да и не надо вроде, а одна осталась по инерции... Вот поискал на форуме и в сети программы реализации арифметики 16-24-32 разряда, в частности деление, и вы знаете, не так уж много нашёл, а то что нашёл, проигрывает по скорости моим программам, надо будет, пожалуй, открыть соответствующую тему, поделиться с народом, глядишь и сам что-то новенькое узнаю...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 17 2008, 07:40
|
Группа: Новичок
Сообщений: 2
Регистрация: 21-12-07
Пользователь №: 33 520

|
Для 18 серии еще возможен вот такой вариант на все случаи жизни и код будет перемещаемым, и размер k любой. Код clrf PCLATH rlcf k, w btfsc STATUS, C ;это можно опустить если k<128 incf PCLATH, f ;это можно опустить если k<128 addlw low TAB_GOTO movlw high TAB_GOTO addwfc PCLATH, f rlcf k, w addlw low TAB_GOTO movwf PCL
TAB_GOTO bra L_1 bra L_2 ...
Сообщение отредактировал buka_2004 - Jun 17 2008, 07:42
|
|
|
|
|
Jun 20 2008, 11:17
|
Группа: Новичок
Сообщений: 7
Регистрация: 7-10-05
Из: СПб
Пользователь №: 9 345

|
Код UART2_State_tbl bra UART2_wt_strt bra UART2_wait bra UART2_reci
UART2_State_tbl_end if(high(UART2_State_tbl)!=high(UART2_State_tbl_end)) error "UART2_State_tbl broken" endif
Сообщение отредактировал ant333 - Jun 20 2008, 11:18
|
|
|
|
|
Jul 1 2008, 16:52
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(buka_2004 @ Jun 17 2008, 06:40)  Для 18 серии еще возможен вот такой вариант на все случаи жизни, и код будет перемещаемым, и размер k любой. Код clrf PCLATH rlcf k, w btfsc STATUS, C ;это можно опустить если k<128 incf PCLATH, f ;это можно опустить если k<128 Здесь у вас возможна неуловимая ошибка во второй строке, если при выполнении фрагмента бит переноса будет установлен. Такие ошибки весьма опасны, поскольку их трудно отследить. Лучше код переписать так Код clrf PCLATH bcf STATUS,C rlcf k,w rlcf PCLATH и далее по тексту Но код всё равно получается длинный, если сравнивать с моим последним вариантом, а стоит он у меня в прерывании.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|