Skip to content

Commit 4f4026e

Browse files
authored
Merge pull request #2451 from taichi-ishitani/add_select_distribute_functions
Add `select_*` and `dispatch_*` functions
2 parents 5198dbf + 223443a commit 4f4026e

3 files changed

Lines changed: 158 additions & 98 deletions

File tree

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,49 @@
1-
import selector_pkg::*;
1+
pub function dispatch_binary::<N: p32, T: type,> (
2+
sel : input logic<selector_pkg::calc_binary_select_width(N)>,
3+
data : input T ,
4+
default_data: input T ,
5+
) -> T<N> {
6+
var result: T<N>;
7+
8+
for i: u32 in 0..N {
9+
result[i] = default_data;
10+
}
11+
result[sel] = data;
12+
13+
return result;
14+
}
15+
16+
pub function dispatch_vector::<N: p32, T: type,> (
17+
sel : input logic<N>,
18+
data : input T ,
19+
default_data: input T ,
20+
) -> T<N> {
21+
var result: T<N>;
22+
23+
for i: u32 in 0..N {
24+
if sel[i] {
25+
result[i] = data;
26+
} else {
27+
result[i] = default_data;
28+
}
29+
}
30+
31+
return result;
32+
}
33+
34+
pub function dispatch::<KIND: selector_pkg::selector_kind, N: p32, T: type,> (
35+
sel : input logic<selector_pkg::calc_select_width(N, KIND)>,
36+
data : input T ,
37+
default_data: input T ,
38+
) -> T<N> {
39+
const BINARY_SEL_WIDTH: u32 = selector_pkg::calc_binary_select_width(N);
40+
41+
if KIND == selector_pkg::selector_kind::BINARY {
42+
return dispatch_binary::<N, T>(sel as BINARY_SEL_WIDTH, data, default_data);
43+
} else {
44+
return dispatch_vector::<N, T>(sel as N, data, default_data);
45+
}
46+
}
247

348
pub module demux #(
449
param WIDTH : u32 = 1 ,
@@ -12,17 +57,9 @@ pub module demux #(
1257
i_data : input DATA_TYPE ,
1358
o_data : output DATA_TYPE<ENTRIES> ,
1459
) {
15-
if KIND == selector_kind::BINARY :g_demux {
16-
always_comb {
17-
for i: u32 in 0..ENTRIES {
18-
o_data[i] = if i_select == i as SELECT_WIDTH ? i_data : DEFUALT_DATA;
19-
}
20-
}
21-
} else {
22-
always_comb {
23-
for i: u32 in 0..ENTRIES {
24-
o_data[i] = if i_select[i] ? i_data : DEFUALT_DATA;
25-
}
26-
}
60+
import selector_pkg::*;
61+
62+
always_comb {
63+
o_data = dispatch::<KIND, ENTRIES, DATA_TYPE>(i_select, i_data, DEFUALT_DATA);
2764
}
2865
}
Lines changed: 107 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,122 @@
1-
import selector_pkg::*;
1+
pub function select_binary::<N: p32, T: type,> (
2+
sel : input logic<selector_pkg::calc_binary_select_width(N)>,
3+
data: input T <N> ,
4+
) -> T {
5+
return data[sel];
6+
}
27

3-
pub module mux #(
4-
param WIDTH : u32 = 1 ,
5-
param DATA_TYPE : type = logic<WIDTH> ,
6-
param ENTRIES : u32 = 2 ,
7-
param KIND : selector_kind = selector_kind::BINARY ,
8-
const SELECT_WIDTH: u32 = calc_select_width(ENTRIES, KIND),
9-
) (
10-
i_select: input logic <SELECT_WIDTH>,
11-
i_data : input DATA_TYPE<ENTRIES> ,
12-
o_data : output DATA_TYPE ,
13-
) {
14-
const BINARY_SELECT_WIDTH: u32 = calc_binary_select_width(ENTRIES);
15-
const MAX_DEPTH : u32 = $clog2(ENTRIES);
16-
17-
function binary_mux (
18-
select: input logic <BINARY_SELECT_WIDTH>,
19-
data : input DATA_TYPE<ENTRIES> ,
20-
) -> DATA_TYPE {
21-
return data[select];
22-
}
8+
pub function select_vector::<N: p32, T: type,> (
9+
sel : input logic<N>,
10+
data: input T <N>,
11+
) -> T {
12+
const DEPTH: u32 = $clog2(N);
13+
14+
var current_n: u32 ;
15+
var current_s: logic<N>;
16+
var current_d: T <N>;
17+
var next_n : u32 ;
18+
var next_s : logic<N>;
19+
var next_d : T <N>;
2320

24-
function vector_mux (
25-
select: input logic <ENTRIES>,
26-
data : input DATA_TYPE<ENTRIES>,
27-
) -> DATA_TYPE {
28-
var current_n : u32 ;
29-
var current_select: logic <ENTRIES>;
30-
var current_data : DATA_TYPE<ENTRIES>;
31-
var next_n : u32 ;
32-
var next_select : logic <ENTRIES>;
33-
var next_data : DATA_TYPE<ENTRIES>;
34-
35-
next_n = ENTRIES;
36-
next_select = select;
37-
next_data = data;
38-
for _i: u32 in 0..MAX_DEPTH {
39-
current_n = next_n;
40-
current_select = next_select;
41-
current_data = next_data;
42-
43-
next_n = (current_n / 2) + (current_n % 2);
44-
for j: u32 in 0..next_n {
45-
let select_even: logic = current_select[2 * j + 0] || ((j + 1) == next_n && (current_n % 2) == 1);
46-
if select_even {
47-
next_select[j] = current_select[2 * j + 0];
48-
next_data[j] = current_data[2 * j + 0];
49-
} else {
50-
next_select[j] = current_select[2 * j + 1];
51-
next_data[j] = current_data[2 * j + 1];
52-
}
21+
next_n = N;
22+
next_s = sel;
23+
next_d = data;
24+
for _i: u32 in 0..DEPTH {
25+
current_n = next_n;
26+
current_s = next_s;
27+
current_d = next_d;
28+
29+
next_n = (current_n / 2) + (current_n % 2);
30+
for j: u32 in 0..next_n {
31+
var select_even: logic;
32+
33+
if (j + 1) == next_n && (current_n % 2) == 1 {
34+
select_even = true;
35+
} else {
36+
select_even = current_s[2 * j + 0];
5337
}
54-
}
5538

56-
return next_data[0];
39+
if select_even {
40+
next_s[j] = current_s[2 * j + 0];
41+
next_d[j] = current_d[2 * j + 0];
42+
} else {
43+
next_s[j] = current_s[2 * j + 1];
44+
next_d[j] = current_d[2 * j + 1];
45+
}
46+
}
5747
}
5848

59-
function onehot_mux (
60-
select: input logic <ENTRIES>,
61-
data : input DATA_TYPE<ENTRIES>,
62-
) -> DATA_TYPE {
63-
var current_n : u32 ;
64-
var current_data: DATA_TYPE<ENTRIES>;
65-
var next_n : u32 ;
66-
var next_data : DATA_TYPE<ENTRIES>;
67-
68-
next_n = ENTRIES;
69-
for i: u32 in 0..ENTRIES {
70-
next_data[i] = {select[i] repeat $bits(DATA_TYPE)} & data[i];
49+
return next_d[0];
50+
}
51+
52+
pub function select_onehot::<N: p32, T: type,> (
53+
sel : input logic<N>,
54+
data: input T <N>,
55+
) -> T {
56+
const DEPTH: u32 = $clog2(N);
57+
58+
var current_n: u32 ;
59+
var current_d: T <N>;
60+
var next_n : u32 ;
61+
var next_d : T <N>;
62+
63+
next_n = N;
64+
for i: u32 in 0..N {
65+
if sel[i] {
66+
next_d[i] = data[i];
67+
} else {
68+
next_d[i] = 0 as T;
7169
}
70+
}
71+
72+
for _i: u32 in 0..DEPTH {
73+
current_n = next_n;
74+
current_d = next_d;
7275

73-
for _i: u32 in 0..MAX_DEPTH {
74-
current_n = next_n;
75-
current_data = next_data;
76-
77-
next_n = (current_n / 2) + (current_n % 2);
78-
for j: u32 in 0..current_n {
79-
if (j + 1) == next_n && ((current_n % 2) == 1) {
80-
next_data[j] = current_data[2 * j + 0];
81-
} else {
82-
next_data[j] = current_data[2 * j + 0] | current_data[2 * j + 1];
83-
}
76+
next_n = (current_n / 2) + (current_n % 2);
77+
for j: u32 in 0..next_n {
78+
if (j + 1) == next_n && (current_n % 2) == 1 {
79+
next_d[j] = current_d[2 * j + 0];
80+
} else {
81+
next_d[j] = (current_d[2 * j + 0] | current_d[2 * j + 1]) as T;
8482
}
8583
}
86-
87-
return next_data[0];
8884
}
8985

90-
if ENTRIES <= 1 :g_mux {
91-
assign o_data = i_data[0];
92-
} else if KIND == selector_kind::BINARY {
93-
assign o_data = binary_mux(i_select, i_data);
94-
} else if KIND == selector_kind::VECTOR {
95-
assign o_data = vector_mux(i_select, i_data);
86+
return next_d[0];
87+
}
88+
89+
pub function select::<KIND: selector_pkg::selector_kind, N: p32, T: type,> (
90+
sel : input logic<selector_pkg::calc_select_width(N, KIND)>,
91+
data: input T <N> ,
92+
) -> T {
93+
const BINARY_SEL_WIDTH: u32 = selector_pkg::calc_binary_select_width(N);
94+
95+
if N == 1 {
96+
return data[0];
97+
} else if KIND == selector_pkg::selector_kind::BINARY {
98+
return select_binary::<N, T>(sel as BINARY_SEL_WIDTH, data);
99+
} else if KIND == selector_pkg::selector_kind::VECTOR {
100+
return select_vector::<N, T>(sel as N, data);
96101
} else {
97-
assign o_data = onehot_mux(i_select, i_data);
102+
return select_onehot::<N, T>(sel as N, data);
103+
}
104+
}
105+
106+
pub module mux #(
107+
param WIDTH : u32 = 1 ,
108+
param DATA_TYPE : type = logic<WIDTH> ,
109+
param ENTRIES : u32 = 2 ,
110+
param KIND : selector_kind = selector_kind::BINARY ,
111+
const SELECT_WIDTH: u32 = calc_select_width(ENTRIES, KIND),
112+
) (
113+
i_select: input logic <SELECT_WIDTH>,
114+
i_data : input DATA_TYPE<ENTRIES> ,
115+
o_data : output DATA_TYPE ,
116+
) {
117+
import selector_pkg::*;
118+
119+
always_comb {
120+
o_data = select::<KIND, ENTRIES, DATA_TYPE>(i_select, i_data);
98121
}
99122
}

crates/std/veryl/src/selector/test_selector.veryl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module test_binary_mux;
5555
endmodule
5656
}}}
5757

58-
#[test(test_binary_vector)]
58+
#[test(test_vector_mux)]
5959
embed (inline) sv{{{
6060
module test_vector_mux;
6161
import std_selector_pkg::*;

0 commit comments

Comments
 (0)