From 76674549c37883b30c6863eda21e71adeecd75e0 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Sat, 25 Dec 2021 22:53:30 +0300 Subject: [PATCH] Added teo types of encoders --- priority_enc.sv | 69 +++++++++++++++++++++++++++++++++++++++++ round_robin_enc.sv | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100755 priority_enc.sv create mode 100755 round_robin_enc.sv diff --git a/priority_enc.sv b/priority_enc.sv new file mode 100755 index 0000000..fd3a1f6 --- /dev/null +++ b/priority_enc.sv @@ -0,0 +1,69 @@ +//------------------------------------------------------------------------------ +// priority_enc.sv +// Konstantin Pavlov, pavlovconst@gmail.com +//------------------------------------------------------------------------------ + +// INFO ------------------------------------------------------------------------- +// Completely combinational priority_encoder +// +// See also round_robin_enc.sv +// See also round_robin_performance_enc.sv +// + +/* --- INSTANTIATION TEMPLATE BEGIN --- + +priority_enc #( + .WIDTH( 32 ) // WIDTH must be >=2 +) PE1 ( + .id( ), + .od_valid( ), + .od_filt( ), + .od_bin( ) +); + +--- INSTANTIATION TEMPLATE END ---*/ + + +module priority_enc #( parameter + WIDTH = 32, + WIDTH_W = $clog2(WIDTH) +)( + input [WIDTH-1:0] id, // input data bus + + output od_valid, // output valid (some bits are active) + output [WIDTH-1:0] od_filt, // filtered data (only one priority bit active) + output [WIDTH_W-1:0] od_bin // priority bit binary index +); + + +// reversed id[] data +// conventional operation of priority encoder is when MSB bits have a priority +logic [WIDTH-1:0] id_r; +reverse_vector #( + .WIDTH( WIDTH ) // WIDTH must be >=2 +) reverse_b ( + .in( id[WIDTH-1:0] ), + .out( id_r[WIDTH-1:0] ) +); + +leave_one_hot #( + .WIDTH( WIDTH ) +) one_hot_b ( + .in( id_r[WIDTH-1:0] ), + .out( od_filt[WIDTH-1:0] ) +); + +logic err_no_hot; +assign od_valid = ~err_no_hot; + +pos2bin #( + .BIN_WIDTH( WIDTH_W ) +) pos2bin_b ( + .pos( od_filt[WIDTH-1:0] ), + .bin( od_bin[WIDTH_W-1:0] ), + + .err_no_hot( err_no_hot ), + .err_multi_hot( ) +); + +endmodule diff --git a/round_robin_enc.sv b/round_robin_enc.sv new file mode 100755 index 0000000..b102193 --- /dev/null +++ b/round_robin_enc.sv @@ -0,0 +1,76 @@ +//------------------------------------------------------------------------------ +// round_robin_enc.sv +// Konstantin Pavlov, pavlovconst@gmail.com +//------------------------------------------------------------------------------ + +// INFO ------------------------------------------------------------------------- +// Round robin combinational encoder to select only one bit from the input bus. +// In contrast to priority encoder, it features cyclically changing priority +// pointer inside, so every input bit (on aaverage) has equal chance +// to get to the output +// +// This module is meant to be as simple as possible. It is possible to make +// more efficient, but complicated circuit +// +// See also priority_enc.sv +// See also round_robin_performance_enc.sv +// + + +/* --- INSTANTIATION TEMPLATE BEGIN --- + +round_robin_enc #( + .WIDTH( 32 ) +) RE1 ( + .clk( clk ), + .nrst( nrst ), + .id( ), + .od_valid( ), + .od_filt( ), + .od_bin( ) +); + +--- INSTANTIATION TEMPLATE END ---*/ + + +module round_robin_enc #( parameter + WIDTH = 32, + WIDTH_W = $clog2(WIDTH) +)( + input clk, // clock + input nrst, // inversed reset, synchronous + + input [WIDTH-1:0] id, // input data bus + output logic od_valid, // output valid (some bits are active) + output logic [WIDTH-1:0] od_filt, // filtered data (only one priority bit active) + output logic [WIDTH_W-1:0] od_bin // priority bit binary index +); + + +// current bit selector +logic [WIDTH_W-1:0] priority_bit = '0; +always_ff @(posedge clk) begin + if( ~nrst ) begin + priority_bit[WIDTH_W-1:0] <= '0; + end else begin + if( priority_bit[WIDTH_W-1:0] == WIDTH-1 ) begin + priority_bit[WIDTH_W-1:0] <= '0; + end else begin + priority_bit[WIDTH_W-1:0] <= priority_bit[WIDTH_W-1:0] + 1'b1; + end // if + end // if nrst +end + +always_comb begin + if( id[priority_bit[WIDTH_W-1:0]] ) begin + od_valid = id[priority_bit[WIDTH_W-1:0]]; + od_filt[WIDTH-1:0] = 1'b1 << priority_bit[WIDTH_W-1:0]; + od_bin[WIDTH_W-1:0] = priority_bit[WIDTH_W-1:0]; + end else begin + od_valid = 1'b0; + od_filt[WIDTH-1:0] = '0; + od_bin[WIDTH_W-1:0] = '0; + end +end + +endmodule