Skip to content

Commit 6ca833c

Browse files
rw1nklerlpawelcz
authored andcommitted
[TEMP] Add Raw Block Decoder
google#1212 modules/zstd: Add common zstd definitions Internal-tag: [#51343] Signed-off-by: Robert Winkler <[email protected]> modules/zstd: Add raw block decoder Internal-tag: [#51343] Signed-off-by: Robert Winkler <[email protected]> modules/zstd/raw_block_decoder: Add benchmarking rules Internal-tag: [#53329] Signed-off-by: Pawel Czarnecki <[email protected]>
1 parent 53e1f94 commit 6ca833c

File tree

3 files changed

+244
-0
lines changed

3 files changed

+244
-0
lines changed

xls/modules/zstd/BUILD

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ xls_dslx_library(
8888
],
8989
)
9090

91+
xls_dslx_library(
92+
name = "common_dslx",
93+
srcs = [
94+
"common.x",
95+
],
96+
deps = [],
97+
)
98+
9199
xls_dslx_test(
92100
name = "frame_header_dslx_test",
93101
library = ":frame_header_dslx",
@@ -190,3 +198,74 @@ place_and_route(
190198
synthesized_rtl = ":frame_header_synth_asap7",
191199
target_die_utilization_percentage = "10",
192200
)
201+
202+
xls_dslx_library(
203+
name = "raw_block_dec_dslx",
204+
srcs = [
205+
"raw_block_dec.x",
206+
],
207+
deps = [
208+
":buffer_dslx",
209+
":common_dslx",
210+
],
211+
)
212+
213+
xls_dslx_test(
214+
name = "raw_block_dec_dslx_test",
215+
library = ":raw_block_dec_dslx",
216+
)
217+
218+
xls_dslx_verilog(
219+
name = "raw_block_dec_verilog",
220+
codegen_args = {
221+
"module_name": "RawBlockDecoder",
222+
"delay_model": "asap7",
223+
"pipeline_stages": "2",
224+
"reset": "rst",
225+
"use_system_verilog": "false",
226+
},
227+
dslx_top = "RawBlockDecoder",
228+
library = ":raw_block_dec_dslx",
229+
verilog_file = "raw_block_dec.v",
230+
)
231+
232+
xls_benchmark_ir(
233+
name = "raw_block_dec_opt_ir_benchmark",
234+
src = ":raw_block_dec_verilog.opt.ir",
235+
benchmark_ir_args = {
236+
"pipeline_stages": "2",
237+
"delay_model": "asap7",
238+
},
239+
)
240+
241+
verilog_library(
242+
name = "raw_block_dec_verilog_lib",
243+
srcs = [
244+
":raw_block_dec.v",
245+
],
246+
)
247+
248+
synthesize_rtl(
249+
name = "raw_block_dec_synth_asap7",
250+
standard_cells = "@org_theopenroadproject_asap7sc7p5t_28//:asap7-sc7p5t_rev28_rvt",
251+
top_module = "RawBlockDecoder",
252+
deps = [
253+
":raw_block_dec_verilog_lib",
254+
],
255+
)
256+
257+
benchmark_synth(
258+
name = "raw_block_dec_benchmark_synth",
259+
synth_target = ":raw_block_dec_synth_asap7",
260+
)
261+
262+
place_and_route(
263+
name = "raw_block_dec_place_and_route",
264+
clock_period = "750",
265+
core_padding_microns = 2,
266+
min_pin_distance = "0.5",
267+
placement_density = "0.30",
268+
skip_detailed_routing = True,
269+
synthesized_rtl = ":raw_block_dec_synth_asap7",
270+
target_die_utilization_percentage = "10",
271+
)

xls/modules/zstd/common.x

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2023 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
pub const DATA_WIDTH = u32:64;
16+
pub const MAX_ID = u32::MAX;
17+
pub const SYMBOL_WIDTH = u32:8;
18+
pub const BLOCK_SIZE_WIDTH = u32:21;
19+
20+
pub type BlockData = bits[DATA_WIDTH];
21+
pub type BlockPacketLength = u32;
22+
pub type BlockSize = bits[BLOCK_SIZE_WIDTH];
23+
pub type CopyOrMatchContent = BlockData;
24+
pub type CopyOrMatchLength = u64;
25+
26+
pub enum BlockType : u2 {
27+
RAW = 0,
28+
RLE = 1,
29+
COMPRESSED = 2,
30+
RESERVED = 3,
31+
}
32+
33+
pub struct BlockDataPacket {
34+
last: bool,
35+
last_block: bool,
36+
id: u32,
37+
data: BlockData,
38+
length: BlockPacketLength,
39+
}
40+
41+
pub enum SequenceExecutorMessageType : u1 {
42+
LITERAL = 0,
43+
SEQUENCE = 1,
44+
}
45+
46+
pub struct ExtendedBlockDataPacket {
47+
msg_type: SequenceExecutorMessageType,
48+
packet: BlockDataPacket,
49+
}

xls/modules/zstd/raw_block_dec.x

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2023 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// This file contains the implementation of RawBlockDecoder responsible for decoding
16+
// ZSTD Raw Blocks. More information about Raw Block's format can be found in:
17+
// https://datatracker.ietf.org/doc/html/rfc8878#section-3.1.1.2.2
18+
19+
import xls.modules.zstd.common as common;
20+
21+
type BlockDataPacket = common::BlockDataPacket;
22+
type BlockPacketLength = common::BlockPacketLength;
23+
type BlockData = common::BlockData;
24+
type ExtendedBlockDataPacket = common::ExtendedBlockDataPacket;
25+
type CopyOrMatchContent = common::CopyOrMatchContent;
26+
type CopyOrMatchLength = common::CopyOrMatchLength;
27+
type SequenceExecutorMessageType = common::SequenceExecutorMessageType;
28+
29+
struct RawBlockDecoderState {
30+
prev_id: u32, // ID of the previous block
31+
prev_last: bool, // if the previous packet was the last one that makes up the whole block
32+
prev_valid: bool, // if prev_id and prev_last contain valid data
33+
}
34+
35+
const ZERO_RAW_BLOCK_DECODER_STATE = zero!<RawBlockDecoderState>();
36+
37+
// RawBlockDecoder is responsible for decoding Raw Blocks,
38+
// it should be a part of the ZSTD Decoder pipeline.
39+
pub proc RawBlockDecoder {
40+
input_r: chan<BlockDataPacket> in;
41+
output_s: chan<ExtendedBlockDataPacket> out;
42+
43+
init { (ZERO_RAW_BLOCK_DECODER_STATE) }
44+
45+
config(
46+
input_r: chan<BlockDataPacket> in,
47+
output_s: chan<ExtendedBlockDataPacket> out
48+
) {(input_r, output_s)}
49+
50+
next(tok: token, state: RawBlockDecoderState) {
51+
let (tok, data) = recv(tok, input_r);
52+
if state.prev_valid && (data.id != state.prev_id) && (state.prev_last == false) {
53+
trace_fmt!("ID changed but previous packet have no last!");
54+
fail!("no_last", ());
55+
} else {};
56+
57+
let output_data = ExtendedBlockDataPacket {
58+
// Decoded RAW block is always a literal
59+
msg_type: SequenceExecutorMessageType::LITERAL,
60+
packet: BlockDataPacket {
61+
last: data.last,
62+
last_block: data.last_block,
63+
id: data.id,
64+
data: data.data as BlockData,
65+
length: data.length as BlockPacketLength,
66+
},
67+
};
68+
69+
let tok = send(tok, output_s, output_data);
70+
71+
RawBlockDecoderState {
72+
prev_valid: true,
73+
prev_id: output_data.packet.id,
74+
prev_last: output_data.packet.last
75+
}
76+
}
77+
}
78+
79+
#[test_proc]
80+
proc RawBlockDecoderTest {
81+
terminator: chan<bool> out;
82+
dec_input_s: chan<BlockDataPacket> out;
83+
dec_output_r: chan<ExtendedBlockDataPacket> in;
84+
85+
config(terminator: chan<bool> out) {
86+
let (dec_input_s, dec_input_r) = chan<BlockDataPacket>;
87+
let (dec_output_s, dec_output_r) = chan<ExtendedBlockDataPacket>;
88+
spawn RawBlockDecoder(dec_input_r, dec_output_s);
89+
(terminator, dec_input_s, dec_output_r)
90+
}
91+
92+
init { }
93+
94+
next(tok: token, state: ()) {
95+
let data_to_send: BlockDataPacket[5] = [
96+
BlockDataPacket { id: u32:1, last: u1:false, last_block: u1:false, data: BlockData:1, length: BlockPacketLength:32 },
97+
BlockDataPacket { id: u32:1, last: u1:false, last_block: u1:false, data: BlockData:2, length: BlockPacketLength:32 },
98+
BlockDataPacket { id: u32:1, last: u1:true, last_block: u1:false, data: BlockData:3, length: BlockPacketLength:32 },
99+
BlockDataPacket { id: u32:2, last: u1:false, last_block: u1:false, data: BlockData:4, length: BlockPacketLength:32 },
100+
BlockDataPacket { id: u32:2, last: u1:true, last_block: u1:true, data: BlockData:5, length: BlockPacketLength:32 },
101+
];
102+
103+
let tok = for ((_, data), tok): ((u32, BlockDataPacket), token) in enumerate(data_to_send) {
104+
let tok = send(tok, dec_input_s, data);
105+
let (tok, received_data) = recv(tok, dec_output_r);
106+
let expected_data = ExtendedBlockDataPacket {
107+
msg_type: SequenceExecutorMessageType::LITERAL,
108+
packet: data,
109+
};
110+
assert_eq(expected_data, received_data);
111+
(tok)
112+
}(tok);
113+
114+
send(tok, terminator, true);
115+
}
116+
}

0 commit comments

Comments
 (0)