Асинхронный регистр
2016-07-12 21:19Регистр в подходе NCL logic выглядит так:

Попробуем изобразить его на Верилоге. Трудность в том, что Верилог не даёт простого способа обозначить Dual Rail encoding, то есть сигналы, представленные в виде пары проводов. Один из вариантов - задействовать состояние X, приписав ему другую семантику. Будем считать, что X - это когда оба провода логического сигнала принимают значения Low (то есть NULL). В этом случае асинхронный регистр может выглядеть так:

Попробуем изобразить его на Верилоге. Трудность в том, что Верилог не даёт простого способа обозначить Dual Rail encoding, то есть сигналы, представленные в виде пары проводов. Один из вариантов - задействовать состояние X, приписав ему другую семантику. Будем считать, что X - это когда оба провода логического сигнала принимают значения Low (то есть NULL). В этом случае асинхронный регистр может выглядеть так:
module areg #(
parameter WIDTH = 2 // ширина регистра
)(
input wire reset, // сброс
input wire [WIDTH-1:0] d, // данные на входе
input wire ki, // вход подтверждения
output reg [WIDTH-1:0] q, // данные на выходе
output wire ko // выход подтверждения
);
always @(*) begin
if (reset)
q <= {WIDTH{1'bx}}; // при сбросе выдаём NULL
else if (ki)
q <= d; // защёлкиваем вход (возможно, содержащий NULL-и)
else for (i=0; i<WIDTH; i=i+1)
if (d[i] === 1'bx)
q[i] <= 1'bx; // сбрасываем выход в NULL
assign ko = (^q === 1'bx); // выдаём подтверждение, пока выход не полностью определён
endmodule
Не знаю пока, вылезут ли грабли при симуляции из-за нештатного использования состояния X, или прокатит.
no subject
Date: 2016-07-13 16:17 (UTC)Кстати, reduction XOR никогда не бывает равен Z, для вектора длиннее 1 уж точно.
no subject
Date: 2016-07-13 18:43 (UTC)Действительно, с reduction XOR я промахнулся: у него на выходе всегда X вместо Z. Вообще, похоже, моя идея проходит, если задействовать не Z а X для обозначения состояния NULL. Правда, тогда теряется полезная функция состояния X как неопределённого при старте.
no subject
Date: 2016-07-13 18:51 (UTC)Oops. Sorry, профессиональная деформация. :)
тогда теряется полезная функция состояния X как неопределённого при старте
Ну так всегда можно написать initial foo = 1'bz;
no subject
Date: 2016-07-13 18:49 (UTC)module areg #( parameter WIDTH = 2 // ширина регистра )( input wire reset, // сброс input wire [WIDTH-1:0] d, // данные на входе input wire ki, // вход подтверждения output reg [WIDTH-1:0] q, // данные на выходе output wire ko // выход подтверждения ); always @(*) if (ki & !reset) q <= d; // защёлкиваем вход (возможно, содержащий NULL-и) else q <= {WIDTH{1'bx}}; // при сбросе выдаём NULL assign ko = (^q === 1'bx); // выдаём подтверждение, пока выход не полностью определён endmoduleno subject
Date: 2016-07-13 19:45 (UTC)no subject
Date: 2016-07-13 20:10 (UTC)no subject
Date: 2016-07-14 00:18 (UTC)always @(*) for (i=0; i<WIDTH; i=i+1) if (reset) q[i] <= 1'bx; // при сбросе выдаём NULL else if (ki && d[i] !== 1'bx) q[i] <= d[i]; // продвигаем значения 0/1 else if (!ki && d[i] === 1'bx) q[i] <= 1'bx; // продвигаем NULLs assign ko = (^q === 1'bx); // выдаём подтверждение, пока на выходе имеются NULLs