Структурный Verilog 8-Function ALU
Я знаю, как кодировать ALU, используя поведенческий стиль, но я полностью потерян, как сделать это, используя структурное проектирование. Мне нужен структурный ALU с 8-битным фрагментом, чтобы я мог изменить размер слова с помощью параметра, который передается, и он все еще работает. Я нашел схему для ALU с 2 функциями, но кто-нибудь скажет мне, как я могу перевести его в 8-функцию или, возможно, свяжу меня с примером Verilog для него? Вот схема ALU с двумя функциями:
Я не могу вспомнить достаточно отдаленно о таблицах истинности, k-картах и т. Д., Чтобы даже попытаться выяснить логику для этого самостоятельно. Не уверен, с чего начать. Любая помощь с благодарностью, спасибо!
1 ответ
Если вы не пытаетесь упростить логику до минимальной формы (что, честно говоря, является пустой тратой усилий, поскольку инструменты синтеза очень хорошо справляются с этим сами, по крайней мере, когда дело доходит до объединения терминов, чтобы получить меньшую функциональную эквивалентную логику), вы можете нарушить эта проблема в дальнейшем. Обычно вы должны так думать при написании поведенческого Verilog, так как это повышает вероятность того, что ваш проект будет синтезирован в работоспособный, твердый список соединений.
У вас есть схема, поэтому начните с того, что возьмите основные части проекта и внедрите модули для выполнения этих функций. Например, у вас есть несколько 2х1 муксов в дизайне. Итак, мы должны реализовать логику, которая выбирает из правильного ввода. Теперь, что такое мукс? Ну, это базовая комбинационная функция, которая выглядит так:
S A B O
----------
0 0 x 0
0 1 x 1
1 x 0 0
1 x 1 1
Т.е. если S
это 0, O = A
, если S
это 1, O = B
, Итак, мы можем переформатировать их в логические выражения: O = ~S & A | S & B
(Обратите внимание, если S = 0
мы пройдем A
и B
срок будет 0'вне, и наоборот, если S
это 1).
Теперь просто реализуем это в примитивах ворот Verilog:
module mux2x1(input A,
input B,
input S,
output O);
wire AO, BO, NOT_S;
not n1(NOT_S, S); // NOT_S = ~S;
and a1(AO, A, NOT_S), // AO = A & ~S;
a2(BO, B, S); // BO = B & S;
or o1(O, BO, AO); // O = (A & ~S) | (B & S);
endmodule
Теперь, чтобы увеличить ширину A
, B
а также O
нам нужно только сделать кучу этих муксов для каждого бита A
, B
а также O
, Мы можем сделать это, но сгенерировав большую часть нашего модуля mux, или сделав это с логикой внутри модуля, вот так:
module mux2x1 #(parameter W = 1)
(input [W-1:0] A,
input [W-1:0] B,
input S,
output [W-1:0] O);
wire [W-1:0] AO, BO;
wire NOT_S;
genvar i;
not n1(NOT_S, S); // NOT_S = ~S;
generate begin
for (i = 0; i < W; i = i + 1) begin : mux_w
and a1(AO[i], A[i], NOT_S), // AO[i] = A[i] & ~S;
a2(BO[i], B[i], S); // BO[i] = B[i] & S;
or o1(O[i], BO[i], AO[i]); // O[i] = (A[i] & ~S) | (B[i] & S);
end
end
endmodule
Теперь, когда вы видите проработанный пример, я надеюсь, что вы сможете работать с другими модулями таким же образом (например, с сумматором и мультиплексором 4x1). Это действительно не был формальный способ сделать это, но это помогает просто продумать вещи. Также обратите внимание, что в сети есть множество архитектур сумматоров, если у вас возникли проблемы с выяснением логики.