Перейти к содержанию
    

Параметризированный Priority Encoder

Господа, кто может подсказать, как создать параметризированный Priority Encoder в Vierilog (2001)?

 

 

 

Необходимо что то вроде

 

 

 

  

module PriEncoder #(parameter INP_WIDTH=32, parameter OUT_WIDTH = 5)

( input [INP_WIDTH-1:0] input_lines,

  output [OUT_WIDTH-1:0] hit_line_index,

  output hit_line);

 

 

 

Думаю, что надо копать в сторону for/while циклов, но не очень понятно, как их отработают синтезаторы :(

 

 

 

Нужно для XST / ISE 8.2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думаю, что надо копать в сторону for/while циклов, но не очень понятно, как их отработают синтезаторы :(

Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод.
Это понятно, непонятно что делать если ни один сигнал не совпал - default к циклу не присобачишь :unsure:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это понятно, непонятно что делать если ни один сигнал не совпал - default к циклу не присобачишь :unsure:

 

 

ну думаю что эту ситуацию нужно обработать отдельно %)))

вот пример. искусства ради экспериментировал с возможностями синтеза с систем верилога для round-robin арбитра (по сути приоритетный арбитр с циклически изменяемым приоритетом).

 

module rrarb_2(request, grant, reset, clk);

parameter N = 2;
parameter Nlog2 = 1;

input logic [N-1:0] request;
output logic [N-1:0] grant;

input reset;
input clk;

logic [Nlog2-1:0]     last_winner;
logic [N-1:0]       next_grant;

typedef logic [Nlog2-1:0] arb_t; 
typedef logic [N-1:0] m_t; 

always_ff @ (posedge clk) begin
    if (reset)                 last_winner <= '0; 
    else if (request != 0)    last_winner <= get_winner(request);
end 

always_ff @ (posedge clk) begin
    grant <= '0;
    if (request != 0) grant[get_winner(request)] <= 1'b1;
end 

function automatic logic [Nlog2-1:0] get_winner (input logic [N-1:0] request); 
    int i; 
    logic [Nlog2-1:0] curr_winner; 
    //
    curr_winner = last_winner; 
    for (i = 0; i < N; i++) 
    begin
        curr_winner = curr_winner + 1'b1;
        if (curr_winner == N) curr_winner = 0;
        if (request [curr_winner] != 0) return curr_winner;
    end 
    return curr_winner;
endfunction 
    
endmodule

 

PS. Кста результат синтеза, по ресурсу близок к оптимальному, если расписать такой арбитр без циклов ручками

 

 

Удачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод.
Попробовал, почти получилось:

 

  

module p_enc #(parameter INP_WIDTH=8, parameter OUT_WIDTH=3)
( 
  input      [INP_WIDTH-1 :0] inputs,      // Inputs (index 0 has high priority)
  output reg [OUT_WIDTH-1:0]  hit_index,   // Index of input hit
  output reg                  hit          // 1 if any input hit
);

reg [OUT_WIDTH-1:0] cnt;
reg [OUT_WIDTH-1:0] hit_index_int;
reg hit_int;

always @(inputs)
begin 
hit_index_int = 0;
hit_int = 0;
for(cnt=0;cnt<INP_WIDTH;cnt=cnt+1)
  begin
   if (!hit_int && inputs[cnt])
    begin
     hit_int = 1'b1;
     hit_index_int = cnt;
    end
  end
hit_index = hit_index_int;
hit = hit_int;
end

endmodule

 

XST сделал длинную 'кишку' из логики, но как 'priority encoder' он это не опознал :( Т.е. его специальные методы для синтеза энкодеров работать не будут (а есть ли они вообще?)

 

 

 

PS. 2 des00: спасибо за round-robin арбитр, пригодится :) Кстати, чем синтезировали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

пример Priority Encoder рассмотрен в xst.pdf

Приоритетное мультиплексирование легко ложится на цикл for

PriEncoder_a.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал, почти получилось:

 

XST сделал длинную 'кишку' из логики, но как 'priority encoder' он это не опознал :( Т.е. его специальные методы для синтеза энкодеров работать не будут (а есть ли они вообще?)

 

я бы все же сделал по другому :

 

module p_enc 
  #(parameter INP_WIDTH = 8, 
    parameter OUT_WIDTH = 3
   )
(
  input      [INP_WIDTH-1 :0] inputs,      // Inputs (index 0 has high priority)
  output reg [OUT_WIDTH-1:0]  hit_index,   // Index of input hit
  output reg                  hit          // 1 if any input hit
);

  
  assign hit = (inputs != 0); 
  
  assign hit_index = SearchIdx(inputs); 


  function automatic bit [OUT_WIDTH-1:0] SearchIdx (input bit [INP_WIDTH-1:0] inputs);
    integer i; 
  
    for (i = 0; i < INP_WIDTH; i++) begin     
      if (inputs[i]) 
        return i[OUT_WIDTH-1:0];
    end 
  
    return 0;
  
  endfunction

endmodule

 

 

Так будет и понятнее ИМХО.

 

Как ква он распознает это незнаю, результат 9 LC.

 

спасибо за round-robin арбитр, пригодится :) Кстати, чем синтезировали?

 

да незачто, синтезил квартусом, результат отличался на 1-2 LC (для арбитров на 2, 4, 8). Арбитры не кратности 2^x лучше не делать, жрет ресурса больше.

 

Удачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TO des00

 

  input      [INP_WIDTH-1 :0] inputs,      // Inputs (index 0 has high priority)

      for (i = 0; i < INP_WIDTH; i++) begin     
      if (inputs[i]) 
        return i[OUT_WIDTH-1:0];
    end

 

В квартусе действительно получается в систем верилоге приоритетность с младшего разряда.

Но ведь должно то быть по идее

for (i = INP_WIDTH-1; i >= 0; i--) begin

Получается, что в квартусе верилог и систем верилог по разному приоритетность понимают?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но ведь должно то быть по идее

for (i = INP_WIDTH-1; i >= 0; i--) begin

Получается, что в квартусе верилог и систем верилог по разному приоритетность понимают?

 

почему ? то что вы указали имеет обратный приоритет. Т.е. начинаем просматривать со старшего бита inputs[iNP_WIDTH-1] до младшего. Выходим на первом единичном бите.

 

В моем примере начинаем забег по вектору с бита №0. и так же выходим из забега на первом бите равном единице, сохраняя его индекс.

 

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

почему ? то что вы указали имеет обратный приоритет. Т.е. начинаем просматривать со старшего бита inputs[iNP_WIDTH-1] до младшего. Выходим на первом единичном бите.

 

В моем примере начинаем забег по вектору с бита №0. и так же выходим из забега на первом бите равном единице, сохраняя его индекс.

 

Удачи!

 

так в том то и дело, что не выходим мы из забега на первом 1 бите.

Мы весь цикл пробегаем. И выходим с последней 1.

Посмотрите мой пример на верилоге. Все в точности до наоборот по сравнению с Вами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я бы все же сделал по другому :

 

module p_enc 
  #(parameter INP_WIDTH = 8, 
    parameter OUT_WIDTH = 3
   )
(
  input      [INP_WIDTH-1 :0] inputs,      // Inputs (index 0 has high priority)
  output reg [OUT_WIDTH-1:0]  hit_index,   // Index of input hit
  output reg                  hit          // 1 if any input hit
);

  
  assign hit = (inputs != 0); 
  
  assign hit_index = SearchIdx(inputs); 


  function automatic bit [OUT_WIDTH-1:0] SearchIdx (input bit [INP_WIDTH-1:0] inputs);
    integer i; 
  
    for (i = 0; i < INP_WIDTH; i++) begin     
      if (inputs[i]) 
        return i[OUT_WIDTH-1:0];
    end 
  
    return 0;
  
  endfunction

endmodule

 

Так будет и понятнее ИМХО.

Попробовал, увы return Verilog не понимает :(

 

 

 

Простой цикл (без дополнительной проверки на сработавший hit) понимает, получилась очень широкая структура (по отдельному логическому блоку на каждый бит выхода), как ни странно она заняла почти в 2 раза меньше ресурсов и стала слегка быстрее, на чем я пожалуй и остановлюсь :beer:

 

 

 

 

always @(inputs)
begin 
hit_index_int = 0;
for(cnt=0;cnt<INP_WIDTH;cnt=cnt+1)
   if (inputs[cnt]) hit_index_int = cnt;
hit_index = hit_index_int;
hit = (inputs!=0);
end

 

Приоритеты правда изменились на противоположные, но для моего случая это не существенно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так в том то и дело, что не выходим мы из забега на первом 1 бите.

Мы весь цикл пробегаем. И выходим с последней 1.

Посмотрите мой пример на верилоге. Все в точности до наоборот по сравнению с Вами.

 

кто сказал что не выходим ? как только находим первую единицу следует return. Который прекращает функционирование цикла и присваивает выходному значению функции номер первого единичного бита.

если все биты в нуле то вернется ноль.

 

 

2 XVR

 

return появился только в систем верилоге, ква нормально есть сие (в отличие от оператора break у меня 7.2sp1 ругнулся на него:()

 

симплифай да не понимает, у него с этим проблемы. но можно пойдти от противного и изменить цикл на while. так будет еще прозрачнее. (do while ква тоже не поддерживает :()

 

 

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...