Результат сравнения различных методов построения модулярных умножителей (индексный метод, разность квадратов, метод Espresso) — различия между версиями
DimaT (обсуждение | вклад) |
DimaT (обсуждение | вклад) |
||
| Строка 8: | Строка 8: | ||
== Типовые Verilog-модули == | == Типовые Verilog-модули == | ||
| − | 1. | + | |
| + | 1. Индексный модулярный умножитель (на примере модуля 7) | ||
<pre> | <pre> | ||
| − | // | + | module multiplication_mod_7(inp1, inp2, out); |
| − | module | + | input [2:0] inp1; |
| − | input [3:0] | + | input [2:0] inp2; |
| − | input [3:0] | + | output reg [2:0] out; |
| − | output reg[3:0] | + | wire [2:0] out_pre; |
| + | wire [1:0] w_1_0; | ||
| + | wire [1:0] w_2_0; | ||
| + | wire [1:0] wout_0; | ||
| + | wire [1:0] w_1_1; | ||
| + | wire [1:0] w_2_1; | ||
| + | wire [1:0] wout_1; | ||
| + | lut_input_7 lut1(inp1, w_1_0, w_1_1); | ||
| + | lut_input_7 lut2(inp2, w_2_0, w_2_1); | ||
| + | sum_modulo_2 sm0(w_1_0, w_2_0, wout_0); | ||
| + | sum_modulo_3 sm1(w_1_1, w_2_1, wout_1); | ||
| + | lut_output_7 lut3(wout_0, wout_1, out_pre); | ||
| + | always @ (*) | ||
| + | begin | ||
| + | if (inp1 == 0 || inp2 == 0) | ||
| + | begin | ||
| + | out = 0; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | out = out_pre; | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module sum_modulo_2(inp1, inp2, out); | ||
| + | input [1:0] inp1; | ||
| + | input [1:0] inp2; | ||
| + | output reg [1:0] out; | ||
| + | wire [2:0] int; | ||
| + | assign int = inp1 + inp2; | ||
| + | always @ (*) | ||
| + | begin | ||
| + | if (int < 2) | ||
| + | begin | ||
| + | out = int; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | out = int - 2; | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module sum_modulo_3(inp1, inp2, out); | ||
| + | input [1:0] inp1; | ||
| + | input [1:0] inp2; | ||
| + | output reg [1:0] out; | ||
| + | wire [2:0] int; | ||
| + | assign int = inp1 + inp2; | ||
| + | always @ (*) | ||
| + | begin | ||
| + | if (int < 3) | ||
| + | begin | ||
| + | out = int; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | out = int - 3; | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module lut_output_7(inp0, inp1, out); | ||
| + | output reg [2:0] out; | ||
| + | input [1:0] inp0; | ||
| + | input [1:0] inp1; | ||
| + | always @ (*) | ||
| + | begin | ||
| + | if (inp0 == 0 && inp1 == 0) | ||
| + | begin | ||
| + | out <= 1; | ||
| + | end | ||
| + | else if (inp0 == 0 && inp1 == 2) | ||
| + | begin | ||
| + | out <= 2; | ||
| + | end | ||
| + | else if (inp0 == 1 && inp1 == 1) | ||
| + | begin | ||
| + | out <= 3; | ||
| + | end | ||
| + | else if (inp0 == 0 && inp1 == 1) | ||
| + | begin | ||
| + | out <= 4; | ||
| + | end | ||
| + | else if (inp0 == 1 && inp1 == 2) | ||
| + | begin | ||
| + | out <= 5; | ||
| + | end | ||
| + | else if (inp0 == 1 && inp1 == 0) | ||
| + | begin | ||
| + | out <= 6; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | out <= 0; | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module lut_input_7(inp, out0, out1); | ||
| + | input [2:0] inp; | ||
| + | output reg [1:0] out0; | ||
| + | output reg [1:0] out1; | ||
| + | always @ (inp) | ||
| + | begin | ||
| + | case(inp) | ||
| + | 1: | ||
| + | begin | ||
| + | out0 <= 0; | ||
| + | out1 <= 0; | ||
| + | end | ||
| + | 2: | ||
| + | begin | ||
| + | out0 <= 0; | ||
| + | out1 <= 2; | ||
| + | end | ||
| + | 3: | ||
| + | begin | ||
| + | out0 <= 1; | ||
| + | out1 <= 1; | ||
| + | end | ||
| + | 4: | ||
| + | begin | ||
| + | out0 <= 0; | ||
| + | out1 <= 1; | ||
| + | end | ||
| + | 5: | ||
| + | begin | ||
| + | out0 <= 1; | ||
| + | out1 <= 2; | ||
| + | end | ||
| + | 6: | ||
| + | begin | ||
| + | out0 <= 1; | ||
| + | out1 <= 0; | ||
| + | end | ||
| + | default: | ||
| + | begin | ||
| + | out0 <= 0; | ||
| + | out1 <= 0; | ||
| + | end | ||
| + | endcase | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module atop_testbench(); | ||
| + | reg [2:0] inp1; | ||
| + | reg [2:0] inp2; | ||
| + | wire [2:0] out; | ||
| + | |||
| + | integer i, j, l, m, k, t; | ||
| + | reg dummy; | ||
| + | integer fori, forj; | ||
| + | multiplication_mod_7 mul1(inp1, inp2, out); | ||
| + | initial | ||
| + | begin | ||
| + | k = 1; | ||
| + | for (fori = 0; fori < 7; fori = fori + 1) | ||
| + | begin | ||
| + | for (forj = 0; forj < 7; forj = forj + 1) | ||
| + | begin | ||
| + | inp1 = fori; | ||
| + | inp2 = forj; | ||
| + | #1 dummy = 1; | ||
| + | i = (fori*forj)%7; | ||
| + | $display ("!!! OP1 = (%d) OP2 = (%d) RES = (%d) EXPECT = (%d)", fori, forj, out, i); | ||
| + | l = out; | ||
| + | if (l != i) | ||
| + | begin | ||
| + | $display ("!!! Error (%d, %d)!!!", i, l); | ||
| + | end | ||
| + | #1 dummy = 1; | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | |||
| + | </pre> | ||
| + | |||
| + | 2. Модулярный умножитель на базе формулы разности квадратов (на примере модуля 7) | ||
| + | <pre> | ||
| + | module multiplication_mod_7(inp1, inp2, out); | ||
| + | input [2:0] inp1; | ||
| + | input [2:0] inp2; | ||
| + | output [2:0] out; | ||
| + | wire [3:0] plus; | ||
| + | wire [3:0] minus; | ||
| + | wire [2:0] plout; | ||
| + | wire [2:0] miout; | ||
| + | assign plus = inp1 + inp2; // [0; 12] | ||
| + | assign minus = 6 + inp1 - inp2; // [0; 12] | ||
| + | lut_sqr_sum ls1(plus, plout); | ||
| + | lut_sqr_sub ls2(minus, miout); | ||
| + | sub_mod_7 sub1(plout, miout, out); | ||
| + | endmodule | ||
| + | |||
| + | module lut_sqr_sum (in, out); | ||
| + | input [3:0] in; | ||
| + | output reg [2:0] out; | ||
| + | always @ (in) | ||
| + | begin | ||
| + | case (in) | ||
| + | 0: out = 0; | ||
| + | 1: out = 2; | ||
| + | 2: out = 1; | ||
| + | 3: out = 4; | ||
| + | 4: out = 4; | ||
| + | 5: out = 1; | ||
| + | 6: out = 2; | ||
| + | 7: out = 0; | ||
| + | 8: out = 2; | ||
| + | 9: out = 1; | ||
| + | 10: out = 4; | ||
| + | 11: out = 4; | ||
| + | 12: out = 1; | ||
| + | default: out = 0; | ||
| + | endcase | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module lut_sqr_sub (in, out); | ||
| + | input [3:0] in; | ||
| + | output reg [2:0] out; | ||
| + | always @ (in) | ||
| + | begin | ||
| + | case (in) | ||
| + | 0: out = 2; | ||
| + | 1: out = 1; | ||
| + | 2: out = 4; | ||
| + | 3: out = 4; | ||
| + | 4: out = 1; | ||
| + | 5: out = 2; | ||
| + | 6: out = 0; | ||
| + | 7: out = 2; | ||
| + | 8: out = 1; | ||
| + | 9: out = 4; | ||
| + | 10: out = 4; | ||
| + | 11: out = 1; | ||
| + | 12: out = 2; | ||
| + | default: out = 0; | ||
| + | endcase | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module sub_mod_7 (in1, in2, out); | ||
| + | input [2:0] in1, in2; | ||
| + | output [2:0] out; | ||
| + | wire [3:0] data; | ||
| + | |||
| + | assign data = 7 + in1 - in2; | ||
| + | mod_7_13 mdval(data, out); | ||
| + | endmodule | ||
| + | |||
| + | module mod_7_13 (in, out); | ||
| + | input [3:0] in; | ||
| + | output reg [2:0] out; | ||
| + | always @ (in) | ||
| + | begin | ||
| + | // we have small max value so we can use table here | ||
| + | case (in) | ||
| + | 0: out = 0; | ||
| + | 1: out = 1; | ||
| + | 2: out = 2; | ||
| + | 3: out = 3; | ||
| + | 4: out = 4; | ||
| + | 5: out = 5; | ||
| + | 6: out = 6; | ||
| + | 7: out = 0; | ||
| + | 8: out = 1; | ||
| + | 9: out = 2; | ||
| + | 10: out = 3; | ||
| + | 11: out = 4; | ||
| + | 12: out = 5; | ||
| + | 13: out = 6; | ||
| + | default: out = 0; | ||
| + | endcase | ||
| + | end | ||
| + | endmodule | ||
| + | |||
| + | module atop_testbench(); | ||
| + | reg [2:0] inp1; | ||
| + | reg [2:0] inp2; | ||
| + | wire [2:0] out; | ||
| + | |||
| + | integer i, j, l, m, k, t; | ||
| + | reg dummy; | ||
| + | integer fori, forj; | ||
| + | multiplication_mod_7 mul1(inp1, inp2, out); | ||
| + | initial | ||
| + | begin | ||
| + | k = 1; | ||
| + | for (fori = 0; fori < 7; fori = fori + 1) | ||
| + | begin | ||
| + | for (forj = 0; forj < 7; forj = forj + 1) | ||
| + | begin | ||
| + | inp1 = fori; | ||
| + | inp2 = forj; | ||
| + | #1 dummy = 1; | ||
| + | i = (fori*forj)%7; | ||
| + | $display ("!!! OP1 = (%d) OP2 = (%d) RES = (%d) EXPECT = (%d)", fori, forj, out, i); | ||
| + | l = out; | ||
| + | if (l != i) | ||
| + | begin | ||
| + | $display ("!!! Error (%d, %d)!!!", i, l); | ||
| + | end | ||
| + | #1 dummy = 1; | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | endmodule | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
</pre> | </pre> | ||
| − | 2. Модулярный сумматор по методу Espresso (на примере модуля | + | 2. Модулярный сумматор по методу Espresso (на примере модуля 10) |
<pre> | <pre> | ||
| − | module | + | module mul_mod10 (out, a, b); |
| − | input [ | + | input [3:0] a, b; |
| − | output [ | + | output [3:0] out; |
| − | assign out[ | + | assign out[3] = (~a[3]&~a[2]&~a[1]&a[0]&b[3]) | (~a[2]&a[1]&~a[0]&b[3]&b[0]) | (a[3]&~b[3]&~b[2]&~b[1]&b[0]) | (a[2]&a[1]&~a[0]&b[3]&~b[0]) | (a[3]&~a[0]&b[2]&b[1]&~b[0]) | (a[3]&a[0]&~b[2]&b[1]&~b[0]) | (a[2]&a[1]&a[0]&b[2]&b[1]&b[0]) | (a[2]&~a[1]&~a[0]&b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&~b[2]&b[1]&b[0]) | (a[2]&a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&b[2]&b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&~b[2]&b[1]&~b[0]) | (a[2]&a[1]&a[0]&b[2]&~b[1]&~b[0]) | (~a[2]&a[1]&~a[0]&b[2]&~b[1]&~b[0]); |
| − | + | assign out[2] = (~a[2]&a[1]&a[0]&b[3]) | (a[3]&~a[0]&~b[2]&b[1]) | (a[2]&~a[1]&a[0]&b[0]) | (a[3]&~a[0]&b[1]&b[0]) | (a[3]&~b[2]&b[1]&b[0]) | (a[0]&b[2]&~b[1]&b[0]) | (~a[2]&a[1]&b[3]&~b[0]) | (a[1]&a[0]&b[3]&~b[0]) | (a[3]&~a[0]&b[3]&~b[0]) | (a[2]&~a[0]&b[2]&~b[0]) | (~a[2]&a[1]&~a[0]&b[1]&b[0]) | (a[1]&a[0]&~b[2]&b[1]&~b[0]) | (~a[3]&~a[2]&~a[1]&a[0]&b[2]) | (a[2]&~a[0]&~b[2]&~b[1]&b[0]) | (a[2]&~b[3]&~b[2]&~b[1]&b[0]) | (~a[2]&~a[1]&a[0]&b[2]&~b[0]) | (~a[2]&a[1]&~b[2]&b[1]&~b[0]); | |
| − | (a[2]&~b[2]& | + | assign out[1] = (a[2]&a[1]&a[0]&b[3]) | (a[2]&~a[1]&~a[0]&b[3]) | (a[3]&~a[0]&b[3]&b[0]) | (a[3]&b[2]&b[1]&b[0]) | (a[3]&a[0]&b[3]&~b[0]) | (a[3]&b[2]&~b[1]&~b[0]) | (~a[3]&~a[2]&~a[1]&a[0]&b[1]) | (a[2]&a[1]&~a[0]&b[2]&b[1]) | (a[1]&~b[3]&~b[2]&~b[1]&b[0]) | (~a[2]&a[1]&~a[0]&b[3]&~b[0]) | (a[2]&a[1]&~a[0]&b[1]&~b[0]) | (a[2]&a[1]&b[2]&b[1]&~b[0]) | (a[1]&~a[0]&b[2]&b[1]&~b[0]) | (a[3]&~a[0]&~b[2]&b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&b[2]&~b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&b[2]&~b[1]&~b[0]) | (~a[2]&~a[1]&a[0]&b[1]&b[0]) | (a[1]&a[0]&~b[2]&~b[1]&b[0]) | (~a[2]&a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&~b[2]&b[1]&~b[0]); |
| − | assign out[ | + | assign out[0] = (a[0]&b[0]); |
| − | (a[2]&a[1]&b[ | + | |
| − | (a[1]&~b[2]&~b[1]&~b[0]) | (~a[2]&a[1]& | + | |
| − | assign out[ | + | |
| − | (~a[2]&~a[0]&~b[2]&b[0]) | (a[2]&a[0]&b[1]&b[0]) | (a[2]& | + | |
| − | (a[0]&~b[2]&~b[1]& | + | |
Версия 07:36, 27 мая 2013
Было проведено сравнение модулярных умножителей. Рассматриваемые методы:
- Метод минимизации логических функций на базе алгоритма Espresso
- Метод разности квадратов
- Индексная реализация умножителя
Метод Espresso заключается в построении таблицы истинности для операции модулярного умножения, и дальнейшей минимизации получившейся булевой функции методом Espresso. Сравнение проводилось для расширенного набора оснований в диапазоне 3-149. Индексный метод работает только для простых чисел, метод, основанный на разности квадратов допускает любые нечетные числа, а метод Espresso работает для любых целых чисел. Маршрут проектирования для схем Espresso включал минимизацию булевых функций с помощью программного средства Logic Friday. Для автоматизации запуска Logic Friday использовался язык автоматизации AutoIt. Для остальных двух схем использовался стандартный подход с реализацией автоматизироанных генераторов.
Содержание
Типовые Verilog-модули
1. Индексный модулярный умножитель (на примере модуля 7)
module multiplication_mod_7(inp1, inp2, out);
input [2:0] inp1;
input [2:0] inp2;
output reg [2:0] out;
wire [2:0] out_pre;
wire [1:0] w_1_0;
wire [1:0] w_2_0;
wire [1:0] wout_0;
wire [1:0] w_1_1;
wire [1:0] w_2_1;
wire [1:0] wout_1;
lut_input_7 lut1(inp1, w_1_0, w_1_1);
lut_input_7 lut2(inp2, w_2_0, w_2_1);
sum_modulo_2 sm0(w_1_0, w_2_0, wout_0);
sum_modulo_3 sm1(w_1_1, w_2_1, wout_1);
lut_output_7 lut3(wout_0, wout_1, out_pre);
always @ (*)
begin
if (inp1 == 0 || inp2 == 0)
begin
out = 0;
end
else
begin
out = out_pre;
end
end
endmodule
module sum_modulo_2(inp1, inp2, out);
input [1:0] inp1;
input [1:0] inp2;
output reg [1:0] out;
wire [2:0] int;
assign int = inp1 + inp2;
always @ (*)
begin
if (int < 2)
begin
out = int;
end
else
begin
out = int - 2;
end
end
endmodule
module sum_modulo_3(inp1, inp2, out);
input [1:0] inp1;
input [1:0] inp2;
output reg [1:0] out;
wire [2:0] int;
assign int = inp1 + inp2;
always @ (*)
begin
if (int < 3)
begin
out = int;
end
else
begin
out = int - 3;
end
end
endmodule
module lut_output_7(inp0, inp1, out);
output reg [2:0] out;
input [1:0] inp0;
input [1:0] inp1;
always @ (*)
begin
if (inp0 == 0 && inp1 == 0)
begin
out <= 1;
end
else if (inp0 == 0 && inp1 == 2)
begin
out <= 2;
end
else if (inp0 == 1 && inp1 == 1)
begin
out <= 3;
end
else if (inp0 == 0 && inp1 == 1)
begin
out <= 4;
end
else if (inp0 == 1 && inp1 == 2)
begin
out <= 5;
end
else if (inp0 == 1 && inp1 == 0)
begin
out <= 6;
end
else
begin
out <= 0;
end
end
endmodule
module lut_input_7(inp, out0, out1);
input [2:0] inp;
output reg [1:0] out0;
output reg [1:0] out1;
always @ (inp)
begin
case(inp)
1:
begin
out0 <= 0;
out1 <= 0;
end
2:
begin
out0 <= 0;
out1 <= 2;
end
3:
begin
out0 <= 1;
out1 <= 1;
end
4:
begin
out0 <= 0;
out1 <= 1;
end
5:
begin
out0 <= 1;
out1 <= 2;
end
6:
begin
out0 <= 1;
out1 <= 0;
end
default:
begin
out0 <= 0;
out1 <= 0;
end
endcase
end
endmodule
module atop_testbench();
reg [2:0] inp1;
reg [2:0] inp2;
wire [2:0] out;
integer i, j, l, m, k, t;
reg dummy;
integer fori, forj;
multiplication_mod_7 mul1(inp1, inp2, out);
initial
begin
k = 1;
for (fori = 0; fori < 7; fori = fori + 1)
begin
for (forj = 0; forj < 7; forj = forj + 1)
begin
inp1 = fori;
inp2 = forj;
#1 dummy = 1;
i = (fori*forj)%7;
$display ("!!! OP1 = (%d) OP2 = (%d) RES = (%d) EXPECT = (%d)", fori, forj, out, i);
l = out;
if (l != i)
begin
$display ("!!! Error (%d, %d)!!!", i, l);
end
#1 dummy = 1;
end
end
end
endmodule
2. Модулярный умножитель на базе формулы разности квадратов (на примере модуля 7)
module multiplication_mod_7(inp1, inp2, out);
input [2:0] inp1;
input [2:0] inp2;
output [2:0] out;
wire [3:0] plus;
wire [3:0] minus;
wire [2:0] plout;
wire [2:0] miout;
assign plus = inp1 + inp2; // [0; 12]
assign minus = 6 + inp1 - inp2; // [0; 12]
lut_sqr_sum ls1(plus, plout);
lut_sqr_sub ls2(minus, miout);
sub_mod_7 sub1(plout, miout, out);
endmodule
module lut_sqr_sum (in, out);
input [3:0] in;
output reg [2:0] out;
always @ (in)
begin
case (in)
0: out = 0;
1: out = 2;
2: out = 1;
3: out = 4;
4: out = 4;
5: out = 1;
6: out = 2;
7: out = 0;
8: out = 2;
9: out = 1;
10: out = 4;
11: out = 4;
12: out = 1;
default: out = 0;
endcase
end
endmodule
module lut_sqr_sub (in, out);
input [3:0] in;
output reg [2:0] out;
always @ (in)
begin
case (in)
0: out = 2;
1: out = 1;
2: out = 4;
3: out = 4;
4: out = 1;
5: out = 2;
6: out = 0;
7: out = 2;
8: out = 1;
9: out = 4;
10: out = 4;
11: out = 1;
12: out = 2;
default: out = 0;
endcase
end
endmodule
module sub_mod_7 (in1, in2, out);
input [2:0] in1, in2;
output [2:0] out;
wire [3:0] data;
assign data = 7 + in1 - in2;
mod_7_13 mdval(data, out);
endmodule
module mod_7_13 (in, out);
input [3:0] in;
output reg [2:0] out;
always @ (in)
begin
// we have small max value so we can use table here
case (in)
0: out = 0;
1: out = 1;
2: out = 2;
3: out = 3;
4: out = 4;
5: out = 5;
6: out = 6;
7: out = 0;
8: out = 1;
9: out = 2;
10: out = 3;
11: out = 4;
12: out = 5;
13: out = 6;
default: out = 0;
endcase
end
endmodule
module atop_testbench();
reg [2:0] inp1;
reg [2:0] inp2;
wire [2:0] out;
integer i, j, l, m, k, t;
reg dummy;
integer fori, forj;
multiplication_mod_7 mul1(inp1, inp2, out);
initial
begin
k = 1;
for (fori = 0; fori < 7; fori = fori + 1)
begin
for (forj = 0; forj < 7; forj = forj + 1)
begin
inp1 = fori;
inp2 = forj;
#1 dummy = 1;
i = (fori*forj)%7;
$display ("!!! OP1 = (%d) OP2 = (%d) RES = (%d) EXPECT = (%d)", fori, forj, out, i);
l = out;
if (l != i)
begin
$display ("!!! Error (%d, %d)!!!", i, l);
end
#1 dummy = 1;
end
end
end
endmodule
2. Модулярный сумматор по методу Espresso (на примере модуля 10)
module mul_mod10 (out, a, b); input [3:0] a, b; output [3:0] out; assign out[3] = (~a[3]&~a[2]&~a[1]&a[0]&b[3]) | (~a[2]&a[1]&~a[0]&b[3]&b[0]) | (a[3]&~b[3]&~b[2]&~b[1]&b[0]) | (a[2]&a[1]&~a[0]&b[3]&~b[0]) | (a[3]&~a[0]&b[2]&b[1]&~b[0]) | (a[3]&a[0]&~b[2]&b[1]&~b[0]) | (a[2]&a[1]&a[0]&b[2]&b[1]&b[0]) | (a[2]&~a[1]&~a[0]&b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&~b[2]&b[1]&b[0]) | (a[2]&a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&b[2]&b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&~b[2]&b[1]&~b[0]) | (a[2]&a[1]&a[0]&b[2]&~b[1]&~b[0]) | (~a[2]&a[1]&~a[0]&b[2]&~b[1]&~b[0]); assign out[2] = (~a[2]&a[1]&a[0]&b[3]) | (a[3]&~a[0]&~b[2]&b[1]) | (a[2]&~a[1]&a[0]&b[0]) | (a[3]&~a[0]&b[1]&b[0]) | (a[3]&~b[2]&b[1]&b[0]) | (a[0]&b[2]&~b[1]&b[0]) | (~a[2]&a[1]&b[3]&~b[0]) | (a[1]&a[0]&b[3]&~b[0]) | (a[3]&~a[0]&b[3]&~b[0]) | (a[2]&~a[0]&b[2]&~b[0]) | (~a[2]&a[1]&~a[0]&b[1]&b[0]) | (a[1]&a[0]&~b[2]&b[1]&~b[0]) | (~a[3]&~a[2]&~a[1]&a[0]&b[2]) | (a[2]&~a[0]&~b[2]&~b[1]&b[0]) | (a[2]&~b[3]&~b[2]&~b[1]&b[0]) | (~a[2]&~a[1]&a[0]&b[2]&~b[0]) | (~a[2]&a[1]&~b[2]&b[1]&~b[0]); assign out[1] = (a[2]&a[1]&a[0]&b[3]) | (a[2]&~a[1]&~a[0]&b[3]) | (a[3]&~a[0]&b[3]&b[0]) | (a[3]&b[2]&b[1]&b[0]) | (a[3]&a[0]&b[3]&~b[0]) | (a[3]&b[2]&~b[1]&~b[0]) | (~a[3]&~a[2]&~a[1]&a[0]&b[1]) | (a[2]&a[1]&~a[0]&b[2]&b[1]) | (a[1]&~b[3]&~b[2]&~b[1]&b[0]) | (~a[2]&a[1]&~a[0]&b[3]&~b[0]) | (a[2]&a[1]&~a[0]&b[1]&~b[0]) | (a[2]&a[1]&b[2]&b[1]&~b[0]) | (a[1]&~a[0]&b[2]&b[1]&~b[0]) | (a[3]&~a[0]&~b[2]&b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&b[2]&~b[1]&~b[0]) | (a[2]&~a[1]&~a[0]&b[2]&~b[1]&~b[0]) | (~a[2]&~a[1]&a[0]&b[1]&b[0]) | (a[1]&a[0]&~b[2]&~b[1]&b[0]) | (~a[2]&a[1]&~a[0]&~b[2]&b[1]&b[0]) | (~a[2]&a[1]&a[0]&~b[2]&b[1]&~b[0]); assign out[0] = (a[0]&b[0]); endmodule
Библиотека стандартных ячеек
NangateOpenCellLibrary.lib
Скрипт для запуска
lappend search_path "../libs" "../src" set target_library "NangateOpenCellLibrary.db" set link_library [list "*" $target_library] analyze -f <имя модуля>.v elaborate <имя модуля> uniquify current_design <имя модуля> check_design set_load [load_of [get_lib_pins NangateOpenCellLibrary/INV_X4/A]] [all_outputs] set_driving_cell -lib_cell DFFRS_X2 -library NangateOpenCellLibrary -pin Q [all_inputs] set_max_delay -to [all_outputs] 0 set_max_area 0 compile report_timing > result/timing_<имя модуля>.rpt report_area > result/area_<имя модуля>.rpt remove_design -all
Файлы для эксперимента
- Несжатые таблицы истинности для сумматоров (.csv, 2MB)
- Сжатые Espresso таблицы истинности для сумматоров (.csv, 3MB)
- Verilog на основе таблиц истинности для сумматоров (.csv, 3MB)