Мелкие вопросы по МК и ПЛИС.

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Аlex »

Вот это уже ближе к делу :idea:
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение zero648 »

На асме AVR это занимает 34 байта ROM, 0 RAM и 20 циклов
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение HHIMERA »

Ладно... С30 PIC24...
39 байт ROM, 0 байт RAM и 13 cycles...
:)))
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Kavka »

zero648 писал(а):На асме AVR это занимает 34 байта ROM, 0 RAM и 20 циклов
Хмм... Код покажи.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение zero648 »

Вход - r17:r16, выход - r1:r0

Код: Выделить всё

            movw    r18, r16
            swap    r19
            andi    r19, $0f
            swap    r18
            andi    r18, $0f
            andi    r17, $0f
            andi    r16, $0f
            ldi     r20, 10
            mul     r18, r20
            add     r16, r0
            mul     r19, r20
            add     r17, r0
            ldi     r20, 100
            mul     r17, r20
            clr     r17
            add     r0, r16
            adc     r1, r17


Может, у кого еще получится ужать код
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Kavka »

zero648 писал(а):Может, у кого еще получится ужать код
У вас без разбора из ниблов в байты: 20 байт, 13 тактов. Красиво!
С умножением здорово сэкономил! 8)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение FreshMan »

в AVR, в режиме Normal при разрешении прерывания по совпадению счетчик продолжает считать дальше или сбрасывается ?
Tell Me The Truth
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение HHIMERA »

Kavka писал(а): 13 тактов. Красиво!

Вот только привирать... некрасиво... :)))
3*2 + 14*1 = 20 тактов... да и то... на Мега-тру-АСМ-джедайстве.. :)))
Компилятор СИ не смог одолеть архитектуру времён развитого АСМоциализма и пасущихся мамонтов... :)))

А вот это... действительно красиво... С30... GCC кстати...

Код: Выделить всё

56:                X=D*1000 + C*100 + B*10 + A;
  02A2  97B85F     mov.w [w15-6],w0         // Загружаем А, B, C и D
  02A4  97B94F     mov.w [w15-8],w2
  02A6  97BA3F     mov.w [w15-10],w4
  02A8  97BBFF     mov.w [w15-2],w7

  02AA  203E86     mov.w #0x3e8,w6         // Умножаем и складываем
  02AC  B98006     mul.ss w0,w6,w0
  02AE  200646     mov.w #0x64,w6
  02B0  B99106     mul.ss w2,w6,w2
  02B2  400002     add.w w0,w2,w0
  02B4  B9226A     mul.su w4,#10,w4
  02B6  400004     add.w w0,w4,w0
  02B8  400007     add.w w0,w7,w0

  02BA  9FBFE0     mov.w w0,[w15-4]         // Получаем результат
57:               

И ничего лишнего... как на АСМе... и каждая строчка 1 такт... :)))
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Kavka »

HHIMERA писал(а):Вот только привирать... некрасиво... :)))
3*2 + 14*1 = 20 тактов... да и то... на Мега-тру-АСМ-джедайстве.. :)))
Это верно для полного кода приведённого zero648.
Прочитай внимательно моё сообщение!!! :evil:
Я написал про основное преобразование, т.к. исходные цифры могут храниться в разном виде.
СпойлерИзображение

Выход ассемблера (без NOP-а)

Код: Выделить всё

ATmega32A memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
----------
[.cseg] 0x000000 0x000014     20      0     20   32768   0.1%
[.dseg] 0x000060 0x000060      0      0      0    2048   0.0%
[.eseg] 0x000000 0x000000      0      0      0    1024   0.0%
Вложения
test-bcd1.png
(11.31 КБ) 380 скачиваний
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

Короче,
A - единицы;
B - десятки;
С - сотни;
В - тысячи;
X - результат.

В итоге:

Код: Выделить всё

X = A + (B<<3) + (B<<1) + (C<<6) + (C<<5) + (C<<2) + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);

Для X э [0, 9999]
Башка уже не варит в математике, пойду спать, завтра додумаю.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Kavka »

Chettuser, 82 байта, 41 такт (против 20 байт, 13 тактов у zero648).
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.
Для контроллеров где нет умножения пойдёт. :)
Спойлер

Код: Выделить всё

; input - r19,r18,r17,r16
; output - r21:r20

; R = A + (B<<3) + (B<<1)
;       + (C<<6) + (C<<5) + (C<<2)
;       + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);

.def rD = r19
.def rC = r18
.def rB = r17
.def rA = r16

.def rRL = r20
.def rRH = r21

         mov      rRL,   rA      ; RES = A
         mov      rRH,   rD      ; RES = RES + (D << 8)
         lsl      rD            ; D << 9
         add      rRH,   rD      ; RES = RES + (D << 9)


         lsl      rB            ; B << 1
         add      rRL,   rB      ; RES = RES + (B << 1)
         lsl      rB            ; B << 2
         lsl      rB            ; B << 3
         add      rRL,   rB      ; RES = RES + (B << 3)

.undef rB
.def rCH = r17
         clr      rCH

         lsl      rC            ; C << 1
         lsl      rC            ; C << 2
         add      rRL,   rC      ; RES = RES + (C << 2)
         lsl      rC            ; C << 3
         lsl      rC            ; C << 4

         lsl      rC
         rol      rCH            ; C << 5 ; (rCH:rC)

         add      rRL,   rC
         adc      rRH,   rCH      ; RES = RES + (C << 5)

         lsl      rC
         rol      rCH            ; C << 6

         add      rRL,   rC
         adc      rRH,   rCH      ; RES = RES + (C << 6)

.undef rCH
.def rDH = r17
         clr      rDH

         lsl      rD            ; D << 1
         lsl      rD            ; D << 2
         lsl      rD            ; D << 3
         add      rRL,   rD      ; RES = RES + (C << 2)
         lsl      rD            ; C << 4

         lsl      rD
         rol      rDH            ; D << 5 ; (rDH:rD)

         add      rRL,   rD
         adc      rRH,   rDH      ; RES = RES + (D << 5)

         lsl      rD
         rol      rDH            ; D << 6 ; (rDH:rD)

         add      rRL,   rD
         adc      rRH,   rDH      ; RES = RES + (D << 6)

         lsl      rD
         rol      rDH            ; D << 7 ; (rDH:rD)

         add      rRL,   rD
         adc      rRH,   rDH      ; RES = RES + (D << 7)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение HHIMERA »

Kavka писал(а):Chettuser, 82 байта, 41 такт (против 20 байт, 13 тактов у zero648).
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.

:)))
Что в лужу... :)))
Вспомните, о чём писал вопрошающий... :)))
Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18. :))


Chettuser писал(а):Опять ассемблер :(
В сети ассемблера завались, а вот на Сях...
"Я не даю готовых решений, я заставляю думать!"(С)
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

Я на работе, занят, вечером буду оптимизировать. То что выше выкладывал можно еще математически укоротить. А потом уже по железу.
Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25172
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение КРАМ »

Chettuser писал(а):Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].

Какая разница, сколько знаков после запятой? Это лишь вопрос множителя. Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение HHIMERA »

Chettuser писал(а):Я на работе, занят, вечером буду оптимизировать. То что выше выкладывал можно еще математически укоротить.

Тогда берите PIC18 и HI-TECH...

Код: Выделить всё

unsigned char A,B,C,D;
unsigned int X, Y;

//X=D*1000 + C*100 + B*10 + A;

X = D*1000;
X += C*100;
X += B*10;
X += A;

выполняется за 46 cycles... что практически вровень с Мегой на СИ... :)))
На PIC18F25K20@16MHz c PLL - 2,875мкС...
"Я не даю готовых решений, я заставляю думать!"(С)
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

КРАМ писал(а):Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.

X э [0, 99999999]
Где запятая? :) От 0 до 99999999.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25172
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение КРАМ »

Это я слету неправильно прочел... :)
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

На текущий момент:
Спойлер

Код: Выделить всё

long int A, B, C, D, E, F, G, H, X;

int main()
{
   A = 9;
   B = 9;
   C = 9;
   D = 9;
   E = 9;
   F = 9;
   G = 9;
   H = 9;
   
   X = A;                  // Прибавили еденицы
   X = X + (B<<3) + (B<<1);         // Прибавили десятки
   X = X + (C<<6) + (C<<5) + (C<<2);         // Прибавили сотни
   X = X + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);   // Прибавили тысячи
   X = X + (E<<13) + (E<<10) + (E<<9) + (E<<8) + (E<<4);         // Прибавили десятки тысяч
   X = X + (F<<16) + (F<<15) + (F<<10) + (F<<9) + (F<<7) + (F<<5);    // Прибавили сотни тысяч
   X = X + (G<<19) + (G<<18) + (G<<17) + (G<<16) + (G<<14) + (G<<9) + (G<<6); // Прибавили миллионы
   X = X + (H<<23) + (H<<20) + (H<<19) + (H<<15) + (H<<12) + (H<<10) + (H<<9) + (H<<7); // Прибавили десятки миллионов
   
    printf ("%d\n", X);

}

занимает 3758 Instruction Cycles на MCC18. Ушёл спать, оптимизирую потом.

PS: Зря я не доверял компилятору!
код

Код: Выделить всё

   X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);

занимает всего 676 Instruction Cycles
:)))
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Kavka »

HHIMERA писал(а):Вспомните, о чём писал вопрошающий... :)))
Не на то внимание обращаешь!

Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18. :))

Chettuser, если в МК есть аппаратное умножение, то такое лучше написать как есть. Перевод на сдвиги может быть только хуже, так как элементарных операций получается значительно больше. Если умножителя нет, тогда со сдвигами может быть лучше.

Могу продемонстрировать на примере AVR.
gcc version 4.3.3 (WinAVR 20100110)
Спойлер

Код: Выделить всё

unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
  return ( d*1000 + c*100 + b*10 + a );
}
С аппаратным умножением: 50 байт, 30 тактов
Без аппаратного умножения: 80 байт, 36 из них процедура умножения, 91..233 такта

Спойлер

Код: Выделить всё

unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {

  return ( a + (b<<3) + (b<<1) + (c<<6) + (c<<5) + (c<<2) + (d<<9) + (d<<8) + (d<<7) + (d<<6) + (d<<5) + (d<<3) );
}
170 байт, 195 тактов (с циклами)

Слегка модифицированный вариант - попытка отучить компилятор от циклов при сдвигах.
Спойлер

Код: Выделить всё

unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {

unsigned int x;
unsigned int tmp;

   x = a | (d<<8) + (d<<9);
   b = b << 1;
   x+= b;
   b = b << 1;
   b = b << 1;
   x+= b;
   c = c << 1;
   c = c << 1;  // c << 2
   x+= c;
   c = c << 1;  // c << 3
   c = c << 1;  // c << 4

   tmp = c;
   tmp = tmp << 1; // c << 5
   x+= tmp;
   tmp = tmp << 1; // c << 6
   x+= tmp;

   d = d << 1;
   d = d << 1;
   d = d << 1;  // d << 3
   x+= d;
   d = d << 1;  // d << 4
   tmp = d;
   tmp = tmp << 1; // d << 5
   x+= tmp;
   tmp = tmp << 1; // d << 6
   x+= tmp;
   tmp = tmp << 1; // d << 7
   x+= tmp;
  return ( x );
}
134 байт, 75 тактов

Варианты с аппаратным умножением и со сдвигами имеют ещё такое преимущество как фиксированное время выполнения.

Ну вот, пока я писал, Chettuser сам получил результат. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение HHIMERA »

Chettuser писал(а):Зря я не доверял компилятору!
код

Код: Выделить всё

   X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);

занимает всего 676 Instruction Cycles
:)))

Вообще то... 442 Cycles на С18 и 440 Cycles на HI-TECH PICC18...
"Я не даю готовых решений, я заставляю думать!"(С)
Ответить

Вернуться в «Разные вопросы по МК»