From 11508800cfaefc1c25a793760bf10d3fd997af80 Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Wed, 14 May 2025 19:16:38 +0300 Subject: Initial and probably final commit --- 1-a.v | 5 +++++ 1-b.v | 36 ++++++++++++++++++++++++++++++ 1-c.v | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1-d.v | 49 +++++++++++++++++++++++++++++++++++++++++ 1-e.v | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2-a.v | 34 ++++++++++++++++++++++++++++ 2-b.v | 46 ++++++++++++++++++++++++++++++++++++++ 2-c.v | 34 ++++++++++++++++++++++++++++ 2-d.v | 2 ++ LICENSE | 15 +++++++++++++ README.md | 35 +++++++++++++++++++++++++++++ questions/1-a.txt | 19 ++++++++++++++++ questions/1-b.txt | 18 +++++++++++++++ questions/1-c.txt | 34 ++++++++++++++++++++++++++++ questions/1-d.txt | 25 +++++++++++++++++++++ questions/1-e.txt | 26 ++++++++++++++++++++++ questions/2-a.txt | 24 ++++++++++++++++++++ questions/2-b.txt | 33 ++++++++++++++++++++++++++++ questions/2-c.txt | 38 ++++++++++++++++++++++++++++++++ questions/2-d.txt | 28 +++++++++++++++++++++++ 20 files changed, 633 insertions(+) create mode 100644 1-a.v create mode 100644 1-b.v create mode 100644 1-c.v create mode 100644 1-d.v create mode 100644 1-e.v create mode 100644 2-a.v create mode 100644 2-b.v create mode 100644 2-c.v create mode 100644 2-d.v create mode 100644 LICENSE create mode 100644 README.md create mode 100644 questions/1-a.txt create mode 100644 questions/1-b.txt create mode 100644 questions/1-c.txt create mode 100644 questions/1-d.txt create mode 100644 questions/1-e.txt create mode 100644 questions/2-a.txt create mode 100644 questions/2-b.txt create mode 100644 questions/2-c.txt create mode 100644 questions/2-d.txt 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< 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< 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< + +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. + + -- cgit v1.2.3-70-g09d2