AVR, ARM, CPLD и VGA… 1760 часов чистого времени

Как вывести картинку (живую) с микроконтроллера, логической схемы, кофеварки, чтобы ее мог видеть человек? Ха! Существует чертова куча дисплеев, будь то color, либо monochrome. А если вам нужно не просто текст выводить, а графику, может да же и видео. Гораздо универсальнее будет монитор/TV, который есть почти в каждом доме.

Я остановился на VGA интерфейсе, так как с остальными наша кофеварка не справится. Рассмотрим его с железной части.

Вот все, что нам нужно. Остальные можно смело отрезать.

Я думаю, вы уже поняли, что RBG — цвет пикселя, а HSYNC — горизонтальная и VSYNC — вертикальная синхронизации. Все они INPUT. Так как сигнал RGB идет аналоговый — нужны 3 ЦАП-а, причем учитывается, что напряжение на RGB — не должно превышать 0.7v. Вот простейшая схема, для кофеварки с напряжением питания 3.3v.

Ashampoo_Snap_2014.01.13_19h38m43s_008_

ЦАП — универсальны, можно легко увеличить или уменьшить их разрядность, путем очевидного добавления или удаления пары резисторов.

И что же делать? Немного теории…

Линии синхронизации служат для того, чтобы монитор знал, где начало кадра, какое разрешение и какова частота кадров. Аналоговые входы служат для задания цвета. Чем выше напряжение мы подаем на аналоговый вход, тем более яркий оттенок соответствующего цвета мы получим.

Картинка на экране прорисовывается построчно сверху-вниз. А каждая строка прорисовывается слева-направо, и в конце каждой строки нужно подавать горизонтальный синхроимпульс.  Можно сказать, сдвиг «рисующего луча монитора» на следующую строку. Когда мы прорисовали все строчки, нужно подать вертикальный синхроимпульс, сообщая монитору, что нужно вернуть «рисующий луч» в начальное положение. Но… также существуют, так называемые «бордюры», это участки, которые не являются видимыми. Они служат для дополнительной синхронизации ЭЛТ («рисующего луча») старых мониторов, а в современных они только для соблюдения стандарта.

 

 Истинный стандартный VGA сигнал:

  • Разрешение: 640x480
  • Частота обновления экрана: 60-72Гц
  • Количество цветов: n

Теперь дополним нашу картину бордюрами и прочим.

 Вместе с «бордюрами» получается 525 строк, из них — 480 информационные.

screen2

 

Время одной строки вычисляется так: 1сек/60 кадров / 525 строк = 31.75 мкс. То есть, чтобы нарисовать 640 пикселей в 1-ну строку, необходимо пулять RGB данные с частотой ~25.175MHz. С синхроимпульсами — проще, так как их можно генерировать по таймерам.

И не дай Бог, вы хотя бы чуть-чуть, хотя бы на 2 мкс ошибётесь по таймингам… монитор даст вам пинка под зад и пошлет куда подальше, со своей табличкой! 

237644ad0d4226238d

 

Из соображений производительности было принято решение понизить «виртуальное» разрешение экрана, а физически оставить стандарт. (1 виртуальный пиксель будет занимать несколько реальных):

  • Разрешение: 256×208, 272х208, 320×240
  • Количество цветов одновременно: 256

Собственно говоря, начнем.

Реализация на ARM

ArduinoDue, у нее полным полно ресурсов. Существует специальная библиотека VGA. ЦАП и прочая периферия у нас уже есть. Подключаем так:

vgacolour

 

 

И тестовый скетч для этой конструкции:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Hello World Colour using VGA library by stimmer
// include VGA library
#include <VGA.h>
 
void setup() {
  // start 320×240 mode
  VGA.begin(320,240,VGA_COLOUR);
}
 
void loop() {
  // text colour
  VGA.setInk(random(256));
 
  // text background colour
  VGA.setPaper(random(256));
 
  // print message
  VGA.print(» Hello Arduino «);
 
  VGA.waitSync();
}

Результат 320x240x8bb:

vgaha

Да, это все хорошо, но теперь ложка дегтя: на формирование vga изображения уходит чертова куча ресурсов, из-за того, что архитектура микроконтроллера не подходит для генерации VGA. По другому, использование микроскопа для забивания гвоздей.

Реализация на AVR

Достаем Arduino Duemil. или голую avr. Берем пример отсюда.

11

 

Код, опять же:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#define NOP asm(«nop»)
#define BLACK PORTB = B00000000;
#define BLUE PORTB = B00000001;
#define GREEN PORTB = B00000010;
#define CYAN PORTB = B00000011;
#define RED PORTB = B00000100;
#define MAGENTA PORTB = B00000101;
#define YELLOW PORTB = B00000110;
#define WHITE PORTB = B00000111;
 
unsigned int linecount = 1;
 
void setup()
{
  //Set pins 5 to 10 as outputs
  // 7 — HSYNC
  // 6 — VSYNC
  // 10, 9 e 8 — RGB
  DDRD |= B11100000;
  DDRB |= B11100111;
  PORTD |= B11000000;
 
  //set timer
  TCCR2A = 0×02; // WGM22=0 + WGM21=1 + WGM20=0 = Mode2 (CTC)
  TCCR2B |= (1 << CS20); //
  TCCR2B |= (1 << CS21); // Set prescaler
  TCCR2B &= ~(1 << CS22); //
 
  TCNT2 = 0; // clean counter
 
  TIMSK2 &= ~(1<<OCIE2A); // set comparison interrupt
  TIMSK2 |= (1<<TOIE2); // set overflow interrupt
}
 
void loop()
{
  noInterrupts();
  do{
    BLACK;
    if (TCNT2 > 0x0f){
 
      delayMicroseconds(1);
      NOP;NOP;NOP;NOP;
 
      TCNT2 = 0×00;
 
      // #### HSYNC ###
      PORTD &= ~(1 << 7);
      if (++linecount >= 525){ //525 lines
        linecount = 1;
      }
      PORTD |= (1 << 7); 
 
      // ### VSYNC ###
      if ((linecount == 1)||(linecount == 2)){
        PORTD &= ~(1 << 6);
      } else {
      PORTD |= (1 << 6);
 
      NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
      NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
      NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
      NOP;NOP;NOP;NOP;NOP;
 
      if ((linecount >= 9) && (linecount <= 489)){
 
        WHITE;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        BLACK;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        BLUE;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        GREEN;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        CYAN;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        RED;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        MAGENTA;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        YELLOW;
        delayMicroseconds(3);NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        BLACK;
        NOP;NOP;NOP;NOP;
      }
 
     }
   }
  }while(1);
}

DSCN1629

Выводим изображение формата 800×600, разрешением 8×1. Мм-да… Это никуда не годиться. Однако, появилась идея подключить к ней SRAM, которая будет выступать в качестве видеопамяти, а МК будет всего лишь переключать адреса и генерировать синхроимпульсы. Появился концепт:

 DSCN5380

Но он так и не стал реальностью, atmega168 не могла с такой скоростью переключать адреса, в случае с разгоном — то же ничего не вышло, так как на 3.3в ничего не работало.

——

Немного позже, один добрый человек MisterDi подсказал мне, что сделать видео-контроллер — дело не хитрое, обойдется в несколько корпусов микросхем серии к555. Либо, пишет, можно использовать ПЛИС. ПЛИС? — тогда я и понятия не имел что такое ПЛИС и с чем его едят.

——

Реализация на ПЛИС

Мне посоветовали некую особу: EPM240, серии MAXII. Имеет 80-портов и 240Ле — логических элементов. Я заказал у узкоглазых друзей это чудо.

Первая ошибка, которую я допустил — не заказал программатор  понадеялся на LPT. Оказалось, что через LPT на Windows 7 x64 — программировать нельзя. Поэтому  я заказал еще несколько плат у сайта Marsohod. (г.Таганрог). Выражаю им огромую благодарность. Концепт видео-контроллера:

Ashampoo_Snap_2013.12.26_10h04m40s_004_

Необходимые возможности:

  • Генерация видеосигнала 640×480@60Hz
  • Видеопамять
  • Вывод изображения из видеопамяти 272x208x8bb
  • Палитра цветов 12бит (256цветов).
  • Аппаратная регулировка яркости всего изображения
  • Эффект Scanline (для улучшения качества изображения)
  • Прямой параллельный доступ к видеопамяти по общей шине 8бит

Необходимые железки:

  • ПЛИС: EPM240
  • Микросхема ОЗУ 128×8: CY7C1019DV33-10ZSX
  • 3 ЦАП по 4бит каждый
  • Кварц 25.175 MHz для генерации VGA
  • Кварц 100MHz для работы с видеопамятью и палитрой.

Опять же, выражаю благодарность форуму Марсохода, благодаря им я познал все прелести работы с ПЛИС. Представьте, какие горы можно свернуть, используя МК и ПЛИС?!

Схему подключения можете увидеть в assigment editor-e.

Я также развел спец плату для этого, вывел все пины и подключил ОЗУ:

Ashampoo_Snap_2013.12.26_10h40m40s_005_

После нескольких недель работы и тестирования была составлена схема в Altera Quartus:

Pal

Логика алгоритма:

  1. Всегда генерируем синхроимпульсы
  2. Когда появился сигнал горизонтальной развертки — начинаем с помощью счетчиков считать адреса ОЗУ и выводить содержимое ячеек в ЦАП.
  3. Во время вертикальных бордюров передаем сигнал контроллеру, что, мол, надо отправлять мне данные, и открываем доступ контроллеру к видеопамяти.

Генерация VGA:

Первое, что нам нужно — два 10-ти битных счетчика: горизонтальный и вертикальный. Постоянный меандр, с частотой 25.175MHz необходимо подавать на вход горизонтального счетчика и при его переполнении подавать импульс вертикальному. Получается координатная система XY, также для удобства представим счетчики в виде десятичных:

screen3

Как вы могли заметить, мы используем не весь 10-ти битный счетчик. При достижении 799dec — необходимо его сбросить и подать импульс на второй. Второй считает до 524dec, затем вся система сбрасывается. Но не стоит забывать, что нам необходимо еще подавать синхроимпульсы, поэтому несложно додумать алгоритм использую стандарт 640×480@60Hz:

X

  • От 0 до 799, при переполнении делаем сброс и переключаем вертикальный счетчик.(vertical clock)
    • От 0 до 639 — разрешаем вывод пикселей на экран, иначе — запрещаем
    • От 655 до 751 — горизонтальный синхроимпульс

Y

  • Считаем от 0 до 524, при переполнение делаем сброс.
    • От 0 до 479 — разрешаем вывод пикселей на экран, иначе запрещаем
    • От 489 до 491 — вертикальный синхроимпульс

Станет понятнее, если нарисовать таблицу:

Горизонтальный счет Пиксели Время~ [мкс]
Видео-данные 640 25.422045680238
Передний бордюр 16 0.63555114200596
Синхроимпульс 96 3.8133068520357
Задний бордюр 48 1.9066534260179
Всего 800 31.777557100298
Вертикальный счет Линии Время~ [мс]
Видео-данные 480 15.253227408143
Передний бордюр 10 0.31777557100298
Синхроимпульс 2 0.063555114200596
Задний бордюр 33 1.0486593843098
Всего 525 16.683217477656

На языке программирования Verilog это можно описать таким образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
///////////////////////////////////////////////////////////////
//module which generates video sync impulses
///////////////////////////////////////////////////////////////
 
module hvsync (
// inputs:
input wire clock,
 
// outputs:
output reg line,
output reg frame,
output reg hsync,
output reg vsync
);
 
//variables
reg [10:0]char_count;
reg [10:0]line_count;
reg end_of_line;
reg [2:0]pixel_st;
reg [2:0]line_st;
reg end_of_frame;
 
//permanent comb computations:
always @*
begin
//horizontal processing
 if(char_count < 640)
  pixel_st = 0; //active video
 else
 if(char_count < 656)
  pixel_st = 1; //front porch
 else
 if(char_count < 752)
  pixel_st = 2; //hsync impuls
 else
  pixel_st = 3; //back porch
 
 if(char_count < 800)
  end_of_line = 0;
 else
  end_of_line = 1;
 
//vert processing
 if(line_count < 480)
   line_st = 0; //active video lines
 else
 if(line_count < 490)
  line_st = 1; //front porch
 else
 if(line_count < 492)
  line_st = 2; //vsync impuls
 else
  line_st = 3; //front porch
 
if(line_count < 525)
  end_of_frame = 0;
else
  end_of_frame = 1;
end
 
//synchronous process
always @(posedge clock)
begin
 hsync <= (pixel_st==2′b10);
 vsync <= (line_st==2′b10);
 line <= (pixel_st==3′d4);
 frame <= (line_st==3′d4);
 
 if(end_of_line)
  begin
   char_count <= 0;
   if(end_of_frame)
    line_count <= 0;
   else
      line_count <= line_count + 1′b1;
   end
   else
    begin
      char_count <= char_count + 1′b1;
    end
  end
endmodule

 

Автор этого кода синхронизации: Николай.

 

Вывод изображения:

Теперь у нас два варианта: выводить данные из видеопамяти по координатам XY счетчиков синхронизации или завести еще один счетчик, который будет линейно считать адреса памяти. Я предпочел второй.

Так как разрешение 272x208x8bb будет занимать 56576байт — это адресное пространство шириной 16бит — необходим 16бит счетчикAshampoo_Snap_2014.01.12_20h03m45s_006_

Счет он должен начинать только тогда, когда горизонтальный и вертикальный ==0 и частота его работы должна быть равна 25.175MHz/2=12.5875MHz для уменьшения горизонтального разрешения.

  • Работа от частоты пикселей /2 = ~12MHz
  • Считать от 1 до 56576
  • Запрещать счет, если горизонтальный счетчик находится в Бордюре/Синхроимпульсе.
  • Сбрасывать счет, если вертикальный счетчик находится в Бордюре(ах)/Синхроимпульсе.

Кроме того, необходимо уменьшить вертикальное разрешение, путем удвоения горизонтальных строк. Не все так просто, как кажется, ведь нам нужно разрешение 272×208, а из 640×480 мы можем получить только 320×240, в связи с этим нужно сделать «рамку» вокруг изображения.

screen4

Для получения «рамки» — пропускаем по горизонтальному счетчику 48 строк слева и справа; по вертикальному 32 сверху и снизу.

Как придать изображению эффект Scanline?

Эффект улучшает изображение низкого разрешения. При выводе изображения нужно затемнять все четные строки, убавлять яркость. Пример:Ashampoo_Snap_2013.10.29_11h01m38s_001_ ->

В этой версии ВП этот эффект реализован немного криво. Еще можно применить hd2x, но это сложнее.

 

Работа системы палитр.

В видепроцессор необходимо загружать индексированные данные или изображение с палитрой. Сама матрица изображения 272×208 и 8бит на пиксель, к этой матрице необходима палитра 256цветов и по 8бит на каждый цвет — в сумме 768байт. Как это работает:

indexed

 Тем самым мы сокращаем размер изображения и не теряем качество. Кроме того, мы можем изменять изображения, путем смены палитры, что гораздо быстрее, чем его перерисовывать. Яркий пример можно увидеть здесь ->/.

 Ashampoo_Snap_2014.01.12_20h42m23s_007_

Регулировка яркости.

Здесь все просто. На определенном адресе SRAM находится байт управления яркостью. Он знакового типа: -127 +127. Записывая туда значения, мы можем изменять яркость изображения, не меняя палитру. В ПЛИС стоит знаковый сумматор с сатурацией, который просто складывает этот байт со значением пикселя.

Cпособ подключения.

Подключение осуществляется с помощью параллельного интерфейса с 8бит шиной данных и 16бит шиной адреса.

screen5

Также используются сигналы —CS (Выбор устройства — видеопроцеесора), чтобы можно было использовать эту шину для нескольких устройств и —WE — разрешение записи.

Логика записи данных должна быть такой:

  1. -CS — низкий уровень
  2. Установка адреса
  3. Установка данных
  4. -WE — низкий уровень
  5. Задержка
  6. -CS и —WE — высокий уровень

Либо

  1. -CS — низкий уровень
  2. Установка адреса1
  3. -WE — низкий уровень
  4. Установка данных1
  5. Задержка (небольшая)
  6. Установка адреса2
  7. Установка данных2
  8. Задержка (небольшая)
  9. -CS и -WE — высокий уровень

Еще есть один вывод — —VSYNC, означающий: производится ли вывод на экран. Фактически, он будет низкого уровня(LOW), когда происходят VerticalPorch, VerticalPulse, верхняя и нижняя части «рамки». Это и есть время для записи данных в видеопамять, в любой другой момент видеопроцессор просто закроет доступ к видеопамяти.

В общей сумме, максимальное время, нужное для записи будет равно: ~3.431976166832184мс, с связи этим, частота работы всей передающей шины должна быть: ~17MHz, ну а, соответственно, скорость 17МегаБайт/в сек. Сопротивление портов видеопроцессора и передатчика должны быть согласованы. (резисторы в помощь!)

Формат изображения: Bitmap, разрешением 272×208 (1байт на пиксель) передается последовательно; цветовая палитра 1байт на канал, формата [r1 r2…r256]-[g1 g2…g256]-[b1 b2…b256].

Адреса

  • 0x0000 - 0xDCFF (включительно) - Bitmap
  • 0xDD00 - 0xDFFF (включительно) - Palette
  • 0xE000 - Яркость

screen6

Я связал этот видеопроцессор и ArduinoDue. У чипа SAM3X имеется специальная ретрансляционная параллельная шина  адреса и данных для таких целей. Однако в ArduinoDue были выведены не все пины (A6 и A9), поэтому пришлось выводить их напрямую от микросхемы. ATSAM3X позволила развить скорость передачи данных 38МегаБайт/сек, возможно можно и больше, тут необходимо тонко настраивать SMC контроллер.

DSCN5475

DSCN5476

А код для этой картинки — очень прост:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <GraphicsEngine.h>
#include "bmp.h"
 
uint8_t palette[768]; //Palette
 
int8_t light = 0; //L
 
#include <Parallel.h>
 
uint8_t* gram = (uint8_t*)0x60000000; //GPU ADDR
 
void setup() {
 
  Parallel.begin(PARALLEL_BUS_WIDTH_8, PARALLEL_CS_0, 16, false, true);
  Parallel.setCycleTiming(1,1);
  Parallel.setPulseTiming(0,0,0,0);
  Parallel.setAddressSetupTiming(0,0,0,0);
 
  GFX.Init(VGA_MODE_272x208);
  GFX.FillScreenFromBuffer(image+3);
 
  memcpy(palette, image+3+56576, 768);
 
  pinMode(53, INPUT);  //FRAME (GPU) /VSYNC
 
}
 
void render() {
  while(PIO_Get( g_APinDescription[53].pPort, PIO_INPUT, g_APinDescription[53].ulPin ) == 0);
  while(PIO_Get( g_APinDescription[53].pPort, PIO_INPUT, g_APinDescription[53].ulPin ) == 1);
      memcpy(gram+56576, palette, 768);
	  memset(gram+57344, light, 1);
      GFX.SendScreenTo(gram);
}
 
void loop() {
  render();
}

Собственно говоря, это наилучший вариант, который я смог сделать, видео-контроллера. Напоследок демо-видео:

[Прошивка ПЛИС v.2.5]
[Прошивка ПЛИС v.2.0]
[Прошивка ПЛИС v.1.0]

[Плата видео-контроллера]

Все обновления видеопроцессора будут в этой записи.

Для конвертации картинок  — используйте эту программу//. Читает .bmp 8bbIndexed. 272×208

 

Вы можите оставить комментарий, или поставить трэкбек со своего сайта.

13 комментариев к “AVR, ARM, CPLD и VGA… 1760 часов чистого времени”

  1. Nick:

    Да, вы правильно поняли. Для формирования изображения использовался следующий код:

    always @(posedge VGA_CTRL_CLK)//25 МГц
    begin
    counter = counter + 1'd1;
    if (counter <320)//первые 320
    begin ///////первая камера
    //data_adres=0;
    CCD_R=sCCD_R;//Красный канал,идет на VGA адаптер, отображаем данные с камеры
    CCD_G=sCCD_G;//Зеленый канал,идет на VGA адаптер
    CCD_B=sCCD_B;//Синий канал,идет на VGA адаптер
    end

    else if(counter640)//если больше счетчик равен нулю
    begin
    counter=1'b0;
    end
    end

    Причем если выводить полное изображение проблем не возникает.
    И я не могу понять, то ли неправильно формирую изображение на вход VGA контроллера(скорее всего), то ли нужно сам контроллер изменить.

    • Nick:

      И извиняюсь за плохо оформленый код, с тегами не разобрался.

      • Старайтесь не использовать неблокирующие присваивания «=» — это не позволяет вам контролировать время на выполнение операций.

        Насчет кода, не могу найти ошибки, но попробуйте этот:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        
        always @(posedge VGA_CTRL_CLK)//25 МГц
        begin
        	counter <= counter + 1;
        	if (counter < 320)//первые 320
        	begin ///////первая камера
        		//data_adres=0;
        		CCD_R <= sCCD_R; //Красный канал,идет на VGA адаптер, отображаем данные с камеры
        		CCD_G <= sCCD_G; //Зеленый канал,идет на VGA адаптер
        		CCD_B <= sCCD_B; //Синий канал,идет на VGA адаптер
        	end
         
        	else if(counter >= 640) //если больше счетчик равен нулю
        	begin
        		counter <= 0;
        	end
        end

        Советую вам привязывать все ваши операции с пикселями и строками к модулю синхронизации (char_count и line_count), иначе возможны расхождения в счетах. Там бы это выглядело так:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        
        always @(posedge VGA_CTRL_CLK)//25 МГц
        begin
        	if (char_count < 320 && line_count < 480)//первые 320
        	begin ///////Первая камера
        		CCD_R <= sCCD_R; //Красный канал,идет на VGA адаптер, отображаем данные с камеры
        		CCD_G <= sCCD_G; //Зеленый канал,идет на VGA адаптер
        		CCD_B <= sCCD_B; //Синий канал,идет на VGA адаптер
        	end
        	else if (line_count < 480)
        	begin
        	.... ///////Вторая камера
        	end
        end
  2. Nick:

    Дефект сохранился, но несколько в иной форме.

    Попробую переписать код VGA контроллера подобно вашему, с привязкой координат пикселей к модулю синхронизации. Когда будет что-то определенное-обязательно поделюсь.
    Спасибо за помощь.

      • Хм… Очень странно, видимо есть еще некоторые нюансы, которые я не учел.
        Насчет модуля синхронизации, то все верно, но не обращайте внимание на готовый проект в этой статье: там как раз наоборот сделано, еще один счетчик считает параллельно, что вызывает глюки.

  3. Andrey:

    Как вы думаете, реально ли на этой плисине вытянуть разрешение 1280×1024? Или не выдаст она 108 мегагерц / память подкачает?

    • Нет, не вытянет. Проблема будет в блоке палитры, частота чтения значений цветов там — 100MHz, чтобы успеть подставить необходимые компоненты (RGB) в период 24MHz.
      Если же частота пикселей уже ваши ~100MHz, в таком случае память должна работать на ~400MHz, что уже не реально. Впрочем, расширяя шину данных видеопамяти, скажем, до 32бит, будет возможность снизить эти 400 до ~200. Однако с таким количеством проводников и верхней частотой MAXII вряд ли справится. 🙂

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Bug Report
Локализовано: шаблоны Wordpress