Определяем модуль всей цепочки. у него есть входы, выходы и внутренние модули, всё это надо связать в единую сеть с помощью комбинационной схемы. Регистров тут в явном виде нет, они инкапсулированы внутри сортировочных ячеек.
Рассмотрим подробнее подстановку одного модуля в другой
Cell_Compare — тип модуля
#(HBIT) — установка числовых параметров
ribbon — имя экземпляра
[_R_SZ] — это массив, указываем количество
( clk, hold, is_input, — общие сигналы для всех
in_prev, in_next, out ); — специфические сигналы для каждого элемента массива.
Теперь модуль сортировочной ячейки.
Здесь начинается собственно логика сортировки. Каждая ячейка хранит два числа, одно меньше другого. Каждый такт (если не hold) ячейка сравнивает число, пришедшее от соседа со своим «чемпионом». Чемпион — максимальное число при записи и минимальное при чтении. Проигравший покинет ячейку на следующем такте. В результате, данные движутся по цепочке сначала в одном направлении, потом в другом. Количество чисел, помещающихся в устройстве равно удвоенному количеству ячеек.
Всё.
// Заголовок
module Sorting_Stack ( clk, hold, is_input, data_in, data_out );
// Числовые параметры
parameter HBIT= 15; // size of number in bits
parameter R_SZ= 256; // capacity, max sequence size
parameter _R_SZ= (R_SZ+1)/2; // not to modify
// Перечисляем входы-выходы схемы
// Тактовый сигнал
input clk;
...
// входы-выходы данных
input [HBIT:0] data_in; // load one number per clock
output [HBIT:0] data_out; // while is_input==0, max value popping out here
// в квадратных скобках перед именем - разрядность
...
// Промежуточные точки схемы
wire [HBIT:0] in_prev[_R_SZ];
wire [HBIT:0] in_next[_R_SZ];
wire [HBIT:0] out[_R_SZ];
// в квадратных скобках после имени - размерности массивов
// Внутренние подмодули модуля
// Здесь определён целый массив подмодулей
// storage
Cell_Compare #(HBIT) ribbon[_R_SZ] ( clk, hold, is_input, in_prev, in_next, out );
Рассмотрим подробнее подстановку одного модуля в другой
Cell_Compare — тип модуля
#(HBIT) — установка числовых параметров
ribbon — имя экземпляра
[_R_SZ] — это массив, указываем количество
( clk, hold, is_input, — общие сигналы для всех
in_prev, in_next, out ); — специфические сигналы для каждого элемента массива.
Далее generate — полезная конструкция, которая позволяет
применять циклы и т.д. при описании комбинационных схем.
// Соединяем некоторые точки схемы
generate
genvar i,j;
for (i=0; i<_R_SZ-1; i=i+1)
begin : block_name01
assign in_prev[i+1]= out[i];
assign in_next[i]= out[i+1];
end
assign in_prev[0]= data_in;
assign data_out= out[0];
assign in_next[_R_SZ-1]= 0;
endgenerate
endmodule
Теперь модуль сортировочной ячейки.
module Cell_Compare ( clk, hold, is_input, in_prev, in_next, out );
parameter HBIT= 15;
input clk;
input hold;
input is_input;
input [HBIT:0] in_prev;
input [HBIT:0] in_next;
Здесь начинается собственно логика сортировки. Каждая ячейка хранит два числа, одно меньше другого. Каждый такт (если не hold) ячейка сравнивает число, пришедшее от соседа со своим «чемпионом». Чемпион — максимальное число при записи и минимальное при чтении. Проигравший покинет ячейку на следующем такте. В результате, данные движутся по цепочке сначала в одном направлении, потом в другом. Количество чисел, помещающихся в устройстве равно удвоенному количеству ячеек.
Вернёмся к исходному коду. Здесь при описании выхода применён селектор, (скомпилируется в мультиплексор). is_input определяет, читаем мы данные или пишем, от него зависит, в каком направлении движутся данные по цепочке.
output [HBIT:0] out= is_input ? lower : higher;
// Хранилище. Это все регистры, что есть в сортировщике
bit [HBIT:0] higher;
bit [HBIT:0] lower;
// Здесь определяется, что будет в хранилище на следующем такте.
// В зависимости от направления движения данных, это будет
// либо higher и in_prev (lower выталкивается к хвосту),
// либо lower и in_next (higher выталкивается к голове)
wire [HBIT:0] cand_h= is_input ? higher : lower;
wire [HBIT:0] cand_l= is_input ? in_prev : in_next;
// Далее описывается синхронная логика.
// В отличие от комбинационной схемы, от времени не зависещей,
// в регистры можно писать только в определённые моменты.
always@(posedge clk )
if (~hold)
begin
// Здесь мы наконец сравниваем два числа-кандидата.
higher <= ( cand_h >= cand_l ) ? cand_h : cand_l;
lower <= ( cand_h >= cand_l ) ? cand_l : cand_h;
end
endmodule
Всё.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий