Skip to content

Commit a1608c2

Browse files
committed
Added performance variant of encoder and tb
1 parent 7667454 commit a1608c2

File tree

2 files changed

+234
-0
lines changed

2 files changed

+234
-0
lines changed

round_robin_performance_enc.sv

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//------------------------------------------------------------------------------
2+
// round_robin_performance_enc.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO -------------------------------------------------------------------------
7+
// VErsion of round robin combinational encoder to select only one bit from
8+
// the input bus. Feature of this particular version is a performance boost
9+
// motivated by skipping inactive inputs while performing round_robin.
10+
//
11+
// In contrast to priority encoder, every input bit (on average) has equal
12+
// chance to get to the output when all inputs are equally probable
13+
//
14+
// See also round_robin_enc.sv
15+
// See also priority_enc.sv
16+
//
17+
18+
19+
/* --- INSTANTIATION TEMPLATE BEGIN ---
20+
21+
round_robin_performance_enc #(
22+
.WIDTH( 32 )
23+
) RE1 (
24+
.clk( clk ),
25+
.nrst( nrst ),
26+
.id( ),
27+
.od_valid( ),
28+
.od_filt( ),
29+
.od_bin( )
30+
);
31+
32+
--- INSTANTIATION TEMPLATE END ---*/
33+
34+
35+
module round_robin_performance_enc #( parameter
36+
WIDTH = 32,
37+
WIDTH_W = $clog2(WIDTH)
38+
)(
39+
input clk, // clock
40+
input nrst, // inversed reset, synchronous
41+
42+
input [WIDTH-1:0] id, // input data bus
43+
output od_valid, // output valid (some bits are active)
44+
output logic [WIDTH-1:0] od_filt, // filtered data (only one priority bit active)
45+
output logic [WIDTH_W-1:0] od_bin // priority bit binary index
46+
);
47+
48+
49+
// current bit selector
50+
logic [WIDTH_W-1:0] priority_bit = '0;
51+
52+
// prepare double width buffer with LSB bits masked out
53+
logic [2*WIDTH-1:0] mask;
54+
logic [2*WIDTH-1:0] id_buf;
55+
always_comb begin
56+
integer i;
57+
for ( i=0; i<2*WIDTH; i++ ) begin
58+
if( i>priority_bit[WIDTH_W-1:0] ) begin
59+
mask[i] = 1'b1;
60+
end else begin
61+
mask[i] = 1'b0;
62+
end
63+
end
64+
id_buf[2*WIDTH-1:0] = {2{id[WIDTH-1:0]}} & mask[2*WIDTH-1:0];
65+
end
66+
67+
logic [2*WIDTH-1:0] id_buf_filt;
68+
leave_one_hot #(
69+
.WIDTH( 2*WIDTH )
70+
) one_hot_b (
71+
.in( id_buf[2*WIDTH-1:0] ),
72+
.out( id_buf_filt[2*WIDTH-1:0] )
73+
);
74+
75+
logic [(WIDTH_W+1)-1:0] id_buf_bin; // one more bit to decode double width input
76+
77+
logic err_no_hot;
78+
assign od_valid = ~err_no_hot;
79+
80+
pos2bin #(
81+
.BIN_WIDTH( (WIDTH_W+1) )
82+
) pos2bin_b (
83+
.pos( id_buf_filt[2*WIDTH-1:0] ),
84+
.bin( id_buf_bin[(WIDTH_W+1)-1:0] ),
85+
86+
.err_no_hot( err_no_hot ),
87+
.err_multi_hot( )
88+
);
89+
90+
always_comb begin
91+
if( od_valid ) begin
92+
od_bin[WIDTH_W-1:0] = id_buf_bin[(WIDTH_W+1)-1:0] % WIDTH;
93+
od_filt[WIDTH-1:0] = 1'b1 << od_bin[WIDTH_W-1:0];
94+
end else begin
95+
od_bin[WIDTH_W-1:0] = '0;
96+
od_filt[WIDTH-1:0] = '0;
97+
end
98+
end
99+
100+
// latching current
101+
always_ff @(posedge clk) begin
102+
if( ~nrst ) begin
103+
priority_bit[WIDTH_W-1:0] <= '0;
104+
end else begin
105+
if( od_valid ) begin
106+
priority_bit[WIDTH_W-1:0] <= od_bin[WIDTH_W-1:0];
107+
end else begin
108+
// nop,
109+
end // if
110+
end // if nrst
111+
end
112+
113+
endmodule

round_robin_performance_enc_tb.sv

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//------------------------------------------------------------------------------
2+
// round_robin_performance_enc_tb.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
// testbench for round_robin_performance_enc.sv module
8+
//
9+
10+
`timescale 1ns / 1ps
11+
12+
module round_robin_performance_enc_tb();
13+
14+
logic clk200;
15+
initial begin
16+
#0 clk200 = 1'b0;
17+
forever
18+
#2.5 clk200 = ~clk200;
19+
end
20+
21+
// external device "asynchronous" clock
22+
logic clk33a;
23+
initial begin
24+
#0 clk33a = 1'b0;
25+
forever
26+
#7 clk33a = ~clk33a;
27+
end
28+
29+
logic clk33;
30+
//assign clk33 = clk33a;
31+
always @(*) begin
32+
clk33 = #($urandom_range(0, 2000)*10ps) clk33a;
33+
end
34+
35+
logic rst;
36+
initial begin
37+
#0 rst = 1'b0;
38+
#10.2 rst = 1'b1;
39+
#5 rst = 1'b0;
40+
//#10000;
41+
forever begin
42+
#9985 rst = ~rst;
43+
#5 rst = ~rst;
44+
end
45+
end
46+
47+
logic nrst;
48+
assign nrst = ~rst;
49+
50+
logic rst_once;
51+
initial begin
52+
#0 rst_once = 1'b0;
53+
#10.2 rst_once = 1'b1;
54+
#5 rst_once = 1'b0;
55+
end
56+
57+
logic nrst_once;
58+
assign nrst_once = ~rst_once;
59+
60+
logic [31:0] DerivedClocks;
61+
clk_divider #(
62+
.WIDTH( 32 )
63+
) cd1 (
64+
.clk( clk200 ),
65+
.nrst( nrst_once ),
66+
.ena( 1'b1 ),
67+
.out( DerivedClocks[31:0] )
68+
);
69+
70+
logic [31:0] E_DerivedClocks;
71+
edge_detect ed1[31:0] (
72+
.clk( {32{clk200}} ),
73+
.nrst( {32{nrst_once}} ),
74+
.in( DerivedClocks[31:0] ),
75+
.rising( E_DerivedClocks[31:0] ),
76+
.falling( ),
77+
.both( )
78+
);
79+
80+
logic [15:0] RandomNumber1;
81+
c_rand rng1 (
82+
.clk(clk200),
83+
.rst(rst_once),
84+
.reseed(1'b0),
85+
.seed_val(DerivedClocks[31:0]),
86+
.out( RandomNumber1[15:0] )
87+
);
88+
89+
logic start;
90+
initial begin
91+
#0 start = 1'b0;
92+
#100 start = 1'b1;
93+
#20 start = 1'b0;
94+
end
95+
96+
// Module under test ==========================================================
97+
98+
`define WIDTH_W 3
99+
`define WIDTH (2**`WIDTH_W)
100+
101+
logic [`WIDTH-1:0] pos;
102+
bin2pos #(
103+
.BIN_WIDTH( `WIDTH_W )
104+
) BP1 (
105+
.bin( RandomNumber1[`WIDTH_W-1:0] ),
106+
.pos( pos[`WIDTH-1:0] )
107+
);
108+
109+
round_robin_performance_enc #(
110+
.WIDTH( `WIDTH )
111+
) RE1 (
112+
.clk( clk200 ),
113+
.nrst( nrst_once ),
114+
.id( RandomNumber1[`WIDTH-1:0] ), //pos[`WIDTH-1:0] ),
115+
.od_valid( ),
116+
.od_filt( ),
117+
.od_bin( )
118+
);
119+
120+
121+
endmodule

0 commit comments

Comments
 (0)