Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
c15f2eab
Commit
c15f2eab
authored
Jan 29, 2022
by
Antoine Kaufmann
Browse files
sims/net/menshen: add
parent
3be11ceb
Changes
42
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
7468 additions
and
0 deletions
+7468
-0
sims/net/menshen/rtl/action/crossbar.v
sims/net/menshen/rtl/action/crossbar.v
+260
-0
sims/net/menshen/rtl/depar_do_deparsing.v
sims/net/menshen/rtl/depar_do_deparsing.v
+608
-0
sims/net/menshen/rtl/depar_wait_segs.v
sims/net/menshen/rtl/depar_wait_segs.v
+227
-0
sims/net/menshen/rtl/deparser_top.v
sims/net/menshen/rtl/deparser_top.v
+316
-0
sims/net/menshen/rtl/extract/key_extract.v
sims/net/menshen/rtl/extract/key_extract.v
+174
-0
sims/net/menshen/rtl/extract/key_extract_top.v
sims/net/menshen/rtl/extract/key_extract_top.v
+702
-0
sims/net/menshen/rtl/last_stage.v
sims/net/menshen/rtl/last_stage.v
+329
-0
sims/net/menshen/rtl/lookup/lke_cam_part.v
sims/net/menshen/rtl/lookup/lke_cam_part.v
+710
-0
sims/net/menshen/rtl/lookup/lke_ram_part.v
sims/net/menshen/rtl/lookup/lke_ram_part.v
+631
-0
sims/net/menshen/rtl/lookup/lookup_engine_top.v
sims/net/menshen/rtl/lookup/lookup_engine_top.v
+168
-0
sims/net/menshen/rtl/output_arbiter.v
sims/net/menshen/rtl/output_arbiter.v
+176
-0
sims/net/menshen/rtl/parser_do_parsing.v
sims/net/menshen/rtl/parser_do_parsing.v
+360
-0
sims/net/menshen/rtl/parser_do_parsing_top.v
sims/net/menshen/rtl/parser_do_parsing_top.v
+312
-0
sims/net/menshen/rtl/parser_top.v
sims/net/menshen/rtl/parser_top.v
+626
-0
sims/net/menshen/rtl/parser_wait_segs.v
sims/net/menshen/rtl/parser_wait_segs.v
+105
-0
sims/net/menshen/rtl/pkt_filter.v
sims/net/menshen/rtl/pkt_filter.v
+294
-0
sims/net/menshen/rtl/rmt_wrapper.v
sims/net/menshen/rtl/rmt_wrapper.v
+1028
-0
sims/net/menshen/rtl/stage.v
sims/net/menshen/rtl/stage.v
+257
-0
sims/net/menshen/rtl/sub_deparser.v
sims/net/menshen/rtl/sub_deparser.v
+104
-0
sims/net/menshen/rtl/sub_parser.v
sims/net/menshen/rtl/sub_parser.v
+81
-0
No files found.
sims/net/menshen/rtl/action/crossbar.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
crossbar
#(
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
ACT_LEN
=
25
,
parameter
width_2B
=
16
,
parameter
width_4B
=
32
,
parameter
width_6B
=
48
)
(
input
clk
,
input
rst_n
,
//input from PHV
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_in_valid
,
//input from action
input
[
ACT_LEN
*
25
-
1
:
0
]
action_in
,
input
action_in_valid
,
output
reg
ready_out
,
//output to the ALU
output
reg
alu_in_valid
,
output
reg
[
width_6B
*
8
-
1
:
0
]
alu_in_6B_1
,
output
reg
[
width_6B
*
8
-
1
:
0
]
alu_in_6B_2
,
output
reg
[
width_4B
*
8
-
1
:
0
]
alu_in_4B_1
,
output
reg
[
width_4B
*
8
-
1
:
0
]
alu_in_4B_2
,
output
reg
[
width_4B
*
8
-
1
:
0
]
alu_in_4B_3
,
output
reg
[
width_2B
*
8
-
1
:
0
]
alu_in_2B_1
,
output
reg
[
width_2B
*
8
-
1
:
0
]
alu_in_2B_2
,
output
reg
[
255
:
0
]
phv_remain_data
,
//I have to delay action_in for ALUs for 1 cycle
output
reg
[
ACT_LEN
*
25
-
1
:
0
]
action_out
,
output
reg
action_valid_out
,
input
ready_in
);
/********intermediate variables declared here********/
integer
i
;
wire
[
width_6B
-
1
:
0
]
cont_6B
[
0
:
7
];
wire
[
width_4B
-
1
:
0
]
cont_4B
[
0
:
7
];
wire
[
width_2B
-
1
:
0
]
cont_2B
[
0
:
7
];
wire
[
ACT_LEN
-
1
:
0
]
sub_action
[
24
:
0
];
/********intermediate variables declared here********/
assign
cont_6B
[
7
]
=
phv_in
[
PHV_LEN
-
1
-:
width_6B
];
assign
cont_6B
[
6
]
=
phv_in
[
PHV_LEN
-
1
-
width_6B
-:
width_6B
];
assign
cont_6B
[
5
]
=
phv_in
[
PHV_LEN
-
1
-
2
*
width_6B
-:
width_6B
];
assign
cont_6B
[
4
]
=
phv_in
[
PHV_LEN
-
1
-
3
*
width_6B
-:
width_6B
];
assign
cont_6B
[
3
]
=
phv_in
[
PHV_LEN
-
1
-
4
*
width_6B
-:
width_6B
];
assign
cont_6B
[
2
]
=
phv_in
[
PHV_LEN
-
1
-
5
*
width_6B
-:
width_6B
];
assign
cont_6B
[
1
]
=
phv_in
[
PHV_LEN
-
1
-
6
*
width_6B
-:
width_6B
];
assign
cont_6B
[
0
]
=
phv_in
[
PHV_LEN
-
1
-
7
*
width_6B
-:
width_6B
];
assign
cont_4B
[
7
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-:
width_4B
];
assign
cont_4B
[
6
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
width_4B
-:
width_4B
];
assign
cont_4B
[
5
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
2
*
width_4B
-:
width_4B
];
assign
cont_4B
[
4
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
3
*
width_4B
-:
width_4B
];
assign
cont_4B
[
3
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
4
*
width_4B
-:
width_4B
];
assign
cont_4B
[
2
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
5
*
width_4B
-:
width_4B
];
assign
cont_4B
[
1
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
6
*
width_4B
-:
width_4B
];
assign
cont_4B
[
0
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
7
*
width_4B
-:
width_4B
];
assign
cont_2B
[
7
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-:
width_2B
];
assign
cont_2B
[
6
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
width_2B
-:
width_2B
];
assign
cont_2B
[
5
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
2
*
width_2B
-:
width_2B
];
assign
cont_2B
[
4
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
3
*
width_2B
-:
width_2B
];
assign
cont_2B
[
3
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
4
*
width_2B
-:
width_2B
];
assign
cont_2B
[
2
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
5
*
width_2B
-:
width_2B
];
assign
cont_2B
[
1
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
6
*
width_2B
-:
width_2B
];
assign
cont_2B
[
0
]
=
phv_in
[
PHV_LEN
-
1
-
8
*
width_6B
-
8
*
width_4B
-
7
*
width_2B
-:
width_2B
];
// Tao: get action for each PHV container
assign
sub_action
[
24
]
=
action_in
[
ACT_LEN
*
25
-
1
-:
ACT_LEN
];
// 1st action
assign
sub_action
[
23
]
=
action_in
[
ACT_LEN
*
25
-
1
-
ACT_LEN
-:
ACT_LEN
];
// 2nd action
assign
sub_action
[
22
]
=
action_in
[
ACT_LEN
*
25
-
1
-
2
*
ACT_LEN
-:
ACT_LEN
];
// 3rd action
assign
sub_action
[
21
]
=
action_in
[
ACT_LEN
*
25
-
1
-
3
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
20
]
=
action_in
[
ACT_LEN
*
25
-
1
-
4
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
19
]
=
action_in
[
ACT_LEN
*
25
-
1
-
5
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
18
]
=
action_in
[
ACT_LEN
*
25
-
1
-
6
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
17
]
=
action_in
[
ACT_LEN
*
25
-
1
-
7
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
16
]
=
action_in
[
ACT_LEN
*
25
-
1
-
8
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
15
]
=
action_in
[
ACT_LEN
*
25
-
1
-
9
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
14
]
=
action_in
[
ACT_LEN
*
25
-
1
-
10
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
13
]
=
action_in
[
ACT_LEN
*
25
-
1
-
11
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
12
]
=
action_in
[
ACT_LEN
*
25
-
1
-
12
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
11
]
=
action_in
[
ACT_LEN
*
25
-
1
-
13
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
10
]
=
action_in
[
ACT_LEN
*
25
-
1
-
14
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
9
]
=
action_in
[
ACT_LEN
*
25
-
1
-
15
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
8
]
=
action_in
[
ACT_LEN
*
25
-
1
-
16
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
7
]
=
action_in
[
ACT_LEN
*
25
-
1
-
17
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
6
]
=
action_in
[
ACT_LEN
*
25
-
1
-
18
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
5
]
=
action_in
[
ACT_LEN
*
25
-
1
-
19
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
4
]
=
action_in
[
ACT_LEN
*
25
-
1
-
20
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
3
]
=
action_in
[
ACT_LEN
*
25
-
1
-
21
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
2
]
=
action_in
[
ACT_LEN
*
25
-
1
-
22
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
1
]
=
action_in
[
ACT_LEN
*
25
-
1
-
23
*
ACT_LEN
-:
ACT_LEN
];
assign
sub_action
[
0
]
=
action_in
[
ACT_LEN
*
25
-
1
-
24
*
ACT_LEN
-:
ACT_LEN
];
//assign inputs for ALUs
always
@
(
posedge
clk
)
begin
action_out
<=
action_in
;
action_valid_out
<=
action_in_valid
;
end
localparam
IDLE
=
0
,
PROCESS
=
1
,
HALT
=
2
;
reg
[
2
:
0
]
state
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
// phv_reg <= 1124'b0;
// action_full_reg <= 625'b0;
// phv_valid_reg <= 1'b0;
// action_valid_reg <= 1'b0;
//reset outputs
alu_in_valid
<=
1'b0
;
phv_remain_data
<=
256'b0
;
//reset all the outputs
alu_in_6B_1
<=
384'b0
;
alu_in_6B_2
<=
384'b0
;
alu_in_4B_1
<=
256'b0
;
alu_in_4B_2
<=
256'b0
;
alu_in_4B_3
<=
256'b0
;
alu_in_2B_1
<=
128'b0
;
alu_in_2B_2
<=
128'b0
;
state
<=
IDLE
;
ready_out
<=
1
;
end
else
begin
case
(
state
)
IDLE:
begin
if
(
phv_in_valid
==
1'b1
)
begin
if
(
ready_in
)
begin
alu_in_valid
<=
1'b1
;
end
else
begin
ready_out
<=
0
;
state
<=
HALT
;
end
//assign values one by one (of course need to consider act format)
for
(
i
=
7
;
i
>=
0
;
i
=
i
-
1
)
begin
case
(
sub_action
[
16
+
i
+
1
][
24
:
21
])
//be noted that 2 ops need to be the same width
4'b0001
,
4'b0010
:
begin
alu_in_6B_1
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
cont_6B
[
sub_action
[
16
+
i
+
1
][
18
:
16
]];
alu_in_6B_2
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
cont_6B
[
sub_action
[
16
+
i
+
1
][
13
:
11
]];
end
//extracted from action field (imm)
4'b1001
,
4'b1010
:
begin
alu_in_6B_1
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
cont_6B
[
sub_action
[
16
+
i
+
1
][
18
:
16
]];
alu_in_6B_2
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
{
32'b0
,
sub_action
[
16
+
i
+
1
][
15
:
0
]
}
;
end
// set operation, operand A set to 0, operand B set to imm
4'b1110
:
begin
alu_in_6B_1
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
48'b0
;
alu_in_6B_2
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
{
32'b0
,
sub_action
[
16
+
i
+
1
][
15
:
0
]
}
;
end
//if there is no action to take, output the original value
default:
begin
//alu_1 should be set to the phv value
alu_in_6B_1
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
cont_6B
[
i
];
alu_in_6B_2
[(
i
+
1
)
*
width_6B
-
1
-:
width_6B
]
<=
48'b0
;
end
endcase
end
//4B is a bit of differernt from 2B and 6B
for
(
i
=
7
;
i
>=
0
;
i
=
i
-
1
)
begin
alu_in_4B_3
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
i
];
casez
(
sub_action
[
8
+
i
+
1
][
24
:
21
])
//be noted that 2 ops need to be the same width
4'b0001
,
4'b0010
:
begin
alu_in_4B_1
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
sub_action
[
8
+
i
+
1
][
18
:
16
]];
alu_in_4B_2
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
sub_action
[
8
+
i
+
1
][
13
:
11
]];
end
4'b1001
,
4'b1010
:
begin
alu_in_4B_1
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
sub_action
[
8
+
i
+
1
][
18
:
16
]];
alu_in_4B_2
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
{
16'b0
,
sub_action
[
8
+
i
+
1
][
15
:
0
]
}
;
end
// set operation, operand A set to 0, operand B set to imm
4'b1110
:
begin
alu_in_4B_1
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
32'b0
;
alu_in_4B_2
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
{
16'b0
,
sub_action
[
8
+
i
+
1
][
15
:
0
]
}
;
end
//loadd put here
4'b1011
,
4'b1000
,
4'b0111
:
begin
alu_in_4B_1
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
sub_action
[
8
+
i
+
1
][
18
:
16
]];
//alu_in_4B_2[(i+1)*width_4B-1 -: width_4B] <= {16'b0,sub_action[8+i+1][15:0]};
alu_in_4B_2
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
sub_action
[
8
+
i
+
1
][
13
:
11
]];
end
//if there is no action to take, output the original value
default:
begin
//alu_1 should be set to the phv value
alu_in_4B_1
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
cont_4B
[
i
];
alu_in_4B_2
[(
i
+
1
)
*
width_4B
-
1
-:
width_4B
]
<=
32'b0
;
end
endcase
end
for
(
i
=
7
;
i
>=
0
;
i
=
i
-
1
)
begin
casez
(
sub_action
[
i
+
1
][
24
:
21
])
//be noted that 2 ops need to be the same width
4'b0001
,
4'b0010
:
begin
alu_in_2B_1
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
cont_2B
[
sub_action
[
i
+
1
][
18
:
16
]];
alu_in_2B_2
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
cont_2B
[
sub_action
[
i
+
1
][
13
:
11
]];
end
4'b1001
,
4'b1010
:
begin
alu_in_2B_1
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
cont_2B
[
sub_action
[
i
+
1
][
18
:
16
]];
alu_in_2B_2
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
sub_action
[
i
+
1
][
15
:
0
];
end
// set operation, operand A set to 0, operand B set to imm
4'b1110
:
begin
alu_in_2B_1
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
16'b0
;
alu_in_2B_2
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
sub_action
[
i
+
1
][
15
:
0
];
end
//if there is no action to take, output the original value
default:
begin
//alu_1 should be set to the phv value
alu_in_2B_1
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
cont_2B
[
i
];
alu_in_2B_2
[(
i
+
1
)
*
width_2B
-
1
-:
width_2B
]
<=
16'b0
;
end
endcase
end
//the left is metadata & conditional ins, no need to modify
phv_remain_data
<=
phv_in
[
255
:
0
];
end
else
begin
alu_in_valid
<=
1'b0
;
end
end
HALT:
begin
if
(
ready_in
)
begin
alu_in_valid
<=
1'b1
;
state
<=
IDLE
;
ready_out
<=
1'b1
;
end
end
endcase
end
end
endmodule
sims/net/menshen/rtl/depar_do_deparsing.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
`define
SUB_DEPARSE_1P
(
idx
)
\
if
(
parse_action
[
idx
][
0
])
begin \
case
(
sub_depar_val_out_type_d1
[
idx
])
\
2
'
b01
:
pkts_tdata_stored_1p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
16
]
=
sub_depar_val_out_swapped
[
idx
][
32
+:
16
]
;
\
2
'
b10
:
pkts_tdata_stored_1p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
32
]
=
sub_depar_val_out_swapped
[
idx
][
16
+:
32
]
;
\
2
'
b11
:
pkts_tdata_stored_1p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
48
]
=
sub_depar_val_out_swapped
[
idx
][
0
+:
48
]
;
\
endcase \
end \
`define
SUB_DEPARSE_2P
(
idx
)
\
if
(
parse_action
[
idx
][
0
])
begin \
case
(
sub_depar_val_out_type_d1
[
idx
])
\
2
'
b01
:
pkts_tdata_stored_2p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
16
]
=
sub_depar_val_out_swapped
[
idx
][
32
+:
16
]
;
\
2
'
b10
:
pkts_tdata_stored_2p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
32
]
=
sub_depar_val_out_swapped
[
idx
][
16
+:
32
]
;
\
2
'
b11
:
pkts_tdata_stored_2p_next
[
parse_action_ind_10b
[
idx
]<<
3
+:
48
]
=
sub_depar_val_out_swapped
[
idx
][
0
+:
48
]
;
\
endcase \
end \
`define
SWAP_BYTE_ORDER2
(
idx
)
\
assign sub_depar_val_out_swapped
[
idx
]
=
{
sub_depar_val_out_d1
[
idx
][
0
+:
8
],
\
sub_depar_val_out_d1
[
idx
][
8
+:
8
],
\
sub_depar_val_out_d1
[
idx
][
16
+:
8
],
\
sub_depar_val_out_d1
[
idx
][
24
+:
8
],
\
sub_depar_val_out_d1
[
idx
][
32
+:
8
],
\
sub_depar_val_out_d1
[
idx
][
40
+:
8
]}
;
\
module
depar_do_deparsing
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
C_PKT_VEC_WIDTH
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
parameter
DEPARSER_MOD_ID
=
3'b101
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
aresetn
,
// phv
input
[
C_PKT_VEC_WIDTH
-
1
:
0
]
phv_fifo_out
,
input
phv_fifo_empty
,
output
reg
phv_fifo_rd_en
,
//
input
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_id
,
input
vlan_fifo_empty
,
output
reg
vlan_fifo_rd_en
,
//
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fst_half_fifo_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fst_half_fifo_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fst_half_fifo_tkeep
,
input
fst_half_fifo_tlast
,
input
fst_half_fifo_empty
,
output
reg
fst_half_fifo_rd_en
,
//
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
snd_half_fifo_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
snd_half_fifo_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
snd_half_fifo_tkeep
,
input
snd_half_fifo_tlast
,
input
snd_half_fifo_empty
,
output
reg
snd_half_fifo_rd_en
,
//
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
pkt_fifo_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
pkt_fifo_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
pkt_fifo_tkeep
,
input
pkt_fifo_tlast
,
input
pkt_fifo_empty
,
output
reg
pkt_fifo_rd_en
,
// output
output
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
depar_out_tdata
,
output
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
depar_out_tkeep
,
output
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
depar_out_tuser
,
output
reg
depar_out_tvalid
,
output
reg
depar_out_tlast
,
input
depar_out_tready
,
// control path
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
ctrl_s_axis_tkeep
,
input
ctrl_s_axis_tvalid
,
input
ctrl_s_axis_tlast
);
integer
i
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
depar_out_tdata_next
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
depar_out_tkeep_next
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
depar_out_tuser_next
;
reg
depar_out_tlast_next
;
reg
depar_out_tvalid_next
;
wire
[
159
:
0
]
bram_out
;
wire
[
6
:
0
]
parse_action_ind
[
0
:
9
];
wire
[
9
:
0
]
parse_action_ind_10b
[
0
:
9
];
wire
[
15
:
0
]
parse_action
[
0
:
9
];
// we have 10 parse action
assign
parse_action
[
9
]
=
bram_out
[
0
+:
16
];
assign
parse_action
[
8
]
=
bram_out
[
16
+:
16
];
assign
parse_action
[
7
]
=
bram_out
[
32
+:
16
];
assign
parse_action
[
6
]
=
bram_out
[
48
+:
16
];
assign
parse_action
[
5
]
=
bram_out
[
64
+:
16
];
assign
parse_action
[
4
]
=
bram_out
[
80
+:
16
];
assign
parse_action
[
3
]
=
bram_out
[
96
+:
16
];
assign
parse_action
[
2
]
=
bram_out
[
112
+:
16
];
assign
parse_action
[
1
]
=
bram_out
[
128
+:
16
];
assign
parse_action
[
0
]
=
bram_out
[
144
+:
16
];
assign
parse_action_ind
[
0
]
=
parse_action
[
0
][
12
:
6
];
assign
parse_action_ind
[
1
]
=
parse_action
[
1
][
12
:
6
];
assign
parse_action_ind
[
2
]
=
parse_action
[
2
][
12
:
6
];
assign
parse_action_ind
[
3
]
=
parse_action
[
3
][
12
:
6
];
assign
parse_action_ind
[
4
]
=
parse_action
[
4
][
12
:
6
];
assign
parse_action_ind
[
5
]
=
parse_action
[
5
][
12
:
6
];
assign
parse_action_ind
[
6
]
=
parse_action
[
6
][
12
:
6
];
assign
parse_action_ind
[
7
]
=
parse_action
[
7
][
12
:
6
];
assign
parse_action_ind
[
8
]
=
parse_action
[
8
][
12
:
6
];
assign
parse_action_ind
[
9
]
=
parse_action
[
9
][
12
:
6
];
assign
parse_action_ind_10b
[
0
]
=
parse_action_ind
[
0
];
assign
parse_action_ind_10b
[
1
]
=
parse_action_ind
[
1
];
assign
parse_action_ind_10b
[
2
]
=
parse_action_ind
[
2
];
assign
parse_action_ind_10b
[
3
]
=
parse_action_ind
[
3
];
assign
parse_action_ind_10b
[
4
]
=
parse_action_ind
[
4
];
assign
parse_action_ind_10b
[
5
]
=
parse_action_ind
[
5
];
assign
parse_action_ind_10b
[
6
]
=
parse_action_ind
[
6
];
assign
parse_action_ind_10b
[
7
]
=
parse_action_ind
[
7
];
assign
parse_action_ind_10b
[
8
]
=
parse_action_ind
[
8
];
assign
parse_action_ind_10b
[
9
]
=
parse_action_ind
[
9
];
reg
[
9
:
0
]
sub_depar_act_valid
;
wire
[
47
:
0
]
sub_depar_val_out_swapped
[
0
:
9
];
wire
[
47
:
0
]
sub_depar_val_out
[
0
:
9
];
wire
[
1
:
0
]
sub_depar_val_out_type
[
0
:
9
];
wire
[
9
:
0
]
sub_depar_val_out_valid
;
reg
[
47
:
0
]
sub_depar_val_out_d1
[
0
:
9
];
reg
[
1
:
0
]
sub_depar_val_out_type_d1
[
0
:
9
];
reg
[
9
:
0
]
sub_depar_val_out_valid_d1
;
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
for
(
i
=
0
;
i
<
10
;
i
=
i
+
1
)
begin
sub_depar_val_out_d1
[
i
]
<=
0
;
sub_depar_val_out_type_d1
[
i
]
<=
0
;
end
sub_depar_val_out_valid_d1
<=
0
;
end
else
begin
for
(
i
=
0
;
i
<
10
;
i
=
i
+
1
)
begin
sub_depar_val_out_d1
[
i
]
<=
sub_depar_val_out
[
i
];
sub_depar_val_out_type_d1
[
i
]
<=
sub_depar_val_out_type
[
i
];
end
sub_depar_val_out_valid_d1
<=
sub_depar_val_out_valid
;
end
end
`SWAP_BYTE_ORDER2
(
0
)
`SWAP_BYTE_ORDER2
(
1
)
`SWAP_BYTE_ORDER2
(
2
)
`SWAP_BYTE_ORDER2
(
3
)
`SWAP_BYTE_ORDER2
(
4
)
`SWAP_BYTE_ORDER2
(
5
)
`SWAP_BYTE_ORDER2
(
6
)
`SWAP_BYTE_ORDER2
(
7
)
`SWAP_BYTE_ORDER2
(
8
)
`SWAP_BYTE_ORDER2
(
9
)
wire
discard_signal
;
assign
discard_signal
=
phv_fifo_out
[
128
];
localparam
IDLE
=
0
,
WAIT_1CYCLE_RAM
=
1
,
START_SUB_DEPARSE
=
2
,
FINISH_SUB_DEPARSER_0
=
3
,
FINISH_SUB_DEPARSER_1
=
4
,
FINISH_SUB_DEPARSER_2
=
5
,
FLUSH_PKT_0
=
6
,
FLUSH_PKT_1
=
7
,
FLUSH_PKT_2
=
8
,
FLUSH_PKT_3
=
9
,
FLUSH_PKT
=
10
,
DROP_PKT
=
11
,
DROP_PKT_REMAINING
=
12
,
EMPTY_1
=
13
,
EMPTY_2
=
14
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
pkts_tdata_stored_1p
,
pkts_tdata_stored_2p
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
pkts_tuser_stored_1p
,
pkts_tuser_stored_2p
;
reg
[(
C_AXIS_DATA_WIDTH
/
8
)
-
1
:
0
]
pkts_tkeep_stored_1p
,
pkts_tkeep_stored_2p
;
reg
pkts_tlast_stored_1p
,
pkts_tlast_stored_2p
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
pkts_tdata_stored_1p_next
,
pkts_tdata_stored_2p_next
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
pkts_tuser_stored_1p_next
,
pkts_tuser_stored_2p_next
;
reg
[(
C_AXIS_DATA_WIDTH
/
8
)
-
1
:
0
]
pkts_tkeep_stored_1p_next
,
pkts_tkeep_stored_2p_next
;
reg
pkts_tlast_stored_1p_next
,
pkts_tlast_stored_2p_next
;
reg
[
4
:
0
]
state
,
state_next
;
always
@
(
*
)
begin
phv_fifo_rd_en
=
0
;
vlan_fifo_rd_en
=
0
;
fst_half_fifo_rd_en
=
0
;
snd_half_fifo_rd_en
=
0
;
pkt_fifo_rd_en
=
0
;
// output
depar_out_tdata_next
=
depar_out_tdata
;
depar_out_tuser_next
=
depar_out_tuser
;
depar_out_tkeep_next
=
depar_out_tkeep
;
depar_out_tlast_next
=
depar_out_tlast
;
depar_out_tvalid_next
=
0
;
sub_depar_act_valid
=
10'b0
;
state_next
=
state
;
//
pkts_tdata_stored_1p_next
=
pkts_tdata_stored_1p
;
pkts_tuser_stored_1p_next
=
pkts_tuser_stored_1p
;
pkts_tkeep_stored_1p_next
=
pkts_tkeep_stored_1p
;
pkts_tlast_stored_1p_next
=
pkts_tlast_stored_1p
;
//
pkts_tdata_stored_2p_next
=
pkts_tdata_stored_2p
;
pkts_tuser_stored_2p_next
=
pkts_tuser_stored_2p
;
pkts_tkeep_stored_2p_next
=
pkts_tkeep_stored_2p
;
pkts_tlast_stored_2p_next
=
pkts_tlast_stored_2p
;
case
(
state
)
IDLE:
begin
if
(
!
vlan_fifo_empty
)
begin
state_next
=
WAIT_1CYCLE_RAM
;
end
end
WAIT_1CYCLE_RAM:
begin
state_next
=
START_SUB_DEPARSE
;
end
START_SUB_DEPARSE:
begin
if
(
!
fst_half_fifo_empty
&&
!
snd_half_fifo_empty
&&
!
phv_fifo_empty
)
begin
if
(
discard_signal
==
1
)
begin
state_next
=
DROP_PKT
;
phv_fifo_rd_en
=
1
;
end
else
begin
sub_depar_act_valid
=
10'b1111111111
;
state_next
=
EMPTY_2
;
pkts_tdata_stored_1p_next
=
fst_half_fifo_tdata
;
pkts_tuser_stored_1p_next
=
phv_fifo_out
[
0
+:
128
];
pkts_tkeep_stored_1p_next
=
fst_half_fifo_tkeep
;
pkts_tlast_stored_1p_next
=
fst_half_fifo_tlast
;
//
pkts_tdata_stored_2p_next
=
snd_half_fifo_tdata
;
pkts_tuser_stored_2p_next
=
snd_half_fifo_tuser
;
pkts_tkeep_stored_2p_next
=
snd_half_fifo_tkeep
;
pkts_tlast_stored_2p_next
=
snd_half_fifo_tlast
;
end
end
end
EMPTY_1:
begin
// sub_depar_act_valid = 10'b1111111111;
state_next
=
EMPTY_2
;
end
EMPTY_2:
begin
state_next
=
FINISH_SUB_DEPARSER_0
;
end
FINISH_SUB_DEPARSER_0:
begin
`SUB_DEPARSE_1P
(
0
)
`SUB_DEPARSE_1P
(
1
)
`SUB_DEPARSE_2P
(
5
)
state_next
=
FINISH_SUB_DEPARSER_1
;
end
FINISH_SUB_DEPARSER_1:
begin
`SUB_DEPARSE_1P
(
2
)
`SUB_DEPARSE_2P
(
6
)
`SUB_DEPARSE_2P
(
7
)
state_next
=
FINISH_SUB_DEPARSER_2
;
end
FINISH_SUB_DEPARSER_2:
begin
`SUB_DEPARSE_1P
(
3
)
`SUB_DEPARSE_1P
(
4
)
`SUB_DEPARSE_2P
(
8
)
`SUB_DEPARSE_2P
(
9
)
state_next
=
FLUSH_PKT_0
;
end
FLUSH_PKT_0:
begin
phv_fifo_rd_en
=
1
;
vlan_fifo_rd_en
=
1
;
fst_half_fifo_rd_en
=
1
;
snd_half_fifo_rd_en
=
1
;
depar_out_tdata_next
=
pkts_tdata_stored_1p
;
depar_out_tuser_next
=
pkts_tuser_stored_1p
;
depar_out_tkeep_next
=
pkts_tkeep_stored_1p
;
depar_out_tlast_next
=
pkts_tlast_stored_1p
;
if
(
depar_out_tready
)
begin
depar_out_tvalid_next
=
1
;
if
(
pkts_tlast_stored_1p
)
begin
state_next
=
IDLE
;
end
else
begin
state_next
=
FLUSH_PKT_1
;
end
end
end
FLUSH_PKT_1:
begin
depar_out_tdata_next
=
pkts_tdata_stored_2p
;
depar_out_tuser_next
=
pkts_tuser_stored_2p
;
depar_out_tkeep_next
=
pkts_tkeep_stored_2p
;
depar_out_tlast_next
=
pkts_tlast_stored_2p
;
if
(
depar_out_tready
)
begin
depar_out_tvalid_next
=
1
;
if
(
pkts_tlast_stored_2p
)
begin
state_next
=
IDLE
;
end
else
begin
state_next
=
FLUSH_PKT
;
end
end
end
FLUSH_PKT:
begin
if
(
!
pkt_fifo_empty
)
begin
depar_out_tdata_next
=
pkt_fifo_tdata
;
depar_out_tuser_next
=
pkt_fifo_tuser
;
depar_out_tkeep_next
=
pkt_fifo_tkeep
;
depar_out_tlast_next
=
pkt_fifo_tlast
;
if
(
depar_out_tready
)
begin
pkt_fifo_rd_en
=
1
;
depar_out_tvalid_next
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
IDLE
;
end
end
end
end
DROP_PKT:
begin
if
(
fst_half_fifo_tlast
==
1
||
snd_half_fifo_tlast
==
1
)
begin
fst_half_fifo_rd_en
=
1
;
snd_half_fifo_rd_en
=
1
;
vlan_fifo_rd_en
=
1
;
state_next
=
IDLE
;
end
else
begin
fst_half_fifo_rd_en
=
1
;
snd_half_fifo_rd_en
=
1
;
vlan_fifo_rd_en
=
1
;
state_next
=
DROP_PKT_REMAINING
;
end
end
DROP_PKT_REMAINING:
begin
pkt_fifo_rd_en
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
IDLE
;
end
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
state
<=
IDLE
;
//
pkts_tdata_stored_1p
<=
0
;
pkts_tuser_stored_1p
<=
0
;
pkts_tkeep_stored_1p
<=
0
;
pkts_tlast_stored_1p
<=
0
;
//
pkts_tdata_stored_2p
<=
0
;
pkts_tuser_stored_2p
<=
0
;
pkts_tkeep_stored_2p
<=
0
;
pkts_tlast_stored_2p
<=
0
;
//
depar_out_tdata
<=
0
;
depar_out_tkeep
<=
0
;
depar_out_tuser
<=
0
;
depar_out_tlast
<=
0
;
depar_out_tvalid
<=
0
;
end
else
begin
state
<=
state_next
;
//
pkts_tdata_stored_1p
<=
pkts_tdata_stored_1p_next
;
pkts_tuser_stored_1p
<=
pkts_tuser_stored_1p_next
;
pkts_tkeep_stored_1p
<=
pkts_tkeep_stored_1p_next
;
pkts_tlast_stored_1p
<=
pkts_tlast_stored_1p_next
;
//
pkts_tdata_stored_2p
<=
pkts_tdata_stored_2p_next
;
pkts_tuser_stored_2p
<=
pkts_tuser_stored_2p_next
;
pkts_tkeep_stored_2p
<=
pkts_tkeep_stored_2p_next
;
pkts_tlast_stored_2p
<=
pkts_tlast_stored_2p_next
;
//
depar_out_tdata
<=
depar_out_tdata_next
;
depar_out_tkeep
<=
depar_out_tkeep_next
;
depar_out_tuser
<=
depar_out_tuser_next
;
depar_out_tlast
<=
depar_out_tlast_next
;
depar_out_tvalid
<=
depar_out_tvalid_next
;
end
end
//===================== sub deparser
generate
genvar
index
;
for
(
index
=
0
;
index
<
10
;
index
=
index
+
1
)
begin:
sub_op
sub_deparser
#(
.
C_PKT_VEC_WIDTH
(),
.
C_PARSE_ACT_LEN
()
)
sub_deparser
(
.
clk
(
clk
),
.
aresetn
(
aresetn
),
.
parse_act_valid
(
sub_depar_act_valid
[
index
]),
.
parse_act
(
parse_action
[
index
][
5
:
0
]),
.
phv_in
(
phv_fifo_out
),
.
val_out_valid
(
sub_depar_val_out_valid
[
index
]),
.
val_out
(
sub_depar_val_out
[
index
]),
.
val_out_type
(
sub_depar_val_out_type
[
index
])
);
end
endgenerate
/*================Control Path====================*/
wire
[
7
:
0
]
mod_id
;
//module ID
wire
[
15
:
0
]
control_flag
;
//dst udp port num
reg
[
7
:
0
]
c_index
;
//table index(addr)
reg
c_wr_en
;
//enable table write(wen)
reg
[
159
:
0
]
entry_reg
;
reg
[
2
:
0
]
c_state
;
localparam
IDLE_C
=
1
,
WRITE_C
=
2
,
SU_WRITE_C
=
3
;
assign
mod_id
=
ctrl_s_axis_tdata
[
368
+:
8
];
assign
control_flag
=
ctrl_s_axis_tdata
[
335
:
320
];
//LE to BE switching
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_swapped
;
assign
ctrl_s_axis_tdata_swapped
=
{
ctrl_s_axis_tdata
[
0
+:
8
],
ctrl_s_axis_tdata
[
8
+:
8
],
ctrl_s_axis_tdata
[
16
+:
8
],
ctrl_s_axis_tdata
[
24
+:
8
],
ctrl_s_axis_tdata
[
32
+:
8
],
ctrl_s_axis_tdata
[
40
+:
8
],
ctrl_s_axis_tdata
[
48
+:
8
],
ctrl_s_axis_tdata
[
56
+:
8
],
ctrl_s_axis_tdata
[
64
+:
8
],
ctrl_s_axis_tdata
[
72
+:
8
],
ctrl_s_axis_tdata
[
80
+:
8
],
ctrl_s_axis_tdata
[
88
+:
8
],
ctrl_s_axis_tdata
[
96
+:
8
],
ctrl_s_axis_tdata
[
104
+:
8
],
ctrl_s_axis_tdata
[
112
+:
8
],
ctrl_s_axis_tdata
[
120
+:
8
],
ctrl_s_axis_tdata
[
128
+:
8
],
ctrl_s_axis_tdata
[
136
+:
8
],
ctrl_s_axis_tdata
[
144
+:
8
],
ctrl_s_axis_tdata
[
152
+:
8
],
ctrl_s_axis_tdata
[
160
+:
8
],
ctrl_s_axis_tdata
[
168
+:
8
],
ctrl_s_axis_tdata
[
176
+:
8
],
ctrl_s_axis_tdata
[
184
+:
8
],
ctrl_s_axis_tdata
[
192
+:
8
],
ctrl_s_axis_tdata
[
200
+:
8
],
ctrl_s_axis_tdata
[
208
+:
8
],
ctrl_s_axis_tdata
[
216
+:
8
],
ctrl_s_axis_tdata
[
224
+:
8
],
ctrl_s_axis_tdata
[
232
+:
8
],
ctrl_s_axis_tdata
[
240
+:
8
],
ctrl_s_axis_tdata
[
248
+:
8
],
ctrl_s_axis_tdata
[
256
+:
8
],
ctrl_s_axis_tdata
[
264
+:
8
],
ctrl_s_axis_tdata
[
272
+:
8
],
ctrl_s_axis_tdata
[
280
+:
8
],
ctrl_s_axis_tdata
[
288
+:
8
],
ctrl_s_axis_tdata
[
296
+:
8
],
ctrl_s_axis_tdata
[
304
+:
8
],
ctrl_s_axis_tdata
[
312
+:
8
],
ctrl_s_axis_tdata
[
320
+:
8
],
ctrl_s_axis_tdata
[
328
+:
8
],
ctrl_s_axis_tdata
[
336
+:
8
],
ctrl_s_axis_tdata
[
344
+:
8
],
ctrl_s_axis_tdata
[
352
+:
8
],
ctrl_s_axis_tdata
[
360
+:
8
],
ctrl_s_axis_tdata
[
368
+:
8
],
ctrl_s_axis_tdata
[
376
+:
8
],
ctrl_s_axis_tdata
[
384
+:
8
],
ctrl_s_axis_tdata
[
392
+:
8
],
ctrl_s_axis_tdata
[
400
+:
8
],
ctrl_s_axis_tdata
[
408
+:
8
],
ctrl_s_axis_tdata
[
416
+:
8
],
ctrl_s_axis_tdata
[
424
+:
8
],
ctrl_s_axis_tdata
[
432
+:
8
],
ctrl_s_axis_tdata
[
440
+:
8
],
ctrl_s_axis_tdata
[
448
+:
8
],
ctrl_s_axis_tdata
[
456
+:
8
],
ctrl_s_axis_tdata
[
464
+:
8
],
ctrl_s_axis_tdata
[
472
+:
8
],
ctrl_s_axis_tdata
[
480
+:
8
],
ctrl_s_axis_tdata
[
488
+:
8
],
ctrl_s_axis_tdata
[
496
+:
8
],
ctrl_s_axis_tdata
[
504
+:
8
]
}
;
always
@
(
posedge
clk
or
negedge
aresetn
)
begin
if
(
~
aresetn
)
begin
c_wr_en
<=
1'b0
;
c_index
<=
4'b0
;
entry_reg
<=
0
;
c_state
<=
IDLE_C
;
end
else
begin
case
(
c_state
)
IDLE_C:
begin
if
(
ctrl_s_axis_tvalid
&&
mod_id
[
2
:
0
]
==
DEPARSER_MOD_ID
&&
control_flag
==
16'hf2f1
)
begin
c_wr_en
<=
1'b0
;
c_index
<=
ctrl_s_axis_tdata
[
384
+:
8
];
c_state
<=
WRITE_C
;
end
else
begin
c_wr_en
<=
1'b0
;
c_index
<=
4'b0
;
entry_reg
<=
0
;
c_state
<=
IDLE_C
;
end
end
//support full table flush
WRITE_C:
begin
if
(
ctrl_s_axis_tvalid
)
begin
c_wr_en
<=
1'b1
;
entry_reg
<=
ctrl_s_axis_tdata_swapped
[
511
-:
160
];
if
(
ctrl_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_C
;
end
end
else
begin
c_wr_en
<=
1'b0
;
end
end
SU_WRITE_C:
begin
if
(
ctrl_s_axis_tvalid
)
begin
entry_reg
<=
ctrl_s_axis_tdata_swapped
[
511
-:
160
];
c_wr_en
<=
1'b1
;
c_index
<=
c_index
+
1'b1
;
if
(
ctrl_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_C
;
end
end
else
begin
c_wr_en
<=
1'b0
;
end
end
endcase
end
end
parse_act_ram_ip
parse_act_ram
(
// write port
.
clka
(
clk
),
.
addra
(
c_index
[
4
:
0
]),
.
dina
(
entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en
),
//
.
clkb
(
clk
),
.
addrb
(
vlan_id
[
8
:
4
]),
// TODO: note that we may change due to little or big endian
.
doutb
(
bram_out
),
.
enb
(
1'b1
)
// always set to 1
);
endmodule
sims/net/menshen/rtl/depar_wait_segs.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
depar_wait_segs
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
)
(
input
clk
,
input
aresetn
,
// input from pkt fifo
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
pkt_fifo_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
pkt_fifo_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
pkt_fifo_tkeep
,
input
pkt_fifo_tlast
,
input
pkt_fifo_empty
,
input
fst_half_fifo_ready
,
input
snd_half_fifo_ready
,
// output
output
reg
pkt_fifo_rd_en
,
output
reg
[
11
:
0
]
vlan
,
output
reg
vlan_valid
,
output
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fst_half_tdata
,
output
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fst_half_tuser
,
output
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fst_half_tkeep
,
output
reg
fst_half_tlast
,
output
reg
fst_half_valid
,
output
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
snd_half_tdata
,
output
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
snd_half_tuser
,
output
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
snd_half_tkeep
,
output
reg
snd_half_tlast
,
output
reg
snd_half_valid
,
// output remaining segs to FIFO
output
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
output_fifo_tdata
,
output
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
output_fifo_tuser
,
output
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
output_fifo_tkeep
,
output
reg
output_fifo_tlast
,
output
reg
output_fifo_valid
,
input
output_fifo_ready
);
localparam
WAIT_FIRST_SEG
=
0
,
WAIT_SECOND_SEG
=
1
,
EMPTY_1
=
2
,
EMPTY_2
=
3
,
FLUSH_SEG
=
4
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
output_fifo_tdata_next
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
output_fifo_tuser_next
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
output_fifo_tkeep_next
;
reg
output_fifo_tlast_next
;
reg
output_fifo_valid_next
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fst_half_tdata_next
,
snd_half_tdata_next
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fst_half_tuser_next
,
snd_half_tuser_next
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fst_half_tkeep_next
,
snd_half_tkeep_next
;
reg
fst_half_tlast_next
,
snd_half_tlast_next
;
reg
fst_half_valid_next
,
snd_half_valid_next
;
reg
vlan_valid_next
;
reg
[
11
:
0
]
vlan_next
;
reg
[
2
:
0
]
state
,
state_next
;
// we delay the processing of PHV to the next module
always
@
(
*
)
begin
state_next
=
state
;
pkt_fifo_rd_en
=
0
;
fst_half_tdata_next
=
0
;
fst_half_tuser_next
=
0
;
fst_half_tkeep_next
=
0
;
fst_half_tlast_next
=
0
;
snd_half_tdata_next
=
0
;
snd_half_tuser_next
=
0
;
snd_half_tkeep_next
=
0
;
snd_half_tlast_next
=
0
;
fst_half_valid_next
=
0
;
snd_half_valid_next
=
0
;
vlan_valid_next
=
0
;
vlan_next
=
vlan
;
// output remaining segs
output_fifo_tdata_next
=
0
;
output_fifo_tuser_next
=
0
;
output_fifo_tkeep_next
=
0
;
output_fifo_tlast_next
=
0
;
output_fifo_valid_next
=
0
;
case
(
state
)
WAIT_FIRST_SEG:
begin
if
(
!
pkt_fifo_empty
)
begin
fst_half_tdata_next
=
pkt_fifo_tdata
;
fst_half_tuser_next
=
pkt_fifo_tuser
;
fst_half_tkeep_next
=
pkt_fifo_tkeep
;
fst_half_tlast_next
=
pkt_fifo_tlast
;
vlan_next
=
pkt_fifo_tdata
[
116
+:
12
];
if
(
pkt_fifo_tlast
)
begin
if
(
fst_half_fifo_ready
&&
snd_half_fifo_ready
)
begin
pkt_fifo_rd_en
=
1
;
fst_half_valid_next
=
1
;
snd_half_valid_next
=
1
;
vlan_valid_next
=
1
;
state_next
=
WAIT_FIRST_SEG
;
end
end
else
begin
if
(
fst_half_fifo_ready
)
begin
pkt_fifo_rd_en
=
1
;
fst_half_valid_next
=
1
;
vlan_valid_next
=
1
;
state_next
=
WAIT_SECOND_SEG
;
end
end
end
end
WAIT_SECOND_SEG:
begin
if
(
!
pkt_fifo_empty
)
begin
snd_half_tdata_next
=
pkt_fifo_tdata
;
snd_half_tuser_next
=
pkt_fifo_tuser
;
snd_half_tkeep_next
=
pkt_fifo_tkeep
;
snd_half_tlast_next
=
pkt_fifo_tlast
;
if
(
pkt_fifo_tlast
)
begin
if
(
snd_half_fifo_ready
)
begin
pkt_fifo_rd_en
=
1
;
snd_half_valid_next
=
1
;
state_next
=
WAIT_FIRST_SEG
;
end
end
else
begin
if
(
snd_half_fifo_ready
)
begin
pkt_fifo_rd_en
=
1
;
snd_half_valid_next
=
1
;
state_next
=
FLUSH_SEG
;
end
end
end
end
FLUSH_SEG:
begin
if
(
!
pkt_fifo_empty
)
begin
output_fifo_tdata_next
=
pkt_fifo_tdata
;
output_fifo_tuser_next
=
pkt_fifo_tuser
;
output_fifo_tkeep_next
=
pkt_fifo_tkeep
;
output_fifo_tlast_next
=
pkt_fifo_tlast
;
if
(
output_fifo_ready
)
begin
output_fifo_valid_next
=
1
;
pkt_fifo_rd_en
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
WAIT_FIRST_SEG
;
end
end
end
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
state
<=
WAIT_FIRST_SEG
;
fst_half_tdata
<=
0
;
fst_half_tuser
<=
0
;
fst_half_tkeep
<=
0
;
fst_half_tlast
<=
0
;
snd_half_tdata
<=
0
;
snd_half_tuser
<=
0
;
snd_half_tkeep
<=
0
;
snd_half_tlast
<=
0
;
fst_half_valid
<=
0
;
snd_half_valid
<=
0
;
vlan_valid
<=
0
;
vlan
<=
0
;
//
output_fifo_tdata
<=
0
;
output_fifo_tuser
<=
0
;
output_fifo_tkeep
<=
0
;
output_fifo_tlast
<=
0
;
output_fifo_valid
<=
0
;
end
else
begin
state
<=
state_next
;
fst_half_tdata
<=
fst_half_tdata_next
;
fst_half_tuser
<=
fst_half_tuser_next
;
fst_half_tkeep
<=
fst_half_tkeep_next
;
fst_half_tlast
<=
fst_half_tlast_next
;
snd_half_tdata
<=
snd_half_tdata_next
;
snd_half_tuser
<=
snd_half_tuser_next
;
snd_half_tkeep
<=
snd_half_tkeep_next
;
snd_half_tlast
<=
snd_half_tlast_next
;
fst_half_valid
<=
fst_half_valid_next
;
snd_half_valid
<=
snd_half_valid_next
;
vlan_valid
<=
vlan_valid_next
;
vlan
<=
vlan_next
;
//
output_fifo_tdata
<=
output_fifo_tdata_next
;
output_fifo_tuser
<=
output_fifo_tuser_next
;
output_fifo_tkeep
<=
output_fifo_tkeep_next
;
output_fifo_tlast
<=
output_fifo_tlast_next
;
output_fifo_valid
<=
output_fifo_valid_next
;
end
end
endmodule
sims/net/menshen/rtl/deparser_top.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
deparser_top
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
C_PKT_VEC_WIDTH
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
parameter
DEPARSER_MOD_ID
=
3'b101
,
parameter
C_VLANID_WIDTH
=
12
,
parameter
C_FIFO_BITS_WIDTH
=
4
)
(
input
axis_clk
,
input
aresetn
,
//
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
pkt_fifo_tdata
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
pkt_fifo_tkeep
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
pkt_fifo_tuser
,
input
pkt_fifo_tlast
,
input
pkt_fifo_empty
,
output
pkt_fifo_rd_en
,
input
[
C_PKT_VEC_WIDTH
-
1
:
0
]
phv_fifo_out
,
input
phv_fifo_empty
,
output
phv_fifo_rd_en
,
output
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
depar_out_tdata
,
output
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
depar_out_tkeep
,
output
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
depar_out_tuser
,
output
depar_out_tvalid
,
output
depar_out_tlast
,
input
depar_out_tready
,
// control path
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
ctrl_s_axis_tkeep
,
input
ctrl_s_axis_tvalid
,
input
ctrl_s_axis_tlast
);
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fst_half_fifo_tdata_in
,
fst_half_fifo_tdata_out
;
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fst_half_fifo_tuser_in
,
fst_half_fifo_tuser_out
;
wire
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fst_half_fifo_tkeep_in
,
fst_half_fifo_tkeep_out
;
wire
fst_half_fifo_tlast_in
,
fst_half_fifo_tlast_out
;
wire
fst_half_fifo_empty
;
wire
fst_half_fifo_full
;
wire
fst_half_fifo_valid_in
;
wire
fst_half_fifo_rd_en
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fst_half_fifo_tdata_in_r
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fst_half_fifo_tuser_in_r
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fst_half_fifo_tkeep_in_r
;
reg
fst_half_fifo_tlast_in_r
;
reg
fst_half_fifo_valid_in_r
;
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
snd_half_fifo_tdata_in
,
snd_half_fifo_tdata_out
;
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
snd_half_fifo_tuser_in
,
snd_half_fifo_tuser_out
;
wire
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
snd_half_fifo_tkeep_in
,
snd_half_fifo_tkeep_out
;
wire
snd_half_fifo_tlast_in
,
snd_half_fifo_tlast_out
;
wire
snd_half_fifo_empty
;
wire
snd_half_fifo_full
;
wire
snd_half_fifo_valid_in
;
wire
snd_half_fifo_rd_en
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
snd_half_fifo_tdata_in_r
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
snd_half_fifo_tuser_in_r
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
snd_half_fifo_tkeep_in_r
;
reg
snd_half_fifo_tlast_in_r
;
reg
snd_half_fifo_valid_in_r
;
fallthrough_small_fifo
#(
.
WIDTH
(
C_AXIS_DATA_WIDTH
+
C_AXIS_TUSER_WIDTH
+
C_AXIS_DATA_WIDTH
/
8
+
1
),
.
MAX_DEPTH_BITS
(
4
)
)
fst_half_fifo
(
.
din
(
{
fst_half_fifo_tdata_in_r
,
fst_half_fifo_tuser_in_r
,
fst_half_fifo_tkeep_in_r
,
fst_half_fifo_tlast_in_r
}
),
.
wr_en
(
fst_half_fifo_valid_in_r
),
// .din ({fst_half_fifo_tdata_in, fst_half_fifo_tuser_in, fst_half_fifo_tkeep_in, fst_half_fifo_tlast_in}),
// .wr_en (fst_half_fifo_valid_in),
//
.
rd_en
(
fst_half_fifo_rd_en
),
.
dout
(
{
fst_half_fifo_tdata_out
,
fst_half_fifo_tuser_out
,
fst_half_fifo_tkeep_out
,
fst_half_fifo_tlast_out
}
),
//
.
full
(),
.
prog_full
(),
.
nearly_full
(
fst_half_fifo_full
),
.
empty
(
fst_half_fifo_empty
),
.
reset
(
~
aresetn
),
.
clk
(
axis_clk
)
);
fallthrough_small_fifo
#(
.
WIDTH
(
C_AXIS_DATA_WIDTH
+
C_AXIS_TUSER_WIDTH
+
C_AXIS_DATA_WIDTH
/
8
+
1
),
.
MAX_DEPTH_BITS
(
4
)
)
snd_half_fifo
(
.
din
(
{
snd_half_fifo_tdata_in_r
,
snd_half_fifo_tuser_in_r
,
snd_half_fifo_tkeep_in_r
,
snd_half_fifo_tlast_in_r
}
),
.
wr_en
(
snd_half_fifo_valid_in_r
),
// .din ({snd_half_fifo_tdata_in, snd_half_fifo_tuser_in, snd_half_fifo_tkeep_in, snd_half_fifo_tlast_in}),
// .wr_en (snd_half_fifo_valid_in),
//
.
rd_en
(
snd_half_fifo_rd_en
),
.
dout
(
{
snd_half_fifo_tdata_out
,
snd_half_fifo_tuser_out
,
snd_half_fifo_tkeep_out
,
snd_half_fifo_tlast_out
}
),
//
.
full
(),
.
prog_full
(),
.
nearly_full
(
snd_half_fifo_full
),
.
empty
(
snd_half_fifo_empty
),
.
reset
(
~
aresetn
),
.
clk
(
axis_clk
)
);
//===============================================
wire
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_fifo_in
,
vlan_fifo_out
;
wire
vlan_valid_in
;
wire
vlan_fifo_rd_en
;
wire
vlan_fifo_full
;
wire
vlan_fifo_empty
;
// vlan fifo
fallthrough_small_fifo
#(
.
WIDTH
(
C_VLANID_WIDTH
),
.
MAX_DEPTH_BITS
(
5
)
)
vlan_fifo
(
.
din
(
vlan_fifo_in
),
.
wr_en
(
vlan_valid_in
),
//
.
rd_en
(
vlan_fifo_rd_en
),
.
dout
(
vlan_fifo_out
),
//
.
full
(),
.
prog_full
(),
.
nearly_full
(
vlan_fifo_full
),
.
empty
(
vlan_fifo_empty
),
.
reset
(
~
aresetn
),
.
clk
(
axis_clk
)
);
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
seg_fifo_tdata_in
,
seg_fifo_tdata_out
;
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
seg_fifo_tuser_in
,
seg_fifo_tuser_out
;
wire
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
seg_fifo_tkeep_in
,
seg_fifo_tkeep_out
;
wire
seg_fifo_tlast_in
,
seg_fifo_tlast_out
;
wire
seg_fifo_valid_in
;
wire
seg_fifo_rd_en
;
wire
seg_fifo_full
;
wire
seg_fifo_empty
;
reg
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
seg_fifo_tdata_in_r
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
seg_fifo_tuser_in_r
;
reg
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
seg_fifo_tkeep_in_r
;
reg
seg_fifo_tlast_in_r
;
reg
seg_fifo_valid_in_r
;
// seg fifo
fallthrough_small_fifo
#(
.
WIDTH
(
C_AXIS_DATA_WIDTH
+
C_AXIS_TUSER_WIDTH
+
C_AXIS_DATA_WIDTH
/
8
+
1
),
.
MAX_DEPTH_BITS
(
5
)
)
seg_fifo
(
.
din
(
{
seg_fifo_tdata_in_r
,
seg_fifo_tuser_in_r
,
seg_fifo_tkeep_in_r
,
seg_fifo_tlast_in_r
}
),
.
wr_en
(
seg_fifo_valid_in_r
),
// .din ({seg_fifo_tdata_in, seg_fifo_tuser_in, seg_fifo_tkeep_in, seg_fifo_tlast_in}),
// .wr_en (seg_fifo_valid_in),
//
.
rd_en
(
seg_fifo_rd_en
),
.
dout
(
{
seg_fifo_tdata_out
,
seg_fifo_tuser_out
,
seg_fifo_tkeep_out
,
seg_fifo_tlast_out
}
),
//
.
full
(),
.
prog_full
(),
.
nearly_full
(
seg_fifo_full
),
.
empty
(
seg_fifo_empty
),
.
reset
(
~
aresetn
),
.
clk
(
axis_clk
)
);
//
depar_wait_segs
#(
)
wait_segs
(
.
clk
(
axis_clk
),
.
aresetn
(
aresetn
),
.
pkt_fifo_tdata
(
pkt_fifo_tdata
),
.
pkt_fifo_tuser
(
pkt_fifo_tuser
),
.
pkt_fifo_tkeep
(
pkt_fifo_tkeep
),
.
pkt_fifo_tlast
(
pkt_fifo_tlast
),
.
pkt_fifo_empty
(
pkt_fifo_empty
),
.
fst_half_fifo_ready
(
~
fst_half_fifo_full
),
.
snd_half_fifo_ready
(
~
snd_half_fifo_full
),
.
pkt_fifo_rd_en
(
pkt_fifo_rd_en
),
.
vlan
(
vlan_fifo_in
),
.
vlan_valid
(
vlan_valid_in
),
.
fst_half_tdata
(
fst_half_fifo_tdata_in
),
.
fst_half_tuser
(
fst_half_fifo_tuser_in
),
.
fst_half_tkeep
(
fst_half_fifo_tkeep_in
),
.
fst_half_tlast
(
fst_half_fifo_tlast_in
),
.
fst_half_valid
(
fst_half_fifo_valid_in
),
//
.
snd_half_tdata
(
snd_half_fifo_tdata_in
),
.
snd_half_tuser
(
snd_half_fifo_tuser_in
),
.
snd_half_tkeep
(
snd_half_fifo_tkeep_in
),
.
snd_half_tlast
(
snd_half_fifo_tlast_in
),
.
snd_half_valid
(
snd_half_fifo_valid_in
),
//
.
output_fifo_tdata
(
seg_fifo_tdata_in
),
.
output_fifo_tuser
(
seg_fifo_tuser_in
),
.
output_fifo_tkeep
(
seg_fifo_tkeep_in
),
.
output_fifo_tlast
(
seg_fifo_tlast_in
),
.
output_fifo_valid
(
seg_fifo_valid_in
),
.
output_fifo_ready
(
~
seg_fifo_full
)
);
//
depar_do_deparsing
#(
.
C_PKT_VEC_WIDTH
(
C_PKT_VEC_WIDTH
),
.
DEPARSER_MOD_ID
(
DEPARSER_MOD_ID
)
)
do_deparsing
(
.
clk
(
axis_clk
),
.
aresetn
(
aresetn
),
// phv
.
phv_fifo_out
(
phv_fifo_out
),
.
phv_fifo_empty
(
phv_fifo_empty
),
.
phv_fifo_rd_en
(
phv_fifo_rd_en
),
// vlan
.
vlan_id
(
vlan_fifo_out
),
.
vlan_fifo_empty
(
vlan_fifo_empty
),
.
vlan_fifo_rd_en
(
vlan_fifo_rd_en
),
// first half
.
fst_half_fifo_tdata
(
fst_half_fifo_tdata_out
),
.
fst_half_fifo_tuser
(
fst_half_fifo_tuser_out
),
.
fst_half_fifo_tkeep
(
fst_half_fifo_tkeep_out
),
.
fst_half_fifo_tlast
(
fst_half_fifo_tlast_out
),
.
fst_half_fifo_empty
(
fst_half_fifo_empty
),
.
fst_half_fifo_rd_en
(
fst_half_fifo_rd_en
),
// second half
.
snd_half_fifo_tdata
(
snd_half_fifo_tdata_out
),
.
snd_half_fifo_tuser
(
snd_half_fifo_tuser_out
),
.
snd_half_fifo_tkeep
(
snd_half_fifo_tkeep_out
),
.
snd_half_fifo_tlast
(
snd_half_fifo_tlast_out
),
.
snd_half_fifo_empty
(
snd_half_fifo_empty
),
.
snd_half_fifo_rd_en
(
snd_half_fifo_rd_en
),
// segs
.
pkt_fifo_tdata
(
seg_fifo_tdata_out
),
.
pkt_fifo_tuser
(
seg_fifo_tuser_out
),
.
pkt_fifo_tkeep
(
seg_fifo_tkeep_out
),
.
pkt_fifo_tlast
(
seg_fifo_tlast_out
),
.
pkt_fifo_empty
(
seg_fifo_empty
),
.
pkt_fifo_rd_en
(
seg_fifo_rd_en
),
// output
.
depar_out_tdata
(
depar_out_tdata
),
.
depar_out_tuser
(
depar_out_tuser
),
.
depar_out_tkeep
(
depar_out_tkeep
),
.
depar_out_tlast
(
depar_out_tlast
),
.
depar_out_tvalid
(
depar_out_tvalid
),
.
depar_out_tready
(
depar_out_tready
),
// control path
.
ctrl_s_axis_tdata
(
ctrl_s_axis_tdata
),
.
ctrl_s_axis_tuser
(
ctrl_s_axis_tuser
),
.
ctrl_s_axis_tkeep
(
ctrl_s_axis_tkeep
),
.
ctrl_s_axis_tvalid
(
ctrl_s_axis_tvalid
),
.
ctrl_s_axis_tlast
(
ctrl_s_axis_tlast
)
);
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
//
fst_half_fifo_tdata_in_r
<=
0
;
fst_half_fifo_tuser_in_r
<=
0
;
fst_half_fifo_tkeep_in_r
<=
0
;
fst_half_fifo_tlast_in_r
<=
0
;
fst_half_fifo_valid_in_r
<=
0
;
//
snd_half_fifo_tdata_in_r
<=
0
;
snd_half_fifo_tuser_in_r
<=
0
;
snd_half_fifo_tkeep_in_r
<=
0
;
snd_half_fifo_tlast_in_r
<=
0
;
snd_half_fifo_valid_in_r
<=
0
;
//
seg_fifo_tdata_in_r
<=
0
;
seg_fifo_tuser_in_r
<=
0
;
seg_fifo_tkeep_in_r
<=
0
;
seg_fifo_tlast_in_r
<=
0
;
seg_fifo_valid_in_r
<=
0
;
end
else
begin
//
fst_half_fifo_tdata_in_r
<=
fst_half_fifo_tdata_in
;
fst_half_fifo_tuser_in_r
<=
fst_half_fifo_tuser_in
;
fst_half_fifo_tkeep_in_r
<=
fst_half_fifo_tkeep_in
;
fst_half_fifo_tlast_in_r
<=
fst_half_fifo_tlast_in
;
fst_half_fifo_valid_in_r
<=
fst_half_fifo_valid_in
;
//
snd_half_fifo_tdata_in_r
<=
snd_half_fifo_tdata_in
;
snd_half_fifo_tuser_in_r
<=
snd_half_fifo_tuser_in
;
snd_half_fifo_tkeep_in_r
<=
snd_half_fifo_tkeep_in
;
snd_half_fifo_tlast_in_r
<=
snd_half_fifo_tlast_in
;
snd_half_fifo_valid_in_r
<=
snd_half_fifo_valid_in
;
//
seg_fifo_tdata_in_r
<=
seg_fifo_tdata_in
;
seg_fifo_tuser_in_r
<=
seg_fifo_tuser_in
;
seg_fifo_tkeep_in_r
<=
seg_fifo_tkeep_in
;
seg_fifo_tlast_in_r
<=
seg_fifo_tlast_in
;
seg_fifo_valid_in_r
<=
seg_fifo_valid_in
;
end
end
endmodule
sims/net/menshen/rtl/extract/key_extract.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
key_extract
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
1
,
// format of KEY_OFF entry: |--3(6B)--|--3(6B)--|--3(4B)--|--3(4B)--|--3(2B)--|--3(2B)--|
parameter
KEY_OFF
=
(
3
+
3
)
*
3
+
20
,
parameter
AXIL_WIDTH
=
32
,
parameter
KEY_OFF_ADDR_WIDTH
=
4
,
parameter
KEY_EX_ID
=
1
,
parameter
C_VLANID_WIDTH
=
12
)(
input
clk
,
input
rst_n
,
//
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_valid_in
,
output
ready_out
,
// input from vlan fifo
input
key_offset_valid
,
input
[
KEY_OFF
-
1
:
0
]
key_offset_w
,
input
[
KEY_LEN
-
1
:
0
]
key_mask_w
,
// output PHV and key
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out
,
output
reg
phv_valid_out
,
output
[
KEY_LEN
-
1
:
0
]
key_out_masked
,
output
reg
key_valid_out
,
input
ready_in
);
integer
i
;
localparam
WIDTH_2B
=
16
;
localparam
WIDTH_4B
=
32
;
localparam
WIDTH_6B
=
48
;
//reg [KEY_LEN-1:0] key_out;
//24 fields to be retrived from the pkt header
reg
[
WIDTH_2B
-
1
:
0
]
cont_2B
[
0
:
7
];
reg
[
WIDTH_4B
-
1
:
0
]
cont_4B
[
0
:
7
];
reg
[
WIDTH_6B
-
1
:
0
]
cont_6B
[
0
:
7
];
wire
[
19
:
0
]
com_op
;
wire
[
47
:
0
]
com_op_1
,
com_op_2
;
wire
[
47
:
0
]
com_op_1_val
,
com_op_2_val
;
//
reg
[
KEY_OFF
-
1
:
0
]
key_offset_r
;
//
reg
[
KEY_LEN
-
1
:
0
]
key_mask_out_r
;
//
assign
com_op
=
key_offset_r
[
0
+:
20
];
assign
com_op_1
=
com_op
[
17
]
==
1
?
{
40'b0
,
com_op
[
16
:
9
]
}
:
com_op_1_val
;
assign
com_op_1_val
=
com_op
[
13
:
12
]
==
2
?
cont_6B
[
com_op
[
11
:
9
]][
7
:
0
]
:
(
com_op
[
13
:
12
]
==
1
?{
16'b0
,
cont_4B
[
com_op
[
11
:
9
]][
7
:
0
]
}:
(
com_op
[
13
:
12
]
==
0
?{
32'b0
,
cont_2B
[
com_op
[
11
:
9
]][
7
:
0
]
}:
0
));
assign
com_op_2
=
com_op
[
8
]
==
1
?
{
40'b0
,
com_op
[
7
:
0
]
}
:
com_op_2_val
;
assign
com_op_2_val
=
com_op
[
4
:
3
]
==
2
?
cont_6B
[
com_op
[
2
:
0
]][
7
:
0
]
:
(
com_op
[
4
:
3
]
==
1
?{
16'b0
,
cont_4B
[
com_op
[
2
:
0
]][
7
:
0
]
}:
(
com_op
[
4
:
3
]
==
0
?{
32'b0
,
cont_2B
[
com_op
[
2
:
0
]][
7
:
0
]
}:
0
));
localparam
IDLE_S
=
0
,
CYCLE_1
=
1
;
reg
[
2
:
0
]
state
,
state_next
;
reg
[
KEY_LEN
-
1
:
0
]
key_out
;
// reg ready_out_next;
assign
ready_out
=
1
;
assign
key_out_masked
=
key_out
&
(
~
key_mask_out_r
);
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
key_out
<=
0
;
state
<=
IDLE_S
;
for
(
i
=
0
;
i
<
8
;
i
=
i
+
1
)
begin
cont_6B
[
i
]
<=
0
;
cont_4B
[
i
]
<=
0
;
cont_2B
[
i
]
<=
0
;
end
phv_out
<=
0
;
phv_valid_out
<=
0
;
key_valid_out
<=
0
;
key_offset_r
<=
0
;
key_mask_out_r
<=
0
;
end
else
begin
case
(
state
)
IDLE_S:
begin
if
(
phv_valid_in
)
begin
key_offset_r
<=
key_offset_w
;
key_mask_out_r
<=
key_mask_w
;
phv_out
<=
phv_in
;
cont_6B
[
7
]
<=
phv_in
[
PHV_LEN
-
1
-:
WIDTH_6B
];
cont_6B
[
6
]
<=
phv_in
[
PHV_LEN
-
1
-
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
5
]
<=
phv_in
[
PHV_LEN
-
1
-
2
*
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
4
]
<=
phv_in
[
PHV_LEN
-
1
-
3
*
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
3
]
<=
phv_in
[
PHV_LEN
-
1
-
4
*
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
2
]
<=
phv_in
[
PHV_LEN
-
1
-
5
*
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
1
]
<=
phv_in
[
PHV_LEN
-
1
-
6
*
WIDTH_6B
-:
WIDTH_6B
];
cont_6B
[
0
]
<=
phv_in
[
PHV_LEN
-
1
-
7
*
WIDTH_6B
-:
WIDTH_6B
];
cont_4B
[
7
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-:
WIDTH_4B
];
cont_4B
[
6
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
5
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
2
*
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
4
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
3
*
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
3
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
4
*
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
2
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
5
*
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
1
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
6
*
WIDTH_4B
-:
WIDTH_4B
];
cont_4B
[
0
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
7
*
WIDTH_4B
-:
WIDTH_4B
];
cont_2B
[
7
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-:
WIDTH_2B
];
cont_2B
[
6
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
5
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
2
*
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
4
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
3
*
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
3
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
4
*
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
2
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
5
*
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
1
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
6
*
WIDTH_2B
-:
WIDTH_2B
];
cont_2B
[
0
]
<=
phv_in
[
PHV_LEN
-
1
-
8
*
WIDTH_6B
-
8
*
WIDTH_4B
-
7
*
WIDTH_2B
-:
WIDTH_2B
];
state
<=
CYCLE_1
;
end
else
begin
phv_valid_out
<=
0
;
key_valid_out
<=
0
;
end
end
CYCLE_1:
begin
key_out
[
KEY_LEN
-
1
-:
WIDTH_6B
]
<=
cont_6B
[
key_offset_r
[
KEY_OFF
-
1
-:
3
]];
key_out
[
KEY_LEN
-
1
-
1
*
WIDTH_6B
-:
WIDTH_6B
]
<=
cont_6B
[
key_offset_r
[
KEY_OFF
-
1
-
1
*
3
-:
3
]];
key_out
[
KEY_LEN
-
1
-
2
*
WIDTH_6B
-:
WIDTH_4B
]
<=
cont_4B
[
key_offset_r
[
KEY_OFF
-
1
-
2
*
3
-:
3
]];
key_out
[
KEY_LEN
-
1
-
2
*
WIDTH_6B
-
1
*
WIDTH_4B
-:
WIDTH_4B
]
<=
cont_4B
[
key_offset_r
[
KEY_OFF
-
1
-
3
*
3
-:
3
]];
key_out
[
KEY_LEN
-
1
-
2
*
WIDTH_6B
-
2
*
WIDTH_4B
-:
WIDTH_2B
]
<=
cont_2B
[
key_offset_r
[
KEY_OFF
-
1
-
4
*
3
-:
3
]];
key_out
[
KEY_LEN
-
1
-
2
*
WIDTH_6B
-
2
*
WIDTH_4B
-
WIDTH_2B
-:
WIDTH_2B
]
<=
cont_2B
[
key_offset_r
[
KEY_OFF
-
1
-
5
*
3
-:
3
]];
case
(
com_op
[
19
:
18
])
2'b00
:
begin
key_out
[
0
]
<=
(
com_op_1
>
com_op_2
)
?
1'b1
:
1'b0
;
end
2'b01
:
begin
key_out
[
0
]
<=
(
com_op_1
>=
com_op_2
)
?
1'b1
:
1'b0
;
end
2'b10
:
begin
key_out
[
0
]
<=
(
com_op_1
==
com_op_2
)
?
1'b1
:
1'b0
;
end
default:
begin
key_out
[
0
]
<=
1'b1
;
end
endcase
phv_valid_out
<=
1
;
key_valid_out
<=
1
;
state
<=
IDLE_S
;
end
endcase
end
end
endmodule
sims/net/menshen/rtl/extract/key_extract_top.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
key_extract_top
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
1
,
// format of KEY_OFF entry: |--3(6B)--|--3(6B)--|--3(4B)--|--3(4B)--|--3(2B)--|--3(2B)--|
parameter
KEY_OFF
=
(
3
+
3
)
*
3
+
20
,
parameter
AXIL_WIDTH
=
32
,
parameter
KEY_OFF_ADDR_WIDTH
=
4
,
parameter
KEY_EX_ID
=
1
,
parameter
C_VLANID_WIDTH
=
12
)(
input
clk
,
input
rst_n
,
//
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_valid_in
,
output
ready_out
,
// input from vlan fifo
input
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_in
,
input
vlan_in_valid
,
output
vlan_ready
,
// output PHV and key
output
[
PHV_LEN
-
1
:
0
]
phv_out
,
output
phv_valid_out
,
output
[
KEY_LEN
-
1
:
0
]
key_out_masked
,
output
key_valid_out
,
input
ready_in
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
reg
c_m_axis_tvalid
,
output
reg
c_m_axis_tlast
);
wire
[
KEY_OFF
-
1
:
0
]
key_offset_w
;
// output from RAM
//
wire
[
KEY_LEN
-
1
:
0
]
key_mask_out_w
;
// output from RAM
//
wire
extract_ready_out
;
assign
ready_out
=
extract_ready_out
;
assign
vlan_ready
=
extract_ready_out
;
//
localparam
BRAM_IDLE
=
0
,
BRAM_CYCLE_1
=
1
,
BRAM_CYCLE_2
=
2
,
BRAM_CYCLE_3
=
3
;
reg
[
2
:
0
]
bram_state
,
bram_state_next
;
reg
key_offset_valid
,
key_offset_valid_next
;
always
@
(
*
)
begin
bram_state_next
=
bram_state
;
key_offset_valid_next
=
0
;
case
(
bram_state
)
BRAM_IDLE:
begin
if
(
vlan_in_valid
)
begin
bram_state_next
=
BRAM_CYCLE_1
;
end
end
BRAM_CYCLE_1:
begin
bram_state_next
=
BRAM_IDLE
;
key_offset_valid_next
=
1
;
end
BRAM_CYCLE_2:
begin
bram_state_next
=
BRAM_CYCLE_3
;
end
BRAM_CYCLE_3:
begin
bram_state_next
=
BRAM_IDLE
;
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
bram_state
<=
BRAM_IDLE
;
key_offset_valid
<=
0
;
end
else
begin
bram_state
<=
bram_state_next
;
key_offset_valid
<=
key_offset_valid_next
;
end
end
reg
[
PHV_LEN
-
1
:
0
]
phv_in_d1
;
reg
phv_valid_in_d1
;
reg
key_offset_valid_d1
;
reg
[
KEY_OFF
-
1
:
0
]
key_offset_w_d1
;
// output from RAM
reg
[
KEY_LEN
-
1
:
0
]
key_mask_out_w_d1
;
// output from RAM
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
phv_in_d1
<=
0
;
phv_valid_in_d1
<=
0
;
key_offset_valid_d1
<=
0
;
key_offset_w_d1
<=
0
;
key_mask_out_w_d1
<=
0
;
end
else
begin
phv_in_d1
<=
phv_in
;
phv_valid_in_d1
<=
phv_valid_in
;
key_offset_valid_d1
<=
key_offset_valid
;
key_offset_w_d1
<=
key_offset_w
;
key_mask_out_w_d1
<=
key_mask_out_w
;
end
end
//
key_extract
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(
PHV_LEN
),
.
KEY_LEN
(
KEY_LEN
),
.
KEY_OFF
(
KEY_OFF
)
)
extractor
(
.
clk
(
clk
),
.
rst_n
(
rst_n
),
.
phv_in
(
phv_in_d1
),
.
phv_valid_in
(
phv_valid_in_d1
),
.
ready_out
(
extract_ready_out
),
//
.
key_offset_valid
(
key_offset_valid_d1
),
.
key_offset_w
(
key_offset_w_d1
),
.
key_mask_w
(
key_mask_out_w_d1
),
// output
.
phv_out
(
phv_out
),
.
phv_valid_out
(
phv_valid_out
),
.
key_out_masked
(
key_out_masked
),
.
key_valid_out
(
key_valid_out
),
.
ready_in
(
ready_in
)
);
//======================================================================================
/****control path for 512b*****/
wire
[
7
:
0
]
mod_id
;
//module ID
wire
[
3
:
0
]
resv
;
wire
[
15
:
0
]
control_flag
;
//dst udp port num
reg
[
7
:
0
]
c_index
;
//table index(addr)
reg
c_wr_en_off
;
//enable table write(wena)
reg
c_wr_en_mask
;
reg
[
2
:
0
]
c_state
;
localparam
IDLE_C
=
0
,
PARSE_C
=
1
,
WRITE_OFF_C
=
2
,
SU_WRITE_OFF_C
=
3
,
WRITE_MASK_C
=
4
,
SU_WRITE_MASK_C
=
5
,
FLUSH_PKT_C
=
6
;
generate
if
(
C_S_AXIS_DATA_WIDTH
==
512
)
begin
assign
mod_id
=
c_s_axis_tdata
[
368
+:
8
];
//4'b0 for key offset
//4'b1 for key mask
assign
resv
=
c_s_axis_tdata
[
376
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
335
:
320
];
reg
[
37
:
0
]
key_off_entry_reg
;
reg
[
192
:
0
]
key_mask_entry_reg
;
//LE to BE switching
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
],
c_s_axis_tdata
[
256
+:
8
],
c_s_axis_tdata
[
264
+:
8
],
c_s_axis_tdata
[
272
+:
8
],
c_s_axis_tdata
[
280
+:
8
],
c_s_axis_tdata
[
288
+:
8
],
c_s_axis_tdata
[
296
+:
8
],
c_s_axis_tdata
[
304
+:
8
],
c_s_axis_tdata
[
312
+:
8
],
c_s_axis_tdata
[
320
+:
8
],
c_s_axis_tdata
[
328
+:
8
],
c_s_axis_tdata
[
336
+:
8
],
c_s_axis_tdata
[
344
+:
8
],
c_s_axis_tdata
[
352
+:
8
],
c_s_axis_tdata
[
360
+:
8
],
c_s_axis_tdata
[
368
+:
8
],
c_s_axis_tdata
[
376
+:
8
],
c_s_axis_tdata
[
384
+:
8
],
c_s_axis_tdata
[
392
+:
8
],
c_s_axis_tdata
[
400
+:
8
],
c_s_axis_tdata
[
408
+:
8
],
c_s_axis_tdata
[
416
+:
8
],
c_s_axis_tdata
[
424
+:
8
],
c_s_axis_tdata
[
432
+:
8
],
c_s_axis_tdata
[
440
+:
8
],
c_s_axis_tdata
[
448
+:
8
],
c_s_axis_tdata
[
456
+:
8
],
c_s_axis_tdata
[
464
+:
8
],
c_s_axis_tdata
[
472
+:
8
],
c_s_axis_tdata
[
480
+:
8
],
c_s_axis_tdata
[
488
+:
8
],
c_s_axis_tdata
[
496
+:
8
],
c_s_axis_tdata
[
504
+:
8
]
}
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
c_wr_en_off
<=
1'b0
;
c_wr_en_mask
<=
1'b0
;
c_index
<=
8'b0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
key_off_entry_reg
<=
0
;
key_mask_entry_reg
<=
0
;
c_state
<=
IDLE_C
;
end
else
begin
case
(
c_state
)
IDLE_C:
begin
if
(
c_s_axis_tvalid
&&
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
KEY_EX_ID
&&
control_flag
==
16'hf2f1
)
begin
//c_wr_en <= 1'b1;
c_index
<=
c_s_axis_tdata
[
384
+:
8
];
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
//c_state <= WRITE_C;
if
(
resv
==
4'b0
)
begin
c_wr_en_off
<=
1'b0
;
c_state
<=
WRITE_OFF_C
;
end
else
begin
c_wr_en_mask
<=
1'b0
;
c_state
<=
WRITE_MASK_C
;
end
end
else
begin
c_wr_en_off
<=
1'b0
;
c_wr_en_mask
<=
1'b0
;
c_index
<=
8'b0
;
c_m_axis_tdata
<=
c_s_axis_tdata
;
c_m_axis_tuser
<=
c_s_axis_tuser
;
c_m_axis_tkeep
<=
c_s_axis_tkeep
;
c_m_axis_tvalid
<=
c_s_axis_tvalid
;
c_m_axis_tlast
<=
c_s_axis_tlast
;
c_state
<=
IDLE_C
;
end
end
//support full table flush
WRITE_OFF_C:
begin
if
(
c_s_axis_tvalid
)
begin
key_off_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
38
];
c_wr_en_off
<=
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_OFF_C
;
end
end
else
begin
c_wr_en_off
<=
0
;
end
end
SU_WRITE_OFF_C:
begin
if
(
c_s_axis_tvalid
)
begin
key_off_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
38
];
c_wr_en_off
<=
1'b1
;
c_index
<=
c_index
+
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_OFF_C
;
end
end
else
begin
c_wr_en_off
<=
1'b0
;
end
end
WRITE_MASK_C:
begin
if
(
c_s_axis_tvalid
)
begin
key_mask_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
193
];
c_wr_en_mask
<=
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_MASK_C
;
end
end
else
begin
c_wr_en_mask
<=
0
;
end
end
SU_WRITE_MASK_C:
begin
if
(
c_s_axis_tvalid
)
begin
key_mask_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
193
];
c_wr_en_mask
<=
1'b1
;
c_index
<=
c_index
+
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_MASK_C
;
end
end
else
begin
c_wr_en_mask
<=
1'b0
;
end
end
default:
begin
c_wr_en_off
<=
1'b0
;
c_wr_en_mask
<=
1'b0
;
c_index
<=
8'b0
;
c_m_axis_tdata
<=
c_s_axis_tdata
;
c_m_axis_tuser
<=
c_s_axis_tuser
;
c_m_axis_tkeep
<=
c_s_axis_tkeep
;
c_m_axis_tvalid
<=
c_s_axis_tvalid
;
c_m_axis_tlast
<=
c_s_axis_tlast
;
end
endcase
end
end
//ram for key extract
blk_mem_gen_2
key_ram_38w_32d
(
.
addra
(
c_index
[
4
:
0
]),
.
clka
(
clk
),
.
dina
(
key_off_entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en_off
),
//only [3:0] is needed for addressing
.
addrb
(
vlan_in
[
8
:
4
]),
.
clkb
(
clk
),
.
doutb
(
key_offset_w
),
.
enb
(
1'b1
)
);
blk_mem_gen_3
mask_ram_193w_32d
(
.
addra
(
c_index
[
4
:
0
]),
.
clka
(
clk
),
.
dina
(
key_mask_entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en_mask
),
//only [3:0] is needed for addressing
.
addrb
(
vlan_in
[
8
:
4
]),
.
clkb
(
clk
),
.
doutb
(
key_mask_out_w
),
.
enb
(
1'b1
)
);
end
else
if
(
C_S_AXIS_DATA_WIDTH
==
256
)
begin
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
]
}
;
assign
mod_id
=
c_s_axis_tdata
[
112
+:
8
];
//4'b0 for key offset
//4'b1 for key mask
assign
resv
=
c_s_axis_tdata
[
120
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
64
+:
16
];
reg
[
7
:
0
]
c_index_next
;
reg
[
2
:
0
]
c_state_next
;
reg
c_wr_en_off_next
,
c_wr_en_mask_next
;
reg
[
37
:
0
]
key_off_entry_reg
,
key_off_entry_reg_next
;
reg
[
192
:
0
]
key_mask_entry_reg
,
key_mask_entry_reg_next
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_tdata
,
c_s_axis_tdata_d1
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_tuser
,
c_s_axis_tuser_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_tkeep
,
c_s_axis_tkeep_d1
;
reg
r_tlast
,
c_s_axis_tlast_d1
;
reg
r_tvalid
,
c_s_axis_tvalid_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_1st_tdata
,
r_1st_tdata_next
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_1st_tuser
,
r_1st_tuser_next
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_1st_tkeep
,
r_1st_tkeep_next
;
reg
r_1st_tlast
,
r_1st_tlast_next
;
reg
r_1st_tvalid
,
r_1st_tvalid_next
;
always
@
(
*
)
begin
c_state_next
=
c_state
;
r_tdata
=
0
;
r_tkeep
=
0
;
r_tuser
=
0
;
r_tlast
=
0
;
r_tvalid
=
0
;
r_1st_tdata_next
=
r_1st_tdata
;
r_1st_tkeep_next
=
r_1st_tkeep
;
r_1st_tuser_next
=
r_1st_tuser
;
r_1st_tlast_next
=
r_1st_tlast
;
r_1st_tvalid_next
=
r_1st_tvalid
;
c_wr_en_mask_next
=
0
;
c_wr_en_off_next
=
0
;
c_index_next
=
c_index
;
key_off_entry_reg_next
=
key_off_entry_reg
;
key_mask_entry_reg_next
=
key_mask_entry_reg
;
case
(
c_state
)
IDLE_C:
begin
r_tvalid
=
0
;
// 1st segment
if
(
c_s_axis_tvalid
)
begin
// store 1st element
r_1st_tdata_next
=
c_s_axis_tdata
;
r_1st_tuser_next
=
c_s_axis_tuser
;
r_1st_tkeep_next
=
c_s_axis_tkeep
;
r_1st_tlast_next
=
c_s_axis_tlast
;
r_1st_tvalid_next
=
c_s_axis_tvalid
;
c_state_next
=
PARSE_C
;
end
end
PARSE_C:
begin
// 2nd segment
if
(
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
KEY_EX_ID
&&
control_flag
==
16'hf2f1
&&
c_s_axis_tvalid
)
begin
if
(
resv
==
4'b0
&&
c_s_axis_tvalid
)
begin
c_index_next
=
c_s_axis_tdata
[
128
+:
8
];
c_state_next
=
WRITE_OFF_C
;
end
else
begin
c_index_next
=
c_s_axis_tdata
[
128
+:
8
];
c_state_next
=
WRITE_MASK_C
;
end
end
else
if
(
!
c_s_axis_tvalid
)
begin
end
else
begin
// emit
r_tdata
=
r_1st_tdata
;
r_tkeep
=
r_1st_tkeep
;
r_tuser
=
r_1st_tuser
;
r_tlast
=
r_1st_tlast
;
r_tvalid
=
r_1st_tvalid
;
c_state_next
=
FLUSH_PKT_C
;
end
end
WRITE_OFF_C:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_en_off_next
=
1
;
key_off_entry_reg_next
=
c_s_axis_tdata_swapped
[
255
-:
38
];
c_state_next
=
FLUSH_PKT_C
;
end
end
WRITE_MASK_C:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_en_mask_next
=
1
;
key_mask_entry_reg_next
=
c_s_axis_tdata_swapped
[
255
-:
193
];
c_state_next
=
FLUSH_PKT_C
;
end
end
FLUSH_PKT_C:
begin
c_wr_en_off_next
=
0
;
c_wr_en_mask_next
=
0
;
r_tdata
=
c_s_axis_tdata_d1
;
r_tkeep
=
c_s_axis_tkeep_d1
;
r_tuser
=
c_s_axis_tuser_d1
;
r_tlast
=
c_s_axis_tlast_d1
;
r_tvalid
=
c_s_axis_tvalid_d1
;
if
(
c_s_axis_tvalid_d1
&&
c_s_axis_tlast_d1
)
begin
c_state_next
=
IDLE_C
;
end
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
c_state
<=
IDLE_C
;
// ctrl output
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tlast
<=
0
;
c_m_axis_tvalid
<=
0
;
//
c_index
<=
0
;
c_wr_en_off
<=
0
;
c_wr_en_mask
<=
0
;
key_off_entry_reg
<=
0
;
key_mask_entry_reg
<=
0
;
end
else
begin
c_state
<=
c_state_next
;
// output ctrl master signals
c_m_axis_tdata
<=
r_tdata
;
c_m_axis_tkeep
<=
r_tkeep
;
c_m_axis_tuser
<=
r_tuser
;
c_m_axis_tlast
<=
r_tlast
;
c_m_axis_tvalid
<=
r_tvalid
;
//
c_index
<=
c_index_next
;
c_wr_en_off
<=
c_wr_en_off_next
;
c_wr_en_mask
<=
c_wr_en_mask_next
;
key_off_entry_reg
<=
key_off_entry_reg_next
;
key_mask_entry_reg
<=
key_mask_entry_reg_next
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
0
;
c_s_axis_tuser_d1
<=
0
;
c_s_axis_tkeep_d1
<=
0
;
c_s_axis_tlast_d1
<=
0
;
c_s_axis_tvalid_d1
<=
0
;
//
r_1st_tdata
<=
0
;
r_1st_tkeep
<=
0
;
r_1st_tuser
<=
0
;
r_1st_tlast
<=
0
;
r_1st_tvalid
<=
0
;
end
else
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
c_s_axis_tdata
;
c_s_axis_tuser_d1
<=
c_s_axis_tuser
;
c_s_axis_tkeep_d1
<=
c_s_axis_tkeep
;
c_s_axis_tlast_d1
<=
c_s_axis_tlast
;
c_s_axis_tvalid_d1
<=
c_s_axis_tvalid
;
//
r_1st_tdata
<=
r_1st_tdata_next
;
r_1st_tkeep
<=
r_1st_tkeep_next
;
r_1st_tuser
<=
r_1st_tuser_next
;
r_1st_tlast
<=
r_1st_tlast_next
;
r_1st_tvalid
<=
r_1st_tvalid_next
;
end
end
//ram for key extract
//blk_mem_gen_2 act_ram_18w_16d
// blk_mem_gen_2 #(
// .C_INIT_FILE_NAME ("./key_extract.mif"),
// .C_LOAD_INIT_FILE (1)
// )
blk_mem_gen_2
key_ram_38w_32d
(
.
addra
(
c_index
[
4
:
0
]),
.
clka
(
clk
),
.
dina
(
key_off_entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en_off
),
//only [3:0] is needed for addressing
.
addrb
(
vlan_in
[
8
:
4
]),
.
clkb
(
clk
),
.
doutb
(
key_offset_w
),
.
enb
(
1'b1
)
);
blk_mem_gen_3
mask_ram_193w_16d
(
.
addra
(
c_index
[
4
:
0
]),
.
clka
(
clk
),
.
dina
(
key_mask_entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en_mask
),
//only [3:0] is needed for addressing
.
addrb
(
vlan_in
[
8
:
4
]),
.
clkb
(
clk
),
.
doutb
(
key_mask_out_w
),
.
enb
(
1'b1
)
);
end
endgenerate
//==========================================================
endmodule
sims/net/menshen/rtl/last_stage.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
last_stage
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
// valid: 0-4
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
1
,
parameter
ACT_LEN
=
25
,
parameter
KEY_OFF
=
6
*
3
+
20
,
parameter
C_NUM_QUEUES
=
4
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
axis_clk
,
input
aresetn
,
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_in_valid
,
output
stage_ready_out
,
output
vlan_ready_out
,
input
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_in
,
input
vlan_valid_in
,
//
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out_0
,
output
reg
phv_out_valid_0
,
input
phv_fifo_ready_0
,
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out_1
,
output
reg
phv_out_valid_1
,
input
phv_fifo_ready_1
,
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out_2
,
output
reg
phv_out_valid_2
,
input
phv_fifo_ready_2
,
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out_3
,
output
reg
phv_out_valid_3
,
input
phv_fifo_ready_3
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
c_m_axis_tvalid
,
output
c_m_axis_tlast
);
//key_extract to lookup_engine
wire
[
KEY_LEN
-
1
:
0
]
key2lookup_key
;
wire
key2lookup_key_valid
;
wire
key2lookup_phv_valid
;
wire
[
PHV_LEN
-
1
:
0
]
key2lookup_phv
;
wire
lookup2key_ready
;
reg
[
KEY_LEN
-
1
:
0
]
key2lookup_key_r
;
reg
key2lookup_key_valid_r
;
reg
key2lookup_phv_valid_r
;
reg
[
PHV_LEN
-
1
:
0
]
key2lookup_phv_r
;
//control path 1 (key2lookup)
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_1
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
c_s_axis_tkeep_1
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser_1
;
wire
c_s_axis_tvalid_1
;
wire
c_s_axis_tlast_1
;
//control path 2 (lkup2action)
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_2
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
c_s_axis_tkeep_2
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser_2
;
wire
c_s_axis_tvalid_2
;
wire
c_s_axis_tlast_2
;
//lookup_engine to action_engine
wire
[
ACT_LEN
*
25
-
1
:
0
]
lookup2action_action
;
wire
lookup2action_action_valid
;
wire
[
PHV_LEN
-
1
:
0
]
lookup2action_phv
;
wire
action2lookup_ready
;
reg
[
ACT_LEN
*
25
-
1
:
0
]
lookup2action_action_r
;
reg
lookup2action_action_valid_r
;
reg
[
PHV_LEN
-
1
:
0
]
lookup2action_phv_r
;
wire
[
PHV_LEN
-
1
:
0
]
phv_out
;
wire
phv_out_valid_from_ae
;
//
wire
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out
;
wire
act_vlan_out_valid
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out_r
;
reg
act_vlan_out_valid_r
;
wire
act_vlan_ready
;
key_extract_top
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(),
.
KEY_LEN
(
KEY_LEN
),
// format of KEY_OFF entry: |--3(6B)--|--3(6B)--|--3(4B)--|--3(4B)--|--3(2B)--|--3(2B)--|
.
KEY_OFF
(
KEY_OFF
),
.
AXIL_WIDTH
(),
.
KEY_OFF_ADDR_WIDTH
(),
.
KEY_EX_ID
()
)
key_extract
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
.
phv_in
(
phv_in
),
.
phv_valid_in
(
phv_in_valid
),
.
ready_out
(
stage_ready_out
),
// vlan
.
vlan_in
(
vlan_in
),
.
vlan_in_valid
(
vlan_valid_in
),
.
vlan_ready
(
vlan_ready_out
),
.
phv_out
(
key2lookup_phv
),
.
phv_valid_out
(
key2lookup_phv_valid
),
.
key_out_masked
(
key2lookup_key
),
.
key_valid_out
(
key2lookup_key_valid
),
.
ready_in
(
lookup2key_ready
),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata
),
.
c_s_axis_tuser
(
c_s_axis_tuser
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid
),
.
c_s_axis_tlast
(
c_s_axis_tlast
),
.
c_m_axis_tdata
(
c_s_axis_tdata_1
),
.
c_m_axis_tuser
(
c_s_axis_tuser_1
),
.
c_m_axis_tkeep
(
c_s_axis_tkeep_1
),
.
c_m_axis_tvalid
(
c_s_axis_tvalid_1
),
.
c_m_axis_tlast
(
c_s_axis_tlast_1
)
);
lookup_engine_top
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(),
.
KEY_LEN
(
KEY_LEN
),
.
ACT_LEN
(),
.
LOOKUP_ID
()
)
lookup_engine
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
//output from key extractor
.
extract_key
(
key2lookup_key_r
),
.
key_valid
(
key2lookup_key_valid_r
),
.
phv_valid
(
key2lookup_phv_valid_r
),
.
phv_in
(
key2lookup_phv_r
),
.
ready_out
(
lookup2key_ready
),
//output to the action engine
.
action
(
lookup2action_action
),
.
action_valid
(
lookup2action_action_valid
),
.
phv_out
(
lookup2action_phv
),
.
ready_in
(
action2lookup_ready
),
//
.
act_vlan_out
(
act_vlan_out
),
.
act_vlan_valid_out
(
act_vlan_out_valid
),
// .act_vlan_ready (act_vlan_ready),
.
act_vlan_ready
(
action2lookup_ready
),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata_1
),
.
c_s_axis_tuser
(
c_s_axis_tuser_1
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep_1
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid_1
),
.
c_s_axis_tlast
(
c_s_axis_tlast_1
),
.
c_m_axis_tdata
(
c_s_axis_tdata_2
),
.
c_m_axis_tuser
(
c_s_axis_tuser_2
),
.
c_m_axis_tkeep
(
c_s_axis_tkeep_2
),
.
c_m_axis_tvalid
(
c_s_axis_tvalid_2
),
.
c_m_axis_tlast
(
c_s_axis_tlast_2
)
);
action_engine
#(
.
STAGE_ID
(
STAGE_ID
),
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
PHV_LEN
(),
.
ACT_LEN
(),
.
ACTION_ID
()
)
action_engine
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
//signals from lookup to ALUs
.
phv_in
(
lookup2action_phv_r
),
.
phv_valid_in
(
lookup2action_action_valid_r
),
.
action_in
(
lookup2action_action_r
),
.
action_valid_in
(
lookup2action_action_valid_r
),
.
ready_out
(
action2lookup_ready
),
//signals output from ALUs
.
phv_out
(
phv_out
),
.
phv_valid_out
(
phv_out_valid_from_ae
),
.
ready_in
(
phv_fifo_ready_0
||
phv_fifo_ready_1
||
phv_fifo_ready_2
||
phv_fifo_ready_3
),
.
act_vlan_in
(
act_vlan_out_r
),
.
act_vlan_valid_in
(
act_vlan_out_valid_r
),
.
act_vlan_ready
(
act_vlan_ready
),
// vlan
.
vlan_out
(),
.
vlan_out_valid
(),
.
vlan_out_ready
(),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata_2
),
.
c_s_axis_tuser
(
c_s_axis_tuser_2
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep_2
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid_2
),
.
c_s_axis_tlast
(
c_s_axis_tlast_2
),
.
c_m_axis_tdata
(
c_m_axis_tdata
),
.
c_m_axis_tuser
(
c_m_axis_tuser
),
.
c_m_axis_tkeep
(
c_m_axis_tkeep
),
.
c_m_axis_tvalid
(
c_m_axis_tvalid
),
.
c_m_axis_tlast
(
c_m_axis_tlast
)
);
// pkt_hdr_vec_next = {pkt_hdr_vec_w[PKT_HDR_LEN-1:145], p_cur_queue_val, pkt_hdr_vec_w[0+:141]};
// position: [141+:4]
//
reg
[
PHV_LEN
-
1
:
0
]
phv_out_0_next
;
reg
[
PHV_LEN
-
1
:
0
]
phv_out_1_next
;
reg
[
PHV_LEN
-
1
:
0
]
phv_out_2_next
;
reg
[
PHV_LEN
-
1
:
0
]
phv_out_3_next
;
reg
phv_out_valid_0_next
;
reg
phv_out_valid_1_next
;
reg
phv_out_valid_2_next
;
reg
phv_out_valid_3_next
;
always
@
(
*
)
begin
phv_out_valid_0_next
=
0
;
phv_out_valid_1_next
=
0
;
phv_out_valid_2_next
=
0
;
phv_out_valid_3_next
=
0
;
phv_out_0_next
=
phv_out
;
phv_out_1_next
=
phv_out
;
phv_out_2_next
=
phv_out
;
phv_out_3_next
=
phv_out
;
if
(
phv_out_valid_from_ae
)
begin
if
(
phv_out
[
141
])
begin
phv_out_valid_0_next
=
1
;
end
if
(
phv_out
[
142
])
begin
phv_out_valid_1_next
=
1
;
end
if
(
phv_out
[
143
])
begin
phv_out_valid_2_next
=
1
;
end
if
(
phv_out
[
144
])
begin
phv_out_valid_3_next
=
1
;
end
end
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
phv_out_0
<=
0
;
phv_out_1
<=
0
;
phv_out_2
<=
0
;
phv_out_3
<=
0
;
phv_out_valid_0
<=
0
;
phv_out_valid_1
<=
0
;
phv_out_valid_2
<=
0
;
phv_out_valid_3
<=
0
;
end
else
begin
phv_out_0
<=
phv_out_0_next
;
phv_out_1
<=
phv_out_1_next
;
phv_out_2
<=
phv_out_2_next
;
phv_out_3
<=
phv_out_3_next
;
phv_out_valid_0
<=
phv_out_valid_0_next
;
phv_out_valid_1
<=
phv_out_valid_1_next
;
phv_out_valid_2
<=
phv_out_valid_2_next
;
phv_out_valid_3
<=
phv_out_valid_3_next
;
end
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
key2lookup_key_r
<=
0
;
key2lookup_key_valid_r
<=
0
;
key2lookup_phv_valid_r
<=
0
;
key2lookup_phv_r
<=
0
;
lookup2action_action_r
<=
0
;
lookup2action_action_valid_r
<=
0
;
lookup2action_phv_r
<=
0
;
//
act_vlan_out_r
<=
0
;
act_vlan_out_valid_r
<=
0
;
end
else
begin
key2lookup_key_r
<=
key2lookup_key
;
key2lookup_key_valid_r
<=
key2lookup_key_valid
;
key2lookup_phv_valid_r
<=
key2lookup_phv_valid
;
key2lookup_phv_r
<=
key2lookup_phv
;
lookup2action_action_r
<=
lookup2action_action
;
lookup2action_action_valid_r
<=
lookup2action_action_valid
;
lookup2action_phv_r
<=
lookup2action_phv
;
//
act_vlan_out_r
<=
act_vlan_out
;
act_vlan_out_valid_r
<=
act_vlan_out_valid
;
end
end
endmodule
sims/net/menshen/rtl/lookup/lke_cam_part.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
lke_cam_part
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
5
,
parameter
ACT_LEN
=
625
,
parameter
LOOKUP_ID
=
2
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
rst_n
,
//output from key extractor
input
[
KEY_LEN
-
1
:
0
]
extract_key
,
input
key_valid
,
input
phv_valid
,
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
output
ready_out
,
// output to the ram part
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out
,
output
reg
phv_out_valid
,
output
reg
[
3
:
0
]
match_addr_out
,
output
reg
if_match
,
input
ready_in
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
reg
c_m_axis_tvalid
,
output
reg
c_m_axis_tlast
);
/********intermediate variables declared here********/
wire
[
3
:
0
]
match_addr
;
wire
match
;
reg
[
PHV_LEN
-
1
:
0
]
phv_reg
;
reg
[
2
:
0
]
lookup_state
;
wire
[
11
:
0
]
vlan_id
;
assign
vlan_id
=
phv_in
[
140
:
129
];
wire
[
204
:
0
]
dbg_input
;
assign
dbg_input
=
{
vlan_id
[
3
:
0
],
vlan_id
[
11
:
4
],
extract_key
}
;
/********intermediate variables declared here********/
//here, the output should be controlled.
localparam
IDLE_S
=
3'd0
,
WAIT1_S
=
3'd1
,
WAIT2_S
=
3'd2
,
TRANS_S
=
3'd3
,
HALT_S
=
3'd4
,
EMPTY1_S
=
3'd5
,
OUTPUT_S
=
3'd6
;
assign
ready_out
=
lookup_state
!=
HALT_S
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
phv_reg
<=
0
;
lookup_state
<=
IDLE_S
;
phv_out
<=
0
;
phv_out_valid
<=
0
;
match_addr_out
<=
0
;
if_match
<=
0
;
// ready_out <= 1'b1;
end
else
begin
case
(
lookup_state
)
IDLE_S:
begin
if
(
key_valid
==
1'b1
)
begin
// ready_out <= 1'b0;
phv_reg
<=
phv_in
;
lookup_state
<=
WAIT1_S
;
end
else
begin
phv_out_valid
<=
0
;
if_match
<=
0
;
// ready_out <= 1'b1;
lookup_state
<=
IDLE_S
;
end
end
WAIT1_S:
begin
if
(
ready_in
)
begin
phv_out
<=
phv_reg
;
phv_out_valid
<=
1'b1
;
if
(
match
==
1'b0
)
begin
// CAM miss
if_match
<=
0
;
match_addr_out
<=
4'hf
;
end
else
begin
// CAM hit
if_match
<=
1
;
match_addr_out
<=
match_addr
;
end
lookup_state
<=
IDLE_S
;
// ready_out <= 1'b1;
end
else
begin
lookup_state
<=
HALT_S
;
end
end
HALT_S:
begin
if
(
ready_in
)
begin
phv_out
<=
phv_reg
;
phv_out_valid
<=
1'b1
;
if
(
match
==
1'b0
)
begin
// CAM miss
if_match
<=
0
;
match_addr_out
<=
4'hf
;
end
else
begin
// CAM hit
if_match
<=
1
;
match_addr_out
<=
match_addr
;
end
lookup_state
<=
IDLE_S
;
// ready_out <= 1'b1;
end
end
endcase
end
end
//======================================================================
//======================================================================
/****control path*****/
wire
[
7
:
0
]
mod_id
;
//module ID
//4'b0 for tcam entry;
//NOTE: we don't need tcam entry mask
//4'b2 for action table entry;
wire
[
3
:
0
]
resv
;
//recog between tcam and action
wire
[
15
:
0
]
control_flag
;
//dst udp port num
reg
[
7
:
0
]
c_index_cam
;
//table index(addr)
reg
c_wr_en_cam
;
//enable table write(wena)
reg
[
7
:
0
]
c_index_act
;
reg
c_wr_en_act
;
reg
[
ACT_LEN
-
1
:
0
]
act_entry_tmp
;
reg
continous_flag
;
reg
[
204
:
0
]
cam_entry_reg
;
reg
[
2
:
0
]
c_state
;
/****for 256b exclusively*****/
reg
c_m_axis_tvalid_r
;
reg
c_m_axis_tlast_r
;
localparam
IDLE_C
=
0
,
PARSE_C
=
1
,
CAM_TMP_ENTRY
=
2
,
SU_CAM_TMP_ENTRY
=
3
,
ACT_TMP_ENTRY_WAIT
=
4
,
ACT_TMP_ENTRY_WAIT_2
=
5
,
ACT_TMP_ENTRY
=
6
,
FLUSH_REST_C
=
7
;
generate
if
(
C_S_AXIS_DATA_WIDTH
==
512
)
begin
assign
mod_id
=
c_s_axis_tdata
[
368
+:
8
];
assign
resv
=
c_s_axis_tdata
[
376
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
335
:
320
];
//LE to BE switching
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
],
c_s_axis_tdata
[
256
+:
8
],
c_s_axis_tdata
[
264
+:
8
],
c_s_axis_tdata
[
272
+:
8
],
c_s_axis_tdata
[
280
+:
8
],
c_s_axis_tdata
[
288
+:
8
],
c_s_axis_tdata
[
296
+:
8
],
c_s_axis_tdata
[
304
+:
8
],
c_s_axis_tdata
[
312
+:
8
],
c_s_axis_tdata
[
320
+:
8
],
c_s_axis_tdata
[
328
+:
8
],
c_s_axis_tdata
[
336
+:
8
],
c_s_axis_tdata
[
344
+:
8
],
c_s_axis_tdata
[
352
+:
8
],
c_s_axis_tdata
[
360
+:
8
],
c_s_axis_tdata
[
368
+:
8
],
c_s_axis_tdata
[
376
+:
8
],
c_s_axis_tdata
[
384
+:
8
],
c_s_axis_tdata
[
392
+:
8
],
c_s_axis_tdata
[
400
+:
8
],
c_s_axis_tdata
[
408
+:
8
],
c_s_axis_tdata
[
416
+:
8
],
c_s_axis_tdata
[
424
+:
8
],
c_s_axis_tdata
[
432
+:
8
],
c_s_axis_tdata
[
440
+:
8
],
c_s_axis_tdata
[
448
+:
8
],
c_s_axis_tdata
[
456
+:
8
],
c_s_axis_tdata
[
464
+:
8
],
c_s_axis_tdata
[
472
+:
8
],
c_s_axis_tdata
[
480
+:
8
],
c_s_axis_tdata
[
488
+:
8
],
c_s_axis_tdata
[
496
+:
8
],
c_s_axis_tdata
[
504
+:
8
]
}
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
cam_entry_reg
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
c_state
<=
IDLE_C
;
end
else
begin
case
(
c_state
)
IDLE_C:
begin
if
(
c_s_axis_tvalid
)
begin
if
(
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
LOOKUP_ID
&&
control_flag
==
16'hf2f1
&&
resv
==
4'b0
)
begin
// TCAM entry
c_wr_en_cam
<=
1'b0
;
c_index_cam
<=
c_s_axis_tdata
[
384
+:
8
];
c_state
<=
CAM_TMP_ENTRY
;
end
//not for lookup
else
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
c_s_axis_tdata
;
c_m_axis_tuser
<=
c_s_axis_tuser
;
c_m_axis_tkeep
<=
c_s_axis_tkeep
;
c_m_axis_tvalid
<=
c_s_axis_tvalid
;
c_m_axis_tlast
<=
c_s_axis_tlast
;
c_state
<=
IDLE_C
;
end
end
//stay halt
else
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
c_state
<=
IDLE_C
;
end
end
CAM_TMP_ENTRY:
begin
if
(
c_s_axis_tvalid
)
begin
cam_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
205
];
c_wr_en_cam
<=
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_CAM_TMP_ENTRY
;
end
end
else
begin
c_wr_en_cam
<=
1'b0
;
end
end
SU_CAM_TMP_ENTRY:
begin
if
(
c_s_axis_tvalid
)
begin
cam_entry_reg
<=
c_s_axis_tdata_swapped
[
511
-:
205
];
c_wr_en_cam
<=
1'b1
;
c_index_cam
<=
c_index_cam
+
1'b1
;
if
(
c_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_CAM_TMP_ENTRY
;
end
end
else
begin
c_wr_en_cam
<=
1'b0
;
end
end
endcase
end
end
if
(
STAGE_ID
==
4
)
begin
// tcam1 for lookup
cam_top
#
(
.
C_DEPTH
(
16
),
// .C_WIDTH (256),
.
C_WIDTH
(
205
),
.
C_MEM_INIT
(
0
)
// .C_MEM_INIT_FILE ("./cam_init_file.mif")
)
cam_0
(
.
CLK
(
clk
),
.
CMP_DIN
(
{
vlan_id
[
3
:
0
],
vlan_id
[
11
:
4
],
extract_key
}
),
//.CMP_DATA_MASK ({4'b1111, extract_mask}),
.
CMP_DATA_MASK
(),
.
BUSY
(),
.
MATCH
(
match
),
.
MATCH_ADDR
(
match_addr
[
3
:
0
]),
//.WE (lookup_din_en),
//.WR_ADDR (lookup_din_addr),
//.DATA_MASK (lookup_din_mask),
//.DIN (lookup_din),
.
WE
(
c_wr_en_cam
),
.
WR_ADDR
(
c_index_cam
[
3
:
0
]),
.
DATA_MASK
(),
//TODO do we need ternary matching?
.
DIN
(
cam_entry_reg
),
.
EN
(
1'b1
)
);
end
else
begin
// tcam1 for lookup
cam_top
#
(
.
C_DEPTH
(
16
),
// .C_WIDTH (256),
.
C_WIDTH
(
205
),
.
C_MEM_INIT
(
0
)
// .C_MEM_INIT_FILE ("./cam_init_file.mif")
)
cam_0
(
.
CLK
(
clk
),
.
CMP_DIN
(
{
vlan_id
[
3
:
0
],
vlan_id
[
11
:
4
],
extract_key
}
),
//.CMP_DATA_MASK ({4'b0000, extract_mask}),
.
CMP_DATA_MASK
(),
.
BUSY
(),
.
MATCH
(
match
),
.
MATCH_ADDR
(
match_addr
[
3
:
0
]),
//.WE (lookup_din_en),
//.WR_ADDR (lookup_din_addr),
//.DATA_MASK (lookup_din_mask),
//.DIN (lookup_din),
.
WE
(
c_wr_en_cam
),
.
WR_ADDR
(
c_index_cam
[
3
:
0
]),
.
DATA_MASK
(),
//TODO do we need ternary matching?
.
DIN
(
cam_entry_reg
),
.
EN
(
1'b1
)
);
end
end
//NOTE: data width is 256b
else
begin
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
]
}
;
assign
mod_id
=
c_s_axis_tdata
[
112
+:
8
];
assign
resv
=
c_s_axis_tdata
[
120
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
64
+:
16
];
//
reg
[
2
:
0
]
c_state_next
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_tdata
,
c_s_axis_tdata_d1
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_tuser
,
c_s_axis_tuser_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_tkeep
,
c_s_axis_tkeep_d1
;
reg
r_tlast
,
c_s_axis_tlast_d1
;
reg
r_tvalid
,
c_s_axis_tvalid_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_1st_tdata
,
r_1st_tdata_next
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_1st_tuser
,
r_1st_tuser_next
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_1st_tkeep
,
r_1st_tkeep_next
;
reg
r_1st_tlast
,
r_1st_tlast_next
;
reg
r_1st_tvalid
,
r_1st_tvalid_next
;
reg
[
7
:
0
]
c_index_cam_next
,
c_index_act_next
;
reg
c_wr_en_cam_next
,
c_wr_en_act_next
;
reg
[
204
:
0
]
c_wr_cam_data
,
c_wr_cam_data_next
;
reg
[
ACT_LEN
-
1
:
0
]
c_wr_act_data
,
c_wr_act_data_next
;
always
@
(
*
)
begin
c_state_next
=
c_state
;
r_tdata
=
0
;
r_tkeep
=
0
;
r_tuser
=
0
;
r_tlast
=
0
;
r_tvalid
=
0
;
r_1st_tdata_next
=
r_1st_tdata
;
r_1st_tkeep_next
=
r_1st_tkeep
;
r_1st_tuser_next
=
r_1st_tuser
;
r_1st_tlast_next
=
r_1st_tlast
;
r_1st_tvalid_next
=
r_1st_tvalid
;
c_index_cam_next
=
c_index_cam
;
c_index_act_next
=
c_index_act
;
c_wr_en_cam_next
=
0
;
c_wr_en_act_next
=
0
;
c_wr_cam_data_next
=
c_wr_cam_data
;
c_wr_act_data_next
=
c_wr_act_data
;
case
(
c_state
)
IDLE_C:
begin
// 1st segment
r_tvalid
=
0
;
if
(
c_s_axis_tvalid
)
begin
// store 1st segment
r_1st_tdata_next
=
c_s_axis_tdata
;
r_1st_tuser_next
=
c_s_axis_tuser
;
r_1st_tkeep_next
=
c_s_axis_tkeep
;
r_1st_tlast_next
=
c_s_axis_tlast
;
r_1st_tvalid_next
=
c_s_axis_tvalid
;
c_state_next
=
PARSE_C
;
end
end
PARSE_C:
begin
// 2nd segment
if
(
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
LOOKUP_ID
&&
control_flag
==
16'hf2f1
&&
c_s_axis_tvalid
&&
resv
==
4'b0
)
begin
// should not emit segment
c_index_cam_next
=
c_s_axis_tdata
[
128
+:
8
];
c_state_next
=
CAM_TMP_ENTRY
;
end
else
if
(
!
c_s_axis_tvalid
)
begin
end
else
begin
// emit
r_tdata
=
r_1st_tdata
;
r_tkeep
=
r_1st_tkeep
;
r_tuser
=
r_1st_tuser
;
r_tlast
=
r_1st_tlast
;
r_tvalid
=
r_1st_tvalid
;
c_state_next
=
FLUSH_REST_C
;
end
end
CAM_TMP_ENTRY:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_en_cam_next
=
1
;
// next clk to write
c_wr_cam_data_next
=
c_s_axis_tdata_swapped
[
51
+:
205
];
c_state_next
=
IDLE_C
;
end
end
FLUSH_REST_C:
begin
c_wr_en_cam_next
=
0
;
c_wr_en_act_next
=
0
;
r_tdata
=
c_s_axis_tdata_d1
;
r_tkeep
=
c_s_axis_tkeep_d1
;
r_tuser
=
c_s_axis_tuser_d1
;
r_tlast
=
c_s_axis_tlast_d1
;
r_tvalid
=
c_s_axis_tvalid_d1
;
if
(
c_s_axis_tvalid_d1
&&
c_s_axis_tlast_d1
)
begin
c_state_next
=
IDLE_C
;
end
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
c_state
<=
IDLE_C
;
// control output
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tlast
<=
0
;
c_m_axis_tvalid
<=
0
;
//
c_index_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_cam
<=
0
;
c_wr_en_act
<=
0
;
c_wr_cam_data
<=
0
;
c_wr_act_data
<=
0
;
end
else
begin
c_state
<=
c_state_next
;
// output ctrl master signals
c_m_axis_tdata
<=
r_tdata
;
c_m_axis_tkeep
<=
r_tkeep
;
c_m_axis_tuser
<=
r_tuser
;
c_m_axis_tlast
<=
r_tlast
;
c_m_axis_tvalid
<=
r_tvalid
;
//
c_index_cam
<=
c_index_cam_next
;
c_index_act
<=
c_index_act_next
;
c_wr_en_cam
<=
c_wr_en_cam_next
;
c_wr_en_act
<=
c_wr_en_act_next
;
c_wr_cam_data
<=
c_wr_cam_data_next
;
c_wr_act_data
<=
c_wr_act_data_next
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
0
;
c_s_axis_tuser_d1
<=
0
;
c_s_axis_tkeep_d1
<=
0
;
c_s_axis_tlast_d1
<=
0
;
c_s_axis_tvalid_d1
<=
0
;
//
r_1st_tdata
<=
0
;
r_1st_tkeep
<=
0
;
r_1st_tuser
<=
0
;
r_1st_tlast
<=
0
;
r_1st_tvalid
<=
0
;
end
else
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
c_s_axis_tdata
;
c_s_axis_tuser_d1
<=
c_s_axis_tuser
;
c_s_axis_tkeep_d1
<=
c_s_axis_tkeep
;
c_s_axis_tlast_d1
<=
c_s_axis_tlast
;
c_s_axis_tvalid_d1
<=
c_s_axis_tvalid
;
//
r_1st_tdata
<=
r_1st_tdata_next
;
r_1st_tkeep
<=
r_1st_tkeep_next
;
r_1st_tuser
<=
r_1st_tuser_next
;
r_1st_tlast
<=
r_1st_tlast_next
;
r_1st_tvalid
<=
r_1st_tvalid_next
;
end
end
if
(
STAGE_ID
==
4
)
begin
// tcam1 for lookup
cam_top
#
(
.
C_DEPTH
(
16
),
// .C_WIDTH (256),
.
C_WIDTH
(
205
),
// 192+1+12
.
C_MEM_INIT
(
0
)
// .C_MEM_INIT_FILE ("./cam_init_file.mif")
)
//TODO remember to change it back.
cam_0
(
.
CLK
(
clk
),
.
RST
(
~
rst_n
),
.
CMP_DIN
(
{
vlan_id
[
3
:
0
],
vlan_id
[
11
:
4
],
extract_key
}
),
// .CMP_DATA_MASK ({4'b1111, extract_mask}),
.
CMP_DATA_MASK
(),
.
BUSY
(),
.
MATCH
(
match
),
.
MATCH_ADDR
(
match_addr
),
//.WE (lookup_din_en),
//.WR_ADDR (lookup_din_addr),
//.DATA_MASK (lookup_din_mask),
//.DIN (lookup_din),
.
WE
(
c_wr_en_cam
),
.
WR_ADDR
(
c_index_cam
[
3
:
0
]),
// .WR_ADDR (c_index_cam),
.
DATA_MASK
(),
//TODO do we need ternary matching?
.
DIN
(
c_wr_cam_data
),
.
EN
(
1'b1
)
);
end
else
begin
// tcam1 for lookup
cam_top
#
(
.
C_DEPTH
(
16
),
// .C_WIDTH (256),
.
C_WIDTH
(
205
),
// 192+1+12
.
C_MEM_INIT
(
0
)
// .C_MEM_INIT_FILE ("./cam_init_file.mif")
)
//TODO remember to change it back.
cam_0
(
.
CLK
(
clk
),
.
RST
(
~
rst_n
),
.
CMP_DIN
(
{
vlan_id
[
3
:
0
],
vlan_id
[
11
:
4
],
extract_key
}
),
// .CMP_DATA_MASK ({4'b0000, extract_mask}),
.
CMP_DATA_MASK
(),
.
BUSY
(),
.
MATCH
(
match
),
.
MATCH_ADDR
(
match_addr
),
//.WE (lookup_din_en),
//.WR_ADDR (lookup_din_addr),
//.DATA_MASK (lookup_din_mask),
//.DIN (lookup_din),
.
WE
(
c_wr_en_cam
),
.
WR_ADDR
(
c_index_cam
[
3
:
0
]),
// .WR_ADDR (c_index_cam),
.
DATA_MASK
(),
//TODO do we need ternary matching?
.
DIN
(
c_wr_cam_data
),
.
EN
(
1'b1
)
);
end
end
endgenerate
endmodule
sims/net/menshen/rtl/lookup/lke_ram_part.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
lke_ram_part
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
5
,
parameter
ACT_LEN
=
625
,
parameter
LOOKUP_ID
=
2
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
rst_n
,
//output from key extractor
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_valid
,
input
[
3
:
0
]
match_addr
,
input
if_match
,
output
ready_out
,
//output to the action engine
output
[
ACT_LEN
-
1
:
0
]
action
,
output
reg
action_valid
,
output
reg
[
PHV_LEN
-
1
:
0
]
phv_out
,
input
ready_in
,
// output vlan to the action engine
output
reg
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out
,
output
reg
act_vlan_out_valid
,
input
act_vlan_ready
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
reg
c_m_axis_tvalid
,
output
reg
c_m_axis_tlast
);
/********intermediate variables declared here********/
wire
[
ACT_LEN
-
1
:
0
]
action_wire
;
wire
[
11
:
0
]
vlan_id
;
assign
vlan_id
=
phv_in
[
140
:
129
];
reg
[
PHV_LEN
-
1
:
0
]
phv_reg
;
reg
if_match_d1
;
reg
[
2
:
0
]
lookup_state
;
assign
action
=
(
if_match_d1
==
1
)
?
action_wire
:
625'h3f
;
//here, the output should be controlled.
localparam
IDLE_S
=
3'd0
,
WAIT1_S
=
3'd1
,
WAIT2_S
=
3'd2
,
TRANS_S
=
3'd3
,
HALT_S
=
3'd4
,
EMPTY1_S
=
3'd5
,
OUTPUT_S
=
3'd6
;
assign
ready_out
=
lookup_state
!=
HALT_S
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
phv_reg
<=
0
;
action_valid
<=
1'b0
;
lookup_state
<=
IDLE_S
;
phv_out
<=
0
;
// ready_out <= 1'b1;
act_vlan_out
<=
0
;
act_vlan_out_valid
<=
0
;
if_match_d1
<=
0
;
end
else
begin
case
(
lookup_state
)
IDLE_S:
begin
if
(
phv_valid
==
1'b1
)
begin
// ready_out <= 1'b0;
phv_reg
<=
phv_in
;
act_vlan_out
<=
vlan_id
;
if_match_d1
<=
if_match
;
if
(
act_vlan_ready
)
begin
act_vlan_out_valid
<=
1
;
end
lookup_state
<=
WAIT1_S
;
end
else
begin
// ready_out <= 1'b1;
lookup_state
<=
IDLE_S
;
action_valid
<=
1'b0
;
act_vlan_out_valid
<=
0
;
if_match_d1
<=
0
;
end
end
WAIT1_S:
begin
if
(
ready_in
)
begin
act_vlan_out_valid
<=
0
;
action_valid
<=
1'b1
;
// ready_out <= 1'b1;
phv_out
<=
phv_reg
;
lookup_state
<=
IDLE_S
;
end
else
begin
lookup_state
<=
HALT_S
;
end
end
HALT_S:
begin
if
(
ready_in
)
begin
act_vlan_out_valid
<=
0
;
action_valid
<=
1'b1
;
// ready_out <= 1'b1;
phv_out
<=
phv_reg
;
lookup_state
<=
IDLE_S
;
end
end
endcase
end
end
//======================================================================
//======================================================================
/****control path*****/
wire
[
7
:
0
]
mod_id
;
//module ID
//4'b0 for tcam entry;
//NOTE: we don't need tcam entry mask
//4'b2 for action table entry;
wire
[
3
:
0
]
resv
;
//recog between tcam and action
wire
[
15
:
0
]
control_flag
;
//dst udp port num
reg
[
7
:
0
]
c_index_cam
;
//table index(addr)
reg
c_wr_en_cam
;
//enable table write(wena)
reg
[
7
:
0
]
c_index_act
;
reg
c_wr_en_act
;
reg
[
ACT_LEN
-
1
:
0
]
act_entry_tmp
;
reg
continous_flag
;
reg
[
204
:
0
]
cam_entry_reg
;
reg
[
2
:
0
]
c_state
;
/****for 256b exclusively*****/
reg
c_m_axis_tvalid_r
;
reg
c_m_axis_tlast_r
;
localparam
IDLE_C
=
0
,
PARSE_C
=
1
,
CAM_TMP_ENTRY
=
2
,
SU_CAM_TMP_ENTRY
=
3
,
ACT_TMP_ENTRY_WAIT
=
4
,
ACT_TMP_ENTRY_WAIT_2
=
5
,
ACT_TMP_ENTRY
=
6
,
FLUSH_REST_C
=
7
;
generate
if
(
C_S_AXIS_DATA_WIDTH
==
512
)
begin
assign
mod_id
=
c_s_axis_tdata
[
368
+:
8
];
assign
resv
=
c_s_axis_tdata
[
376
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
335
:
320
];
//LE to BE switching
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
],
c_s_axis_tdata
[
256
+:
8
],
c_s_axis_tdata
[
264
+:
8
],
c_s_axis_tdata
[
272
+:
8
],
c_s_axis_tdata
[
280
+:
8
],
c_s_axis_tdata
[
288
+:
8
],
c_s_axis_tdata
[
296
+:
8
],
c_s_axis_tdata
[
304
+:
8
],
c_s_axis_tdata
[
312
+:
8
],
c_s_axis_tdata
[
320
+:
8
],
c_s_axis_tdata
[
328
+:
8
],
c_s_axis_tdata
[
336
+:
8
],
c_s_axis_tdata
[
344
+:
8
],
c_s_axis_tdata
[
352
+:
8
],
c_s_axis_tdata
[
360
+:
8
],
c_s_axis_tdata
[
368
+:
8
],
c_s_axis_tdata
[
376
+:
8
],
c_s_axis_tdata
[
384
+:
8
],
c_s_axis_tdata
[
392
+:
8
],
c_s_axis_tdata
[
400
+:
8
],
c_s_axis_tdata
[
408
+:
8
],
c_s_axis_tdata
[
416
+:
8
],
c_s_axis_tdata
[
424
+:
8
],
c_s_axis_tdata
[
432
+:
8
],
c_s_axis_tdata
[
440
+:
8
],
c_s_axis_tdata
[
448
+:
8
],
c_s_axis_tdata
[
456
+:
8
],
c_s_axis_tdata
[
464
+:
8
],
c_s_axis_tdata
[
472
+:
8
],
c_s_axis_tdata
[
480
+:
8
],
c_s_axis_tdata
[
488
+:
8
],
c_s_axis_tdata
[
496
+:
8
],
c_s_axis_tdata
[
504
+:
8
]
}
;
always
@
(
posedge
clk
or
negedge
rst_n
)
begin
if
(
~
rst_n
)
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
cam_entry_reg
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
c_state
<=
IDLE_C
;
end
else
begin
case
(
c_state
)
IDLE_C:
begin
if
(
c_s_axis_tvalid
)
begin
if
(
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
LOOKUP_ID
&&
control_flag
==
16'hf2f1
&&
resv
!=
4'b0
)
begin
//ACTION entry
continous_flag
<=
1'b0
;
c_index_act
<=
c_s_axis_tdata
[
384
+:
8
];
c_state
<=
ACT_TMP_ENTRY_WAIT
;
end
//not for lookup
else
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
c_s_axis_tdata
;
c_m_axis_tuser
<=
c_s_axis_tuser
;
c_m_axis_tkeep
<=
c_s_axis_tkeep
;
c_m_axis_tvalid
<=
c_s_axis_tvalid
;
c_m_axis_tlast
<=
c_s_axis_tlast
;
c_state
<=
IDLE_C
;
end
end
//stay halt
else
begin
c_index_cam
<=
0
;
c_wr_en_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_act
<=
0
;
act_entry_tmp
<=
0
;
continous_flag
<=
0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tvalid
<=
0
;
c_m_axis_tlast
<=
0
;
c_state
<=
IDLE_C
;
end
end
ACT_TMP_ENTRY_WAIT:
begin
c_m_axis_tvalid_r
<=
1'b0
;
c_m_axis_tlast_r
<=
1'b0
;
//flush the whole table
if
(
c_s_axis_tvalid
&&
~
c_s_axis_tlast
)
begin
if
(
continous_flag
)
c_index_act
<=
c_index_act
+
8'b1
;
else
c_index_act
<=
c_index_act
;
act_entry_tmp
[
624
-:
512
]
<=
c_s_axis_tdata_swapped
;
c_wr_en_act
<=
1'b0
;
c_state
<=
ACT_TMP_ENTRY
;
end
else
if
(
c_s_axis_tvalid
&&
c_s_axis_tlast
)
begin
c_wr_en_act
<=
1'b0
;
c_state
<=
IDLE_C
;
end
else
begin
c_wr_en_act
<=
1'b0
;
c_state
<=
c_state
;
end
end
ACT_TMP_ENTRY:
begin
if
(
c_s_axis_tvalid
)
begin
act_entry_tmp
[
112
:
0
]
<=
c_s_axis_tdata_swapped
[
511
-:
113
];
c_wr_en_act
<=
1'b1
;
if
(
c_s_axis_tlast
)
c_state
<=
IDLE_C
;
else
begin
continous_flag
<=
1'b1
;
c_state
<=
ACT_TMP_ENTRY_WAIT
;
end
end
else
begin
c_state
<=
c_state
;
act_entry_tmp
<=
act_entry_tmp
;
c_wr_en_act
<=
c_wr_en_act
;
end
end
endcase
end
end
//ram for action
// blk_mem_gen_1 #(
// .C_INIT_FILE_NAME ("./llup.mif"),
// .C_LOAD_INIT_FILE (1)
// )
blk_mem_gen_1
act_ram_625w_16d
(
.
addra
(
c_index_act
[
3
:
0
]),
.
clka
(
clk
),
.
dina
(
act_entry_tmp
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en_act
),
.
addrb
(
match_addr
[
3
:
0
]),
.
clkb
(
clk
),
.
doutb
(
action_wire
),
.
enb
(
1'b1
)
);
end
//NOTE: data width is 256b
else
begin
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_swapped
;
assign
c_s_axis_tdata_swapped
=
{
c_s_axis_tdata
[
0
+:
8
],
c_s_axis_tdata
[
8
+:
8
],
c_s_axis_tdata
[
16
+:
8
],
c_s_axis_tdata
[
24
+:
8
],
c_s_axis_tdata
[
32
+:
8
],
c_s_axis_tdata
[
40
+:
8
],
c_s_axis_tdata
[
48
+:
8
],
c_s_axis_tdata
[
56
+:
8
],
c_s_axis_tdata
[
64
+:
8
],
c_s_axis_tdata
[
72
+:
8
],
c_s_axis_tdata
[
80
+:
8
],
c_s_axis_tdata
[
88
+:
8
],
c_s_axis_tdata
[
96
+:
8
],
c_s_axis_tdata
[
104
+:
8
],
c_s_axis_tdata
[
112
+:
8
],
c_s_axis_tdata
[
120
+:
8
],
c_s_axis_tdata
[
128
+:
8
],
c_s_axis_tdata
[
136
+:
8
],
c_s_axis_tdata
[
144
+:
8
],
c_s_axis_tdata
[
152
+:
8
],
c_s_axis_tdata
[
160
+:
8
],
c_s_axis_tdata
[
168
+:
8
],
c_s_axis_tdata
[
176
+:
8
],
c_s_axis_tdata
[
184
+:
8
],
c_s_axis_tdata
[
192
+:
8
],
c_s_axis_tdata
[
200
+:
8
],
c_s_axis_tdata
[
208
+:
8
],
c_s_axis_tdata
[
216
+:
8
],
c_s_axis_tdata
[
224
+:
8
],
c_s_axis_tdata
[
232
+:
8
],
c_s_axis_tdata
[
240
+:
8
],
c_s_axis_tdata
[
248
+:
8
]
}
;
assign
mod_id
=
c_s_axis_tdata
[
112
+:
8
];
assign
resv
=
c_s_axis_tdata
[
120
+:
4
];
assign
control_flag
=
c_s_axis_tdata
[
64
+:
16
];
//
reg
[
2
:
0
]
c_state_next
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_tdata
,
c_s_axis_tdata_d1
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_tuser
,
c_s_axis_tuser_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_tkeep
,
c_s_axis_tkeep_d1
;
reg
r_tlast
,
c_s_axis_tlast_d1
;
reg
r_tvalid
,
c_s_axis_tvalid_d1
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_1st_tdata
,
r_1st_tdata_next
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_1st_tuser
,
r_1st_tuser_next
;
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
r_1st_tkeep
,
r_1st_tkeep_next
;
reg
r_1st_tlast
,
r_1st_tlast_next
;
reg
r_1st_tvalid
,
r_1st_tvalid_next
;
reg
[
7
:
0
]
c_index_cam_next
,
c_index_act_next
;
reg
c_wr_en_cam_next
,
c_wr_en_act_next
;
reg
[
204
:
0
]
c_wr_cam_data
,
c_wr_cam_data_next
;
reg
[
ACT_LEN
-
1
:
0
]
c_wr_act_data
,
c_wr_act_data_next
;
always
@
(
*
)
begin
c_state_next
=
c_state
;
r_tdata
=
0
;
r_tkeep
=
0
;
r_tuser
=
0
;
r_tlast
=
0
;
r_tvalid
=
0
;
r_1st_tdata_next
=
r_1st_tdata
;
r_1st_tkeep_next
=
r_1st_tkeep
;
r_1st_tuser_next
=
r_1st_tuser
;
r_1st_tlast_next
=
r_1st_tlast
;
r_1st_tvalid_next
=
r_1st_tvalid
;
c_index_cam_next
=
c_index_cam
;
c_index_act_next
=
c_index_act
;
c_wr_en_cam_next
=
0
;
c_wr_en_act_next
=
0
;
c_wr_cam_data_next
=
c_wr_cam_data
;
c_wr_act_data_next
=
c_wr_act_data
;
case
(
c_state
)
IDLE_C:
begin
// 1st segment
r_tvalid
=
0
;
if
(
c_s_axis_tvalid
)
begin
// store 1st segment
r_1st_tdata_next
=
c_s_axis_tdata
;
r_1st_tuser_next
=
c_s_axis_tuser
;
r_1st_tkeep_next
=
c_s_axis_tkeep
;
r_1st_tlast_next
=
c_s_axis_tlast
;
r_1st_tvalid_next
=
c_s_axis_tvalid
;
c_state_next
=
PARSE_C
;
end
end
PARSE_C:
begin
// 2nd segment
if
(
mod_id
[
7
:
3
]
==
STAGE_ID
&&
mod_id
[
2
:
0
]
==
LOOKUP_ID
&&
control_flag
==
16'hf2f1
&&
c_s_axis_tvalid
&&
resv
!=
4'b0
)
begin
// should not emit segment
c_index_act_next
=
c_s_axis_tdata
[
128
+:
8
];
c_state_next
=
ACT_TMP_ENTRY_WAIT
;
end
else
if
(
!
c_s_axis_tvalid
)
begin
end
else
begin
// emit
r_tdata
=
r_1st_tdata
;
r_tkeep
=
r_1st_tkeep
;
r_tuser
=
r_1st_tuser
;
r_tlast
=
r_1st_tlast
;
r_tvalid
=
r_1st_tvalid
;
c_state_next
=
FLUSH_REST_C
;
end
end
ACT_TMP_ENTRY_WAIT:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_act_data_next
[
369
+:
256
]
=
c_s_axis_tdata_swapped
;
c_state_next
=
ACT_TMP_ENTRY_WAIT_2
;
end
end
ACT_TMP_ENTRY_WAIT_2:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_act_data_next
[
113
+:
256
]
=
c_s_axis_tdata_swapped
;
c_state_next
=
ACT_TMP_ENTRY
;
end
end
ACT_TMP_ENTRY:
begin
if
(
c_s_axis_tvalid
)
begin
c_wr_en_act_next
=
1
;
// next clk to write
c_wr_act_data_next
[
0
+:
113
]
=
c_s_axis_tdata_swapped
[
143
+:
113
];
c_state_next
=
IDLE_C
;
end
end
FLUSH_REST_C:
begin
c_wr_en_cam_next
=
0
;
c_wr_en_act_next
=
0
;
r_tdata
=
c_s_axis_tdata_d1
;
r_tkeep
=
c_s_axis_tkeep_d1
;
r_tuser
=
c_s_axis_tuser_d1
;
r_tlast
=
c_s_axis_tlast_d1
;
r_tvalid
=
c_s_axis_tvalid_d1
;
if
(
c_s_axis_tvalid_d1
&&
c_s_axis_tlast_d1
)
begin
c_state_next
=
IDLE_C
;
end
end
endcase
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
c_state
<=
IDLE_C
;
// control output
c_m_axis_tdata
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tlast
<=
0
;
c_m_axis_tvalid
<=
0
;
//
c_index_cam
<=
0
;
c_index_act
<=
0
;
c_wr_en_cam
<=
0
;
c_wr_en_act
<=
0
;
c_wr_cam_data
<=
0
;
c_wr_act_data
<=
0
;
end
else
begin
c_state
<=
c_state_next
;
// output ctrl master signals
c_m_axis_tdata
<=
r_tdata
;
c_m_axis_tkeep
<=
r_tkeep
;
c_m_axis_tuser
<=
r_tuser
;
c_m_axis_tlast
<=
r_tlast
;
c_m_axis_tvalid
<=
r_tvalid
;
//
c_index_cam
<=
c_index_cam_next
;
c_index_act
<=
c_index_act_next
;
c_wr_en_cam
<=
c_wr_en_cam_next
;
c_wr_en_act
<=
c_wr_en_act_next
;
c_wr_cam_data
<=
c_wr_cam_data_next
;
c_wr_act_data
<=
c_wr_act_data_next
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
0
;
c_s_axis_tuser_d1
<=
0
;
c_s_axis_tkeep_d1
<=
0
;
c_s_axis_tlast_d1
<=
0
;
c_s_axis_tvalid_d1
<=
0
;
//
r_1st_tdata
<=
0
;
r_1st_tkeep
<=
0
;
r_1st_tuser
<=
0
;
r_1st_tlast
<=
0
;
r_1st_tvalid
<=
0
;
end
else
begin
// delayed 1 clk
c_s_axis_tdata_d1
<=
c_s_axis_tdata
;
c_s_axis_tuser_d1
<=
c_s_axis_tuser
;
c_s_axis_tkeep_d1
<=
c_s_axis_tkeep
;
c_s_axis_tlast_d1
<=
c_s_axis_tlast
;
c_s_axis_tvalid_d1
<=
c_s_axis_tvalid
;
//
r_1st_tdata
<=
r_1st_tdata_next
;
r_1st_tkeep
<=
r_1st_tkeep_next
;
r_1st_tuser
<=
r_1st_tuser_next
;
r_1st_tlast
<=
r_1st_tlast_next
;
r_1st_tvalid
<=
r_1st_tvalid_next
;
end
end
//ram for action
// blk_mem_gen_1 #(
// .C_INIT_FILE_NAME ("./llup.mif"),
// .C_LOAD_INIT_FILE (1)
// )
blk_mem_gen_1
act_ram_625w_16d
(
.
addra
(
c_index_act
[
3
:
0
]),
.
clka
(
clk
),
.
dina
(
c_wr_act_data
),
.
ena
(
1'b1
),
// always set to 1
.
wea
(
c_wr_en_act
),
.
addrb
(
match_addr
),
.
clkb
(
clk
),
.
doutb
(
action_wire
),
.
enb
(
1'b1
)
// always set to 1
);
end
endgenerate
endmodule
sims/net/menshen/rtl/lookup/lookup_engine_top.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
lookup_engine_top
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
5
,
parameter
ACT_LEN
=
625
,
parameter
LOOKUP_ID
=
2
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
rst_n
,
//output from key extractor
input
[
KEY_LEN
-
1
:
0
]
extract_key
,
input
key_valid
,
input
phv_valid
,
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
output
ready_out
,
//output to the action engine
output
[
ACT_LEN
-
1
:
0
]
action
,
output
action_valid
,
output
[
PHV_LEN
-
1
:
0
]
phv_out
,
input
ready_in
,
// output vlan to ALU vlan fifo
output
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out
,
output
act_vlan_valid_out
,
input
act_vlan_ready
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
c_m_axis_tvalid
,
output
c_m_axis_tlast
);
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_0
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser_0
;
wire
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep_0
;
wire
c_s_axis_tvalid_0
;
wire
c_s_axis_tlast_0
;
wire
[
PHV_LEN
-
1
:
0
]
cam_phv_out
;
wire
cam_phv_out_valid
;
wire
[
3
:
0
]
cam_match_addr_out
;
wire
cam_if_match
;
wire
lke_ram_ready
;
reg
[
PHV_LEN
-
1
:
0
]
cam_phv_out_d1
;
reg
cam_phv_out_valid_d1
;
reg
[
3
:
0
]
cam_match_addr_out_d1
;
reg
cam_if_match_d1
;
always
@
(
posedge
clk
)
begin
if
(
~
rst_n
)
begin
cam_phv_out_d1
<=
0
;
cam_phv_out_valid_d1
<=
0
;
cam_match_addr_out_d1
<=
0
;
cam_if_match_d1
<=
0
;
end
else
begin
cam_phv_out_d1
<=
cam_phv_out
;
cam_phv_out_valid_d1
<=
cam_phv_out_valid
;
cam_match_addr_out_d1
<=
cam_match_addr_out
;
cam_if_match_d1
<=
cam_if_match
;
end
end
lke_cam_part
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(
PHV_LEN
),
.
KEY_LEN
(
KEY_LEN
),
.
ACT_LEN
(
ACT_LEN
),
.
LOOKUP_ID
(
LOOKUP_ID
),
.
C_VLANID_WIDTH
(
C_VLANID_WIDTH
)
)
lke_cam
(
.
clk
(
clk
),
.
rst_n
(
rst_n
),
.
extract_key
(
extract_key
),
.
key_valid
(
key_valid
),
.
phv_valid
(
phv_valid
),
.
phv_in
(
phv_in
),
.
ready_out
(
ready_out
),
//
.
phv_out
(
cam_phv_out
),
.
phv_out_valid
(
cam_phv_out_valid
),
.
match_addr_out
(
cam_match_addr_out
),
.
if_match
(
cam_if_match
),
.
ready_in
(
lke_ram_ready
),
//
.
c_s_axis_tdata
(
c_s_axis_tdata
),
.
c_s_axis_tuser
(
c_s_axis_tuser
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid
),
.
c_s_axis_tlast
(
c_s_axis_tlast
),
.
c_m_axis_tdata
(
c_s_axis_tdata_0
),
.
c_m_axis_tuser
(
c_s_axis_tuser_0
),
.
c_m_axis_tkeep
(
c_s_axis_tkeep_0
),
.
c_m_axis_tvalid
(
c_s_axis_tvalid_0
),
.
c_m_axis_tlast
(
c_s_axis_tlast_0
)
);
lke_ram_part
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(
PHV_LEN
),
.
KEY_LEN
(
KEY_LEN
),
.
ACT_LEN
(
ACT_LEN
),
.
LOOKUP_ID
(
LOOKUP_ID
),
.
C_VLANID_WIDTH
(
C_VLANID_WIDTH
)
)
lke_ram
(
.
clk
(
clk
),
.
rst_n
(
rst_n
),
.
phv_in
(
cam_phv_out_d1
),
.
phv_valid
(
cam_phv_out_valid_d1
),
.
match_addr
(
cam_match_addr_out_d1
),
.
if_match
(
cam_if_match_d1
),
.
ready_out
(
lke_ram_ready
),
//
.
action
(
action
),
.
action_valid
(
action_valid
),
.
phv_out
(
phv_out
),
.
ready_in
(
ready_in
),
//
.
act_vlan_out
(
act_vlan_out
),
.
act_vlan_out_valid
(
act_vlan_valid_out
),
.
act_vlan_ready
(
act_vlan_ready
),
.
c_s_axis_tdata
(
c_s_axis_tdata_0
),
.
c_s_axis_tuser
(
c_s_axis_tuser_0
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep_0
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid_0
),
.
c_s_axis_tlast
(
c_s_axis_tlast_0
),
.
c_m_axis_tdata
(
c_m_axis_tdata
),
.
c_m_axis_tuser
(
c_m_axis_tuser
),
.
c_m_axis_tkeep
(
c_m_axis_tkeep
),
.
c_m_axis_tvalid
(
c_m_axis_tvalid
),
.
c_m_axis_tlast
(
c_m_axis_tlast
)
);
endmodule
sims/net/menshen/rtl/output_arbiter.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
output_arbiter
#(
parameter
C_AXIS_DATA_WIDTH
=
256
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
C_NUM_QUEUES
=
4
,
parameter
C_NUM_QUEUES_WIDTH
=
2
)
(
input
axis_clk
,
input
aresetn
,
// output
output
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata
,
output
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
m_axis_tkeep
,
output
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser
,
output
m_axis_tvalid
,
output
m_axis_tlast
,
input
m_axis_tready
,
// input
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_0
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep_0
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_0
,
input
s_axis_tlast_0
,
input
s_axis_tvalid_0
,
output
s_axis_tready_0
,
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_1
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep_1
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_1
,
input
s_axis_tlast_1
,
input
s_axis_tvalid_1
,
output
s_axis_tready_1
,
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_2
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep_2
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_2
,
input
s_axis_tlast_2
,
input
s_axis_tvalid_2
,
output
s_axis_tready_2
,
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_3
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep_3
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_3
,
input
s_axis_tlast_3
,
input
s_axis_tvalid_3
,
output
s_axis_tready_3
);
wire
[
C_NUM_QUEUES
-
1
:
0
]
nearly_full
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
empty
;
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
in_tdata
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
in_tkeep
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
in_tuser
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_NUM_QUEUES
-
1
:
0
]
in_tvalid
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
in_tlast
;
wire
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
fifo_out_tdata
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
fifo_out_tkeep
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
fifo_out_tuser
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_NUM_QUEUES
-
1
:
0
]
fifo_out_tlast
;
reg
[
C_NUM_QUEUES
-
1
:
0
]
rd_en
;
wire
[
C_NUM_QUEUES_WIDTH
-
1
:
0
]
cur_queue_plus1
;
reg
[
C_NUM_QUEUES_WIDTH
-
1
:
0
]
cur_queue
,
cur_queue_next
;
reg
state
,
state_next
;
generate
genvar
i
;
for
(
i
=
0
;
i
<
C_NUM_QUEUES
;
i
=
i
+
1
)
begin
:
out_arb_queues
fallthrough_small_fifo
#(
.
WIDTH
(
C_AXIS_DATA_WIDTH
+
C_AXIS_DATA_WIDTH
/
8
+
C_AXIS_TUSER_WIDTH
+
1
),
.
MAX_DEPTH_BITS
(
4
)
)
out_arb_fifo
(
.
dout
(
{
fifo_out_tdata
[
i
],
fifo_out_tuser
[
i
],
fifo_out_tkeep
[
i
],
fifo_out_tlast
[
i
]
}
),
.
rd_en
(
rd_en
[
i
]),
.
din
(
{
in_tdata
[
i
],
in_tuser
[
i
],
in_tkeep
[
i
],
in_tlast
[
i
]
}
),
.
wr_en
(
in_tvalid
[
i
]
&
~
nearly_full
[
i
]),
.
full
(),
.
nearly_full
(
nearly_full
[
i
]),
.
empty
(
empty
[
i
]),
.
reset
(
~
aresetn
),
.
clk
(
axis_clk
)
);
end
endgenerate
assign
in_tdata
[
0
]
=
s_axis_tdata_0
;
assign
in_tkeep
[
0
]
=
s_axis_tkeep_0
;
assign
in_tuser
[
0
]
=
s_axis_tuser_0
;
assign
in_tlast
[
0
]
=
s_axis_tlast_0
;
assign
in_tvalid
[
0
]
=
s_axis_tvalid_0
;
assign
s_axis_tready_0
=
~
nearly_full
[
0
];
assign
in_tdata
[
1
]
=
s_axis_tdata_1
;
assign
in_tkeep
[
1
]
=
s_axis_tkeep_1
;
assign
in_tuser
[
1
]
=
s_axis_tuser_1
;
assign
in_tlast
[
1
]
=
s_axis_tlast_1
;
assign
in_tvalid
[
1
]
=
s_axis_tvalid_1
;
assign
s_axis_tready_1
=
~
nearly_full
[
1
];
assign
in_tdata
[
2
]
=
s_axis_tdata_2
;
assign
in_tkeep
[
2
]
=
s_axis_tkeep_2
;
assign
in_tuser
[
2
]
=
s_axis_tuser_2
;
assign
in_tlast
[
2
]
=
s_axis_tlast_2
;
assign
in_tvalid
[
2
]
=
s_axis_tvalid_2
;
assign
s_axis_tready_2
=
~
nearly_full
[
2
];
assign
in_tdata
[
3
]
=
s_axis_tdata_3
;
assign
in_tkeep
[
3
]
=
s_axis_tkeep_3
;
assign
in_tuser
[
3
]
=
s_axis_tuser_3
;
assign
in_tlast
[
3
]
=
s_axis_tlast_3
;
assign
in_tvalid
[
3
]
=
s_axis_tvalid_3
;
assign
s_axis_tready_3
=
~
nearly_full
[
3
];
assign
cur_queue_plus1
=
(
cur_queue
==
C_NUM_QUEUES
-
1
)
?
0
:
cur_queue
+
1
;
assign
m_axis_tdata
=
fifo_out_tdata
[
cur_queue
];
assign
m_axis_tuser
=
fifo_out_tuser
[
cur_queue
];
assign
m_axis_tkeep
=
fifo_out_tkeep
[
cur_queue
];
assign
m_axis_tlast
=
fifo_out_tlast
[
cur_queue
];
assign
m_axis_tvalid
=
~
empty
[
cur_queue
]
&&
m_axis_tready
;
localparam
IDLE
=
0
,
WR_PKT
=
1
;
always
@
(
*
)
begin
state_next
=
state
;
cur_queue_next
=
cur_queue
;
rd_en
=
0
;
case
(
state
)
IDLE:
begin
if
(
!
empty
[
cur_queue
])
begin
if
(
m_axis_tready
)
begin
state_next
=
WR_PKT
;
rd_en
[
cur_queue
]
=
1
;
end
end
else
begin
cur_queue_next
=
cur_queue_plus1
;
end
end
WR_PKT:
begin
if
(
m_axis_tready
&
m_axis_tlast
)
begin
state_next
=
IDLE
;
rd_en
[
cur_queue
]
=
1
;
cur_queue_next
=
cur_queue_plus1
;
end
else
if
(
m_axis_tready
&&
!
empty
[
cur_queue
])
begin
rd_en
[
cur_queue
]
=
1
;
end
end
endcase
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
state
<=
IDLE
;
cur_queue
<=
0
;
end
else
begin
state
<=
state_next
;
cur_queue
<=
cur_queue_next
;
end
end
endmodule
sims/net/menshen/rtl/parser_do_parsing.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
`define
DEF_MAC_ADDR 48
`define
DEF_VLAN 32
`define
DEF_ETHTYPE 16
`define
TYPE_IPV4 16
'
h0008
`define
TYPE_ARP 16
'
h0608
`define
PROT_ICMP 8
'
h01
`define
PROT_TCP 8
'
h06
`define
PROT_UDP 8
'
h11
`define
SUB_PARSE
(
idx
)
\
case
(
sub_parse_val_out_type_d1
[
idx
])
\
2
'
b01
:
val_2B_nxt
[
sub_parse_val_out_seq_d1
[
idx
]]
=
sub_parse_val_out_d1
[
idx
][
15
:
0
]
;
\
2
'
b10
:
val_4B_nxt
[
sub_parse_val_out_seq_d1
[
idx
]]
=
sub_parse_val_out_d1
[
idx
][
31
:
0
]
;
\
2
'
b11
:
val_6B_nxt
[
sub_parse_val_out_seq_d1
[
idx
]]
=
sub_parse_val_out_d1
[
idx
][
47
:
0
]
;
\
endcase \
`define
SWAP_BYTE_ORDER
(
idx
)
\
assign val_6B_swapped
[
idx
]
=
{
val_6B
[
idx
][
0
+:
8
],
\
val_6B
[
idx
][
8
+:
8
],
\
val_6B
[
idx
][
16
+:
8
],
\
val_6B
[
idx
][
24
+:
8
],
\
val_6B
[
idx
][
32
+:
8
],
\
val_6B
[
idx
][
40
+:
8
]}
;
\
assign val_4B_swapped
[
idx
]
=
{
val_4B
[
idx
][
0
+:
8
],
\
val_4B
[
idx
][
8
+:
8
],
\
val_4B
[
idx
][
16
+:
8
],
\
val_4B
[
idx
][
24
+:
8
]}
;
\
assign val_2B_swapped
[
idx
]
=
{
val_2B
[
idx
][
0
+:
8
],
\
val_2B
[
idx
][
8
+:
8
]}
;
\
module
parser_do_parsing
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
PKT_HDR_LEN
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
// check with the doc
parameter
PARSER_MOD_ID
=
3'b0
,
parameter
C_NUM_SEGS
=
2
,
parameter
C_VLANID_WIDTH
=
12
,
parameter
C_PARSER_RAM_WIDTH
=
160
)
(
input
axis_clk
,
input
aresetn
,
input
[
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
-
1
:
0
]
tdata_segs
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st
,
input
segs_valid
,
input
[
C_PARSER_RAM_WIDTH
-
1
:
0
]
bram_in
,
input
bram_in_valid
,
input
stg_ready_in
,
// phv output
output
reg
parser_valid
,
output
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec
,
// vlan output
output
reg
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_out
,
output
reg
vlan_out_valid
);
integer
i
;
localparam
IDLE
=
0
,
WAIT_1CYCLE_RAM
=
1
,
START_SUB_PARSE
=
2
,
FINISH_SUB_PARSE
=
3
,
GET_PHV_OUTPUT
=
4
,
OUTPUT
=
5
,
EMPTY_1
=
6
;
//
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec_next
;
reg
parser_valid_next
;
reg
[
3
:
0
]
state
,
state_next
;
reg
[
11
:
0
]
vlan_out_next
;
reg
vlan_out_valid_next
;
// parsing actions
wire
[
15
:
0
]
parse_action
[
0
:
9
];
// we have 10 parse action
assign
parse_action
[
9
]
=
bram_in
[
0
+:
16
];
assign
parse_action
[
8
]
=
bram_in
[
16
+:
16
];
assign
parse_action
[
7
]
=
bram_in
[
32
+:
16
];
assign
parse_action
[
6
]
=
bram_in
[
48
+:
16
];
assign
parse_action
[
5
]
=
bram_in
[
64
+:
16
];
assign
parse_action
[
4
]
=
bram_in
[
80
+:
16
];
assign
parse_action
[
3
]
=
bram_in
[
96
+:
16
];
assign
parse_action
[
2
]
=
bram_in
[
112
+:
16
];
assign
parse_action
[
1
]
=
bram_in
[
128
+:
16
];
assign
parse_action
[
0
]
=
bram_in
[
144
+:
16
];
reg
[
9
:
0
]
sub_parse_act_valid
;
wire
[
47
:
0
]
sub_parse_val_out
[
0
:
9
];
wire
[
9
:
0
]
sub_parse_val_out_valid
;
wire
[
1
:
0
]
sub_parse_val_out_type
[
0
:
9
];
wire
[
2
:
0
]
sub_parse_val_out_seq
[
0
:
9
];
reg
[
47
:
0
]
sub_parse_val_out_d1
[
0
:
9
];
reg
[
9
:
0
]
sub_parse_val_out_valid_d1
;
reg
[
1
:
0
]
sub_parse_val_out_type_d1
[
0
:
9
];
reg
[
2
:
0
]
sub_parse_val_out_seq_d1
[
0
:
9
];
reg
[
47
:
0
]
val_6B
[
0
:
7
];
reg
[
31
:
0
]
val_4B
[
0
:
7
];
reg
[
15
:
0
]
val_2B
[
0
:
7
];
reg
[
47
:
0
]
val_6B_nxt
[
0
:
7
];
reg
[
31
:
0
]
val_4B_nxt
[
0
:
7
];
reg
[
15
:
0
]
val_2B_nxt
[
0
:
7
];
wire
[
47
:
0
]
val_6B_swapped
[
0
:
7
];
wire
[
31
:
0
]
val_4B_swapped
[
0
:
7
];
wire
[
15
:
0
]
val_2B_swapped
[
0
:
7
];
`SWAP_BYTE_ORDER
(
0
)
`SWAP_BYTE_ORDER
(
1
)
`SWAP_BYTE_ORDER
(
2
)
`SWAP_BYTE_ORDER
(
3
)
`SWAP_BYTE_ORDER
(
4
)
`SWAP_BYTE_ORDER
(
5
)
`SWAP_BYTE_ORDER
(
6
)
`SWAP_BYTE_ORDER
(
7
)
always
@
(
*
)
begin
state_next
=
state
;
//
parser_valid_next
=
0
;
pkt_hdr_vec_next
=
pkt_hdr_vec
;
//
val_2B_nxt
[
0
]
=
val_2B
[
0
];
val_2B_nxt
[
1
]
=
val_2B
[
1
];
val_2B_nxt
[
2
]
=
val_2B
[
2
];
val_2B_nxt
[
3
]
=
val_2B
[
3
];
val_2B_nxt
[
4
]
=
val_2B
[
4
];
val_2B_nxt
[
5
]
=
val_2B
[
5
];
val_2B_nxt
[
6
]
=
val_2B
[
6
];
val_2B_nxt
[
7
]
=
val_2B
[
7
];
val_4B_nxt
[
0
]
=
val_4B
[
0
];
val_4B_nxt
[
1
]
=
val_4B
[
1
];
val_4B_nxt
[
2
]
=
val_4B
[
2
];
val_4B_nxt
[
3
]
=
val_4B
[
3
];
val_4B_nxt
[
4
]
=
val_4B
[
4
];
val_4B_nxt
[
5
]
=
val_4B
[
5
];
val_4B_nxt
[
6
]
=
val_4B
[
6
];
val_4B_nxt
[
7
]
=
val_4B
[
7
];
val_6B_nxt
[
0
]
=
val_6B
[
0
];
val_6B_nxt
[
1
]
=
val_6B
[
1
];
val_6B_nxt
[
2
]
=
val_6B
[
2
];
val_6B_nxt
[
3
]
=
val_6B
[
3
];
val_6B_nxt
[
4
]
=
val_6B
[
4
];
val_6B_nxt
[
5
]
=
val_6B
[
5
];
val_6B_nxt
[
6
]
=
val_6B
[
6
];
val_6B_nxt
[
7
]
=
val_6B
[
7
];
//
sub_parse_act_valid
=
10'b0
;
//
vlan_out_next
=
vlan_out
;
vlan_out_valid_next
=
0
;
case
(
state
)
IDLE:
begin
if
(
segs_valid
)
begin
sub_parse_act_valid
=
10'b1111111111
;
vlan_out_next
=
tdata_segs
[
116
+:
12
];
state_next
=
FINISH_SUB_PARSE
;
end
end
FINISH_SUB_PARSE:
begin
state_next
=
EMPTY_1
;
end
EMPTY_1:
begin
state_next
=
GET_PHV_OUTPUT
;
`SUB_PARSE
(
0
)
`SUB_PARSE
(
1
)
`SUB_PARSE
(
2
)
`SUB_PARSE
(
3
)
`SUB_PARSE
(
4
)
`SUB_PARSE
(
5
)
`SUB_PARSE
(
6
)
`SUB_PARSE
(
7
)
`SUB_PARSE
(
8
)
`SUB_PARSE
(
9
)
vlan_out_valid_next
=
1
;
end
GET_PHV_OUTPUT:
begin
pkt_hdr_vec_next
={
val_6B_swapped
[
7
],
val_6B_swapped
[
6
],
val_6B_swapped
[
5
],
val_6B_swapped
[
4
],
val_6B_swapped
[
3
],
val_6B_swapped
[
2
],
val_6B_swapped
[
1
],
val_6B_swapped
[
0
],
val_4B_swapped
[
7
],
val_4B_swapped
[
6
],
val_4B_swapped
[
5
],
val_4B_swapped
[
4
],
val_4B_swapped
[
3
],
val_4B_swapped
[
2
],
val_4B_swapped
[
1
],
val_4B_swapped
[
0
],
val_2B_swapped
[
7
],
val_2B_swapped
[
6
],
val_2B_swapped
[
5
],
val_2B_swapped
[
4
],
val_2B_swapped
[
3
],
val_2B_swapped
[
2
],
val_2B_swapped
[
1
],
val_2B_swapped
[
0
],
// Tao: manually set output port to 1 for eazy test
// {115{1'b0}}, vlan_id, 1'b0, tuser_1st[127:32], 8'h04, tuser_1st[23:0]};
{
115
{
1'b0
}}
,
vlan_out
,
1'b0
,
tuser_1st
[
127
:
0
]
}
;
// {115{1'b0}}, vlan_id, 1'b0, tuser_1st};
// {128{1'b0}}, tuser_1st[127:32], 8'h04, tuser_1st[23:0]};
//
if
(
stg_ready_in
)
begin
parser_valid_next
=
1
;
state_next
=
IDLE
;
end
else
begin
state_next
=
OUTPUT
;
end
end
OUTPUT:
begin
if
(
stg_ready_in
)
begin
parser_valid_next
=
1
;
state_next
=
IDLE
;
// zero out
val_2B_nxt
[
0
]
=
0
;
val_2B_nxt
[
1
]
=
0
;
val_2B_nxt
[
2
]
=
0
;
val_2B_nxt
[
3
]
=
0
;
val_2B_nxt
[
4
]
=
0
;
val_2B_nxt
[
5
]
=
0
;
val_2B_nxt
[
6
]
=
0
;
val_2B_nxt
[
7
]
=
0
;
val_4B_nxt
[
0
]
=
0
;
val_4B_nxt
[
1
]
=
0
;
val_4B_nxt
[
2
]
=
0
;
val_4B_nxt
[
3
]
=
0
;
val_4B_nxt
[
4
]
=
0
;
val_4B_nxt
[
5
]
=
0
;
val_4B_nxt
[
6
]
=
0
;
val_4B_nxt
[
7
]
=
0
;
val_6B_nxt
[
0
]
=
0
;
val_6B_nxt
[
1
]
=
0
;
val_6B_nxt
[
2
]
=
0
;
val_6B_nxt
[
3
]
=
0
;
val_6B_nxt
[
4
]
=
0
;
val_6B_nxt
[
5
]
=
0
;
val_6B_nxt
[
6
]
=
0
;
val_6B_nxt
[
7
]
=
0
;
end
end
endcase
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
state
<=
IDLE
;
//
pkt_hdr_vec
<=
0
;
parser_valid
<=
0
;
//
vlan_out
<=
0
;
vlan_out_valid
<=
0
;
//
val_2B
[
0
]
<=
0
;
val_2B
[
1
]
<=
0
;
val_2B
[
2
]
<=
0
;
val_2B
[
3
]
<=
0
;
val_2B
[
4
]
<=
0
;
val_2B
[
5
]
<=
0
;
val_2B
[
6
]
<=
0
;
val_2B
[
7
]
<=
0
;
val_4B
[
0
]
<=
0
;
val_4B
[
1
]
<=
0
;
val_4B
[
2
]
<=
0
;
val_4B
[
3
]
<=
0
;
val_4B
[
4
]
<=
0
;
val_4B
[
5
]
<=
0
;
val_4B
[
6
]
<=
0
;
val_4B
[
7
]
<=
0
;
val_6B
[
0
]
<=
0
;
val_6B
[
1
]
<=
0
;
val_6B
[
2
]
<=
0
;
val_6B
[
3
]
<=
0
;
val_6B
[
4
]
<=
0
;
val_6B
[
5
]
<=
0
;
val_6B
[
6
]
<=
0
;
val_6B
[
7
]
<=
0
;
for
(
i
=
0
;
i
<
10
;
i
=
i
+
1
)
begin
sub_parse_val_out_d1
[
i
]
<=
0
;
sub_parse_val_out_valid_d1
<=
0
;
sub_parse_val_out_type_d1
[
i
]
<=
0
;
sub_parse_val_out_seq_d1
[
i
]
<=
0
;
end
end
else
begin
state
<=
state_next
;
//
pkt_hdr_vec
<=
pkt_hdr_vec_next
;
parser_valid
<=
parser_valid_next
;
//
vlan_out
<=
vlan_out_next
;
vlan_out_valid
<=
vlan_out_valid_next
;
//
val_2B
[
0
]
<=
val_2B_nxt
[
0
];
val_2B
[
1
]
<=
val_2B_nxt
[
1
];
val_2B
[
2
]
<=
val_2B_nxt
[
2
];
val_2B
[
3
]
<=
val_2B_nxt
[
3
];
val_2B
[
4
]
<=
val_2B_nxt
[
4
];
val_2B
[
5
]
<=
val_2B_nxt
[
5
];
val_2B
[
6
]
<=
val_2B_nxt
[
6
];
val_2B
[
7
]
<=
val_2B_nxt
[
7
];
val_4B
[
0
]
<=
val_4B_nxt
[
0
];
val_4B
[
1
]
<=
val_4B_nxt
[
1
];
val_4B
[
2
]
<=
val_4B_nxt
[
2
];
val_4B
[
3
]
<=
val_4B_nxt
[
3
];
val_4B
[
4
]
<=
val_4B_nxt
[
4
];
val_4B
[
5
]
<=
val_4B_nxt
[
5
];
val_4B
[
6
]
<=
val_4B_nxt
[
6
];
val_4B
[
7
]
<=
val_4B_nxt
[
7
];
val_6B
[
0
]
<=
val_6B_nxt
[
0
];
val_6B
[
1
]
<=
val_6B_nxt
[
1
];
val_6B
[
2
]
<=
val_6B_nxt
[
2
];
val_6B
[
3
]
<=
val_6B_nxt
[
3
];
val_6B
[
4
]
<=
val_6B_nxt
[
4
];
val_6B
[
5
]
<=
val_6B_nxt
[
5
];
val_6B
[
6
]
<=
val_6B_nxt
[
6
];
val_6B
[
7
]
<=
val_6B_nxt
[
7
];
//
for
(
i
=
0
;
i
<
10
;
i
=
i
+
1
)
begin
sub_parse_val_out_d1
[
i
]
<=
sub_parse_val_out
[
i
];
sub_parse_val_out_valid_d1
<=
sub_parse_val_out_valid
;
sub_parse_val_out_type_d1
[
i
]
<=
sub_parse_val_out_type
[
i
];
sub_parse_val_out_seq_d1
[
i
]
<=
sub_parse_val_out_seq
[
i
];
end
end
end
// =============================================================== //
// sub parser
generate
genvar
index
;
for
(
index
=
0
;
index
<
10
;
index
=
index
+
1
)
begin
:
sub_op
sub_parser
#(
.
PKTS_HDR_LEN
(),
.
PARSE_ACT_LEN
(),
.
VAL_OUT_LEN
()
)
sub_parser
(
.
clk
(
axis_clk
),
.
aresetn
(
aresetn
),
.
parse_act_valid
(
sub_parse_act_valid
[
index
]),
.
parse_act
(
parse_action
[
index
]),
.
pkts_hdr
(
tdata_segs
),
.
val_out_valid
(
sub_parse_val_out_valid
[
index
]),
.
val_out
(
sub_parse_val_out
[
index
]),
.
val_out_type
(
sub_parse_val_out_type
[
index
]),
.
val_out_seq
(
sub_parse_val_out_seq
[
index
])
);
end
endgenerate
endmodule
sims/net/menshen/rtl/parser_do_parsing_top.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
parser_do_parsing_top
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
PKT_HDR_LEN
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
// check with the doc
parameter
C_NUM_SEGS
=
2
,
parameter
C_PARSER_RAM_WIDTH
=
160
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
aresetn
,
input
[
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
-
1
:
0
]
segs_in
,
input
segs_in_valid
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st_in
,
input
[
C_PARSER_RAM_WIDTH
-
1
:
0
]
bram_in
,
input
bram_in_valid
,
input
stg_ready
,
input
stg_vlan_ready
,
// phv output
output
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec
,
output
reg
parser_valid
,
output
reg
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_out
,
output
reg
vlan_out_valid
);
wire
[
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
-
1
:
0
]
sub_parser_segs_in
[
0
:
1
];
wire
sub_parser_segs_in_valid
[
0
:
1
];
wire
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
sub_parser_tuser_1st_in
[
0
:
1
];
wire
[
C_PARSER_RAM_WIDTH
-
1
:
0
]
sub_parser_bram_in
[
0
:
1
];
wire
sub_parser_bram_in_valid
[
0
:
1
];
reg
[
1
:
0
]
cur_queue
,
cur_queue_next
;
wire
[
1
:
0
]
cur_queue_plus1
;
assign
cur_queue_plus1
=
(
cur_queue
==
1
)
?
0
:
cur_queue
+
1
;
assign
sub_parser_segs_in
[
0
]
=
segs_in
;
assign
sub_parser_segs_in
[
1
]
=
segs_in
;
// assign sub_parser_segs_in[2] = segs_in;
// assign sub_parser_segs_in[3] = segs_in;
assign
sub_parser_segs_in_valid
[
0
]
=
(
cur_queue
==
0
)
?
segs_in_valid
:
0
;
assign
sub_parser_segs_in_valid
[
1
]
=
(
cur_queue
==
1
)
?
segs_in_valid
:
0
;
// assign sub_parser_segs_in_valid[2] = (cur_queue==2)?segs_in_valid:0;
// assign sub_parser_segs_in_valid[3] = (cur_queue==3)?segs_in_valid:0;
assign
sub_parser_tuser_1st_in
[
0
]
=
tuser_1st_in
;
assign
sub_parser_tuser_1st_in
[
1
]
=
tuser_1st_in
;
// assign sub_parser_tuser_1st_in[2] = tuser_1st_in;
// assign sub_parser_tuser_1st_in[3] = tuser_1st_in;
assign
sub_parser_bram_in
[
0
]
=
bram_in
;
assign
sub_parser_bram_in
[
1
]
=
bram_in
;
// assign sub_parser_bram_in[2] = bram_in;
// assign sub_parser_bram_in[3] = bram_in;
assign
sub_parser_bram_in_valid
[
0
]
=
(
cur_queue
==
0
)
?
bram_in_valid
:
0
;
assign
sub_parser_bram_in_valid
[
1
]
=
(
cur_queue
==
1
)
?
bram_in_valid
:
0
;
// assign sub_parser_bram_in_valid[2] = (cur_queue==2)?bram_in_valid:0;
// assign sub_parser_bram_in_valid[3] = (cur_queue==3)?bram_in_valid:0;
always
@
(
*
)
begin
cur_queue_next
=
cur_queue
;
if
(
segs_in_valid
)
begin
cur_queue_next
=
cur_queue_plus1
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
cur_queue
<=
0
;
end
else
begin
cur_queue
<=
cur_queue_next
;
end
end
wire
[
1
:
0
]
nearly_full
;
wire
[
1
:
0
]
empty
;
wire
[
1
:
0
]
vlan_nearly_full
;
wire
[
1
:
0
]
vlan_empty
;
wire
[
PKT_HDR_LEN
-
1
:
0
]
sub_parser_pkt_hdr_out
[
0
:
1
];
wire
[
1
:
0
]
sub_parser_pkt_hdr_valid
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
sub_parser_vlan_out
[
0
:
1
];
wire
[
1
:
0
]
sub_parser_vlan_out_valid
;
reg
[
PKT_HDR_LEN
-
1
:
0
]
sub_parser_pkt_hdr_out_d1
[
0
:
1
];
reg
[
1
:
0
]
sub_parser_pkt_hdr_valid_d1
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
sub_parser_vlan_out_d1
[
0
:
1
];
reg
[
1
:
0
]
sub_parser_vlan_out_valid_d1
;
generate
genvar
i
;
for
(
i
=
0
;
i
<
2
;
i
=
i
+
1
)
begin
:
sub_do_parsing
parser_do_parsing
#(
.
C_AXIS_DATA_WIDTH
(
C_AXIS_DATA_WIDTH
),
.
C_AXIS_TUSER_WIDTH
(
C_AXIS_TUSER_WIDTH
)
)
phv_do_parsing
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
.
tdata_segs
(
sub_parser_segs_in
[
i
]),
.
tuser_1st
(
sub_parser_tuser_1st_in
[
i
]),
.
segs_valid
(
sub_parser_segs_in_valid
[
i
]),
.
bram_in
(
sub_parser_bram_in
[
i
]),
.
bram_in_valid
(
sub_parser_bram_in_valid
[
i
]),
.
stg_ready_in
(
1'b1
),
// output
.
parser_valid
(
sub_parser_pkt_hdr_valid
[
i
]),
.
pkt_hdr_vec
(
sub_parser_pkt_hdr_out
[
i
]),
.
vlan_out
(
sub_parser_vlan_out
[
i
]),
.
vlan_out_valid
(
sub_parser_vlan_out_valid
[
i
])
);
end
endgenerate
reg
[
1
:
0
]
out_cur_queue
,
out_cur_queue_next
;
wire
[
1
:
0
]
out_cur_queue_plus1
;
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec_next
;
reg
parser_valid_next
;
assign
out_cur_queue_plus1
=
(
out_cur_queue
==
1
)
?
0
:
out_cur_queue
+
1
;
always
@
(
*
)
begin
pkt_hdr_vec_next
=
pkt_hdr_vec
;
parser_valid_next
=
0
;
out_cur_queue_next
=
out_cur_queue
;
if
(
sub_parser_pkt_hdr_valid_d1
[
out_cur_queue
])
begin
pkt_hdr_vec_next
=
sub_parser_pkt_hdr_out_d1
[
out_cur_queue
];
parser_valid_next
=
1
;
out_cur_queue_next
=
out_cur_queue_plus1
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
out_cur_queue
<=
0
;
pkt_hdr_vec
<=
0
;
parser_valid
<=
0
;
end
else
begin
out_cur_queue
<=
out_cur_queue_next
;
pkt_hdr_vec
<=
pkt_hdr_vec_next
;
parser_valid
<=
parser_valid_next
;
end
end
reg
[
1
:
0
]
vlan_out_cur_queue
,
vlan_out_cur_queue_next
;
wire
[
1
:
0
]
vlan_out_cur_queue_plus1
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_out_next
;
reg
vlan_out_valid_next
;
assign
vlan_out_cur_queue_plus1
=
(
vlan_out_cur_queue
==
1
)
?
0
:
vlan_out_cur_queue
+
1
;
always
@
(
*
)
begin
vlan_out_next
=
vlan_out
;
vlan_out_valid_next
=
0
;
vlan_out_cur_queue_next
=
vlan_out_cur_queue
;
if
(
sub_parser_vlan_out_valid_d1
[
vlan_out_cur_queue
])
begin
vlan_out_next
=
sub_parser_vlan_out_d1
[
vlan_out_cur_queue
];
vlan_out_valid_next
=
1
;
vlan_out_cur_queue_next
=
vlan_out_cur_queue_plus1
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
vlan_out_cur_queue
<=
0
;
vlan_out
<=
0
;
vlan_out_valid
<=
0
;
end
else
begin
vlan_out_cur_queue
<=
vlan_out_cur_queue_next
;
vlan_out
<=
vlan_out_next
;
vlan_out_valid
<=
vlan_out_valid_next
;
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
sub_parser_pkt_hdr_out_d1
[
0
]
<=
0
;
sub_parser_pkt_hdr_out_d1
[
1
]
<=
0
;
sub_parser_pkt_hdr_valid_d1
<=
0
;
sub_parser_vlan_out_d1
[
0
]
<=
0
;
sub_parser_vlan_out_d1
[
1
]
<=
0
;
sub_parser_vlan_out_valid_d1
<=
0
;
end
else
begin
sub_parser_pkt_hdr_out_d1
[
0
]
<=
sub_parser_pkt_hdr_out
[
0
];
sub_parser_pkt_hdr_out_d1
[
1
]
<=
sub_parser_pkt_hdr_out
[
1
];
sub_parser_pkt_hdr_valid_d1
<=
sub_parser_pkt_hdr_valid
;
sub_parser_vlan_out_d1
[
0
]
<=
sub_parser_vlan_out
[
0
];
sub_parser_vlan_out_d1
[
1
]
<=
sub_parser_vlan_out
[
1
];
sub_parser_vlan_out_valid_d1
<=
sub_parser_vlan_out_valid
;
end
end
/*
generate
for (i=0; i<2; i=i+1) begin:
out_arb_queues
fallthrough_small_fifo #(
.WIDTH(PKT_HDR_LEN),
.MAX_DEPTH_BITS(4)
) out_arb_fifo (
.dout (fifo_pkt_hdr_out[i]),
.rd_en (fifo_rd_en[i]),
.din (sub_parser_pkt_hdr_out[i]),
.wr_en (sub_parser_pkt_hdr_valid[i] & ~nearly_full[i]),
.full (),
.nearly_full (nearly_full[i]),
.empty (empty[i]),
.reset (~aresetn),
.clk (clk)
);
end
// vlan queue
for (i=0; i<2; i=i+1) begin:
vlan_out_arb_queues
fallthrough_small_fifo #(
.WIDTH(C_VLANID_WIDTH),
.MAX_DEPTH_BITS(4)
) vlan_out_arb_fifo (
.dout (fifo_vlan_out[i]),
.rd_en (fifo_vlan_rd_en[i]),
.din (sub_parser_vlan_out[i]),
.wr_en (sub_parser_vlan_out_valid[i] & ~vlan_nearly_full[i]),
.full (),
.nearly_full (vlan_nearly_full[i]),
.empty (vlan_empty[i]),
.reset (~aresetn),
.clk (clk)
);
end
endgenerate
localparam IDLE=0;
reg [1:0] out_cur_queue, out_cur_queue_next;
wire [1:0] out_cur_queue_plus1;
reg [1:0] vlan_out_cur_queue, vlan_out_cur_queue_next;
wire [1:0] vlan_out_cur_queue_plus1;
assign out_cur_queue_plus1 = (out_cur_queue==1)?0:out_cur_queue+1;
assign vlan_out_cur_queue_plus1 = (vlan_out_cur_queue==1)?0:vlan_out_cur_queue+1;
assign pkt_hdr_vec = fifo_pkt_hdr_out[out_cur_queue];
assign parser_valid = ~empty[out_cur_queue];
assign parser_ready = ~nearly_full[0] ||
~nearly_full[1];
// ~nearly_full[2] ||
// ~nearly_full[3];
assign vlan_out = fifo_vlan_out[vlan_out_cur_queue];
assign vlan_out_valid = ~vlan_empty[vlan_out_cur_queue];
always @(*) begin
out_cur_queue_next = out_cur_queue;
fifo_rd_en = 0;
if (!empty[out_cur_queue]) begin
if (stg_ready) begin
fifo_rd_en[out_cur_queue] = 1;
out_cur_queue_next = out_cur_queue_plus1;
end
end
end
always @(*) begin
vlan_out_cur_queue_next = vlan_out_cur_queue;
fifo_vlan_rd_en = 0;
if (!vlan_empty[vlan_out_cur_queue]) begin
if (stg_vlan_ready) begin
fifo_vlan_rd_en[out_cur_queue] = 1;
vlan_out_cur_queue_next = vlan_out_cur_queue_plus1;
end
end
end
always @(posedge clk) begin
if (~aresetn) begin
out_cur_queue <= 0;
vlan_out_cur_queue <= 0;
end
else begin
out_cur_queue <= out_cur_queue_next;
vlan_out_cur_queue <= vlan_out_cur_queue_next;
end
end*/
endmodule
sims/net/menshen/rtl/parser_top.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
parser_top
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
PKT_HDR_LEN
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
// check with the doc
parameter
PARSER_MOD_ID
=
3'b0
,
parameter
C_NUM_SEGS
=
2
,
parameter
C_VLANID_WIDTH
=
12
,
parameter
C_PARSER_RAM_WIDTH
=
160
)
(
input
axis_clk
,
input
aresetn
,
// input slvae axi stream
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep
,
input
s_axis_tvalid
,
input
s_axis_tlast
,
// input vlan info
input
[
C_VLANID_WIDTH
-
1
:
0
]
s_vlan_id
,
input
s_vlan_id_valid
,
// output
output
reg
parser_valid
,
output
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec
,
// back-pressure signals
output
s_axis_tready
,
input
stg_ready_in
,
// output vlan
output
reg
[
C_VLANID_WIDTH
-
1
:
0
]
out_vlan
,
output
reg
out_vlan_valid
,
input
out_vlan_ready
,
// output to different pkt fifo queues (i.e., data cache)
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata_0
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser_0
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
m_axis_tkeep_0
,
output
m_axis_tlast_0
,
output
m_axis_tvalid_0
,
input
m_axis_tready_0
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata_1
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser_1
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
m_axis_tkeep_1
,
output
m_axis_tlast_1
,
output
m_axis_tvalid_1
,
input
m_axis_tready_1
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata_2
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser_2
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
m_axis_tkeep_2
,
output
m_axis_tlast_2
,
output
m_axis_tvalid_2
,
input
m_axis_tready_2
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata_3
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser_3
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
m_axis_tkeep_3
,
output
m_axis_tlast_3
,
output
m_axis_tvalid_3
,
input
m_axis_tready_3
,
// ctrl path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
ctrl_s_axis_tkeep
,
input
ctrl_s_axis_tvalid
,
input
ctrl_s_axis_tlast
,
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_m_axis_tdata
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_m_axis_tuser
,
output
reg
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
ctrl_m_axis_tkeep
,
output
reg
ctrl_m_axis_tvalid
,
output
reg
ctrl_m_axis_tlast
);
wire
[
C_NUM_SEGS
*
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
segs_in
;
reg
[
C_NUM_SEGS
*
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
segs_in_r
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st_in
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st_in_r
;
wire
segs_in_valid
;
reg
segs_in_valid_r
;
// paser bram out
wire
[
C_PARSER_RAM_WIDTH
-
1
:
0
]
bram_out_0
;
reg
[
C_PARSER_RAM_WIDTH
-
1
:
0
]
bram_out_0_d1
;
reg
out_bram_valid
,
out_bram_valid_d1
;
reg
bram_ready
,
bram_ready_next
;
assign
s_axis_tready
=
bram_ready
&&
m_axis_tready_0
&&
m_axis_tready_1
&&
m_axis_tready_2
&&
m_axis_tready_3
;
//
wire
[
3
:
0
]
m_axis_tready_queue
;
assign
m_axis_tready_queue
[
0
]
=
m_axis_tready_0
;
assign
m_axis_tready_queue
[
1
]
=
m_axis_tready_1
;
assign
m_axis_tready_queue
[
2
]
=
m_axis_tready_2
;
assign
m_axis_tready_queue
[
3
]
=
m_axis_tready_3
;
localparam
IDLE
=
0
,
FLUSH_REST_PKTS
=
1
;
reg
[
1
:
0
]
state
,
state_next
;
reg
[
1
:
0
]
cur_queue
,
cur_queue_next
;
wire
[
1
:
0
]
cur_queue_plus1
;
assign
cur_queue_plus1
=
(
cur_queue
==
3
)
?
0
:
cur_queue
+
1
;
// ==================================================
assign
m_axis_tdata_0
=
s_axis_tdata
;
assign
m_axis_tuser_0
=
s_axis_tuser
;
assign
m_axis_tkeep_0
=
s_axis_tkeep
;
assign
m_axis_tlast_0
=
s_axis_tlast
;
assign
m_axis_tvalid_0
=
(
cur_queue
==
0
?
1
:
0
)
&
s_axis_tvalid
&
m_axis_tready_0
;
assign
m_axis_tdata_1
=
s_axis_tdata
;
assign
m_axis_tuser_1
=
s_axis_tuser
;
assign
m_axis_tkeep_1
=
s_axis_tkeep
;
assign
m_axis_tlast_1
=
s_axis_tlast
;
assign
m_axis_tvalid_1
=
(
cur_queue
==
1
?
1
:
0
)
&
s_axis_tvalid
&
m_axis_tready_1
;
assign
m_axis_tdata_2
=
s_axis_tdata
;
assign
m_axis_tuser_2
=
s_axis_tuser
;
assign
m_axis_tkeep_2
=
s_axis_tkeep
;
assign
m_axis_tlast_2
=
s_axis_tlast
;
assign
m_axis_tvalid_2
=
(
cur_queue
==
2
?
1
:
0
)
&
s_axis_tvalid
&
m_axis_tready_2
;
assign
m_axis_tdata_3
=
s_axis_tdata
;
assign
m_axis_tuser_3
=
s_axis_tuser
;
assign
m_axis_tkeep_3
=
s_axis_tkeep
;
assign
m_axis_tlast_3
=
s_axis_tlast
;
assign
m_axis_tvalid_3
=
(
cur_queue
==
3
?
1
:
0
)
&
s_axis_tvalid
&
m_axis_tready_3
;
// ==================================================
always
@
(
*
)
begin
state_next
=
state
;
cur_queue_next
=
cur_queue
;
case
(
state
)
IDLE:
begin
if
(
s_axis_tvalid
)
begin
if
(
m_axis_tready_queue
[
cur_queue
])
begin
if
(
!
s_axis_tlast
)
begin
state_next
=
FLUSH_REST_PKTS
;
end
else
begin
cur_queue_next
=
cur_queue_plus1
;
end
end
end
end
FLUSH_REST_PKTS:
begin
if
(
s_axis_tvalid
)
begin
if
(
m_axis_tready_queue
[
cur_queue
])
begin
if
(
s_axis_tlast
)
begin
cur_queue_next
=
cur_queue_plus1
;
state_next
=
IDLE
;
end
end
end
end
endcase
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
state
<=
IDLE
;
cur_queue
<=
0
;
end
else
begin
state
<=
state_next
;
cur_queue
<=
cur_queue_next
;
end
end
// ==================================================
wire
[
C_VLANID_WIDTH
-
1
:
0
]
parser_out_vlan
,
vlan_fifo_out
;
wire
parser_out_vlan_valid
;
// wire vlan_fifo_empty, vlan_fifo_nearly_full;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
out_vlan_next
;
reg
out_vlan_valid_next
;
// reg vlan_fifo_rd_en;
// wire [PKT_HDR_LEN-1:0] phv_fifo_out;
// wire phv_fifo_empty, phv_fifo_nearly_full;
// reg phv_fifo_rd_en;
localparam
P_IDLE
=
0
;
reg
[
1
:
0
]
p_state
,
p_state_next
;
reg
[
1
:
0
]
p_cur_queue
,
p_cur_queue_next
;
wire
[
1
:
0
]
p_cur_queue_plus1
;
assign
p_cur_queue_plus1
=
(
p_cur_queue
==
3
)
?
0
:
p_cur_queue
+
1
;
wire
[
3
:
0
]
p_cur_queue_val
;
assign
p_cur_queue_val
[
0
]
=
(
p_cur_queue
==
0
)
?
1
:
0
;
assign
p_cur_queue_val
[
1
]
=
(
p_cur_queue
==
1
)
?
1
:
0
;
assign
p_cur_queue_val
[
2
]
=
(
p_cur_queue
==
2
)
?
1
:
0
;
assign
p_cur_queue_val
[
3
]
=
(
p_cur_queue
==
3
)
?
1
:
0
;
wire
parser_valid_w
;
wire
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec_w
;
reg
[
PKT_HDR_LEN
-
1
:
0
]
pkt_hdr_vec_next
,
pkt_hdr_vec_r
;
reg
parser_valid_next
,
parser_valid_r
;
/*
always @(*) begin
p_state_next = p_state;
p_cur_queue_next = p_cur_queue;
pkt_hdr_vec_next = pkt_hdr_vec;
parser_valid_next = 0;
case (p_state)
P_IDLE: begin
if (parser_valid_w) begin
pkt_hdr_vec_next = {pkt_hdr_vec_w[PKT_HDR_LEN-1:145], p_cur_queue_val, pkt_hdr_vec_w[0+:141]};
parser_valid_next = 1;
p_cur_queue_next = p_cur_queue_plus1;
end
end
endcase
end*/
always
@
(
*
)
begin
p_cur_queue_next
=
p_cur_queue
;
pkt_hdr_vec_next
=
pkt_hdr_vec_r
;
parser_valid_next
=
0
;
if
(
parser_valid_w
)
begin
pkt_hdr_vec_next
=
{
pkt_hdr_vec_w
[
PKT_HDR_LEN
-
1
:
145
],
p_cur_queue_val
,
pkt_hdr_vec_w
[
0
+:
141
]
}
;
parser_valid_next
=
1
;
p_cur_queue_next
=
p_cur_queue_plus1
;
end
end
always
@
(
*
)
begin
out_vlan_valid_next
=
0
;
out_vlan_next
=
out_vlan
;
if
(
parser_out_vlan_valid
)
begin
out_vlan_valid_next
=
1
;
out_vlan_next
=
parser_out_vlan
;
end
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
p_state
<=
P_IDLE
;
p_cur_queue
<=
0
;
pkt_hdr_vec
<=
0
;
parser_valid
<=
0
;
out_vlan
<=
0
;
out_vlan_valid
<=
0
;
pkt_hdr_vec_r
<=
0
;
parser_valid_r
<=
0
;
end
else
begin
p_state
<=
p_state_next
;
p_cur_queue
<=
p_cur_queue_next
;
pkt_hdr_vec_r
<=
pkt_hdr_vec_next
;
parser_valid_r
<=
parser_valid_next
;
pkt_hdr_vec
<=
pkt_hdr_vec_r
;
parser_valid
<=
parser_valid_r
;
out_vlan
<=
out_vlan_next
;
out_vlan_valid
<=
out_vlan_valid_next
;
end
end
//
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
segs_in_r
<=
0
;
tuser_1st_in_r
<=
0
;
segs_in_valid_r
<=
0
;
end
else
begin
segs_in_r
<=
segs_in
;
tuser_1st_in_r
<=
tuser_1st_in
;
segs_in_valid_r
<=
segs_in_valid
;
end
end
//
parser_wait_segs
#(
)
get_segs
(
.
axis_clk
(
axis_clk
),
.
aresetn
(
aresetn
),
.
s_axis_tdata
(
s_axis_tdata
),
.
s_axis_tuser
(
s_axis_tuser
),
.
s_axis_tkeep
(
s_axis_tkeep
),
.
s_axis_tvalid
(
s_axis_tvalid
),
.
s_axis_tlast
(
s_axis_tlast
),
// output
.
tdata_segs
(
segs_in
),
.
tuser_1st
(
tuser_1st_in
),
.
segs_valid
(
segs_in_valid
)
);
parser_do_parsing_top
#(
)
do_parsing
(
.
clk
(
axis_clk
),
.
aresetn
(
aresetn
),
.
segs_in
(
segs_in_r
),
.
segs_in_valid
(
segs_in_valid_r
),
.
tuser_1st_in
(
tuser_1st_in_r
),
.
bram_in
(
bram_out_0_d1
),
.
bram_in_valid
(
out_bram_valid_d1
),
.
stg_ready
(
stg_ready_in
),
.
stg_vlan_ready
(
out_vlan_ready
),
// output
.
pkt_hdr_vec
(
pkt_hdr_vec_w
),
.
parser_valid
(
parser_valid_w
),
.
vlan_out
(
parser_out_vlan
),
.
vlan_out_valid
(
parser_out_vlan_valid
)
);
//
localparam
BRAM_IDLE
=
0
,
BRAM_CYCLE_1
=
1
,
BRAM_CYCLE_2
=
2
,
BRAM_CYCLE_3
=
3
;
reg
[
2
:
0
]
bram_state
,
bram_state_next
;
reg
out_bram_valid_next
;
always
@
(
*
)
begin
bram_state_next
=
bram_state
;
out_bram_valid_next
=
0
;
bram_ready_next
=
bram_ready
;
case
(
bram_state
)
BRAM_IDLE:
begin
if
(
s_vlan_id_valid
)
begin
bram_state_next
=
BRAM_CYCLE_1
;
if
(
s_axis_tvalid
&&
s_axis_tlast
)
begin
bram_ready_next
=
0
;
end
end
end
BRAM_CYCLE_1:
begin
bram_state_next
=
BRAM_IDLE
;
out_bram_valid_next
=
1
;
bram_ready_next
=
1
;
end
endcase
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
bram_state
<=
BRAM_IDLE
;
out_bram_valid
<=
0
;
bram_ready
<=
1
;
out_bram_valid_d1
<=
0
;
end
else
begin
bram_state
<=
bram_state_next
;
out_bram_valid
<=
out_bram_valid_next
;
out_bram_valid_d1
<=
out_bram_valid
;
bram_out_0_d1
<=
bram_out_0
;
bram_ready
<=
bram_ready_next
;
end
end
// fifo
/*
fallthrough_small_fifo #(
.WIDTH(PKT_HDR_LEN),
.MAX_DEPTH_BITS(4)
)
pkt_hdr_fifo (
.din (pkt_hdr_vec_w),
.wr_en (parser_valid_w),
.dout (phv_fifo_out),
.rd_en (phv_fifo_rd_en),
.full (),
.nearly_full (phv_fifo_nearly_full),
.empty (phv_fifo_empty),
.reset (~aresetn),
.clk (axis_clk)
);
fallthrough_small_fifo #(
.WIDTH(C_VLANID_WIDTH),
.MAX_DEPTH_BITS(4)
)
vlan_fifo (
.din (parser_out_vlan),
.wr_en (parser_out_vlan_valid),
.dout (vlan_fifo_out),
.rd_en (vlan_fifo_rd_en),
.full (),
.nearly_full (vlan_fifo_nearly_full),
.empty (vlan_fifo_empty),
.reset (~aresetn),
.clk (axis_clk)
);*/
/*================Control Path====================*/
wire
[
7
:
0
]
mod_id
;
//module ID
wire
[
15
:
0
]
control_flag
;
//dst udp port num
reg
[
7
:
0
]
c_index
;
//table index(addr)
reg
c_wr_en
;
//enable table write(wen)
reg
[
159
:
0
]
entry_reg
;
reg
[
2
:
0
]
c_state
;
localparam
IDLE_C
=
1
,
WRITE_C
=
2
,
SU_WRITE_C
=
3
;
assign
mod_id
=
ctrl_s_axis_tdata
[
368
+:
8
];
assign
control_flag
=
ctrl_s_axis_tdata
[
335
:
320
];
//LE to BE switching
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_swapped
;
assign
ctrl_s_axis_tdata_swapped
=
{
ctrl_s_axis_tdata
[
0
+:
8
],
ctrl_s_axis_tdata
[
8
+:
8
],
ctrl_s_axis_tdata
[
16
+:
8
],
ctrl_s_axis_tdata
[
24
+:
8
],
ctrl_s_axis_tdata
[
32
+:
8
],
ctrl_s_axis_tdata
[
40
+:
8
],
ctrl_s_axis_tdata
[
48
+:
8
],
ctrl_s_axis_tdata
[
56
+:
8
],
ctrl_s_axis_tdata
[
64
+:
8
],
ctrl_s_axis_tdata
[
72
+:
8
],
ctrl_s_axis_tdata
[
80
+:
8
],
ctrl_s_axis_tdata
[
88
+:
8
],
ctrl_s_axis_tdata
[
96
+:
8
],
ctrl_s_axis_tdata
[
104
+:
8
],
ctrl_s_axis_tdata
[
112
+:
8
],
ctrl_s_axis_tdata
[
120
+:
8
],
ctrl_s_axis_tdata
[
128
+:
8
],
ctrl_s_axis_tdata
[
136
+:
8
],
ctrl_s_axis_tdata
[
144
+:
8
],
ctrl_s_axis_tdata
[
152
+:
8
],
ctrl_s_axis_tdata
[
160
+:
8
],
ctrl_s_axis_tdata
[
168
+:
8
],
ctrl_s_axis_tdata
[
176
+:
8
],
ctrl_s_axis_tdata
[
184
+:
8
],
ctrl_s_axis_tdata
[
192
+:
8
],
ctrl_s_axis_tdata
[
200
+:
8
],
ctrl_s_axis_tdata
[
208
+:
8
],
ctrl_s_axis_tdata
[
216
+:
8
],
ctrl_s_axis_tdata
[
224
+:
8
],
ctrl_s_axis_tdata
[
232
+:
8
],
ctrl_s_axis_tdata
[
240
+:
8
],
ctrl_s_axis_tdata
[
248
+:
8
],
ctrl_s_axis_tdata
[
256
+:
8
],
ctrl_s_axis_tdata
[
264
+:
8
],
ctrl_s_axis_tdata
[
272
+:
8
],
ctrl_s_axis_tdata
[
280
+:
8
],
ctrl_s_axis_tdata
[
288
+:
8
],
ctrl_s_axis_tdata
[
296
+:
8
],
ctrl_s_axis_tdata
[
304
+:
8
],
ctrl_s_axis_tdata
[
312
+:
8
],
ctrl_s_axis_tdata
[
320
+:
8
],
ctrl_s_axis_tdata
[
328
+:
8
],
ctrl_s_axis_tdata
[
336
+:
8
],
ctrl_s_axis_tdata
[
344
+:
8
],
ctrl_s_axis_tdata
[
352
+:
8
],
ctrl_s_axis_tdata
[
360
+:
8
],
ctrl_s_axis_tdata
[
368
+:
8
],
ctrl_s_axis_tdata
[
376
+:
8
],
ctrl_s_axis_tdata
[
384
+:
8
],
ctrl_s_axis_tdata
[
392
+:
8
],
ctrl_s_axis_tdata
[
400
+:
8
],
ctrl_s_axis_tdata
[
408
+:
8
],
ctrl_s_axis_tdata
[
416
+:
8
],
ctrl_s_axis_tdata
[
424
+:
8
],
ctrl_s_axis_tdata
[
432
+:
8
],
ctrl_s_axis_tdata
[
440
+:
8
],
ctrl_s_axis_tdata
[
448
+:
8
],
ctrl_s_axis_tdata
[
456
+:
8
],
ctrl_s_axis_tdata
[
464
+:
8
],
ctrl_s_axis_tdata
[
472
+:
8
],
ctrl_s_axis_tdata
[
480
+:
8
],
ctrl_s_axis_tdata
[
488
+:
8
],
ctrl_s_axis_tdata
[
496
+:
8
],
ctrl_s_axis_tdata
[
504
+:
8
]
}
;
always
@
(
posedge
axis_clk
or
negedge
aresetn
)
begin
if
(
~
aresetn
)
begin
c_wr_en
<=
1'b0
;
c_index
<=
4'b0
;
ctrl_m_axis_tdata
<=
0
;
ctrl_m_axis_tuser
<=
0
;
ctrl_m_axis_tkeep
<=
0
;
ctrl_m_axis_tvalid
<=
0
;
ctrl_m_axis_tlast
<=
0
;
entry_reg
<=
0
;
c_state
<=
IDLE_C
;
end
else
begin
case
(
c_state
)
IDLE_C:
begin
if
(
ctrl_s_axis_tvalid
&&
mod_id
[
2
:
0
]
==
PARSER_MOD_ID
&&
control_flag
==
16'hf2f1
)
begin
c_wr_en
<=
1'b0
;
c_index
<=
ctrl_s_axis_tdata
[
384
+:
8
];
ctrl_m_axis_tdata
<=
0
;
ctrl_m_axis_tuser
<=
0
;
ctrl_m_axis_tkeep
<=
0
;
ctrl_m_axis_tvalid
<=
0
;
ctrl_m_axis_tlast
<=
0
;
c_state
<=
WRITE_C
;
end
else
begin
c_wr_en
<=
1'b0
;
c_index
<=
4'b0
;
entry_reg
<=
0
;
ctrl_m_axis_tdata
<=
ctrl_s_axis_tdata
;
ctrl_m_axis_tuser
<=
ctrl_s_axis_tuser
;
ctrl_m_axis_tkeep
<=
ctrl_s_axis_tkeep
;
ctrl_m_axis_tvalid
<=
ctrl_s_axis_tvalid
;
ctrl_m_axis_tlast
<=
ctrl_s_axis_tlast
;
c_state
<=
IDLE_C
;
end
end
//support full table flush
WRITE_C:
begin
if
(
ctrl_s_axis_tvalid
)
begin
c_wr_en
<=
1'b1
;
entry_reg
<=
ctrl_s_axis_tdata_swapped
[
511
-:
160
];
if
(
ctrl_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_C
;
end
end
else
begin
c_wr_en
<=
1'b0
;
end
end
SU_WRITE_C:
begin
if
(
ctrl_s_axis_tvalid
)
begin
entry_reg
<=
ctrl_s_axis_tdata_swapped
[
511
-:
160
];
c_wr_en
<=
1'b1
;
c_index
<=
c_index
+
1'b1
;
if
(
ctrl_s_axis_tlast
)
begin
c_state
<=
IDLE_C
;
end
else
begin
c_state
<=
SU_WRITE_C
;
end
end
else
begin
c_wr_en
<=
1'b0
;
end
end
endcase
end
end
// =============================================================== //
// parse_act_ram_ip #(
// .C_INIT_FILE_NAME ("./parse_act_ram_init_file.mif"),
// .C_LOAD_INIT_FILE (1)
// )
parse_act_ram_ip
parse_act_ram_0
(
// write port
.
clka
(
axis_clk
),
.
addra
(
c_index
[
4
:
0
]),
.
dina
(
entry_reg
),
.
ena
(
1'b1
),
.
wea
(
c_wr_en
),
//
.
clkb
(
axis_clk
),
.
addrb
(
s_vlan_id
[
8
:
4
]),
// TODO: note that we may change due to little or big endian
.
doutb
(
bram_out_0
),
.
enb
(
1'b1
)
// always set to 1
);
endmodule
sims/net/menshen/rtl/parser_wait_segs.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
parser_wait_segs
#(
parameter
C_AXIS_DATA_WIDTH
=
512
,
parameter
C_AXIS_TUSER_WIDTH
=
128
,
parameter
C_NUM_SEGS
=
2
)
(
input
axis_clk
,
input
aresetn
,
//
input
[
C_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata
,
input
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser
,
input
[
C_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
s_axis_tkeep
,
input
s_axis_tvalid
,
input
s_axis_tlast
,
//
output
reg
[
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
-
1
:
0
]
tdata_segs
,
output
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st
,
output
reg
segs_valid
);
localparam
WAIT_1ST_SEG
=
0
,
WAIT_2ND_SEG
=
1
,
WAIT_1CYCLE
=
2
,
OUTPUT_SEGS
=
3
,
WAIT_TILL_LAST
=
4
;
reg
[
2
:
0
]
state
,
state_next
;
reg
[
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
-
1
:
0
]
tdata_segs_next
;
reg
[
C_AXIS_TUSER_WIDTH
-
1
:
0
]
tuser_1st_next
;
reg
segs_valid_next
;
always
@
(
*
)
begin
state_next
=
state
;
tdata_segs_next
=
tdata_segs
;
tuser_1st_next
=
tuser_1st
;
segs_valid_next
=
0
;
case
(
state
)
// at-most 2 segs
WAIT_1ST_SEG:
begin
if
(
s_axis_tvalid
)
begin
tdata_segs_next
[
0
*
C_AXIS_DATA_WIDTH
+:
C_AXIS_DATA_WIDTH
]
=
s_axis_tdata
;
tuser_1st_next
=
s_axis_tuser
;
if
(
s_axis_tlast
)
begin
state_next
=
WAIT_1CYCLE
;
end
else
begin
state_next
=
WAIT_2ND_SEG
;
end
end
end
WAIT_1CYCLE:
begin
segs_valid_next
=
1
;
state_next
=
WAIT_1ST_SEG
;
end
WAIT_2ND_SEG:
begin
if
(
s_axis_tvalid
)
begin
tdata_segs_next
[
1
*
C_AXIS_DATA_WIDTH
+:
C_AXIS_DATA_WIDTH
]
=
s_axis_tdata
;
segs_valid_next
=
1
;
if
(
s_axis_tlast
)
begin
state_next
=
WAIT_1ST_SEG
;
end
else
begin
state_next
=
WAIT_TILL_LAST
;
end
end
end
WAIT_TILL_LAST:
begin
if
(
s_axis_tvalid
&&
s_axis_tlast
)
begin
state_next
=
WAIT_1ST_SEG
;
end
end
endcase
end
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
state
<=
WAIT_1ST_SEG
;
tdata_segs
<=
{
C_NUM_SEGS
*
C_AXIS_DATA_WIDTH
{
1'b0
}}
;
tuser_1st
<=
{
C_AXIS_TUSER_WIDTH
{
1'b0
}}
;
segs_valid
<=
0
;
end
else
begin
state
<=
state_next
;
tdata_segs
<=
tdata_segs_next
;
tuser_1st
<=
tuser_1st_next
;
segs_valid
<=
segs_valid_next
;
end
end
endmodule
sims/net/menshen/rtl/pkt_filter.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
`define
ETH_TYPE_IPV4 16
'
h0008
`define
IPPROT_UDP 8
'
h11
`define
CONTROL_PORT 16
'
hf2f1
module
pkt_filter
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
input
aresetn
,
input
[
31
:
0
]
vlan_drop_flags
,
output
[
31
:
0
]
ctrl_token
,
// input Slave AXI Stream
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata
,
input
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
s_axis_tkeep
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser
,
input
s_axis_tvalid
,
output
s_axis_tready
,
input
s_axis_tlast
,
// output Master AXI Stream
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata
,
output
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
m_axis_tkeep
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser
,
output
reg
m_axis_tvalid
,
input
m_axis_tready
,
output
reg
m_axis_tlast
,
output
reg
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_id
,
output
reg
vlan_id_valid
,
//TODO a back-pressure is needed?
output
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
c_m_axis_tkeep
,
output
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
reg
c_m_axis_tvalid
,
output
reg
c_m_axis_tlast
);
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
pkt_fifo_tdata
;
wire
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
pkt_fifo_tkeep
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
pkt_fifo_tuser
;
wire
pkt_fifo_tlast
;
reg
pkt_fifo_rd_en
;
wire
pkt_fifo_empty
,
pkt_fifo_full
;
//
assign
s_axis_tready
=
~
pkt_fifo_full
;
fallthrough_small_fifo
#(
.
WIDTH
(
C_S_AXIS_DATA_WIDTH
+
C_S_AXIS_TUSER_WIDTH
+
C_S_AXIS_DATA_WIDTH
/
8
+
1
),
.
MAX_DEPTH_BITS
(
5
)
)
seg_fifo
(
.
din
(
{
s_axis_tdata
,
s_axis_tkeep
,
s_axis_tuser
,
s_axis_tlast
}
),
.
wr_en
(
s_axis_tvalid
),
//
.
rd_en
(
pkt_fifo_rd_en
),
.
dout
(
{
pkt_fifo_tdata
,
pkt_fifo_tkeep
,
pkt_fifo_tuser
,
pkt_fifo_tlast
}
),
//
.
full
(),
.
prog_full
(),
.
nearly_full
(
pkt_fifo_full
),
.
empty
(
pkt_fifo_empty
),
.
reset
(
~
aresetn
),
.
clk
(
clk
)
);
localparam
WAIT_FIRST_PKT
=
0
,
DROP_PKT
=
1
,
FLUSH_DATA
=
2
,
FLUSH_CTL
=
3
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
r_tdata
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
r_tkeep
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
r_tuser
;
reg
r_tvalid
;
reg
r_tlast
;
reg
r_s_tready
;
reg
[
1
:
0
]
state
,
state_next
;
//1 for control, 0 for data;
reg
c_switch
;
wire
w_c_switch
;
// vlan
reg
vlan_id_valid_next
;
//for security and reliability
reg
[
31
:
0
]
ctrl_token_r
,
ctrl_token_next
;
//checkme: for dropping packets during reconf
wire
[
11
:
0
]
vlan_id_w
;
wire
[
31
:
0
]
vlan_id_one_hot_w
;
assign
w_c_switch
=
c_switch
;
assign
ctrl_token
=
ctrl_token_r
;
assign
vlan_id_w
=
pkt_fifo_tdata
[
116
+:
12
];
assign
vlan_id_one_hot_w
=
(
1'b1
<<
vlan_id_w
[
8
:
4
]);
always
@
(
*
)
begin
r_tdata
=
pkt_fifo_tdata
;
r_tkeep
=
pkt_fifo_tkeep
;
r_tuser
=
pkt_fifo_tuser
;
r_tlast
=
pkt_fifo_tlast
;
r_tvalid
=
0
;
// r_s_tready = m_axis_tready;
c_switch
=
1'b0
;
vlan_id_valid_next
=
0
;
pkt_fifo_rd_en
=
0
;
state_next
=
state
;
ctrl_token_next
=
ctrl_token_r
;
case
(
state
)
WAIT_FIRST_PKT:
begin
if
(
!
pkt_fifo_empty
)
begin
if
(
m_axis_tready
)
begin
if
((
pkt_fifo_tdata
[
143
:
128
]
==
`ETH_TYPE_IPV4
)
&&
(
pkt_fifo_tdata
[
223
:
216
]
==
`IPPROT_UDP
))
begin
//checkme: we put the security check here
// if(s_axis_tdata[335:320] == `CONTROL_PORT && cookie_w == cookie_val_d1) begin
if
(
pkt_fifo_tdata
[
335
:
320
]
==
`CONTROL_PORT
)
begin
state_next
=
FLUSH_CTL
;
c_switch
=
1'b1
;
//modify token once its true
ctrl_token_next
=
ctrl_token_r
+
1
;
pkt_fifo_rd_en
=
1
;
r_tvalid
=
1
;
end
else
if
(
!
pkt_fifo_tlast
)
begin
//checkme: if this vlan is not configed, send it
// TODO: for validity check
//if((vlan_id_one_hot_w & vlan_drop_flags)==0) begin
if
(
1
)
begin
pkt_fifo_rd_en
=
1
;
r_tvalid
=
1
;
state_next
=
FLUSH_DATA
;
c_switch
=
1'b0
;
vlan_id_valid_next
=
1
;
end
else
begin
pkt_fifo_rd_en
=
1
;
state_next
=
DROP_PKT
;
r_tvalid
=
0
;
end
end
else
if
(
pkt_fifo_tlast
)
begin
pkt_fifo_rd_en
=
1
;
state_next
=
WAIT_FIRST_PKT
;
c_switch
=
1'b0
;
vlan_id_valid_next
=
1
;
r_tvalid
=
1
;
//checkme: if this vlan is configed, drop it
//if((vlan_id_one_hot_w & vlan_drop_flags)!=0) begin
// r_tvalid = 0;
//end
end
end
else
begin
pkt_fifo_rd_en
=
1
;
r_tvalid
=
0
;
state_next
=
DROP_PKT
;
end
if
(
pkt_fifo_tlast
)
begin
state_next
=
WAIT_FIRST_PKT
;
end
end
else
begin
c_switch
=
1'b0
;
end
end
end
FLUSH_DATA:
begin
if
(
!
pkt_fifo_empty
)
begin
if
(
m_axis_tready
)
begin
r_tvalid
=
1
;
pkt_fifo_rd_en
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
WAIT_FIRST_PKT
;
end
end
end
end
FLUSH_CTL:
begin
c_switch
=
1'b1
;
if
(
!
pkt_fifo_empty
)
begin
r_tvalid
=
1
;
pkt_fifo_rd_en
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
WAIT_FIRST_PKT
;
end
end
end
DROP_PKT:
begin
r_tvalid
=
0
;
if
(
!
pkt_fifo_empty
)
begin
pkt_fifo_rd_en
=
1
;
if
(
pkt_fifo_tlast
)
begin
state_next
=
WAIT_FIRST_PKT
;
end
end
end
endcase
end
always
@
(
posedge
clk
or
negedge
aresetn
)
begin
if
(
~
aresetn
)
begin
state
<=
WAIT_FIRST_PKT
;
m_axis_tdata
<=
0
;
m_axis_tkeep
<=
0
;
m_axis_tuser
<=
0
;
m_axis_tlast
<=
0
;
m_axis_tvalid
<=
0
;
c_m_axis_tdata
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tlast
<=
0
;
c_m_axis_tvalid
<=
0
;
// s_axis_tready <= 0;
//
vlan_id
<=
0
;
vlan_id_valid
<=
0
;
//
ctrl_token_r
<=
0
;
end
else
begin
state
<=
state_next
;
ctrl_token_r
<=
ctrl_token_next
;
if
(
!
w_c_switch
)
begin
// data pkt
m_axis_tdata
<=
r_tdata
;
m_axis_tkeep
<=
r_tkeep
;
m_axis_tuser
<=
r_tuser
;
m_axis_tlast
<=
r_tlast
;
m_axis_tvalid
<=
r_tvalid
;
// s_axis_tready <= r_s_tready;
//reset control path output
c_m_axis_tdata
<=
0
;
c_m_axis_tkeep
<=
0
;
c_m_axis_tuser
<=
0
;
c_m_axis_tlast
<=
0
;
c_m_axis_tvalid
<=
0
;
vlan_id
<=
vlan_id_w
;
vlan_id_valid
<=
vlan_id_valid_next
;
end
else
begin
// ctrl pkt
m_axis_tdata
<=
0
;
m_axis_tkeep
<=
0
;
m_axis_tuser
<=
0
;
m_axis_tlast
<=
0
;
m_axis_tvalid
<=
0
;
//
c_m_axis_tdata
<=
r_tdata
;
c_m_axis_tkeep
<=
r_tkeep
;
c_m_axis_tuser
<=
r_tuser
;
c_m_axis_tlast
<=
r_tlast
;
c_m_axis_tvalid
<=
r_tvalid
;
end
end
end
endmodule
sims/net/menshen/rtl/rmt_wrapper.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
rmt_wrapper
#(
// AXI-Lite parameters
// Width of AXI lite data bus in bits
parameter
AXIL_DATA_WIDTH
=
32
,
// Width of AXI lite address bus in bits
parameter
AXIL_ADDR_WIDTH
=
16
,
// Width of AXI lite wstrb (width of data bus in words)
parameter
AXIL_STRB_WIDTH
=
(
AXIL_DATA_WIDTH
/
8
),
// AXI Stream parameters
// Slave
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
// Master
// self-defined
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
1
,
parameter
ACT_LEN
=
25
,
parameter
KEY_OFF
=
6
*
3
+
20
,
parameter
C_NUM_QUEUES
=
4
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
clk
,
// axis clk
input
aresetn
,
input
[
31
:
0
]
vlan_drop_flags
,
output
reg
[
31
:
0
]
ctrl_token
,
/*
* input Slave AXI Stream
*/
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata
,
input
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
s_axis_tkeep
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser
,
input
s_axis_tvalid
,
output
s_axis_tready
,
input
s_axis_tlast
,
/*
* output Master AXI Stream
*/
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
m_axis_tdata
,
output
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
m_axis_tkeep
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
m_axis_tuser
,
output
m_axis_tvalid
,
input
m_axis_tready
,
output
m_axis_tlast
);
reg
[
31
:
0
]
vlan_drop_flags_r
;
wire
[
31
:
0
]
ctrl_token_r
;
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
vlan_drop_flags_r
<=
0
;
ctrl_token
<=
0
;
end
else
begin
vlan_drop_flags_r
<=
vlan_drop_flags
;
ctrl_token
<=
ctrl_token_r
;
end
end
integer
idx
;
/*=================================================*/
localparam
PKT_VEC_WIDTH
=
(
6
+
4
+
2
)
*
8
*
8
+
256
;
wire
stg0_phv_in_valid
;
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
stg0_phv_in
;
// stage-related
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
stg0_phv_out
;
wire
stg0_phv_out_valid
;
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
stg1_phv_out
;
wire
stg1_phv_out_valid
;
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
stg2_phv_out
;
wire
stg2_phv_out_valid
;
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
stg3_phv_out
;
wire
stg3_phv_out_valid
;
// wire [PKT_VEC_WIDTH-1:0] stg4_phv_out;
// wire stg4_phv_out_valid;
reg
[
PKT_VEC_WIDTH
-
1
:
0
]
stg0_phv_in_d1
;
reg
[
PKT_VEC_WIDTH
-
1
:
0
]
stg0_phv_out_d1
;
reg
[
PKT_VEC_WIDTH
-
1
:
0
]
stg1_phv_out_d1
;
reg
[
PKT_VEC_WIDTH
-
1
:
0
]
stg2_phv_out_d1
;
reg
[
PKT_VEC_WIDTH
-
1
:
0
]
stg3_phv_out_d1
;
reg
stg0_phv_in_valid_d1
;
reg
stg0_phv_out_valid_d1
;
reg
stg1_phv_out_valid_d1
;
reg
stg2_phv_out_valid_d1
;
reg
stg3_phv_out_valid_d1
;
//
wire
[
C_VLANID_WIDTH
-
1
:
0
]
stg0_vlan_in
;
wire
stg0_vlan_valid_in
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
stg0_vlan_in_r
;
reg
stg0_vlan_valid_in_r
;
wire
stg0_vlan_ready
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
stg0_vlan_out
;
wire
stg0_vlan_valid_out
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
stg0_vlan_out_r
;
reg
stg0_vlan_valid_out_r
;
wire
stg1_vlan_ready
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
stg1_vlan_out
;
wire
stg1_vlan_valid_out
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
stg1_vlan_out_r
;
reg
stg1_vlan_valid_out_r
;
wire
stg2_vlan_ready
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
stg2_vlan_out
;
wire
stg2_vlan_valid_out
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
stg2_vlan_out_r
;
reg
stg2_vlan_valid_out_r
;
wire
stg3_vlan_ready
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
stg3_vlan_out
;
wire
stg3_vlan_valid_out
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
stg3_vlan_out_r
;
reg
stg3_vlan_valid_out_r
;
wire
last_stg_vlan_ready
;
// back pressure signals
wire
s_axis_tready_p
;
wire
stg0_ready
;
wire
stg1_ready
;
wire
stg2_ready
;
wire
stg3_ready
;
wire
last_stg_ready
;
/*=================================================*/
wire
[
C_VLANID_WIDTH
-
1
:
0
]
s_vlan_id
;
wire
s_vlan_id_valid
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
s_vlan_id_r
;
reg
s_vlan_id_valid_r
;
//NOTE: to filter out packets other than UDP/IP.
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_f
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
s_axis_tkeep_f
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_f
;
wire
s_axis_tvalid_f
;
wire
s_axis_tready_f
;
wire
s_axis_tlast_f
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
s_axis_tdata_f_reg
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
s_axis_tkeep_f_reg
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
s_axis_tuser_f_reg
;
reg
s_axis_tvalid_f_reg
;
reg
s_axis_tlast_f_reg
;
//NOTE: filter control packets from data packets.
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_1
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_1
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_1
;
wire
ctrl_s_axis_tvalid_1
;
wire
ctrl_s_axis_tlast_1
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_1_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_1_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_1_r
;
reg
ctrl_s_axis_tvalid_1_r
;
reg
ctrl_s_axis_tlast_1_r
;
pkt_filter
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
)
)
pkt_filter
(
.
clk
(
clk
),
.
aresetn
(
aresetn
),
.
vlan_drop_flags
(
vlan_drop_flags_r
),
.
ctrl_token
(
ctrl_token_r
),
// input Slave AXI Stream
.
s_axis_tdata
(
s_axis_tdata
),
.
s_axis_tkeep
(
s_axis_tkeep
),
.
s_axis_tuser
(
s_axis_tuser
),
.
s_axis_tvalid
(
s_axis_tvalid
),
.
s_axis_tready
(
s_axis_tready
),
.
s_axis_tlast
(
s_axis_tlast
),
.
vlan_id
(
s_vlan_id
),
.
vlan_id_valid
(
s_vlan_id_valid
),
// output Master AXI Stream
.
m_axis_tdata
(
s_axis_tdata_f
),
.
m_axis_tkeep
(
s_axis_tkeep_f
),
.
m_axis_tuser
(
s_axis_tuser_f
),
.
m_axis_tvalid
(
s_axis_tvalid_f
),
// .m_axis_tready(s_axis_tready_f && s_axis_tready_p),
.
m_axis_tready
(
s_axis_tready_p
),
.
m_axis_tlast
(
s_axis_tlast_f
),
//control path
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_1
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_1
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_1
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_1
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_1
)
);
// we will have multiple pkt fifos and phv fifos
// pkt fifo wires
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
pkt_fifo_tdata_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
pkt_fifo_tuser_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
pkt_fifo_tkeep_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_NUM_QUEUES
-
1
:
0
]
pkt_fifo_tlast_out
;
// output from parser
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
parser_m_axis_tdata
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
parser_m_axis_tuser
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
parser_m_axis_tkeep
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_NUM_QUEUES
-
1
:
0
]
parser_m_axis_tlast
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
parser_m_axis_tvalid
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
pkt_fifo_rd_en
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
pkt_fifo_nearly_full
;
wire
[
C_NUM_QUEUES
-
1
:
0
]
pkt_fifo_empty
;
/*
generate
genvar i;
for (i=0; i<C_NUM_QUEUES; i=i+1) begin:
sub_pkt_fifo
fifo_generator_705b
pkt_fifo (
.clk (clk), // input wire clk
.srst (~aresetn), // input wire srst
.din ({parser_m_axis_tdata[i],
parser_m_axis_tuser[i],
parser_m_axis_tkeep[i],
parser_m_axis_tlast[i]}), // input wire [704 : 0] din
.wr_en (parser_m_axis_tvalid[i]), // input wire wr_en
.rd_en (pkt_fifo_rd_en[i]), // input wire rd_en
.dout ({pkt_fifo_tdata_out[i],
pkt_fifo_tuser_out[i],
pkt_fifo_tkeep_out[i],
pkt_fifo_tlast_out[i]}), // output wire [704 : 0] dout
.full (pkt_fifo_nearly_full[i]), // output wire full
.empty (pkt_fifo_empty[i]), // output wire empty
.wr_rst_busy (), // output wire wr_rst_busy
.rd_rst_busy () // output wire rd_rst_busy
);
end
endgenerate
*/
generate
genvar
i
;
for
(
i
=
0
;
i
<
C_NUM_QUEUES
;
i
=
i
+
1
)
begin
:
sub_pkt_fifo
fallthrough_small_fifo
#(
.
WIDTH
(
C_S_AXIS_DATA_WIDTH
+
C_S_AXIS_TUSER_WIDTH
+
C_S_AXIS_DATA_WIDTH
/
8
+
1
),
.
MAX_DEPTH_BITS
(
4
)
)
pkt_fifo
(
.
clk
(
clk
),
// input wire clk
.
reset
(
~
aresetn
),
// input wire srst
.
din
(
{
parser_m_axis_tdata
[
i
],
parser_m_axis_tuser
[
i
],
parser_m_axis_tkeep
[
i
],
parser_m_axis_tlast
[
i
]
}
),
// input wire [704 : 0] din
.
wr_en
(
parser_m_axis_tvalid
[
i
]),
// input wire wr_en
.
rd_en
(
pkt_fifo_rd_en
[
i
]),
// input wire rd_en
.
dout
(
{
pkt_fifo_tdata_out
[
i
],
pkt_fifo_tuser_out
[
i
],
pkt_fifo_tkeep_out
[
i
],
pkt_fifo_tlast_out
[
i
]
}
),
// output wire [704 : 0] dout
.
full
(),
.
nearly_full
(
pkt_fifo_nearly_full
[
i
]),
// output wire full
.
empty
(
pkt_fifo_empty
[
i
])
// output wire empty
);
end
endgenerate
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
last_stg_phv_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
PKT_VEC_WIDTH
-
1
:
0
]
phv_fifo_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
last_stg_phv_out_valid
[
C_NUM_QUEUES
-
1
:
0
];
wire
phv_fifo_rd_en
[
C_NUM_QUEUES
-
1
:
0
];
wire
phv_fifo_nearly_full
[
C_NUM_QUEUES
-
1
:
0
];
wire
phv_fifo_empty
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
511
:
0
]
high_phv_out
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
511
:
0
]
low_phv_out
[
C_NUM_QUEUES
-
1
:
0
];
assign
phv_fifo_out
[
0
]
=
{
high_phv_out
[
0
],
low_phv_out
[
0
]
}
;
assign
phv_fifo_out
[
1
]
=
{
high_phv_out
[
1
],
low_phv_out
[
1
]
}
;
assign
phv_fifo_out
[
2
]
=
{
high_phv_out
[
2
],
low_phv_out
[
2
]
}
;
assign
phv_fifo_out
[
3
]
=
{
high_phv_out
[
3
],
low_phv_out
[
3
]
}
;
assign
s_axis_tready_f
=
(
!
pkt_fifo_nearly_full
[
0
]
||
!
pkt_fifo_nearly_full
[
1
]
||
!
pkt_fifo_nearly_full
[
2
]
||
!
pkt_fifo_nearly_full
[
3
])
&&
(
!
phv_fifo_nearly_full
[
0
]
||
!
phv_fifo_nearly_full
[
1
]
||
!
phv_fifo_nearly_full
[
2
]
||
!
phv_fifo_nearly_full
[
3
]);
generate
for
(
i
=
0
;
i
<
C_NUM_QUEUES
;
i
=
i
+
1
)
begin
:
sub_phv_fifo_1
fallthrough_small_fifo
#(
.
WIDTH
(
512
),
.
MAX_DEPTH_BITS
(
6
)
)
phv_fifo_1
(
.
clk
(
clk
),
.
reset
(
~
aresetn
),
.
din
(
last_stg_phv_out
[
i
][
511
:
0
]),
.
wr_en
(
last_stg_phv_out_valid
[
i
]),
.
rd_en
(
phv_fifo_rd_en
[
i
]),
.
dout
(
low_phv_out
[
i
]),
.
full
(),
.
nearly_full
(
phv_fifo_nearly_full
[
i
]),
.
empty
(
phv_fifo_empty
[
i
])
);
/*
fifo_generator_512b
phv_fifo_1 (
.clk (clk), // input wire clk
.srst (~aresetn), // input wire srst
.din (last_stg_phv_out[i][511:0]), // input wire [511 : 0] din
.wr_en (last_stg_phv_out_valid[i]), // input wire wr_en
.rd_en (phv_fifo_rd_en[i]), // input wire rd_en
.dout (low_phv_out[i]), // output wire [511 : 0] dout
.full (phv_fifo_nearly_full[i]), // output wire full
.empty (phv_fifo_empty[i]), // output wire empty
.wr_rst_busy (), // output wire wr_rst_busy
.rd_rst_busy () // output wire rd_rst_busy
);*/
end
endgenerate
generate
for
(
i
=
0
;
i
<
C_NUM_QUEUES
;
i
=
i
+
1
)
begin
:
sub_phv_fifo_2
fallthrough_small_fifo
#(
.
WIDTH
(
512
),
.
MAX_DEPTH_BITS
(
6
)
)
phv_fifo_2
(
.
clk
(
clk
),
.
reset
(
~
aresetn
),
.
din
(
last_stg_phv_out
[
i
][
1023
:
512
]),
.
wr_en
(
last_stg_phv_out_valid
[
i
]),
.
rd_en
(
phv_fifo_rd_en
[
i
]),
.
dout
(
high_phv_out
[
i
]),
.
full
(),
.
nearly_full
(),
.
empty
()
);
/*
fifo_generator_512b
phv_fifo_2 (
.clk (clk), // input wire clk
.srst (~aresetn), // input wire srst
.din (last_stg_phv_out[i][1023:512]), // input wire [521 : 0] din
.wr_en (last_stg_phv_out_valid[i]), // input wire wr_en
.rd_en (phv_fifo_rd_en[i]), // input wire rd_en
.dout (high_phv_out[i]), // output wire [521 : 0] dout
.full (), // output wire full
.empty (), // output wire empty
.wr_rst_busy (), // output wire wr_rst_busy
.rd_rst_busy () // output wire rd_rst_busy
);*/
end
endgenerate
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_2
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_2
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_2
;
wire
ctrl_s_axis_tvalid_2
;
wire
ctrl_s_axis_tlast_2
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_2_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_2_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_2_r
;
reg
ctrl_s_axis_tvalid_2_r
;
reg
ctrl_s_axis_tlast_2_r
;
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_3
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_3
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_3
;
wire
ctrl_s_axis_tvalid_3
;
wire
ctrl_s_axis_tlast_3
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_3_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_3_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_3_r
;
reg
ctrl_s_axis_tvalid_3_r
;
reg
ctrl_s_axis_tlast_3_r
;
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_4
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_4
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_4
;
wire
ctrl_s_axis_tvalid_4
;
wire
ctrl_s_axis_tlast_4
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_4_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_4_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_4_r
;
reg
ctrl_s_axis_tvalid_4_r
;
reg
ctrl_s_axis_tlast_4_r
;
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_5
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_5
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_5
;
wire
ctrl_s_axis_tvalid_5
;
wire
ctrl_s_axis_tlast_5
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_5_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_5_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_5_r
;
reg
ctrl_s_axis_tvalid_5_r
;
reg
ctrl_s_axis_tlast_5_r
;
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_6
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_6
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_6
;
wire
ctrl_s_axis_tvalid_6
;
wire
ctrl_s_axis_tlast_6
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_6_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_6_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_6_r
;
reg
ctrl_s_axis_tvalid_6_r
;
reg
ctrl_s_axis_tlast_6_r
;
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_7
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_7
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_7
;
wire
ctrl_s_axis_tvalid_7
;
wire
ctrl_s_axis_tlast_7
;
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
ctrl_s_axis_tdata_7_r
;
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
ctrl_s_axis_tkeep_7_r
;
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
ctrl_s_axis_tuser_7_r
;
reg
ctrl_s_axis_tvalid_7_r
;
reg
ctrl_s_axis_tlast_7_r
;
parser_top
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
//for 100g mac exclusively
.
C_S_AXIS_TUSER_WIDTH
(),
.
PKT_HDR_LEN
()
)
phv_parser
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input slvae axi stream
.
s_axis_tdata
(
s_axis_tdata_f_reg
),
.
s_axis_tuser
(
s_axis_tuser_f_reg
),
.
s_axis_tkeep
(
s_axis_tkeep_f_reg
),
// .s_axis_tvalid (s_axis_tvalid_f_reg & s_axis_tready_f),
.
s_axis_tvalid
(
s_axis_tvalid_f_reg
),
.
s_axis_tlast
(
s_axis_tlast_f_reg
),
.
s_axis_tready
(
s_axis_tready_p
),
.
s_vlan_id
(
s_vlan_id_r
),
.
s_vlan_id_valid
(
s_vlan_id_valid_r
),
// output
.
parser_valid
(
stg0_phv_in_valid
),
.
pkt_hdr_vec
(
stg0_phv_in
),
.
out_vlan
(
stg0_vlan_in
),
.
out_vlan_valid
(
stg0_vlan_valid_in
),
.
out_vlan_ready
(
stg0_vlan_ready
),
//
.
stg_ready_in
(
stg0_ready
),
// output to different pkt fifos
.
m_axis_tdata_0
(
parser_m_axis_tdata
[
0
]),
.
m_axis_tuser_0
(
parser_m_axis_tuser
[
0
]),
.
m_axis_tkeep_0
(
parser_m_axis_tkeep
[
0
]),
.
m_axis_tlast_0
(
parser_m_axis_tlast
[
0
]),
.
m_axis_tvalid_0
(
parser_m_axis_tvalid
[
0
]),
.
m_axis_tready_0
(
~
pkt_fifo_nearly_full
[
0
]),
.
m_axis_tdata_1
(
parser_m_axis_tdata
[
1
]),
.
m_axis_tuser_1
(
parser_m_axis_tuser
[
1
]),
.
m_axis_tkeep_1
(
parser_m_axis_tkeep
[
1
]),
.
m_axis_tlast_1
(
parser_m_axis_tlast
[
1
]),
.
m_axis_tvalid_1
(
parser_m_axis_tvalid
[
1
]),
.
m_axis_tready_1
(
~
pkt_fifo_nearly_full
[
1
]),
.
m_axis_tdata_2
(
parser_m_axis_tdata
[
2
]),
.
m_axis_tuser_2
(
parser_m_axis_tuser
[
2
]),
.
m_axis_tkeep_2
(
parser_m_axis_tkeep
[
2
]),
.
m_axis_tlast_2
(
parser_m_axis_tlast
[
2
]),
.
m_axis_tvalid_2
(
parser_m_axis_tvalid
[
2
]),
.
m_axis_tready_2
(
~
pkt_fifo_nearly_full
[
2
]),
.
m_axis_tdata_3
(
parser_m_axis_tdata
[
3
]),
.
m_axis_tuser_3
(
parser_m_axis_tuser
[
3
]),
.
m_axis_tkeep_3
(
parser_m_axis_tkeep
[
3
]),
.
m_axis_tlast_3
(
parser_m_axis_tlast
[
3
]),
.
m_axis_tvalid_3
(
parser_m_axis_tvalid
[
3
]),
.
m_axis_tready_3
(
~
pkt_fifo_nearly_full
[
3
]),
// control path
.
ctrl_s_axis_tdata
(
ctrl_s_axis_tdata_1_r
),
.
ctrl_s_axis_tuser
(
ctrl_s_axis_tuser_1_r
),
.
ctrl_s_axis_tkeep
(
ctrl_s_axis_tkeep_1_r
),
.
ctrl_s_axis_tlast
(
ctrl_s_axis_tlast_1_r
),
.
ctrl_s_axis_tvalid
(
ctrl_s_axis_tvalid_1_r
),
.
ctrl_m_axis_tdata
(
ctrl_s_axis_tdata_2
),
.
ctrl_m_axis_tuser
(
ctrl_s_axis_tuser_2
),
.
ctrl_m_axis_tkeep
(
ctrl_s_axis_tkeep_2
),
.
ctrl_m_axis_tlast
(
ctrl_s_axis_tlast_2
),
.
ctrl_m_axis_tvalid
(
ctrl_s_axis_tvalid_2
)
);
stage
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
STAGE_ID
(
0
)
)
stage0
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input
.
phv_in
(
stg0_phv_in_d1
),
.
phv_in_valid
(
stg0_phv_in_valid_d1
),
.
vlan_in
(
stg0_vlan_in_r
),
.
vlan_valid_in
(
stg0_vlan_valid_in_r
),
.
vlan_ready_out
(
stg0_vlan_ready
),
// output
.
vlan_out
(
stg0_vlan_out
),
.
vlan_valid_out
(
stg0_vlan_valid_out
),
.
vlan_out_ready
(
stg1_vlan_ready
),
// output
.
phv_out
(
stg0_phv_out
),
.
phv_out_valid
(
stg0_phv_out_valid
),
// back-pressure signals
.
stage_ready_out
(
stg0_ready
),
.
stage_ready_in
(
stg1_ready
),
// control path
.
c_s_axis_tdata
(
ctrl_s_axis_tdata_2_r
),
.
c_s_axis_tuser
(
ctrl_s_axis_tuser_2_r
),
.
c_s_axis_tkeep
(
ctrl_s_axis_tkeep_2_r
),
.
c_s_axis_tlast
(
ctrl_s_axis_tlast_2_r
),
.
c_s_axis_tvalid
(
ctrl_s_axis_tvalid_2_r
),
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_3
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_3
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_3
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_3
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_3
)
);
stage
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
STAGE_ID
(
1
)
)
stage1
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input
.
phv_in
(
stg0_phv_out_d1
),
.
phv_in_valid
(
stg0_phv_out_valid_d1
),
.
vlan_in
(
stg0_vlan_out_r
),
.
vlan_valid_in
(
stg0_vlan_valid_out_r
),
.
vlan_ready_out
(
stg1_vlan_ready
),
// output
.
vlan_out
(
stg1_vlan_out
),
.
vlan_valid_out
(
stg1_vlan_valid_out
),
.
vlan_out_ready
(
stg2_vlan_ready
),
// output
.
phv_out
(
stg1_phv_out
),
.
phv_out_valid
(
stg1_phv_out_valid
),
// back-pressure signals
.
stage_ready_out
(
stg1_ready
),
.
stage_ready_in
(
stg2_ready
),
// control path
.
c_s_axis_tdata
(
ctrl_s_axis_tdata_3_r
),
.
c_s_axis_tuser
(
ctrl_s_axis_tuser_3_r
),
.
c_s_axis_tkeep
(
ctrl_s_axis_tkeep_3_r
),
.
c_s_axis_tlast
(
ctrl_s_axis_tlast_3_r
),
.
c_s_axis_tvalid
(
ctrl_s_axis_tvalid_3_r
),
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_4
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_4
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_4
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_4
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_4
)
);
stage
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
STAGE_ID
(
2
)
)
stage2
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input
.
phv_in
(
stg1_phv_out_d1
),
.
phv_in_valid
(
stg1_phv_out_valid_d1
),
.
vlan_in
(
stg1_vlan_out_r
),
.
vlan_valid_in
(
stg1_vlan_valid_out_r
),
.
vlan_ready_out
(
stg2_vlan_ready
),
// output
.
vlan_out
(
stg2_vlan_out
),
.
vlan_valid_out
(
stg2_vlan_valid_out
),
.
vlan_out_ready
(
stg3_vlan_ready
),
// output
.
phv_out
(
stg2_phv_out
),
.
phv_out_valid
(
stg2_phv_out_valid
),
// back-pressure signals
.
stage_ready_out
(
stg2_ready
),
.
stage_ready_in
(
stg3_ready
),
// control path
.
c_s_axis_tdata
(
ctrl_s_axis_tdata_4_r
),
.
c_s_axis_tuser
(
ctrl_s_axis_tuser_4_r
),
.
c_s_axis_tkeep
(
ctrl_s_axis_tkeep_4_r
),
.
c_s_axis_tlast
(
ctrl_s_axis_tlast_4_r
),
.
c_s_axis_tvalid
(
ctrl_s_axis_tvalid_4_r
),
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_5
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_5
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_5
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_5
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_5
)
);
stage
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
STAGE_ID
(
3
)
)
stage3
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input
.
phv_in
(
stg2_phv_out_d1
),
.
phv_in_valid
(
stg2_phv_out_valid_d1
),
.
vlan_in
(
stg2_vlan_out_r
),
.
vlan_valid_in
(
stg2_vlan_valid_out_r
),
.
vlan_ready_out
(
stg3_vlan_ready
),
// output
.
vlan_out
(
stg3_vlan_out
),
.
vlan_valid_out
(
stg3_vlan_valid_out
),
.
vlan_out_ready
(
last_stg_vlan_ready
),
// output
.
phv_out
(
stg3_phv_out
),
.
phv_out_valid
(
stg3_phv_out_valid
),
// back-pressure signals
.
stage_ready_out
(
stg3_ready
),
.
stage_ready_in
(
last_stg_ready
),
// control path
.
c_s_axis_tdata
(
ctrl_s_axis_tdata_5_r
),
.
c_s_axis_tuser
(
ctrl_s_axis_tuser_5_r
),
.
c_s_axis_tkeep
(
ctrl_s_axis_tkeep_5_r
),
.
c_s_axis_tlast
(
ctrl_s_axis_tlast_5_r
),
.
c_s_axis_tvalid
(
ctrl_s_axis_tvalid_5_r
),
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_6
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_6
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_6
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_6
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_6
)
);
// [NOTICE] change to last stage
last_stage
#(
.
C_S_AXIS_DATA_WIDTH
(
512
),
.
STAGE_ID
(
4
)
)
stage4
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// input
.
phv_in
(
stg3_phv_out_d1
),
.
phv_in_valid
(
stg3_phv_out_valid_d1
),
.
vlan_in
(
stg3_vlan_out_r
),
.
vlan_valid_in
(
stg3_vlan_valid_out_r
),
.
vlan_ready_out
(
last_stg_vlan_ready
),
// back-pressure signals
.
stage_ready_out
(
last_stg_ready
),
// .phv_in (stg0_phv_in_d1),
// .phv_in_valid (stg0_phv_in_valid_d1),
// .vlan_in (stg0_vlan_in_r),
// .vlan_valid_in (stg0_vlan_valid_in_r),
// .vlan_ready_out (stg0_vlan_ready),
// // back-pressure signals
// .stage_ready_out (stg0_ready),
// output
.
phv_out_0
(
last_stg_phv_out
[
0
]),
.
phv_out_valid_0
(
last_stg_phv_out_valid
[
0
]),
.
phv_fifo_ready_0
(
~
phv_fifo_nearly_full
[
0
]),
.
phv_out_1
(
last_stg_phv_out
[
1
]),
.
phv_out_valid_1
(
last_stg_phv_out_valid
[
1
]),
.
phv_fifo_ready_1
(
~
phv_fifo_nearly_full
[
1
]),
.
phv_out_2
(
last_stg_phv_out
[
2
]),
.
phv_out_valid_2
(
last_stg_phv_out_valid
[
2
]),
.
phv_fifo_ready_2
(
~
phv_fifo_nearly_full
[
2
]),
.
phv_out_3
(
last_stg_phv_out
[
3
]),
.
phv_out_valid_3
(
last_stg_phv_out_valid
[
3
]),
.
phv_fifo_ready_3
(
~
phv_fifo_nearly_full
[
3
]),
// control path
.
c_s_axis_tdata
(
ctrl_s_axis_tdata_6_r
),
.
c_s_axis_tuser
(
ctrl_s_axis_tuser_6_r
),
.
c_s_axis_tkeep
(
ctrl_s_axis_tkeep_6_r
),
.
c_s_axis_tlast
(
ctrl_s_axis_tlast_6_r
),
.
c_s_axis_tvalid
(
ctrl_s_axis_tvalid_6_r
),
.
c_m_axis_tdata
(
ctrl_s_axis_tdata_7
),
.
c_m_axis_tuser
(
ctrl_s_axis_tuser_7
),
.
c_m_axis_tkeep
(
ctrl_s_axis_tkeep_7
),
.
c_m_axis_tlast
(
ctrl_s_axis_tlast_7
),
.
c_m_axis_tvalid
(
ctrl_s_axis_tvalid_7
)
);
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
depar_out_tdata
[
C_NUM_QUEUES
-
1
:
0
];
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
depar_out_tkeep
[
C_NUM_QUEUES
-
1
:
0
];
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
depar_out_tuser
[
C_NUM_QUEUES
-
1
:
0
];
wire
depar_out_tvalid
[
C_NUM_QUEUES
-
1
:
0
];
wire
depar_out_tlast
[
C_NUM_QUEUES
-
1
:
0
];
wire
depar_out_tready
[
C_NUM_QUEUES
-
1
:
0
];
reg
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
depar_out_tdata_d1
[
C_NUM_QUEUES
-
1
:
0
];
reg
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
depar_out_tkeep_d1
[
C_NUM_QUEUES
-
1
:
0
];
reg
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
depar_out_tuser_d1
[
C_NUM_QUEUES
-
1
:
0
];
reg
depar_out_tvalid_d1
[
C_NUM_QUEUES
-
1
:
0
];
reg
depar_out_tlast_d1
[
C_NUM_QUEUES
-
1
:
0
];
// multiple deparser + output arbiter
generate
for
(
i
=
0
;
i
<
C_NUM_QUEUES
;
i
=
i
+
1
)
begin
:
sub_deparser_top
deparser_top
#(
.
C_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
C_PKT_VEC_WIDTH
(),
.
DEPARSER_MOD_ID
()
)
phv_deparser
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
//data plane
.
pkt_fifo_tdata
(
pkt_fifo_tdata_out
[
i
]),
.
pkt_fifo_tkeep
(
pkt_fifo_tkeep_out
[
i
]),
.
pkt_fifo_tuser
(
pkt_fifo_tuser_out
[
i
]),
.
pkt_fifo_tlast
(
pkt_fifo_tlast_out
[
i
]),
.
pkt_fifo_empty
(
pkt_fifo_empty
[
i
]),
// output from STAGE
.
pkt_fifo_rd_en
(
pkt_fifo_rd_en
[
i
]),
.
phv_fifo_out
(
phv_fifo_out
[
i
]),
.
phv_fifo_empty
(
phv_fifo_empty
[
i
]),
.
phv_fifo_rd_en
(
phv_fifo_rd_en
[
i
]),
// output
.
depar_out_tdata
(
depar_out_tdata
[
i
]),
.
depar_out_tkeep
(
depar_out_tkeep
[
i
]),
.
depar_out_tuser
(
depar_out_tuser
[
i
]),
.
depar_out_tvalid
(
depar_out_tvalid
[
i
]),
.
depar_out_tlast
(
depar_out_tlast
[
i
]),
// input
.
depar_out_tready
(
depar_out_tready
[
i
]),
//control path
.
ctrl_s_axis_tdata
(
ctrl_s_axis_tdata_7_r
),
.
ctrl_s_axis_tuser
(
ctrl_s_axis_tuser_7_r
),
.
ctrl_s_axis_tkeep
(
ctrl_s_axis_tkeep_7_r
),
.
ctrl_s_axis_tvalid
(
ctrl_s_axis_tvalid_7_r
),
.
ctrl_s_axis_tlast
(
ctrl_s_axis_tlast_7_r
)
);
end
endgenerate
// output arbiter
output_arbiter
#(
.
C_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
)
)
out_arb
(
.
axis_clk
(
clk
),
.
aresetn
(
aresetn
),
// output
.
m_axis_tdata
(
m_axis_tdata
),
.
m_axis_tkeep
(
m_axis_tkeep
),
.
m_axis_tuser
(
m_axis_tuser
),
.
m_axis_tlast
(
m_axis_tlast
),
.
m_axis_tvalid
(
m_axis_tvalid
),
.
m_axis_tready
(
m_axis_tready
),
// input from deparser
.
s_axis_tdata_0
(
depar_out_tdata_d1
[
0
]),
.
s_axis_tkeep_0
(
depar_out_tkeep_d1
[
0
]),
.
s_axis_tuser_0
(
depar_out_tuser_d1
[
0
]),
.
s_axis_tlast_0
(
depar_out_tlast_d1
[
0
]),
.
s_axis_tvalid_0
(
depar_out_tvalid_d1
[
0
]),
.
s_axis_tready_0
(
depar_out_tready
[
0
]),
.
s_axis_tdata_1
(
depar_out_tdata_d1
[
1
]),
.
s_axis_tkeep_1
(
depar_out_tkeep_d1
[
1
]),
.
s_axis_tuser_1
(
depar_out_tuser_d1
[
1
]),
.
s_axis_tlast_1
(
depar_out_tlast_d1
[
1
]),
.
s_axis_tvalid_1
(
depar_out_tvalid_d1
[
1
]),
.
s_axis_tready_1
(
depar_out_tready
[
1
]),
.
s_axis_tdata_2
(
depar_out_tdata_d1
[
2
]),
.
s_axis_tkeep_2
(
depar_out_tkeep_d1
[
2
]),
.
s_axis_tuser_2
(
depar_out_tuser_d1
[
2
]),
.
s_axis_tlast_2
(
depar_out_tlast_d1
[
2
]),
.
s_axis_tvalid_2
(
depar_out_tvalid_d1
[
2
]),
.
s_axis_tready_2
(
depar_out_tready
[
2
]),
.
s_axis_tdata_3
(
depar_out_tdata_d1
[
3
]),
.
s_axis_tkeep_3
(
depar_out_tkeep_d1
[
3
]),
.
s_axis_tuser_3
(
depar_out_tuser_d1
[
3
]),
.
s_axis_tlast_3
(
depar_out_tlast_d1
[
3
]),
.
s_axis_tvalid_3
(
depar_out_tvalid_d1
[
3
]),
.
s_axis_tready_3
(
depar_out_tready
[
3
])
);
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
stg0_phv_in_valid_d1
<=
0
;
stg0_phv_out_valid_d1
<=
0
;
stg1_phv_out_valid_d1
<=
0
;
stg2_phv_out_valid_d1
<=
0
;
stg3_phv_out_valid_d1
<=
0
;
stg0_phv_in_d1
<=
0
;
stg0_phv_out_d1
<=
0
;
stg1_phv_out_d1
<=
0
;
stg2_phv_out_d1
<=
0
;
stg3_phv_out_d1
<=
0
;
//
s_axis_tdata_f_reg
<=
0
;
s_axis_tkeep_f_reg
<=
0
;
s_axis_tuser_f_reg
<=
0
;
s_axis_tlast_f_reg
<=
0
;
s_axis_tvalid_f_reg
<=
0
;
//
s_vlan_id_r
<=
0
;
s_vlan_id_valid_r
<=
0
;
//
stg0_vlan_in_r
<=
0
;
stg0_vlan_valid_in_r
<=
0
;
stg0_vlan_out_r
<=
0
;
stg0_vlan_valid_out_r
<=
0
;
stg1_vlan_out_r
<=
0
;
stg1_vlan_valid_out_r
<=
0
;
stg2_vlan_out_r
<=
0
;
stg2_vlan_valid_out_r
<=
0
;
stg3_vlan_out_r
<=
0
;
stg3_vlan_valid_out_r
<=
0
;
end
else
begin
stg0_phv_in_valid_d1
<=
stg0_phv_in_valid
;
stg0_phv_out_valid_d1
<=
stg0_phv_out_valid
;
stg1_phv_out_valid_d1
<=
stg1_phv_out_valid
;
stg2_phv_out_valid_d1
<=
stg2_phv_out_valid
;
stg3_phv_out_valid_d1
<=
stg3_phv_out_valid
;
stg0_phv_in_d1
<=
stg0_phv_in
;
stg0_phv_out_d1
<=
stg0_phv_out
;
stg1_phv_out_d1
<=
stg1_phv_out
;
stg2_phv_out_d1
<=
stg2_phv_out
;
stg3_phv_out_d1
<=
stg3_phv_out
;
//
s_axis_tdata_f_reg
<=
s_axis_tdata_f
;
s_axis_tkeep_f_reg
<=
s_axis_tkeep_f
;
s_axis_tuser_f_reg
<=
s_axis_tuser_f
;
s_axis_tlast_f_reg
<=
s_axis_tlast_f
;
s_axis_tvalid_f_reg
<=
s_axis_tvalid_f
;
//
s_vlan_id_r
<=
s_vlan_id
;
s_vlan_id_valid_r
<=
s_vlan_id_valid
;
//
stg0_vlan_in_r
<=
stg0_vlan_in
;
stg0_vlan_valid_in_r
<=
stg0_vlan_valid_in
;
stg0_vlan_out_r
<=
stg0_vlan_out
;
stg0_vlan_valid_out_r
<=
stg0_vlan_valid_out
;
stg1_vlan_out_r
<=
stg1_vlan_out
;
stg1_vlan_valid_out_r
<=
stg1_vlan_valid_out
;
stg2_vlan_out_r
<=
stg2_vlan_out
;
stg2_vlan_valid_out_r
<=
stg2_vlan_valid_out
;
stg3_vlan_out_r
<=
stg3_vlan_out
;
stg3_vlan_valid_out_r
<=
stg3_vlan_valid_out
;
end
end
// delay deparser out
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
for
(
idx
=
0
;
idx
<
C_NUM_QUEUES
;
idx
=
idx
+
1
)
begin
depar_out_tdata_d1
[
idx
]
<=
0
;
depar_out_tkeep_d1
[
idx
]
<=
0
;
depar_out_tuser_d1
[
idx
]
<=
0
;
depar_out_tvalid_d1
[
idx
]
<=
0
;
depar_out_tlast_d1
[
idx
]
<=
0
;
end
end
else
begin
for
(
idx
=
0
;
idx
<
C_NUM_QUEUES
;
idx
=
idx
+
1
)
begin
depar_out_tdata_d1
[
idx
]
<=
depar_out_tdata
[
idx
];
depar_out_tkeep_d1
[
idx
]
<=
depar_out_tkeep
[
idx
];
depar_out_tuser_d1
[
idx
]
<=
depar_out_tuser
[
idx
];
depar_out_tvalid_d1
[
idx
]
<=
depar_out_tvalid
[
idx
];
depar_out_tlast_d1
[
idx
]
<=
depar_out_tlast
[
idx
];
end
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
ctrl_s_axis_tdata_1_r
<=
0
;
ctrl_s_axis_tuser_1_r
<=
0
;
ctrl_s_axis_tkeep_1_r
<=
0
;
ctrl_s_axis_tlast_1_r
<=
0
;
ctrl_s_axis_tvalid_1_r
<=
0
;
ctrl_s_axis_tdata_2_r
<=
0
;
ctrl_s_axis_tuser_2_r
<=
0
;
ctrl_s_axis_tkeep_2_r
<=
0
;
ctrl_s_axis_tlast_2_r
<=
0
;
ctrl_s_axis_tvalid_2_r
<=
0
;
ctrl_s_axis_tdata_3_r
<=
0
;
ctrl_s_axis_tuser_3_r
<=
0
;
ctrl_s_axis_tkeep_3_r
<=
0
;
ctrl_s_axis_tlast_3_r
<=
0
;
ctrl_s_axis_tvalid_3_r
<=
0
;
ctrl_s_axis_tdata_4_r
<=
0
;
ctrl_s_axis_tuser_4_r
<=
0
;
ctrl_s_axis_tkeep_4_r
<=
0
;
ctrl_s_axis_tlast_4_r
<=
0
;
ctrl_s_axis_tvalid_4_r
<=
0
;
ctrl_s_axis_tdata_5_r
<=
0
;
ctrl_s_axis_tuser_5_r
<=
0
;
ctrl_s_axis_tkeep_5_r
<=
0
;
ctrl_s_axis_tlast_5_r
<=
0
;
ctrl_s_axis_tvalid_5_r
<=
0
;
ctrl_s_axis_tdata_6_r
<=
0
;
ctrl_s_axis_tuser_6_r
<=
0
;
ctrl_s_axis_tkeep_6_r
<=
0
;
ctrl_s_axis_tlast_6_r
<=
0
;
ctrl_s_axis_tvalid_6_r
<=
0
;
ctrl_s_axis_tdata_7_r
<=
0
;
ctrl_s_axis_tuser_7_r
<=
0
;
ctrl_s_axis_tkeep_7_r
<=
0
;
ctrl_s_axis_tlast_7_r
<=
0
;
ctrl_s_axis_tvalid_7_r
<=
0
;
end
else
begin
ctrl_s_axis_tdata_1_r
<=
ctrl_s_axis_tdata_1
;
ctrl_s_axis_tuser_1_r
<=
ctrl_s_axis_tuser_1
;
ctrl_s_axis_tkeep_1_r
<=
ctrl_s_axis_tkeep_1
;
ctrl_s_axis_tlast_1_r
<=
ctrl_s_axis_tlast_1
;
ctrl_s_axis_tvalid_1_r
<=
ctrl_s_axis_tvalid_1
;
ctrl_s_axis_tdata_2_r
<=
ctrl_s_axis_tdata_2
;
ctrl_s_axis_tuser_2_r
<=
ctrl_s_axis_tuser_2
;
ctrl_s_axis_tkeep_2_r
<=
ctrl_s_axis_tkeep_2
;
ctrl_s_axis_tlast_2_r
<=
ctrl_s_axis_tlast_2
;
ctrl_s_axis_tvalid_2_r
<=
ctrl_s_axis_tvalid_2
;
ctrl_s_axis_tdata_3_r
<=
ctrl_s_axis_tdata_3
;
ctrl_s_axis_tuser_3_r
<=
ctrl_s_axis_tuser_3
;
ctrl_s_axis_tkeep_3_r
<=
ctrl_s_axis_tkeep_3
;
ctrl_s_axis_tlast_3_r
<=
ctrl_s_axis_tlast_3
;
ctrl_s_axis_tvalid_3_r
<=
ctrl_s_axis_tvalid_3
;
ctrl_s_axis_tdata_4_r
<=
ctrl_s_axis_tdata_4
;
ctrl_s_axis_tuser_4_r
<=
ctrl_s_axis_tuser_4
;
ctrl_s_axis_tkeep_4_r
<=
ctrl_s_axis_tkeep_4
;
ctrl_s_axis_tlast_4_r
<=
ctrl_s_axis_tlast_4
;
ctrl_s_axis_tvalid_4_r
<=
ctrl_s_axis_tvalid_4
;
ctrl_s_axis_tdata_5_r
<=
ctrl_s_axis_tdata_5
;
ctrl_s_axis_tuser_5_r
<=
ctrl_s_axis_tuser_5
;
ctrl_s_axis_tkeep_5_r
<=
ctrl_s_axis_tkeep_5
;
ctrl_s_axis_tlast_5_r
<=
ctrl_s_axis_tlast_5
;
ctrl_s_axis_tvalid_5_r
<=
ctrl_s_axis_tvalid_5
;
ctrl_s_axis_tdata_6_r
<=
ctrl_s_axis_tdata_6
;
ctrl_s_axis_tuser_6_r
<=
ctrl_s_axis_tuser_6
;
ctrl_s_axis_tkeep_6_r
<=
ctrl_s_axis_tkeep_6
;
ctrl_s_axis_tlast_6_r
<=
ctrl_s_axis_tlast_6
;
ctrl_s_axis_tvalid_6_r
<=
ctrl_s_axis_tvalid_6
;
ctrl_s_axis_tdata_7_r
<=
ctrl_s_axis_tdata_7
;
ctrl_s_axis_tuser_7_r
<=
ctrl_s_axis_tuser_7
;
ctrl_s_axis_tkeep_7_r
<=
ctrl_s_axis_tkeep_7
;
ctrl_s_axis_tlast_7_r
<=
ctrl_s_axis_tlast_7
;
ctrl_s_axis_tvalid_7_r
<=
ctrl_s_axis_tvalid_7
;
end
end
endmodule
sims/net/menshen/rtl/stage.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
stage
#(
parameter
C_S_AXIS_DATA_WIDTH
=
512
,
parameter
C_S_AXIS_TUSER_WIDTH
=
128
,
parameter
STAGE_ID
=
0
,
// valid: 0-4
parameter
PHV_LEN
=
48
*
8
+
32
*
8
+
16
*
8
+
256
,
parameter
KEY_LEN
=
48
*
2
+
32
*
2
+
16
*
2
+
1
,
parameter
ACT_LEN
=
25
,
parameter
KEY_OFF
=
6
*
3
+
20
,
parameter
C_VLANID_WIDTH
=
12
)
(
input
axis_clk
,
input
aresetn
,
input
[
PHV_LEN
-
1
:
0
]
phv_in
,
input
phv_in_valid
,
output
stage_ready_out
,
output
vlan_ready_out
,
input
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_in
,
input
vlan_valid_in
,
//
output
[
PHV_LEN
-
1
:
0
]
phv_out
,
output
phv_out_valid
,
input
stage_ready_in
,
output
[
C_VLANID_WIDTH
-
1
:
0
]
vlan_out
,
output
vlan_valid_out
,
input
vlan_out_ready
,
//control path
input
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata
,
input
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser
,
input
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_s_axis_tkeep
,
input
c_s_axis_tvalid
,
input
c_s_axis_tlast
,
output
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_m_axis_tdata
,
output
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_m_axis_tuser
,
output
[
C_S_AXIS_DATA_WIDTH
/
8
-
1
:
0
]
c_m_axis_tkeep
,
output
c_m_axis_tvalid
,
output
c_m_axis_tlast
);
//key_extract to lookup_engine
wire
[
KEY_LEN
-
1
:
0
]
key2lookup_key
;
wire
key2lookup_key_valid
;
wire
key2lookup_phv_valid
;
wire
[
PHV_LEN
-
1
:
0
]
key2lookup_phv
;
wire
lookup2key_ready
;
reg
[
KEY_LEN
-
1
:
0
]
key2lookup_key_r
;
reg
key2lookup_key_valid_r
;
reg
key2lookup_phv_valid_r
;
reg
[
PHV_LEN
-
1
:
0
]
key2lookup_phv_r
;
//control path 1 (key2lookup)
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_1
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
c_s_axis_tkeep_1
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser_1
;
wire
c_s_axis_tvalid_1
;
wire
c_s_axis_tlast_1
;
//control path 2 (lkup2action)
wire
[
C_S_AXIS_DATA_WIDTH
-
1
:
0
]
c_s_axis_tdata_2
;
wire
[((
C_S_AXIS_DATA_WIDTH
/
8
))
-
1
:
0
]
c_s_axis_tkeep_2
;
wire
[
C_S_AXIS_TUSER_WIDTH
-
1
:
0
]
c_s_axis_tuser_2
;
wire
c_s_axis_tvalid_2
;
wire
c_s_axis_tlast_2
;
// vlan fifo
//lookup_engine to action_engine
wire
[
ACT_LEN
*
25
-
1
:
0
]
lookup2action_action
;
wire
lookup2action_action_valid
;
wire
[
PHV_LEN
-
1
:
0
]
lookup2action_phv
;
wire
action2lookup_ready
;
reg
[
ACT_LEN
*
25
-
1
:
0
]
lookup2action_action_r
;
reg
lookup2action_action_valid_r
;
reg
[
PHV_LEN
-
1
:
0
]
lookup2action_phv_r
;
wire
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out
;
wire
act_vlan_out_valid
;
reg
[
C_VLANID_WIDTH
-
1
:
0
]
act_vlan_out_r
;
reg
act_vlan_out_valid_r
;
wire
act_vlan_ready
;
always
@
(
posedge
axis_clk
)
begin
if
(
~
aresetn
)
begin
key2lookup_key_r
<=
0
;
key2lookup_key_valid_r
<=
0
;
key2lookup_phv_valid_r
<=
0
;
key2lookup_phv_r
<=
0
;
lookup2action_action_r
<=
0
;
lookup2action_action_valid_r
<=
0
;
lookup2action_phv_r
<=
0
;
//
act_vlan_out_r
<=
0
;
act_vlan_out_valid_r
<=
0
;
end
else
begin
key2lookup_key_r
<=
key2lookup_key
;
key2lookup_key_valid_r
<=
key2lookup_key_valid
;
key2lookup_phv_valid_r
<=
key2lookup_phv_valid
;
key2lookup_phv_r
<=
key2lookup_phv
;
lookup2action_action_r
<=
lookup2action_action
;
lookup2action_action_valid_r
<=
lookup2action_action_valid
;
lookup2action_phv_r
<=
lookup2action_phv
;
//
act_vlan_out_r
<=
act_vlan_out
;
act_vlan_out_valid_r
<=
act_vlan_out_valid
;
end
end
//
key_extract_top
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(),
.
KEY_LEN
(
KEY_LEN
),
// format of KEY_OFF entry: |--3(6B)--|--3(6B)--|--3(4B)--|--3(4B)--|--3(2B)--|--3(2B)--|
.
KEY_OFF
(
KEY_OFF
),
.
AXIL_WIDTH
(),
.
KEY_OFF_ADDR_WIDTH
(),
.
KEY_EX_ID
()
)
key_extract
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
.
phv_in
(
phv_in
),
.
phv_valid_in
(
phv_in_valid
),
.
ready_out
(
stage_ready_out
),
.
vlan_in
(
vlan_in
),
.
vlan_in_valid
(
vlan_valid_in
),
.
vlan_ready
(
vlan_ready_out
),
//
.
phv_out
(
key2lookup_phv
),
.
phv_valid_out
(
key2lookup_phv_valid
),
.
key_out_masked
(
key2lookup_key
),
.
key_valid_out
(
key2lookup_key_valid
),
.
ready_in
(
lookup2key_ready
),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata
),
.
c_s_axis_tuser
(
c_s_axis_tuser
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid
),
.
c_s_axis_tlast
(
c_s_axis_tlast
),
.
c_m_axis_tdata
(
c_s_axis_tdata_1
),
.
c_m_axis_tuser
(
c_s_axis_tuser_1
),
.
c_m_axis_tkeep
(
c_s_axis_tkeep_1
),
.
c_m_axis_tvalid
(
c_s_axis_tvalid_1
),
.
c_m_axis_tlast
(
c_s_axis_tlast_1
)
);
lookup_engine_top
#(
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
C_S_AXIS_TUSER_WIDTH
(
C_S_AXIS_TUSER_WIDTH
),
.
STAGE_ID
(
STAGE_ID
),
.
PHV_LEN
(),
.
KEY_LEN
(
KEY_LEN
),
.
ACT_LEN
(),
.
LOOKUP_ID
()
)
lookup_engine
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
//output from key extractor
.
extract_key
(
key2lookup_key_r
),
.
key_valid
(
key2lookup_key_valid_r
),
.
phv_valid
(
key2lookup_phv_valid_r
),
.
phv_in
(
key2lookup_phv_r
),
.
ready_out
(
lookup2key_ready
),
//output to the action engine
.
action
(
lookup2action_action
),
.
action_valid
(
lookup2action_action_valid
),
.
phv_out
(
lookup2action_phv
),
.
ready_in
(
action2lookup_ready
),
//
.
act_vlan_out
(
act_vlan_out
),
.
act_vlan_valid_out
(
act_vlan_out_valid
),
// .act_vlan_ready (act_vlan_ready),
.
act_vlan_ready
(
action2lookup_ready
),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata_1
),
.
c_s_axis_tuser
(
c_s_axis_tuser_1
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep_1
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid_1
),
.
c_s_axis_tlast
(
c_s_axis_tlast_1
),
.
c_m_axis_tdata
(
c_s_axis_tdata_2
),
.
c_m_axis_tuser
(
c_s_axis_tuser_2
),
.
c_m_axis_tkeep
(
c_s_axis_tkeep_2
),
.
c_m_axis_tvalid
(
c_s_axis_tvalid_2
),
.
c_m_axis_tlast
(
c_s_axis_tlast_2
)
);
action_engine
#(
.
STAGE_ID
(
STAGE_ID
),
.
C_S_AXIS_DATA_WIDTH
(
C_S_AXIS_DATA_WIDTH
),
.
PHV_LEN
(),
.
ACT_LEN
(),
.
ACTION_ID
()
)
action_engine
(
.
clk
(
axis_clk
),
.
rst_n
(
aresetn
),
//signals from lookup to ALUs
.
phv_in
(
lookup2action_phv_r
),
.
phv_valid_in
(
lookup2action_action_valid_r
),
.
action_in
(
lookup2action_action_r
),
.
action_valid_in
(
lookup2action_action_valid_r
),
.
ready_out
(
action2lookup_ready
),
//signals output from ALUs
.
phv_out
(
phv_out
),
.
phv_valid_out
(
phv_out_valid
),
.
ready_in
(
stage_ready_in
),
.
act_vlan_in
(
act_vlan_out_r
),
.
act_vlan_valid_in
(
act_vlan_out_valid_r
),
.
act_vlan_ready
(
act_vlan_ready
),
// vlan
.
vlan_out
(
vlan_out
),
.
vlan_out_valid
(
vlan_valid_out
),
.
vlan_out_ready
(
vlan_out_ready
),
//control path
.
c_s_axis_tdata
(
c_s_axis_tdata_2
),
.
c_s_axis_tuser
(
c_s_axis_tuser_2
),
.
c_s_axis_tkeep
(
c_s_axis_tkeep_2
),
.
c_s_axis_tvalid
(
c_s_axis_tvalid_2
),
.
c_s_axis_tlast
(
c_s_axis_tlast_2
),
.
c_m_axis_tdata
(
c_m_axis_tdata
),
.
c_m_axis_tuser
(
c_m_axis_tuser
),
.
c_m_axis_tkeep
(
c_m_axis_tkeep
),
.
c_m_axis_tvalid
(
c_m_axis_tvalid
),
.
c_m_axis_tlast
(
c_m_axis_tlast
)
);
endmodule
sims/net/menshen/rtl/sub_deparser.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
sub_deparser
#(
parameter
C_PKT_VEC_WIDTH
=
(
6
+
4
+
2
)
*
8
*
8
+
256
,
parameter
C_PARSE_ACT_LEN
=
6
// only 6 bits are used here
)
(
input
clk
,
input
aresetn
,
input
parse_act_valid
,
input
[
C_PARSE_ACT_LEN
-
1
:
0
]
parse_act
,
input
[
C_PKT_VEC_WIDTH
-
1
:
0
]
phv_in
,
output
reg
val_out_valid
,
output
reg
[
47
:
0
]
val_out
,
output
reg
[
1
:
0
]
val_out_type
);
localparam
PHV_2B_START_POS
=
0
+
256
;
localparam
PHV_4B_START_POS
=
16
*
8
+
256
;
localparam
PHV_6B_START_POS
=
16
*
8
+
32
*
8
+
256
;
reg
val_out_valid_nxt
;
reg
[
47
:
0
]
val_out_nxt
;
reg
[
1
:
0
]
val_out_type_nxt
;
always
@
(
*
)
begin
val_out_valid_nxt
=
0
;
val_out_nxt
=
val_out
;
val_out_type_nxt
=
val_out_type
;
if
(
parse_act_valid
)
begin
val_out_valid_nxt
=
1
;
case
(
{
parse_act
[
5
:
4
],
parse_act
[
0
]
}
)
// 2B
3'b011
:
begin
val_out_type_nxt
=
2'b01
;
case
(
parse_act
[
3
:
1
])
3'd0
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
0
+:
16
];
3'd1
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
1
+:
16
];
3'd2
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
2
+:
16
];
3'd3
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
3
+:
16
];
3'd4
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
4
+:
16
];
3'd5
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
5
+:
16
];
3'd6
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
6
+:
16
];
3'd7
:
val_out_nxt
[
15
:
0
]
=
phv_in
[
PHV_2B_START_POS
+
16
*
7
+:
16
];
endcase
end
// 4B
3'b101
:
begin
val_out_type_nxt
=
2'b10
;
case
(
parse_act
[
3
:
1
])
3'd0
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
0
+:
32
];
3'd1
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
1
+:
32
];
3'd2
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
2
+:
32
];
3'd3
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
3
+:
32
];
3'd4
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
4
+:
32
];
3'd5
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
5
+:
32
];
3'd6
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
6
+:
32
];
3'd7
:
val_out_nxt
[
31
:
0
]
=
phv_in
[
PHV_4B_START_POS
+
32
*
7
+:
32
];
endcase
end
// 6B
3'b111
:
begin
val_out_type_nxt
=
2'b11
;
case
(
parse_act
[
3
:
1
])
3'd0
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
0
+:
48
];
3'd1
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
1
+:
48
];
3'd2
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
2
+:
48
];
3'd3
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
3
+:
48
];
3'd4
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
4
+:
48
];
3'd5
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
5
+:
48
];
3'd6
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
6
+:
48
];
3'd7
:
val_out_nxt
[
47
:
0
]
=
phv_in
[
PHV_6B_START_POS
+
48
*
7
+:
48
];
endcase
end
default:
begin
val_out_type_nxt
=
0
;
val_out_nxt
=
0
;
end
endcase
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
val_out_valid
<=
0
;
val_out
<=
0
;
val_out_type
<=
0
;
end
else
begin
val_out_valid
<=
val_out_valid_nxt
;
val_out
<=
val_out_nxt
;
val_out_type
<=
val_out_type_nxt
;
end
end
endmodule
sims/net/menshen/rtl/sub_parser.v
0 → 100644
View file @
c15f2eab
`timescale
1
ns
/
1
ps
module
sub_parser
#(
parameter
PKTS_HDR_LEN
=
1024
,
parameter
PARSE_ACT_LEN
=
16
,
parameter
VAL_OUT_LEN
=
48
)
(
input
clk
,
input
aresetn
,
input
parse_act_valid
,
input
[
PARSE_ACT_LEN
-
1
:
0
]
parse_act
,
input
[
PKTS_HDR_LEN
-
1
:
0
]
pkts_hdr
,
output
reg
val_out_valid
,
output
reg
[
VAL_OUT_LEN
-
1
:
0
]
val_out
,
output
reg
[
1
:
0
]
val_out_type
,
output
reg
[
2
:
0
]
val_out_seq
);
reg
[
VAL_OUT_LEN
-
1
:
0
]
val_out_nxt
;
reg
val_out_valid_nxt
;
reg
[
1
:
0
]
val_out_type_nxt
;
reg
[
2
:
0
]
val_out_seq_nxt
;
always
@
(
*
)
begin
val_out_valid_nxt
=
0
;
val_out_nxt
=
val_out
;
val_out_type_nxt
=
val_out_type
;
val_out_seq_nxt
=
val_out_seq
;
if
(
parse_act_valid
)
begin
val_out_valid_nxt
=
1
;
val_out_seq_nxt
=
parse_act
[
3
:
1
];
case
(
{
parse_act
[
5
:
4
],
parse_act
[
0
]
}
)
// 2B
3'b011
:
begin
val_out_type_nxt
=
2'b01
;
val_out_nxt
[
15
:
0
]
=
pkts_hdr
[(
parse_act
[
12
:
6
])
*
8
+:
16
];
end
// 4B
3'b101
:
begin
val_out_type_nxt
=
2'b10
;
val_out_nxt
[
31
:
0
]
=
pkts_hdr
[(
parse_act
[
12
:
6
])
*
8
+:
32
];
end
// 6B
3'b111
:
begin
val_out_type_nxt
=
2'b11
;
val_out_nxt
[
47
:
0
]
=
pkts_hdr
[(
parse_act
[
12
:
6
])
*
8
+:
48
];
end
default:
begin
val_out_type_nxt
=
0
;
val_out_nxt
=
0
;
end
endcase
end
end
always
@
(
posedge
clk
)
begin
if
(
~
aresetn
)
begin
val_out_valid
<=
0
;
val_out
<=
0
;
val_out_type
<=
0
;
val_out_seq
<=
0
;
end
else
begin
val_out_valid
<=
val_out_valid_nxt
;
val_out
<=
val_out_nxt
;
val_out_type
<=
val_out_type_nxt
;
val_out_seq
<=
val_out_seq_nxt
;
end
end
endmodule
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment