Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Реализация алгоритма на логически элементах
Форум разработчиков электроники ELECTRONIX.ru > Аналоговая и цифровая техника, прикладная электроника > Цифровые схемы, высокоскоростные ЦС
arhiv6
Потребовалось реализовать следующую схему:
Входов 9 штук: clk + a1,a2,a3,a4,b1,b2,b3,b4. Выходов 5 штук c1,c2,c3,c4,c5. Всегда только один из выходов находится в лог 1 (после подачи питания по умолчанию это выход с1). По фронту на входе clk состояние на выходе меняется по следующему алгоритму (перечислены все возможные состояния на входах):
- на на всех входах лог 0 - состояние на выходе не меняется.
- a1 в лог 1 - на выходе произойдёт сдвиг на +1.
- a1,a2 в лог 1 - на выходе произойдёт сдвиг на +2.
- a1,a2,a3 в лог 1 - на выходе произойдёт сдвиг на +3.
- a1,a2,a3,a4 в лог 1 - на выходе произойдёт сдвиг на +4.
- b1 в лог 1 - на выходе произойдёт сдвиг на -1.
- b1,b2 в лог 1 - на выходе произойдёт сдвиг на -2.
- b1,b2,b3 в лог 1 - на выходе произойдёт сдвиг на -3.
- b1,b2,b3,b4 в лог 1 - на выходе произойдёт сдвиг на -4.
Сдвиг на +1 означает, что , например, если лог 1 было на выходе с3, то по фронту на clk на выходе с3 станет лог 0, а на выходе с4 - лог1. Сдвиг нужен без переноса - если, например, лог 1 было на выходе с5, любой сдвиг в + ничего на выходе не изменит.
Вопрос: на каких логически микросхемах (сдвиговые регистры, счётчики и т.п.) можно реализовать такую схему? (микроконтроллер не предлагать sm.gif )
saab
ПЛИС батенька ПЛИС.
arhiv6
Ради 12 ножек? + её программировать ещё надо, а для плис ни разу не писал прошивок. Хочется всё-таки на логике попытаться собрать.
TSerg
Цитата(arhiv6 @ Nov 15 2014, 00:30) *
Ради 12 ножек? + её программировать ещё надо, а для плис ни разу не писал прошивок. Хочется всё-таки на логике попытаться собрать.


Конечный автомат + карты Карно, для примера.
RobFPGA
Приветствую!

Хотите горячую TTL логику - пзу 2k x8 типа 573РФ5 и регистр 155ир35 sm.gif

Ну или штук 20-30 155ла3 и 3 штуки 155тм2 вообще полный oldstyle

Успехов! Rob.

P.S. на 155ЛА3 можно сделать все! даже логику core i7 8-()

ZASADA
cpld
lemorus
Цитата(arhiv6 @ Nov 15 2014, 00:30) *
Ради 12 ножек? + её программировать ещё надо, а для плис ни разу не писал прошивок. Хочется всё-таки на логике попытаться собрать.

Правильно написали CPLD, это маленькая ПЛИС, схему можно просто нарисовать, прямо как ЛЕГО набрать из логических элементов.
Потом нажимаете кнопку и схема прошивается в CPLD. Как в том анекдоте "а кто должен кнопку нажимать".
arhiv6
Похоже CPLD придётся использовать. На verilog алгоритм написал (оказывается, это не сложно). В симуляторе (iverilog+vvp) проверил - работает.
CODE
module mod_logic(
input wire clock,
input wire [3:0]in_a,
input wire [3:0]in_b,
output reg [3:0]out_c
);

integer i=0,shift=0,position=0;

initial
out_c = 4'b0001;

always @(posedge clock )
begin

shift=0;

// проверка
if((in_a != 4'b0000) & (in_b != 4'b0000))
out_c <= 4'b1000; // обработка ошибок
else
begin

// определяем позицию на выходе
for(i=0; i<4; i=i+1)
begin
if(out_c[i])
position=i+1;
end

// считаем сдвиг в +, если это возможно
if((in_a != 4'b0000) & (out_c != 4'b1000))
begin
for(i=0; i<4; i=i+1)
begin
if(in_a[i])
shift=shift+1;
end

// сдвигаем
if (shift > (4-position))
out_c <= 4'b1000;
else
out_c <= out_c << shift;
end

// считаем сдвиг в -, если это возможно
if((in_b != 4'b0000) & (out_c != 4'b0001))
begin
for(i=0; i<4; i=i+1)
begin
if(in_b[i])
shift=shift+1;
end

// сдвигаем
if (shift > (position-1))
out_c <= 4'b0001;
else
out_c <= out_c >> shift;
end
end

//$display("position %d",position);
//$display("shift %d",shift);

end
endmodule

Один только минус - для симулирования всей схемы (в основном аналоговые компоненты), в которой эта CPLD будет стоять, нужен какой-то mixed-mode симулятор (spice+HDL(Verilog)). Обычную логику многие spice симуляторы умеют моделировать, а вот которые умеют файлы verilog подключать - не видел.
iosifk
Цитата(arhiv6 @ Nov 15 2014, 20:59) *
Похоже CPLD придётся использовать. На verilog алгоритм написал (оказывается, это не сложно). В симуляторе (iverilog+vvp) проверил - работает.
CODE
module mod_logic(
input wire clock,
input wire [3:0]in_a,
input wire [3:0]in_b,
output reg [3:0]out_c
);

integer i=0,shift=0,position=0;

initial
out_c = 4'b0001;

always @(posedge clock )
begin

shift=0;

// проверка
if((in_a != 4'b0000) & (in_b != 4'b0000))
out_c <= 4'b1000; // обработка ошибок
else
begin

// определяем позицию на выходе
for(i=0; i<4; i=i+1)
begin
if(out_c[i])
position=i+1;
end

// считаем сдвиг в +, если это возможно
if((in_a != 4'b0000) & (out_c != 4'b1000))
begin
for(i=0; i<4; i=i+1)
begin
if(in_a[i])
shift=shift+1;
end

// сдвигаем
if (shift > (4-position))
out_c <= 4'b1000;
else
out_c <= out_c << shift;
end

// считаем сдвиг в -, если это возможно
if((in_b != 4'b0000) & (out_c != 4'b0001))
begin
for(i=0; i<4; i=i+1)
begin
if(in_b[i])
shift=shift+1;
end

// сдвигаем
if (shift > (position-1))
out_c <= 4'b0001;
else
out_c <= out_c >> shift;
end
end

//$display("position %d",position);
//$display("shift %d",shift);

end
endmodule

Один только минус - для симулирования всей схемы (в основном аналоговые компоненты), в которой эта CPLD будет стоять, нужен какой-то mixed-mode симулятор (spice+HDL(Verilog)). Обычную логику многие spice симуляторы умеют моделировать, а вот которые умеют файлы verilog подключать - не видел.

Вот:
shift=0;
....
out_c <= 4'b1000; // обработка ошибок

блокирующие и неблокирующие под одним клоком не делают...
И все вот такие
for(i=0; i<4; i=i+1)
begin
if(in_b[i])
shift=shift+1;
end
это что?
Это же не Си, это должно работать в железе. А там, в железе никто не знает, что такое "i"...
вам надо прочесть о синтезируемых и несинтезируемых конструкциях...
Siluan
Цитата(lemorus @ Nov 15 2014, 12:14) *
Правильно написали CPLD, это маленькая ПЛИС, схему можно просто нарисовать, прямо как ЛЕГО набрать из логических элементов.
Потом нажимаете кнопку и схема прошивается в CPLD. Как в том анекдоте "а кто должен кнопку нажимать".


Очень интересно. Применительно к конечным автоматам, какой продукт можете порекомендовать? Возможна ли реализация параллельной работы участков схемы, как в жесткой логике. Есть ли время инициализации, или работает сразу после включения? Есть ли продукты с числом элементов типа и-не, Д-триггеров общим числом не более 200. И самое главное, есть ли среда программирования без написания текста программ, а типа как в Микрокапе собирается схема из готовых деталей. Можно дать ответ в личную почту.
ZASADA
у каждого производителя есть небольшие отличия. возьмем например древний xilinx 9500...
время включения 200мксек с момента подачи питания.
питание 3,3в, совместимость входов с 5в, 3,3в и 2,5в
частота работы логики до 200 МГц.
от 34 до 192 пользовательских ножек
от 36 до 288 макроячеек.
каждая макроячейка это многовходовая логика (любая) плюс триггер. логикой можно объединить до 90+ сигналов.
и да, можно не изучать никакие языки и тупо нарисовать все в знакомой 74 логике. но это контрпродуктивно.
kovigor
Цитата(Siluan @ Nov 18 2014, 20:04) *
Применительно к конечным автоматам, какой продукт можете порекомендовать?

EPM3064 и компанию, MaxPlus и вот эти статьи:

http://www.epos.ua/view.php/about_pubs_arc...amp;ucat=3&
http://www.epos.ua/view.php/about_pubs_arc...amp;ucat=3&
SM
Цитата(kovigor @ Nov 19 2014, 14:32) *
EPM3064 и компанию, MaxPlus и вот эти статьи:


С ПЛИС согласен, а вот MaxPlus однозначно рекомендовать не стоит, он устарел и морально, и физически, еще лет 10 назад. В том числе, толком не поддерживает verilog, на котором ТС работает.

Для TC:
Я бы рекомендовал, параллельно с этой серией, еще Lattice http://www.latticesemi.com/en/Products/FPG...MACH4000ZE.aspx
Серия аналогична, но имеет пару малозаметных плюсиков - околонулевое потребление в статике, на пару пинов больше для I/O, и среда разработки куда менее монстроидальная, и цена чуток поменьше.

Вдогонку - несложная mixed-signal симуляция имеется вот у них - http://www.tina.com/
SM
Цитата(iosifk @ Nov 15 2014, 22:15) *
блокирующие и неблокирующие под одним клоком не делают...

Это да, безоговорочно.

Цитата(iosifk @ Nov 15 2014, 22:15) *
И все вот такие
for(i=0; i<4; i=i+1)
begin
if(in_b[i])
shift=shift+1;
end


А вот это полностью синтезируемо, и нормально. Для информации (для ТС, разумеется) - это синтезируется в 5 последовательно соединенных условных инкременторов (сумматоров, выполняющих функцию A+1/A+0 по условию). Также как и сдвиг "x >> shift" отлично синтезируется в баррелевский сдвигатель.
iosifk
Цитата(SM @ Nov 24 2014, 14:38) *
А вот это полностью синтезируемо, и нормально. Для информации (для ТС, разумеется) - это синтезируется в 5 последовательно соединенных условных инкременторов (сумматоров, выполняющих функцию A+1/A+0 по условию). Также как и сдвиг "x >> shift" отлично синтезируется в баррелевский сдвигатель.

Это значит, что я не правильно выразил идею... Обычно когда пишется "действие" на Си, то берется слово, накладывается маска, сдвигается и т.д. При этом сдвигается столько раз, сколько указано в команде.
А когда делается описание на Верилоге, то все циклы действительно разворачиваются в соответствующее "количество железа". И если в одной команде на Си надо сдвинуть 3 раза, а в другой - 5 раз, то процессор так и сделает. А Верилог сделает совершенно две разные цепи, первая из них будет состоять из 3-х "сдвигателей", а вторая - из 5-ти.
Вот что я хотел сказать...
SM
Цитата(Siluan @ Nov 18 2014, 19:04) *
Возможна ли реализация параллельной работы участков схемы, как в жесткой логике.

А внутри нее и есть жесткая логика, соединения между которой Вы описываете на том же Verilog-е. Все выражения языка, как то "A+B", например, или "if / else", транслируются синтезатором в различные схемотехнические элементы, в данном случае, сумматор и мультиплексор.

Как раз, Ваш цикл, очень хороший пример.

for(i=0; i<4; i=i+1)
begin
if(in_b[i])
shift=shift+1;
end

это Вы описали последовательно соединенные инкременторы и мультиплексоры, то есть, по сути, такую схему:

// MUX( sel,A,B ) - мультиплексор, выполняющий ф-цию sel ? B:A
sum_0 = MUX(in_b[0], 0, 1)
sum_1 = MUX(in_b[1], sum_0, sum_0+1)
sum_2 = MUX(in_b[2], sum_1, sum_1+1)
sum_3 = MUX(in_b[3], sum_2, sum_2+1)
shift = MUX(in_b[4], sum_3, sum_3+1)


А можете сделать то-же, но параллельно:

wire [1:0] shift_0, shift_1;
wire [2:0] shift;
// сумматор #1 ( A+B+CARRY )
assign shift_0 = in_b[0] + in_b[1] + in_b[2];
// полусумматор #2 ( A+B )
assign shift_1 = in_b[3] + in_b[4];
// сумматор результата
assign shift = shift_0 + shift_1;

Да и в Вашей схеме ( которую Вы описали там - http://electronix.ru/forum/index.php?showt...p;#entry1291840 ), к примеру, position и shift вычисляются совершенно параллельно, несмотря на то, что описаны одно после другого - так как вычисление каждого из них не зависит от результата другого - то и синтезируются они в две параллельно работающие подсхемы. Хорошо запомните - Verilog - это описание схемы на языке, внешне похожим на язык программирования. Но не программирование - так как нет исполнительного устройства, на котором эта программа исполняется. Синтезатор синтезирует схему по Вашему описанию, которая работает так, как Вы описали.

Кстати. Если синтезатору дать в качестве библиотеки (в ней описывается функциональность элементов самого низкого уровня, которые реализуемы в технологии) список микросхем, например, серии 74HCxxxx, вместо списка вариантов внутренностей FPGA, то синтезатор построит схему прямо на них по Вашему описанию.

вот как-то так выглядит результат работы синтезатора:
CODE

.......
(instance AND2_t10 (viewRef PRIM (cellRef AND2 (libraryRef LUCENT)))
)
(instance INV_1 (viewRef PRIM (cellRef INV (libraryRef LUCENT)))
)
(instance AND2_t9 (viewRef PRIM (cellRef AND2 (libraryRef LUCENT)))
)
(instance INV_0 (viewRef PRIM (cellRef INV (libraryRef LUCENT)))
)
(instance OR2_t8 (viewRef PRIM (cellRef OR2 (libraryRef LUCENT)))
)
(instance XOR2_t7 (viewRef PRIM (cellRef XOR2 (libraryRef LUCENT)))
)
(instance XOR2_t6 (viewRef PRIM (cellRef XOR2 (libraryRef LUCENT)))
......
(net fifo_wr_en (joined
(portRef fifo_wr_en)
(portRef A (instanceRef AND2_t10))
))
(net invout_1 (joined
(portRef Z (instanceRef INV_1))
(portRef B (instanceRef AND2_t10))
))
(net wren_i (joined
(portRef Z (instanceRef AND2_t10))
(portRef B1 (instanceRef full_cmp_ci_a))
(portRef A1 (instanceRef full_cmp_ci_a))
(portRef SP (instanceRef FF_101))
(portRef SP (instanceRef FF_102))
(portRef SP (instanceRef FF_103))
(portRef SP (instanceRef FF_104))
(portRef SP (instanceRef FF_105))
(portRef SP (instanceRef FF_106))
(portRef SP (instanceRef FF_107))
(portRef SP (instanceRef FF_108))
(portRef SP (instanceRef FF_109))
(portRef SP (instanceRef FF_110))
(portRef SP (instanceRef FF_111))
(portRef SP (instanceRef FF_112))
(portRef SP (instanceRef FF_113))
(portRef SP (instanceRef FF_114))
(portRef SP (instanceRef FF_115))
(portRef AD2 (instanceRef LUT4_12))
))
(net fifo_full (joined
(portRef Q (instanceRef FF_0))
(portRef A (instanceRef INV_1))
(portRef fifo_full)
))



то есть, мы видим набор логических элементов, и описание цепей, какие выводы этих элементов соединяются с какими - то есть, схему, описанную текстом - нетлист.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.