Если вы не пытаетесь упростить логику до минимальной формы (что, честно говоря, является напрасной тратой усилий, поскольку инструменты синтеза очень хорошо справляются с этим сами по себе, по крайней мере, когда дело доходит до объединения терминов для получения меньшей, функционально эквивалентной логики), вы можете сломать эта проблема ниже. Обычно вы должны думать таким образом при написании поведенческого Verilog, так как это повышает вероятность того, что ваш проект будет синтезирован в работоспособный, надежный список соединений.
У вас есть схема, так что начните с основных частей проекта и реализации модулей для выполнения этих функций. Например, у вас в проекте есть несколько мультиплексоров 2x1. Итак, мы должны реализовать логику, которая выбирает из правильного ввода. Итак, что такое мультиплексор? Ну, это базовая комбинационная функция, которая выглядит так:
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
. Мы можем сделать это, но сгенерировав большую часть нашего модуля мультиплексирования, или проделав это с логикой внутри модуля следующим образом:
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). На самом деле это не был формальный способ сделать это, но это помогает просто все обдумать. Также обратите внимание, что в Интернете есть множество архитектур сумматоров, если у вас возникли проблемы с пониманием логики.
person
Unn
schedule
10.10.2015