Описание работы универсального прямого преобразователя — различия между версиями
Turbo (обсуждение | вклад) |
Turbo (обсуждение | вклад) |
||
Строка 104: | Строка 104: | ||
always @ (in) | always @ (in) | ||
begin | begin | ||
− | + | if (in < 3'd5) | |
− | + | begin | |
− | + | out = in; | |
− | + | end | |
− | + | else if (in < 4'd10) | |
− | + | begin | |
− | 4 | + | out = in - 3'd5; |
− | + | end | |
− | + | else if (in < 4'd15) | |
− | + | begin | |
− | + | out = in - 4'd10; | |
− | + | end | |
− | + | else if (in < 5'd20) | |
− | + | begin | |
− | + | out = in - 4'd15; | |
− | + | end | |
− | + | else | |
− | + | begin | |
− | + | out = in - 5'd20; | |
− | + | end | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
endmodule | endmodule |
Версия 14:14, 29 ноября 2013
Содержание
Описание работы универсального прямого преобразователя из позиционного представления в модулярный код
Постановка задачи
Требуется реализовать микроэлектронное устройство выполняющее преобразование из позиционного представления в модулярный код. Разработку будем вести на языке Verilog. Пусть задано входное число в позиционном виде разрядности -бит. Требуется найти остаток от его деления (вычет) на каждое число из набора, образующих модулярный базис . Так как алгоритм вычисления остатков будет одинаков для каждого из них, то рассмотрим произвольное число из набора размерности -бит.
Схема этого блока с входами и выходами:
Здесь:
- - константа заданная на этапе проектирования
Специальные случаи
При некоторых соотношениях между входными данными и заданным p, модуль взятия остатка от деления можно реализовать простейшим образом. Рассмотрим такие случаи:
Модуль больше входных данных
- в этом случае выходные данные совпадают с входными, то есть .
module forward_conv_module_23 (in, out);
input [3:0] in; // Max value: 15
output [4:0] out; // Max value: 22
assign out = {1'd0,in[3:0]};
endmodule
Модуль равен степени двойки
- в этом случае выходные данные равны младшим t-бит входных данных, то есть .
module forward_conv_module_16 (out0, in);
output [3:0] out0; // Max value: 15
input [7:0] in; // Max value: 255
assign out0 = in[3:0];
endmodule
N незначительно превосходит разрядность модуля
В этом случае достаточно проверить в какой из диапазонов вида попадает и вычесть из него поправочный коэффициент, соответствующий диапазону. для , для , для и.т.д.
module mod_253_511 (in, out);
input [8:0] in;
output reg [7:0] out;
always @ (in)
begin
if (in < 8'd253)
begin
out = in;
end
else if (in < 9'd506)
begin
out = in - 8'd253;
end
else
begin
out = in - 9'd506;
end
end
endmodule
module forward_conv_module_253 (in, out);
input [8:0] in; // Max value: 511
output [7:0] out; // Max value: 252
mod_253_511 inst(in, out);
endmodule
Общий случай
Представим входные данные в следующем виде:
и воспользуемся следующими свойствами вычетов:
- и
Тогда вычет X по модулю p можно записать следующим образом:
- .
Константы вида могут быть рассчитаны на этапе проектирования устройства и каждая константа не превосходит значение . А общее значение выражения . Так как коэффициенты известны, то оценку максимально возможного значения можно сократить ещё больше.
Таким образом что бы посчитать значение вычета требуется выполнить две операции: 1) Найти сумму . 2) Определить в какой интервал вида попадает значение и вычесть из него соответствующее значение для , для , для и.т.д.
Численный пример
Verilog-код для численного примера
module mod_5_23 (in, out);
input [4:0] in;
output reg [2:0] out;
always @ (in)
begin
if (in < 3'd5)
begin
out = in;
end
else if (in < 4'd10)
begin
out = in - 3'd5;
end
else if (in < 4'd15)
begin
out = in - 4'd10;
end
else if (in < 5'd20)
begin
out = in - 4'd15;
end
else
begin
out = in - 5'd20;
end
end
endmodule
module forward_conv_module_5 (in, out);
input [9:0] in; // Max value: 1023
output [2:0] out; // Max value: 4
wire [4:0] inter1; // Max value: 23
assign inter1 = in[2:0] + 3*in[3] + in[4] + 2*in[5] + 4*in[6] + 3*in[7] + in[8] + 2*in[9];
mod_5_23 inst(inter1, out);
endmodule