xvr 12 10 января, 2008 Опубликовано 10 января, 2008 · Жалоба Господа, кто может подсказать, как создать параметризированный 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 10 января, 2008 Опубликовано 10 января, 2008 · Жалоба Думаю, что надо копать в сторону for/while циклов, но не очень понятно, как их отработают синтезаторы :( Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 10 января, 2008 Опубликовано 10 января, 2008 · Жалоба Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод. Это понятно, непонятно что делать если ни один сигнал не совпал - default к циклу не присобачишь :unsure: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба Это понятно, непонятно что делать если ни один сигнал не совпал - 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. Кста результат синтеза, по ресурсу близок к оптимальному, если расписать такой арбитр без циклов ручками Удачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба Думаете правильно. Если цикл можно статически развернуть, то принципиальных проблем для синтезатора нет. У вас размерности вполне конечны, т.ч. все должно получиться. Напишите цикл, в котором проверяете входной сигнал на совпадение и значение счетчика при совпадении - на вывод. Попробовал, почти получилось: 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 арбитр, пригодится :) Кстати, чем синтезировали? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба пример Priority Encoder рассмотрен в xst.pdf Приоритетное мультиплексирование легко ложится на цикл for PriEncoder_a.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба Попробовал, почти получилось: 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 лучше не делать, жрет ресурса больше. Удачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба 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 Получается, что в квартусе верилог и систем верилог по разному приоритетность понимают? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба Но ведь должно то быть по идее for (i = INP_WIDTH-1; i >= 0; i--) begin Получается, что в квартусе верилог и систем верилог по разному приоритетность понимают? почему ? то что вы указали имеет обратный приоритет. Т.е. начинаем просматривать со старшего бита inputs[iNP_WIDTH-1] до младшего. Выходим на первом единичном бите. В моем примере начинаем забег по вектору с бита №0. и так же выходим из забега на первом бите равном единице, сохраняя его индекс. Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба почему ? то что вы указали имеет обратный приоритет. Т.е. начинаем просматривать со старшего бита inputs[iNP_WIDTH-1] до младшего. Выходим на первом единичном бите. В моем примере начинаем забег по вектору с бита №0. и так же выходим из забега на первом бите равном единице, сохраняя его индекс. Удачи! так в том то и дело, что не выходим мы из забега на первом 1 бите. Мы весь цикл пробегаем. И выходим с последней 1. Посмотрите мой пример на верилоге. Все в точности до наоборот по сравнению с Вами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 11 января, 2008 Опубликовано 11 января, 2008 · Жалоба я бы все же сделал по другому : 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 Приоритеты правда изменились на противоположные, но для моего случая это не существенно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 14 января, 2008 Опубликовано 14 января, 2008 · Жалоба так в том то и дело, что не выходим мы из забега на первом 1 бите. Мы весь цикл пробегаем. И выходим с последней 1. Посмотрите мой пример на верилоге. Все в точности до наоборот по сравнению с Вами. кто сказал что не выходим ? как только находим первую единицу следует return. Который прекращает функционирование цикла и присваивает выходному значению функции номер первого единичного бита. если все биты в нуле то вернется ноль. 2 XVR return появился только в систем верилоге, ква нормально есть сие (в отличие от оператора break у меня 7.2sp1 ругнулся на него:() симплифай да не понимает, у него с этим проблемы. но можно пойдти от противного и изменить цикл на while. так будет еще прозрачнее. (do while ква тоже не поддерживает :() Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться