aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--1-a.v5
-rw-r--r--1-b.v36
-rw-r--r--1-c.v66
-rw-r--r--1-d.v49
-rw-r--r--1-e.v66
-rw-r--r--2-a.v34
-rw-r--r--2-b.v46
-rw-r--r--2-c.v34
-rw-r--r--2-d.v2
-rw-r--r--LICENSE15
-rw-r--r--README.md35
-rw-r--r--questions/1-a.txt19
-rw-r--r--questions/1-b.txt18
-rw-r--r--questions/1-c.txt34
-rw-r--r--questions/1-d.txt25
-rw-r--r--questions/1-e.txt26
-rw-r--r--questions/2-a.txt24
-rw-r--r--questions/2-b.txt33
-rw-r--r--questions/2-c.txt38
-rw-r--r--questions/2-d.txt28
20 files changed, 633 insertions, 0 deletions
diff --git a/1-a.v b/1-a.v
new file mode 100644
index 0000000..15e3c7c
--- /dev/null
+++ b/1-a.v
@@ -0,0 +1,5 @@
+module m_a(input x1, x2, x3, output z1, z2);
+ assign z1 = (~x1 & ((x2 | x3) & (~x2 | ~x3))) | (x1 & (~x2 | x3));
+ assign z2 = (~x1 & x2 & x3) | (x1 & (x2 | x3));
+endmodule
+
diff --git a/1-b.v b/1-b.v
new file mode 100644
index 0000000..f4aa486
--- /dev/null
+++ b/1-b.v
@@ -0,0 +1,36 @@
+module mux64_4_2(y0, y1, y2, y3, x, z);
+ input wire [63:0] y0, y1, y2, y3;
+ input wire [1:0] x;
+ output wire [63:0] z;
+ wire [63:0] mx0, mx1, mx2, mx3[63:0] ;
+ genvar i;
+ generate for(i = 0; i < 64; i = i + 1)
+ begin: gen
+ and(mx0[i], y0[i], ~x[0], ~x[1]);
+ and(mx1[i], y1[i], ~x[0], x[1]);
+ and(mx2[i], y2[i], x[0], ~x[1]);
+ and(mx3[i], y3[i], x[0], x[1]);
+ or(z[i], mx0[i], mx1[i], mx2[i], mx3[i]);
+ end;
+ endgenerate;
+endmodule;
+
+/*
+module test;
+ reg [63:0] a1, a2, a3, a4;
+ reg [2:0] muxselect;
+ wire [63:0] out;
+ mux64_4_2 mux(a1, a2, a3, a4, muxselect[1:0], out);
+ initial begin;
+ a1 = 69;
+ a2 = 420;
+ a3 = 727;
+ a4 = 1488;
+ for (muxselect = 2'b00; muxselect <= 2'b11; muxselect += 1) begin
+ #10;
+ $display("current thingy: %d", out);
+ end;
+ end;
+endmodule;
+*/
+
diff --git a/1-c.v b/1-c.v
new file mode 100644
index 0000000..c19bd93
--- /dev/null
+++ b/1-c.v
@@ -0,0 +1,66 @@
+module au(x_int, y_int, x_frac, y_frac, operation, zero, overflow, result_int, result_frac);
+ parameter WIDTH_1 = 4, WIDTH_2 = 4;
+ input [WIDTH_1-1:0] x_int, y_int;
+ input [WIDTH_2-1:0] x_frac, y_frac;
+ input operation;
+ output zero, overflow;
+ output [WIDTH_1-1:0] result_int;
+ output [WIDTH_2-1:0] result_frac;
+ reg z, over;
+ reg [2*(WIDTH_1)-1:0] r_i;
+ reg [2*(WIDTH_2)-1:0] r_f;
+ reg [2*(WIDTH_1+WIDTH_2)-1:0] r_intr;
+ always @* begin
+ r_i = 0;
+ r_f = 0;
+ if (operation == 1'b0) begin
+ r_i = x_int + y_int;
+ r_f = x_frac + y_frac;
+ if (r_f[WIDTH_2] == 1'b1) r_i += 1;
+ if (r_i[WIDTH_1] == 1'b1) over = 1'b1;
+ else over = 1'b0;
+ end
+ else begin
+ r_intr = {x_int, x_frac} * {y_int, y_frac};
+ r_i[WIDTH_1-1:0] = r_intr[2*WIDTH_2+WIDTH_1-1:2*WIDTH_2];
+ r_f[WIDTH_2-1:0] = r_intr[2*WIDTH_2-1:WIDTH_2];
+ if (r_intr[2*(WIDTH_2+WIDTH_1)-1:2*WIDTH_2+WIDTH_1] != 0/* || r_intr[WIDTH_2-1:0] != 0*/)
+ over = 1'b1;
+ else
+ over = 1'b0;
+ end
+ if (r_i[WIDTH_1-1:0] == 0 && r_f[WIDTH_2-1:0] == 0) z = 1;
+ else z = 0;
+ // z = (r_i == 0 && r_f == 0);
+ end
+
+ assign result_int = r_i[WIDTH_1-1:0];
+ assign result_frac = r_f[WIDTH_2-1:0];
+ assign zero = z;
+ assign overflow = over;
+endmodule
+
+/*
+module test;
+ reg [3:0] a, b;
+ reg [3:0] _a, _b;
+ reg switch;
+
+ wire [3:0] r;
+ wire [3:0] _r;
+ wire zero, overflow;
+
+ au summer(a, b, _a, _b, switch, zero, overflow, r, _r);
+
+ initial begin;
+ a = 0;
+ _a = 4'b1100;
+ b = 0;
+ _b = 4'b1100;
+ switch = 1'b0;
+ #1;
+ $display("%d.%b %s %d.%b = %d.%b (overflow: %b, zero: %b)",
+ a, _a, (switch == 1'b0 ? "+" : "*"), b, _b, r, _r, overflow, zero);
+ end
+endmodule
+*/
diff --git a/1-d.v b/1-d.v
new file mode 100644
index 0000000..1c952dc
--- /dev/null
+++ b/1-d.v
@@ -0,0 +1,49 @@
+module ram(data_in, address, clock, write_enable, data_out);
+ parameter DATA_WIDTH = 8;
+ parameter ADDR_WIDTH = 4;
+ input [DATA_WIDTH-1:0] data_in;
+ input [ADDR_WIDTH-1:0] address;
+ input clock, write_enable;
+ output [DATA_WIDTH-1:0] data_out;
+ reg [DATA_WIDTH-1:0] mem [0:(1 << ADDR_WIDTH)-1];
+ always @(posedge clock) begin
+ if (write_enable) mem[address] <= data_in;
+ end
+ assign data_out = mem[address];
+endmodule
+
+/*
+module test;
+ reg [7:0] in;
+ reg [3:0] addr;
+ reg clock, ddr;
+ wire [7:0] out;
+ ram r(in, addr, clock, ddr, out);
+
+ always #1 clock = ~clock;
+
+ initial begin
+ $monitor(out);
+ clock = 0;
+ addr = 'hA;
+ in = 'h69;
+ ddr = 1;
+ #10 ddr = 0;
+ addr = 'hB;
+ in = 'hFF;
+ #10 ddr = 1;
+ #10 ddr=0;
+ addr = 'hC;
+ in = 'h01;
+ #10 ddr=1;
+ #10 ddr=0;
+ $display("0x9 to 0xD test");
+ #10 addr = 'h9;
+ #10 addr = 'hA;
+ #10 addr = 'hB;
+ #10 addr = 'hC;
+ #10 addr = 'hD;
+ end;
+endmodule
+*/
+
diff --git a/1-e.v b/1-e.v
new file mode 100644
index 0000000..b30b9ae
--- /dev/null
+++ b/1-e.v
@@ -0,0 +1,66 @@
+module flipflop(in, clock, reset, out);
+ parameter WIDTH = 8;
+ input [WIDTH-1:0] in;
+ input clock, reset;
+ output [WIDTH-1:0] out;
+ reg [WIDTH-1:0] mem1;
+
+ /* Вот этот вариант не принял
+ always @(posedge clock) mem1 <= in;
+ always @(posedge reset) mem1 <= 0; */
+ // А вот этот принял
+ always @(posedge clock or posedge reset) begin
+ if (reset) mem1 <= 0;
+ else mem1 <= in;
+ end
+ // в чём разница ? Я думал, это эквивалентно
+ assign out = mem1;
+endmodule
+
+/*
+module shift_register(data_in, clock, reset, data_out);
+ parameter WIDTH = 8, LENGTH = 4;
+ input [WIDTH-1:0] data_in;
+ input clock, reset;
+ output [WIDTH-1:0] data_out;
+ wire [WIDTH-1:0] inter[0:LENGTH];
+ generate
+ genvar i;
+ for (i = 0; i < LENGTH; i=i+1)
+ flipflop#(WIDTH) f(inter[i], clock, reset, inter[i+1]);
+ endgenerate
+ assign inter[0] = data_in;
+ assign data_out = inter[LENGTH];
+endmodule
+
+module test;
+ reg clock;
+ reg reset;
+ reg [7:0]in;
+ wire [7:0]out;
+ shift_register#(8, 4) sr(in, clock, reset, out);
+ // always #5 clock = ~clock;
+ initial begin
+ $monitor("%d | %d | %b | %b", in, out, clock, reset);
+ clock = 0;
+ reset = 0;
+ #1 reset = 1; #1 clock = 1; #1 clock = 0;
+ reset = 0; #1 clock = 1; #1 clock = 0;
+ in = 69; #1 clock = 1; #1 clock = 0;
+ in = 42; #1 clock = 1; #1 clock = 0;
+ in = 70; #1 clock = 1; #1 clock = 0;
+ in = 111; #1 clock = 1; #1 clock = 0; #1 clock = 1; #1 clock = 0; #1 clock = 1; #1 clock = 1; #1 clock = 0; #1 clock = 1; #1 clock = 0; #1 clock = 1;
+ reset = 1; #1 clock = 0; #1 clock = 1;
+ reset = 0; in = 1; #1 clock = 1; #1 clock = 0;
+ in = 2; #1clock = 1; #1 clock = 0;
+ in = 3;#1 clock = 1; #1 clock = 0;
+ in = 4;#1 clock = 1; #1 clock = 0;
+ in = 5;#1 clock = 1; #1 clock = 0;
+ in = 6; #1 clock = 1; #1 clock = 0;#1 clock = 1;
+ #1 clock = 0; #1 clock = 1; #1 clock = 0;
+ #1 clock = 1; #1 clock = 0; #1 clock = 1;
+ #1 clock = 0; #1 clock = 1; #1 clock = 0;
+ end;
+endmodule;
+*/
+
diff --git a/2-a.v b/2-a.v
new file mode 100644
index 0000000..2013a6f
--- /dev/null
+++ b/2-a.v
@@ -0,0 +1,34 @@
+module tree_adder(data_in, data_out);
+ parameter WIDTH=8, SIZE=4;
+ input wire [WIDTH*SIZE-1:0] data_in;
+ output wire [WIDTH-1:0] data_out;
+ if (SIZE == 2) begin
+ assign data_out = data_in[WIDTH-1:0] + data_in[2 * WIDTH-1:WIDTH];
+ end else begin
+ wire [WIDTH-1:0]intmd[0:1];
+ tree_adder#(WIDTH, SIZE/2) m1(data_in[SIZE/2*WIDTH-1:0], intmd[0]);
+ tree_adder#(WIDTH, SIZE/2) m2(data_in[SIZE*WIDTH-1:SIZE/2*WIDTH], intmd[1]);
+ assign data_out = intmd[0] + intmd[1];
+ end
+endmodule
+
+/*
+module test;
+ reg [63:0]vals;
+ wire [7:0] out;
+ tree_adder#(8, 8) adder(vals, out);
+ initial begin
+ $monitor(out);
+ vals[7:0] = 1;
+ vals[15:8] = 2;
+ vals[23:16] = 1;
+ vals[31:24] = 2;
+ vals[39:32] = 1;
+ vals[47:40] = 1;
+ vals[55:48] = 1;
+ vals[63:56] = 1;
+ #1;
+ end
+endmodule
+*/
+
diff --git a/2-b.v b/2-b.v
new file mode 100644
index 0000000..55feec1
--- /dev/null
+++ b/2-b.v
@@ -0,0 +1,46 @@
+module max_argmax(data_in, data_max, argmax);
+ parameter WIDTH=8, SIZE=2;
+ input [WIDTH*(1<<SIZE)-1:0] data_in;
+ output [WIDTH-1:0] data_max;
+ output [SIZE-1:0] argmax;
+ if (SIZE == 1) begin
+ wire [WIDTH-1:0]
+ a1 = data_in[WIDTH*2-1:WIDTH],
+ a2 = data_in[WIDTH-1:0];
+ assign data_max = a1 > a2 ? a1 : a2;
+ assign argmax = a1 > a2 ? 1'b0 : 1'b1;
+ end else begin
+ wire [WIDTH*(1<<(SIZE-1))-1:0]
+ w1 = data_in[WIDTH*(1<<SIZE)-1:WIDTH*(1<<(SIZE-1))],
+ w2 = data_in[WIDTH*(1<<(SIZE-1))-1:0];
+ wire [WIDTH-1:0] a1, a2;
+ wire [SIZE-2:0] i1, i2;
+ max_argmax#(WIDTH, SIZE-1) m1(w1, a1, i1);
+ max_argmax#(WIDTH, SIZE-1) m2(w2, a2, i2);
+ assign data_max = a1 > a2 ? a1 : a2;
+ assign argmax[SIZE-2:0] = a1 > a2 ? i1 : i2;
+ assign argmax[SIZE-1] = a1 > a2 ? 1'b0 : 1'b1;
+ end
+endmodule
+
+/*
+module test;
+ reg [63:0]vals;
+ wire [7:0]out;
+ wire [2:0]idx;
+ max_argmax#(8, 3) adder(vals, out, idx);
+ initial begin
+ $monitor("%d, %b", out, idx);
+ vals[63:56] = 25;
+ vals[55:48] = 24;
+ vals[47:40] = 25;
+ vals[39:32] = 13;
+ vals[31:24] = 25;
+ vals[23:16] = 121;
+ vals[15:8] = 2;
+ vals[7:0] = 200;
+ #1;
+ end
+endmodule
+*/
+
diff --git a/2-c.v b/2-c.v
new file mode 100644
index 0000000..33a9d00
--- /dev/null
+++ b/2-c.v
@@ -0,0 +1,34 @@
+// для ненаписанного теста
+// `include "2-a.v"
+// `include "2-b.v"
+
+module linear_classifier(features, weights, r_value, r_class);
+ parameter WIDTH=8, FEATURES=2, C_WIDTH=1;
+ input [FEATURES*WIDTH-1:0]features;
+ input [(1<<C_WIDTH)*FEATURES*WIDTH-1:0]weights;
+ output [WIDTH-1:0]r_value;
+ output [C_WIDTH-1:0]r_class;
+
+ wire [(1<<C_WIDTH)*FEATURES*WIDTH-1:0]prod;
+ wire [(1<<C_WIDTH)*WIDTH-1:0]sum;
+
+ generate
+ genvar i;
+ for (i = 0; i < (1<<C_WIDTH)*FEATURES; i =i+1)
+ assign prod[(i+1)*WIDTH-1:i*WIDTH] = weights[(i+1)*WIDTH-1:i*WIDTH]
+ * features[(i%FEATURES+1)*WIDTH-1:(i%FEATURES)*WIDTH];
+ for (i = 0; i < (1<<C_WIDTH); i = i+1)
+ tree_adder#(WIDTH, FEATURES) adder(
+ prod[WIDTH*FEATURES*(i+1)-1:WIDTH*FEATURES*i],
+ sum[WIDTH*(i+1)-1:WIDTH*i]
+ );
+ endgenerate
+ max_argmax#(WIDTH, C_WIDTH) max(sum, r_value, r_class);
+endmodule
+
+// Я хотел его написать, но решил отправить, и сработало с первой попытки ))
+/*
+module test;
+endmodule;
+*/
+
diff --git a/2-d.v b/2-d.v
new file mode 100644
index 0000000..5e7408e
--- /dev/null
+++ b/2-d.v
@@ -0,0 +1,2 @@
+// Задание муторное, свой зачёт я получил, не уверен, что хочу его делать...
+// Может позже, IDK, но это можно погуглить, если что
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..575bb47
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+BSD Zero Clause License
+
+Copyright (C) 2025 by justanothercatgirl <sotov@twistea.su>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..feeebe0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+# Задачи с МФК "Основы проектирования аппаратных ускорителей систем искусственного интеллекта"
+
+## А код где? [тут](/cgit/verilog-hw/tree)
+
+## Как разрабатывать на своём компе?
+
+Среды программирования я не нашёл, и не то, чтобы искал, поэтому скачал
+компилятор (`iverilog`, или icarus verilog. НЕ СОВЕТУЮ `verilator`, хоть он и
+популярен: во-первых, некоторые вещи в нём несовместимы с verilog на сайте,
+во-вторых, тесты под него надо писать на `C++`, модулем не отделаешься)
+
+Рутина такая (на Linux):
+
+- пишите модуль по заданию, пишите модуль `test` без аргументов, там смотрите
+ всё по задержкам и т.п..
+- компилируете в консоли: `iverilog <ИМЯ ФАЙЛА>.v`
+- запускаете в консоли: `./a.out`
+
+На Windows: просто удачи бро. Сорян, но тут по фактам.
+
+Чтобы выложить на контест, советую убирать ВСЕ лишние запяточки (после
+`endmodule`, `end`, `endgenerate`), даже если у вас компилятор не ругается.
+Оставляйте пустую строку в конце файла. Удаляйте тестовые модули.
+
+## Зачем?
+
+В конце курса вам препод скорее всего даст в районе 10 задач на сайте (в
+контесте), которые надо будет решить на Verilog. Чтобы получить зачёт, в моё
+время было достаточно решить ровно половину (Aka 5\* задач)
+
+\*: у нас по плану было 10, а по факту 8 задач, поэтому достаточно было 4-х.
+Препод это обещал пофискить к следующему году.
+
+## А код правда просто можно взять и пиздить?
+Если задачи такие же, то да. Задания в папке [`questions`](/cgit/verilog-hw/tree/questions)
diff --git a/questions/1-a.txt b/questions/1-a.txt
new file mode 100644
index 0000000..5bfff0e
--- /dev/null
+++ b/questions/1-a.txt
@@ -0,0 +1,19 @@
+Просто модуль
+
+Требуется при помощи языка Verilog спроектировать модуль, который реализует две
+булевых функции от переменных x1, x2 и x3, заданные своими столбцами значений:
+z1 = (10011101) и z2 = (00010111).
+
+Имя модуля должно быть m_a.
+
+Входы модуля: три провода x1, x2 и x3.
+
+Выходы модуля: два провода z1 и z2.
+
+При проектировании модуля можно использовать только стандартные функциональные
+элементы, такие как not, or и and. Другие конструкции и выражения языка Verilog
+использовать запрещается.
+
+ИЗ ПЕРЕПИСКИ В ТЕЛЕГРАМЕ:
+"Спасибо за информацию. Посмотрел, действительно, есть ошибка. В первой задаче
+z1 = (01101101). Пожалуйста, учитывайте это исправление при решении задачи."
diff --git a/questions/1-b.txt b/questions/1-b.txt
new file mode 100644
index 0000000..c11324d
--- /dev/null
+++ b/questions/1-b.txt
@@ -0,0 +1,18 @@
+Просто мультиплексор
+
+Требуется при помощи языка Verilog спроектировать мультиплексор 4-х 64-битных
+шин проводов.
+
+Имя модуля должно быть mux64_4_2.
+
+Входы модуля: 64-битные шины проводов y0, y1, y2, y3 и 2-х битная шина проводов
+x, которая выбирает одну из шин y по ее номеру.
+
+Выход модуля: 64-битная шина z.
+
+При проектировании модуля можно использовать стандартные функциональные
+элементы, такие как not, or и and, и композицию модулей. Другие конструкции и
+выражения языка Verilog использовать запрещается. Файл с описанием модуля
+должен содержать не более 35 строк.
+
+
diff --git a/questions/1-c.txt b/questions/1-c.txt
new file mode 100644
index 0000000..048ca03
--- /dev/null
+++ b/questions/1-c.txt
@@ -0,0 +1,34 @@
+Арифметическое устройство
+
+Требуется при помощи языка Verilog спроектировать параметрическое
+арифметическое устройство для выполнения операций сложения и умножения чисел с
+фиксированной запятой.
+
+Имя модуля должно быть au.
+
+Параметры модуля:
+
+ * WIDTH_1 - размер целой части числа (по умолчанию, 4 бита).
+ * WIDTH_2 - размер дробной части числа (по умолчанию, 4 бита).
+
+Входы модуля:
+
+ * x_int, y_int - шины проводов размера WIDTH_1, которые задают целые части
+ входных аргументов x и y.
+ * x_frac, y_frac - шины проводов размера WIDTH_2, которые задают дробные
+ части входных аргументов x и y.
+ * operation - провод, задающий тип операции (0 - сложение, 1 - умножение).
+
+Выходы модуля:
+
+ * zero - провод, который сигнализирует о том, что результат является 0.
+ * overflow - провод, который сигнализирует о том, что произошло переполнение.
+ * result_int - шина проводов размера WIDTH_1, которая выдает целую часть
+ результата операции.
+ * result_frac - шина проводов размера WIDTH_2, которая задает дробную часть
+ результата.
+
+Примечание: при выходе результирующего значения за пределы ширины целой части
+происходит переполнение.
+
+
diff --git a/questions/1-d.txt b/questions/1-d.txt
new file mode 100644
index 0000000..8d1c15c
--- /dev/null
+++ b/questions/1-d.txt
@@ -0,0 +1,25 @@
+Память с произвольным доступом
+
+Требуется при помощи языка Verilog спроектировать параметрический модуль памяти
+с произвольным доступом.
+
+Имя модуля должно быть ram.
+
+Параметры модуля:
+
+ * DATA_WIDTH размерность данных, хранимых в памяти (по умолчанию 8 бит).
+ * ADDR_WIDTH размер адреса (по умолчанию, 4 бита).
+
+Входы модуля:
+
+ * data_in шина проводов размера DATA_WIDTH, используемая для подачи входной
+ информации в блок памяти.
+ * address шина размера ADDR_WIDTH, задающий адрес в памяти.
+ * провод clock, провод write_enable, который сигнализирует о том, будет ли
+ проводится запись в память или нет (при значении WRITE_ENABLE==1 в
+ момент прихода положительного фронта синхронизирующего сигнала clock).
+
+Выход модуля: data_out шина проводов размера DATA_WIDTH, которая выдает
+значение элемента памяти по адресу, заданному входом address.
+
+
diff --git a/questions/1-e.txt b/questions/1-e.txt
new file mode 100644
index 0000000..0ec3126
--- /dev/null
+++ b/questions/1-e.txt
@@ -0,0 +1,26 @@
+Сдвиговый регистр
+
+Требуется при помощи языка Verilog спроектировать параметрический сдвиговый
+регистр (https://en.wikipedia.org/wiki/Shift_register).
+
+Имя модуля должно быть shift_register.
+
+Параметры модуля:
+
+ * WIDTH - количество бит, которые хранит регистр (по умолчанию, 8 бит).
+ * LENGTH - количество последовательно соединнех регистров (по умолчанию, 4).
+
+Входы модуля:
+
+ * Шина проводов data_in размера WIDTH, поделюченная к первому регистру.
+ * Провод clock, осуществялющий синхронизацию по своему положительному фронту.
+ * Провод reset, осуществляющий сброс по своему положительному фронту.
+
+Выход модуля: шина проводов data_out размера WIDTH, подключенная к последнему
+регистру.
+
+Рекомендация: при проектировании модуля можно спроектировать вспомогательный
+модуль регистра, который в основном модуле будет многократно инстанцироваться
+при помощи конструкции generate.
+
+
diff --git a/questions/2-a.txt b/questions/2-a.txt
new file mode 100644
index 0000000..e272b43
--- /dev/null
+++ b/questions/2-a.txt
@@ -0,0 +1,24 @@
+Дерево сумматоров
+
+Требуется при помощи языка Verilog спроектировать параметрический блок сложения
+нескольких чисел. Схема сложения выполнена в виде дерева, когда нечетные по
+номеру числа складываются с четными и к результирующим числам применяется такая
+же схема, пока не получиться одно число.
+
+Имя модуля должно быть tree_adder.
+
+Парметры модуля:
+
+ * WIDTH - размер числа (по умолчанию, 8 бит).
+ * SIZE - количество складываемых чисел (по умолчанию, 4). Для простоты
+ реализации, считается, что количество чисел является степенью двойки
+ (другими словами, дерево сложения является полным двоичным деревом).
+
+Вход модуля: data_in - шина проводов размера SIZE * WIDTH, представляющая собой
+последовательную конкатенацию всех входных чисел.
+
+Выход модуля: data_out - шина проводов размера WIDTH, представляющая собой
+результат сложения.
+
+При проектировании модуля игнорируется возможное переполнение. Считается, что
+все промеужеточные числа и финальное число имеет размер WIDTH.
diff --git a/questions/2-b.txt b/questions/2-b.txt
new file mode 100644
index 0000000..837c2c3
--- /dev/null
+++ b/questions/2-b.txt
@@ -0,0 +1,33 @@
+Вычисление максимума
+
+Требуется при помощи языка Verilog спроектировать параметрический блок
+вычисления максимума нескольких чисел и индекса исходного числа, на котором
+достигается максимум. Схема вычисления выполнена в виде дерева, когда
+последовательные пары чисел сравниваются и среди них выбирается максимальный.
+Аналогичная схема применяется к результирующим числам, пока не получиться одно
+число.
+
+Имя модуля должно быть max_argmax.
+
+Парметры модуля:
+
+ * WIDTH - размер числа (по умолчанию, 8 бит).
+ * SIZE - количество уровней в дереве вычислений (по умолчанию, 2). При этом
+ количество чисел, для которых вычисляется максимум, равно 2 в степени
+ SIZE.
+
+Вход модуля: data_in - шина проводов размера (2**SIZE) * WIDTH, представляющая
+собой последовательную конкатенацию всех входных чисел.
+
+Выход модуля:
+
+ * data_max - шина проводов размера WIDTH, представляющая собой результат
+ сложения.
+ * argmax - шина проводов размера SIZE, представляющая собой номер числа, на
+ котором достигается максимум (числа нумерутся слева направо, нумерация
+ начинается с 0).
+
+Если максимальное значение достигается на нескольких числах, то argmax
+возращает индекс последнего числа, на котором достигается максимум.
+
+
diff --git a/questions/2-c.txt b/questions/2-c.txt
new file mode 100644
index 0000000..d93b677
--- /dev/null
+++ b/questions/2-c.txt
@@ -0,0 +1,38 @@
+Требуется при помощи языка Verilog спроектировать параметрический блок
+линейного классификатора. Данный блок получает на вход набор значений признаков
+и их веса. Для каждого класса вычисляется сумма произведений значений признаков
+на веса. Среди полученных значений находится максимум и в качестве результата
+блок выдает индекс класса, на котором был достигнут максимум.
+
+Имя модуля должно быть linear_classifier.
+
+Параметры модуля:
+
+ * WIDTH - размер чисел (по умолчанию, 8 бит).
+ * FEATURES - количество признаков (по умолчанию, 2).
+ * C_WIDTH - количество бит, которые используются для хранения индеска класса
+ (по умолчанию, 1). Считается, что число классов является степенью
+ двойки.
+
+Входы модуля:
+
+ * features - шина проводов размера FEATURES * WIDTH, представляющая собой
+ последовательную конкатенацию значений входных признаков.
+ * weights - шина проводов размера (2**C_SIZE) * FEATURES * WIDTH,
+ представляющая собой последовательную конкатенацию значений весов
+ признаков для всех классов.
+
+Выходы модуля:
+
+ * r_value - шина проводов размера WIDTH, представляющая собой результат
+ вычисления максимума.
+ * r_class - шина проводов размера C_WIDTH, представляющая собой индекс
+ класса, на котором достигается максимум (классы нумерутся слева
+ направо, нумерация начинается с 0).
+
+При проектировании модуля можно использовать модули tree_adder и max_argmax,
+описанные в заданиях A и B, в качестве подмодулей (сами модули проектировать не
+нужно, они будут автоматически использованы при проверке, если были
+использованы).
+
+
diff --git a/questions/2-d.txt b/questions/2-d.txt
new file mode 100644
index 0000000..af53680
--- /dev/null
+++ b/questions/2-d.txt
@@ -0,0 +1,28 @@
+Систолический массив
+
+Требуется спроектировать на языке Verilog двухмерный систолический массив для
+выполнения операции матричного умножения
+https://gyires.inf.unideb.hu/KMITT/a52/ch04.html.
+
+Проектируемый модуль должен называться systolic_array.
+
+Параметры модуля: ROWS - количество рядов в массиве, COLUMNS - количество
+столбцов в массиве, WIDTH - размерность шин аргументов.
+
+Входы модуля: clock - провод синхросигнала, reset - провод сигнала сброса
+(сброс при выставлении значения 0), a - шина проводов ширины ROWS*WIDTH,
+подающая значения вектора a (элементы вектора нумеруются справа налево), b -
+шина проводов ширины COLUMNS*WIDTH, подающая значения вектора b (элементы
+вектора нумеруются справа налево). Каждое значение векторов a и b имеет
+размерность WIDTH.
+
+Выходы модуля: c - шина проводов ширины ROWS*COLUMNS*WIDTH, характеризующих
+текущее состояние вычисляемой матрицы. Элементы матрицы нумеруются справа
+налево и сверху вниз. Например, для матрицы размера 2 на 2 из 4-х битовых
+значений шина с будет разбита следующим образом: 00: c[3 : 0], 01: c[7 : 4],
+10: c[11: 8], 11: c[15:12].
+
+Примечание: схема должна иметь асинхронный сброс, латентность вычислений
+(количество тактов, требуемое для вычисления нового значения) равна 1.
+
+