?

Log in

LiveJournal for Vadim Radionov.

View:User Info.
View:Friends.
View:Calendar.
View:Memories.
You're looking at the latest 20 entries. Missed some entries? Then simply jump back 20 entries.

Saturday, December 31st, 2016

Subject:считаем биты, номер младшей и старшей единицы
Time:1:28 am.
В этот раз вроде работает правильно:


mbc = 0x12131210
hbc = 0xffffaa50
cbc = 0x3ee9e994
> print "val,\tmb,\thb,\tcb"
> for val in range(16):
>     mb = (mbc >> (val << 1)) & 3
>     hb = (hbc >> (val << 1)) & 3
>    cb = (cbc >> (val << 1)) & 3
>    print bin(val),"\t", bin(mb),"\t", bin(hb),"\t",cb

val, mb, hb, cb
0b0  0b0  0b0  0
0b1  0b0  0b0  1
0b10  0b1  0b1  1
0b11  0b0  0b1  2
0b100  0b10  0b10  1
0b101  0b0  0b10  2
0b110  0b1  0b10  2
0b111  0b0  0b10  3
0b1000  0b11  0b11  1
0b1001  0b0  0b11  2
0b1010  0b1  0b11  2
0b1011  0b0  0b11  3
0b1100  0b10  0b11  2
0b1101  0b0  0b11  3
0b1110  0b1  0b11  3
0b1111  0b0  0b11  0

Comments: Add Your Own.

Sunday, December 25th, 2016

Subject:магия цифр или симуляция с помощью lut
Time:9:50 pm.
если я правильно понял, то следующая формула найдет самую младшую единицу в четырех мл. разрядах x и подсчитает ее смещение

x = x & 0xf;
shift = (0xf4 >> x) & 1 | (((0xe >> x) & 1) << 1);

Самое забавное это то как я получил ее:

написал логику на verilog, затем с помощью yosys синтезировал в схему с использованием lut'ов. Результат записал обратно в verilog. Откуда и взял константы для формулы:
Comments: Read 3 orAdd Your Own.

Wednesday, December 14th, 2016

Subject:связывание разделяемых библиотек
Time:10:57 am.
Проверил свою догадку: если брать адрес функции malloc, или любой функции из сторонней библиотеки,
то в каждой библиотеке этот адрес функции malloc будет различным.
Действительно, так и есть. Адрес указывает на внутренности секции .plt. своей библиотеки или исполняемого модуля.

Это чтобы минимизировать таблицу переразмещений.
Comments: Add Your Own.

Sunday, October 16th, 2016

Subject:оптимальная схема быстрого сдвига для FPGA
Time:10:13 am.
Эту схему еще называют barrel shifter.

Ее можно делать на 2:1 мультиплексерах. При этом требуется log2(width) слоев из мультиплексоров.
Второй способ предлагает использовать 4:1 мультиплексоры. В этом случае соседние слои объединяются в один.
Хорош он тем, что идеально ложится на ПЛИС, где используются 6-ти входовые таблицы преобразования (LUT).
Но вот у меня в хозяйстве имеется Cyclone IV, построенный на 4-х входовых таблицах (LUT).
Для 4:1 мультиплексора этого мало, а для 2:1 мультиплексора идеальным была бы 3-x входовая таблица. Один вход получается незадействован. А значит и вся схема будет ложиться на Cyclone IV менее чем оптимально.

Интересно, можно ли реализовать это схему более оптимально на 4-x входовых таблицах?

Моя текущая реализация на verilog под катом:


Read more...Collapse )
Comments: Add Your Own.

Thursday, October 6th, 2016

Subject:распараллеливание Load/Store и DataOp
Time:8:30 am.
RISC процессор разделяет команды загрузки/сохранения из памяти с обычными командами,
Казалось бы эти независимые местами команды можно исполнять параллельно, Поскольку загрузка и сохранения требует дополнительный цикл для своей работы, второй цикл можно нагрузить выполнением следующей команды. Однак RISC процессор не такой. Он использует тот же исполнительный блок что и все команды, поэтому вместо параллельного исполнения получаем остановку конвеера на один и больше циклов.
Как решить это проблему? Нужно для Load/Store добавить второй исполнительный блок. И заодно поломать себе голову чем его загрузить в остальные моменты (гипертрединг?)
Comments: Add Your Own.

Subject:Автомат Мура - чистая академщина?
Time:7:06 am.
В  теории цифровых автоматов всегда рассказывают про два вида автоматов: Мура и Мили.
Однако непонятно кто в здравом уме станет делать схему с большим числом состояний и циклов. Где нужные сигналы приходят с задержкой в один такт. Поэтому автомат Мура отдает какой-то академщиной.
Это все равно что рассказывать про ресурсивное вычисление чисел фибоначи.
Comments: Add Your Own.

Monday, September 26th, 2016

Subject:RISC I и СALLINT
Time:8:47 am.
В архитектуре RISC I есть одна странность. Называется она окном регистров. Всего там 6-ть окон. Так что при большей вложенности возникает исключение. Но что характерно, CALLINT который вызывает обработчик прерывания, тоже нуждается в сдвиге окна. Как они разрешили эту коллизию совершенно непонятно.
Comments: Add Your Own.

Sunday, June 26th, 2016

Subject:синтезируемость $readmemb в verilog
Time:10:04 pm.
Бытует распространненое заблуждение, что следующая конструкция на verilog не синтезируемая, и работает только в симуляторе:

initial
begin
  $readmemb("single_port_rom_init.txt", rom);
end

Враки все это. Еще как синтезируема. Только что опробовал на fpga. Естественно, сама прошивка из файла не читает, это инструкция для синтезатора. (а не только для симулятора). Тоже самое работает и для ram. Собственно, rom внутри fpga это как раз ram только запись не используется.
Comments: Add Your Own.

Saturday, June 25th, 2016

Subject:rtl coding style
Time:9:28 pm.
Люди в отрасли подкинули интересную ссылку:

https://www.doulos.com/knowhow/vhdl_designers_guide/rtl_coding/

Правда, к идее описывать "что", а не "как", пришел задолго до этого. Приятно, было увидеть в статье именно мультиплексор в качестве примера. У меня же таким примером был демультиплексор. :)
Comments: Add Your Own.

Sunday, June 19th, 2016

Subject:простейший двоичный калькурятор на светодиодах
Time:8:10 pm.
Сделать из платы DE0-Nano калькулятор надо еще постараться. Из штатных средств там только 4 dip переключателя, две push кнопки. И восемь светодиодов.
Конечно, есть еще всякие ножки к которым можно подключить что угодно, вплоть до клавиатуры и vga, но тут без паяльника не обойтись.


Процессора тоже нет. Ибо это голый fpga. Что хочешь то и лепи из него. Хоть Risc процессор. Но не будем спешить с risk процессором, оставим это занятие на закуску и попробуем сделать все с нуля:

Read more...Collapse )


Вот и все. Не так сложно, правда? И мы подобрались на один шаг ближе к созданию своего универсального процессора. :)
Comments: Add Your Own.

Monday, June 13th, 2016

Subject:прямое управление счетчиком на fpga с помощью кнопок
Time:9:31 am.
В руководстве к DE0-Nano сказано, что кнопки (их там две) избавлены от дребезга (через специальную микросхему) и поэтому могут быть использованы в качестве источника тактов.
Например, можно сделать инкрементирование счетчика при нажатии на одну из кнопок и сброс по другой:
(кнопки инвертированны, когда отжаты, дают лог. единицу)

reg [2:0] counter;

always @(negedge KEY[0] or negedge KEY[1])
   if (~KEY[0])
     counter <= 1'b0;
   else
     counter <= counter + 1'b1;

Этот пример работает  только потому что только одна из кнопок служит источником тактов, а другая лишь сбрасывает (ассинхронно) состояние.
Но если мы захотим по второй кнопке делать декремент, вещи становятся намного сложнее. Потому что теперь вход
будет зависеть от того какую кнопку мы нажали, и если кнопки будут еще и служить часами то стабильный сигнал на вход будет приходить слишком поздно по отношению к фронту тактирующего сигнала.
Я так и не нашел способа, не используя третий источник тактов, как реализовать это. Хотя на verilog все смотрится логично, на реальном железе это работать не будет. Потому что там для триггеров есть такое понятие как setup и hold время. Не соблюдая которое схема работать не будет.

Пришлось вернуться к использованию CLOCK_50 (так называется вход куда подается сигнал тактирующего генератора на 50Mh)
При этом фронт сигналов от кнопок отлавлиется уже по другому:

reg key_pressed;
reg key_pressed_prev;
wire key_clicked;

assign key_clicked = key_pressed &  ~key_pressed_prev;

always @(posedge CLOCK_50) begin
  key_pressed <= ~key;
  key_pressed_prev <= key_pressed;
end

Здесь используются два триггера соединенных последовательно. Это позволяет иметь два состояния кнопки разделенных во времени в один такт.

Проделывая это для двух кнопок мы будем иметь два сигнала: key_0_clicked и key_1_clicked, которые можно использовать
для управления счетчиков:

reg [2:0] counter;

always @(posedge CLOCK_50)
  if (key_0_clicked)
     counter <= counter - 1'b1;
  else if (key_1_clicked)
    counter <= counter + 1'b1;

Вот и все. Правда, по прежнему остается риск словить метастабильное состояние в триггерах читающих состояние кнопки.
Мне кажется, в худшем случае такое нажатие будет просто проигнорированно. Что в о общем-то не страшно. Поскольку и без этого бывает нажимаешь не в удачном месте и кнопка не срабатывает.
Comments: Add Your Own.

Saturday, June 11th, 2016

Subject:мой первый цифровой дизайн для пощупать :))
Time:8:39 pm.
доупрощал свой первый живой пример для DE0-Nano fpga платы до следующего состояния:

module light (SW, LED);
 input [3:0] SW;
 output [7:0] LED;
   
 assign LED = SW[0] << SW[3:1];
endmodule

И что характерно работает. Три переключателя говорят где светить. Четвертый говорит а светить ли вообще.
Время реакции порядка 6нс. Самый быстрый интерактивный дизайн. :))
Comments: Add Your Own.

Subject:компактность и читаемость в verilog
Time:1:28 pm.
Не будет сюрпризом узнать что для повышения читаемости кода приходится жертвовать компактностью. Но оно того стоит.

Следующие в конце два фрагмента на verilog описывают одно и тоже - демультиплексор. Но второй вариант ближе к описанию того, что мы хотим собственно.
(правда, изменив немного интерфейс, второй вариант можно сократить на две строки)

Как я понимаю, компилятор второй вариант превращает в первый. Оба варианта, на fpga от аltera (Cyclon IV), занимают ровно восемь логических элемента LE (которые содержат внутри LUT (lookup table) на три четыре входа)

// вариант 1
...
 assign f1 = x1 & ~x2 & ~x3 & ~x4;
 assign f2 = x1 & x2 & ~x3 & ~x4;
 assign f3 = x1 & ~x2 & x3 & ~x4;
 assign f4 = x1 & x2 & x3 & ~x4;
 assign f5 = x1 & ~x2 & ~x3 & x4;
 assign f6 = x1 & x2 & ~x3 & x4;
 assign f7 = x1 & ~x2 & x3 & x4;
 assign f8 = x1 & x2 & x3 & x4;
...
// вариант 2

 assign sel = {x4,x3,x2};
 always @*
    case (sel)
       3'b000: out = { 7'b0, x1 };
       3'b001: out = { 6'b0, x1, 1'b0 };
       3'b010: out = { 5'b0, x1, 2'b0 };
       3'b011: out = { 4'b0, x1, 3'b0 };
       3'b100: out = { 3'b0, x1, 4'b0 };
       3'b101: out = { 2'b0, x1, 5'b0 };
       3'b110: out = { 1'b0, x1, 6'b0 };
       3'b111: out = { x1, 7'b0 };
       default: out = 8'bx;
     endcase
   
 assign {f8, f7, f6, f5, f4, f3, f2, f1} = out;
Comments: Read 5 orAdd Your Own.

Monday, May 9th, 2016

Subject:старый добрый 8080 (он же 580вм) и как работает mov
Time:9:23 am.
Открыл для себя оригинальное руководство интел по процессору 8080. До этого сталкивался только с отечественной литературой по аналогу (580). Очень толково расписано. Вплоть до того, что и на каком такте происходит.
Вот например, мне непонятно было почему простая операция mov (01 ddd sss) занимает столько тактов.

И вот объяснение:
1 такт: извлекаем инструкцию из памяти
2 такт: инкрементируем pc
3 такт: копируем инструкцию во временный регистр (TMP/IR)
4 такт: копируем регистр sss во временный регистра TMP
5 такт: копируем из временного регистра TMP в ddd

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

И почему нельзя инкрементировать pc и извлекать из регистра в одном такте? Общая внутренняя шина?
Comments: Add Your Own.

Friday, May 6th, 2016

Subject:первый fpga для ознакомления
Time:11:24 pm.
Прям не знаю что и выбрать. Хочется уже поиграться с цифровым дизайном в железе. Нашел два варианта для начала. Может попробовать Панчула в штатах выцепить (планирую посетить долину на недельку в конце месяца). Вдруг посоветует что-нибудь.

https://raspberry.com.ua/p/de0-nano-altera-cyclone-iv-fpga…/
https://raspberry.com.ua/p/mojo-fpga-development-board/
Comments: Add Your Own.

Tuesday, December 22nd, 2015

Subject:грабли при программировании в chromium
Time:6:14 pm.
Дважды натыкаюсь на одни и те же грабли. В результате, выработал правило:
никогда не вызывай инлайн метод за пределами либы (.a), к которую входит класс.
Наверняка собираются они с разными флагами. И не факт что поле находится по тому же адресу.
Хуже всего, что, кажется, этому правилу код chromium сам не следует. Помнится получил креш, когда WebContents пытался обратиться к кешу дергая inline метод из net либы. Метод тупо возвращал ноль, хотя поле было не нулевым. Перенес в .сс и все стало нормально.
Comments: Add Your Own.

Sunday, December 20th, 2015

Subject:изучая Lenses в haskell
Time:11:15 am.
Если использовать Lenses в сочетании со state monad (не путать с costate comonad),
то код выглядит как типичная императивная программа с мутабельными полями. Правда, работает оно менее эффективно.

https://github.com/ekmett/lens/blob/master/examples/Pong.hs

каждая модификации одного поля приводит к создании новой полной копии. А если надо обновить все поля, то копий будет в n раз больше.

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

Шутки, шутками, но Lense действительно позволяет элегантно и легко получать модифицированные копии древовидных структур.
Comments: Read 3 orAdd Your Own.

Wednesday, September 17th, 2014

Subject:java: комбинаторы вместо лямбды
Time:9:55 am.
Все джависты наверное знают, что в 8-ой джаве появились лямбды. Дело конечно хорошее, но вот лично мне так и не довелось их использовать в java. Во первых, потому что включен режим совместимости с 1.6, во вторых я нашел в проекте лучший способ. Я использую комбинаторы для построения геттеров (из более простых геттеров).
Что это дало в отличии от лямбды.
1) не порождается новый класс на каждый чих.
2) построенные с помощью комбинаторов геттеры умеют рапортовать, что они делают и в каком месте что-то пошло не так.
Как следствие, геттеры + комбинаторы просто идеальны для построения валидаторов респонсов, когда требуется не только провалидировать, но и еще сгенерировать репорт.

пример:

один из наших валидаторов в рапорте представляет себя вот так:

 metaInfo . entries . (first with key == "bla-bla-bla") . notEmpty( val )

а вот так конструируется этот геттер:

public static final IGetter<Response, Boolean> notEmptyBlaBlaValue = dot(metaInfo, entries, firstWith( eq(key, "bla-bla-bla")), notEmpty(val));

Я немного подсластил выражение, используя статический импорт для entries, dot, firstWith, eq, key, notEmpty. На самом деле, у себя для геттеров полей я не использую статический импорт, чтобы небыло путаницы скажем между BarGetters.notEmpty и FooGetters.notEmpty. Но для иллюстрации сходства с рапортом я все же отойду от этого правила.

Как видим, даже без лямбды можно строить всякие предикаты, и что характерно, вложенные глубоко в контекст - тоже.
Comments: Add Your Own.

Monday, September 15th, 2014

Subject:комонады vs монады.
Time:1:58 pm.
Cегодня мне вдруг подумалось, что комонадный или даже стрелочный вычислитель выражений должен быть эффективнее монадного.

Потому что команадному интерпретатору не нужно pure значение, полученное на предыдущем шаге лифтить обратно в монаду. Вся комонада может быть построена еще до начала выполнения (за редким исключеним).
Comments: Add Your Own.

Subject:y combinator на java
Time:1:06 am.
Удивительно, но при реализации оператора рекурсивности 'y' на java мне не пришлось использовать рекурсивный вызов y как в классическом определении (y f = f (y f)).

А получилось у меня вот что:

public static <A, B> IGetter<A, B> y(
final IGetter<IGetter<A, B>, IGetter<A, B>> f)
{
return new IGetter<A, B>() {
private final IGetter<A, B> fixpoint = f.get(this);
@Override
public B get(A x) {
  return fixpoint.get(x);
}
};
}
Comments: Add Your Own.

LiveJournal for Vadim Radionov.

View:User Info.
View:Friends.
View:Calendar.
View:Memories.
You're looking at the latest 20 entries. Missed some entries? Then simply jump back 20 entries.