Putnik 0 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба теперь примерно тоже что было с мультиплексором с енкодером module encoder_param #( parameter N = 5//любое может быть )( input[N-1:0] in, output logic [N-1:0] out ); genvar i; generate for (i=0;i<N-1;i++) begin:encoder always @(*) if(in == 1 << i) out <= i; else out <= 'z; end endgenerate endmodule в RTL_Viewer кактуса вроде все как я хотел, но в ncverilog всегда Ζ на выходе out сразу скажу что вот такой вариант даже в квартусе не в енкодер синтезится module encoder_param #( parameter N = 5//может быть любое )( input[N-1:0] in, output logic [N-1:0] out ); always_comb for (int i=0;i<N-1;i++) begin if(in == 1 << i) out <= i; else out <= '0; end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jackov 1 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба теперь примерно тоже что было с мультиплексором с енкодером А что такое енкодер? Можно таблицу истинности? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба похоже что нужен one-hot encoder. но тогда вы его "неправильно готовите". уточните пожалуйста входную и выходную разрядность, а также таблицу истинности Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба Приветствую! Ничего удивительного! В обоих Ваших случаях цикл for проходит полный круг от 0 до N-1 и соответственно даже если на каком то значении i и было совпадение с in то на следующем цикле запомненное в out значение затрется. Для неблокирующего присваивания <= будет применено последнее значение которое было присвоено переменной на текущем delta цикле при симуляции. Надо добавить немного специй :) то есть break always_comb begin for (int i=0;i<N-1;i++) begin if(in == (1 << i)) begin out <= i; break; end else out <= '0; end end endmodule а можно и так always_comb begin out <= '0; for (int i=0;i<N-1;i++) begin if(in == (1 << i)) begin out <= i; break; end end endmodule Причем во втором случае если убрать break то будет выдаваться код ПОСЛЕДНЕГО совпадения. Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FatRobot 0 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба Штука эта называется "приоритетный шифратор". Возни с ней несколько побольше, чем с мультиплексором, т.к. в прямом виде, как вы и ваши коллеги приблизительно это описали, количество слоев комбинаторной логики будет равно разрядности входного сигнала. Этот вариант нам не подходит, а подходит нам хороший вариант - двоичный поиск. Такой вот псевдокод, в котором всё вычисляется параллельно, для входной разрядности до 32. с = 0; if( inp ) begin zero_flg = 0; if( !( inp & 'hFFFF0000 )) c = c | ( 1 << 4 ); if( !( inp & 'hFF00FF00 )) c = c | ( 1 << 3 ); if( !( inp & 'hF0F0F0F0 )) c = c | ( 1 << 2 ); if( !( inp & 'hCCCCCCCC )) c = c | ( 1 << 1 ); if( !( inp & 'hAAAAAAAA )) c = c | ( 1 << 0 ); end else begin zero_flg = 1; end В нужный порядок входные биты вы сами переставите и разрядность тоже сами сумеете поменять и даже параметризировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба Приветствую! Упс - "хороший вариант - двоичный поиск" работает только если у нас на входе ГАРАНТИРОВАННО сигнал только в одном бите! А вот приоритетный шифратор - работает при ЛЮБОМ наборе входных бит. Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FatRobot 0 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба То что вы написали if(in == (1 << i)) begin будет работать только при одном бите, как бы это не называлось. А задача с новыми условиями решается количеством слоев ~log2( N ), где N - разрядность входной шины. Простейший вариант - добавить по мультиплексору для каждой if в моем коде. Или вы знание терминологии хотите продемонстрировать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jackov 1 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба теперь примерно тоже что было с мультиплексором с енкодером Есть у меня один шифратор... Под шифратором я понимаю дивайс обратный дешифратору, т.е. при подаче одной единицы на вход, он показывает номер этого входа. Если подано более одной единицы или вообще не подано - на выходе ошибки (Е) будет единица. module coder_ #(parameter N = 4) ( output reg[N-1:0]Y, output reg E, input [(2**N)-1:0]X); reg [(2**N)-1:0]temp; reg [N:0]temp2; reg [N:0]temp3; always @(*) begin: A_ integer i; integer j; E = 0; temp = X; temp2 = 1'b0; //определение ошибки: //-когда Х == 0; //-когда Х == более одной единицы begin: f2_ for(i = 0; i < (2**N); i = i + 1) begin if(X[i]) begin for(j = i+1; j < (2**N); j = j + 1) begin if(X[j]) begin E = 1'd1; disable f2_; end else begin E = 0; end end end else begin E = 0; end end end if(!X) begin E = 1'd1; end //логика шифратора while(temp) begin temp = temp >> 1; temp2 = temp2 + 1'b1; end temp3 = temp2 - 1'b1; Y = temp3[N-1:0]; end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба Приветствую! if(in == (1 << i)) begin Да это совсем не заливная рыба :( ну в смысле не приоритетный шифратор. для приоритетного шифратора должно быть if( in[i] ) begin Успехов! Rob. P.S. Нее - я уже давно отвоевался. Хотя знание правильной терминологии позволяет легче понимать что нужно написать и чего ожидать от написанного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба есть такой синтезируемый модуль. может не самая эффективная и не самая понятная реализация, но все же. корректно работает только если размерность входного вектора является степенью двойки module onehot_prio_enc (vect_in,vect_out); function integer log2; input integer val; begin log2 = 0; while (val > 0) begin val = val >> 1; log2 = log2 + 1; end if (log2 < 2) log2=2; end endfunction function integer exp2; input integer val; begin exp2 = 1 << val; end endfunction parameter VECT_IN=8; parameter VECT_OUT=log2(VECT_IN)-1; // 3 if VECT_IN=8 input [VECT_IN-1:0] vect_in; output [VECT_OUT-1:0] vect_out; // Do priority encoding wire [VECT_IN-1:0] prio; genvar i,j; generate for (i=0;i<VECT_IN;i=i+1) begin : prio_gen wire [VECT_IN-1:0] tmp_prio; for (j=0;j<VECT_IN;j=j+1) begin : prio_tmp_vect assign tmp_prio[j] = (j<i) ? (1'b1) : ((j == i) ? vect_in[j] : ~vect_in[j]); end assign prio[i] = {&tmp_prio}; end endgenerate // initialize encode matrix integer lower[VECT_OUT][VECT_IN]; integer upper[VECT_OUT][VECT_IN]; integer nextlower; integer nextupper; integer ii,jj; initial begin for (ii=0;ii<VECT_OUT;ii=ii+1) begin nextlower=exp2(ii); nextupper=exp2(ii)+exp2(ii)-1; for (jj=0;jj<VECT_IN;jj=jj+1) begin lower[ii][jj] = nextlower; upper[ii][jj] = nextupper; if (jj == nextupper) begin nextlower = nextupper+exp2(ii)+1; nextupper = nextlower+exp2(ii)-1; end end end end // do actual encoding according to matrix generate for (i=0;i<VECT_OUT;i=i+1) begin : encoder_gen reg [VECT_IN-1:0] tmp_code; for (j=0;j<VECT_IN;j=j+1) begin : encoder_gen always @(prio) begin if ((j == lower[i][j]) | ((j > lower[i][j]) & (j < upper[i][j])) | (j == upper[i][j])) tmp_code[j] = prio[j]; else tmp_code[j] = 1'b0; end end assign vect_out[i] = {|tmp_code}; end endgenerate endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Putnik 0 1 мая, 2014 Опубликовано 1 мая, 2014 · Жалоба Всем спасибо за отличные варианты решения, попробовал варианты RobFPGA, krux, Jackov. Работают в NCverilog как мне надо. Спасибо!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться