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

параметризуемый енкодер, verilog

теперь примерно тоже что было с мультиплексором с енкодером

 

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

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


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

теперь примерно тоже что было с мультиплексором с енкодером

А что такое енкодер? Можно таблицу истинности?

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


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

похоже что нужен one-hot encoder.

но тогда вы его "неправильно готовите".

уточните пожалуйста входную и выходную разрядность, а также таблицу истинности

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


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

Приветствую!

 

Ничего удивительного!

В обоих Ваших случаях цикл 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.

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


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

Штука эта называется "приоритетный шифратор". Возни с ней несколько побольше, чем с мультиплексором, т.к. в прямом виде, как вы и ваши коллеги приблизительно это описали, количество слоев комбинаторной логики будет равно разрядности входного сигнала. Этот вариант нам не подходит, а подходит нам хороший вариант - двоичный поиск. Такой вот псевдокод, в котором всё вычисляется параллельно, для входной разрядности до 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

 

В нужный порядок входные биты вы сами переставите и разрядность тоже сами сумеете поменять и даже параметризировать.

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


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

Приветствую!

 

Упс - "хороший вариант - двоичный поиск" работает только если у нас на входе ГАРАНТИРОВАННО сигнал только в одном бите!

 

А вот приоритетный шифратор - работает при ЛЮБОМ наборе входных бит.

 

Успехов! Rob.

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


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

То что вы написали

if(in == (1 << i)) begin

 

будет работать только при одном бите, как бы это не называлось.

 

А задача с новыми условиями решается количеством слоев ~log2( N ), где N - разрядность входной шины. Простейший вариант - добавить по мультиплексору для каждой if в моем коде.

 

Или вы знание терминологии хотите продемонстрировать?

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


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

теперь примерно тоже что было с мультиплексором с енкодером

Есть у меня один шифратор...

Под шифратором я понимаю дивайс обратный дешифратору, т.е. при подаче одной единицы на вход, он показывает номер этого входа.

Если подано более одной единицы или вообще не подано - на выходе ошибки (Е) будет единица.

 

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

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


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

Приветствую!

 

  if(in == (1 << i)) begin

Да это совсем не заливная рыба :( ну в смысле не приоритетный шифратор.

 

для приоритетного шифратора должно быть

 if( in[i] ) begin

 

Успехов! Rob.

 

P.S. Нее - я уже давно отвоевался. Хотя знание правильной терминологии позволяет легче понимать что нужно написать и чего ожидать от написанного.

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


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

есть такой синтезируемый модуль. может не самая эффективная и не самая понятная реализация, но все же.

корректно работает только если размерность входного вектора является степенью двойки

 

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

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


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

Всем спасибо за отличные варианты решения, попробовал варианты RobFPGA, krux, Jackov. Работают в NCverilog как мне надо. Спасибо!!!

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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