Skip to content

Commit ed24ae9

Browse files
rw1nklermtdudeklpawelcz
committed
[WIP] modules/zstd: Add ZSTD decoder
This commit adds a ZSTD decoder module that parses ZSTD frames. The provided tests examine the model using C++ API, which is a prerequisite for detailed tests using zstd library. Internal-tag: [#50221] Co-authored-by: Maciej Dudek <[email protected]> Co-authored-by: Pawel Czarnecki <[email protected]> Signed-off-by: Maciej Dudek <[email protected]> Signed-off-by: Pawel Czarnecki <[email protected]> Signed-off-by: Robert Winkler <[email protected]>
1 parent 5ea2b7d commit ed24ae9

File tree

9 files changed

+762
-6
lines changed

9 files changed

+762
-6
lines changed

xls/modules/zstd/BUILD

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ load(
2121
"//xls/build_rules:xls_build_defs.bzl",
2222
"xls_benchmark_ir",
2323
"xls_benchmark_verilog",
24-
"xls_dslx_ir",
2524
"xls_dslx_library",
2625
"xls_dslx_test",
2726
"xls_dslx_verilog",
28-
"xls_ir_opt_ir",
2927
)
3028

3129
package(
@@ -774,3 +772,126 @@ place_and_route(
774772
synthesized_rtl = ":repacketizer_synth_asap7",
775773
target_die_utilization_percentage = "10",
776774
)
775+
776+
xls_dslx_library(
777+
name = "zstd_dec_dslx",
778+
srcs = [
779+
"zstd_dec.x",
780+
],
781+
deps = [
782+
":block_dec_dslx",
783+
":block_header_dslx",
784+
":buffer_dslx",
785+
":common_dslx",
786+
":frame_header_dslx",
787+
":frame_header_test_dslx",
788+
":magic_dslx",
789+
":ram_printer_dslx",
790+
":repacketizer_dslx",
791+
":sequence_executor_dslx",
792+
"//xls/examples:ram_dslx",
793+
],
794+
)
795+
796+
xls_dslx_verilog(
797+
name = "zstd_dec_verilog",
798+
codegen_args = {
799+
"module_name": "ZstdDecoder",
800+
"generator": "pipeline",
801+
"delay_model": "asap7",
802+
"ram_configurations": ",".join([
803+
"{ram_name}:1RW:{req}:{resp}:{wr_comp}:{latency}".format(
804+
latency = 5,
805+
ram_name = "ram{}".format(num),
806+
req = "zstd_dec__req{}_s".format(num),
807+
resp = "zstd_dec__resp{}_r".format(num),
808+
wr_comp = "zstd_dec__wr_comp{}_r".format(num),
809+
)
810+
for num in range(7)
811+
]),
812+
"pipeline_stages": "10",
813+
"reset": "rst",
814+
"reset_data_path": "true",
815+
"reset_active_low": "false",
816+
"reset_asynchronous": "true",
817+
"flop_inputs": "false",
818+
"flop_single_value_channels": "false",
819+
"flop_outputs": "false",
820+
"worst_case_throughput": "1",
821+
"use_system_verilog": "false",
822+
},
823+
dslx_top = "ZstdDecoder",
824+
library = ":zstd_dec_dslx",
825+
# TODO: 2024-01-15: Workaround for https://github.com/google/xls/issues/869
826+
# Force proc inlining for IR optimization
827+
opt_ir_args = {
828+
"inline_procs": "true",
829+
},
830+
verilog_file = "zstd_dec.v",
831+
)
832+
833+
cc_test(
834+
name = "zstd_dec_cc_test",
835+
srcs = [
836+
"zstd_dec_test.cc",
837+
],
838+
data = [
839+
":zstd_dec_verilog.ir",
840+
],
841+
#shard_count = 50,
842+
deps = [
843+
":data_generator",
844+
"//xls/common:xls_gunit_main",
845+
"//xls/common/file:filesystem",
846+
"//xls/common/file:get_runfile_path",
847+
"//xls/common/status:matchers",
848+
"//xls/interpreter:interpreter_proc_runtime",
849+
"//xls/ir:events",
850+
"//xls/ir:ir_parser",
851+
"//xls/ir:value",
852+
"@com_github_facebook_zstd//:zstd",
853+
"@com_google_googletest//:gtest",
854+
],
855+
)
856+
857+
xls_benchmark_ir(
858+
name = "zstd_dec_opt_ir_benchmark",
859+
src = ":zstd_dec_verilog.opt.ir",
860+
benchmark_ir_args = {
861+
#TODO: rewrite ram in opt_ir step to perform valid IR benchmark
862+
"pipeline_stages": "1",
863+
"delay_model": "asap7",
864+
},
865+
)
866+
867+
verilog_library(
868+
name = "zstd_dec_verilog_lib",
869+
srcs = [
870+
":zstd_dec.v",
871+
],
872+
)
873+
874+
synthesize_rtl(
875+
name = "zstd_dec_synth_asap7",
876+
standard_cells = "@org_theopenroadproject_asap7sc7p5t_28//:asap7-sc7p5t_rev28_rvt",
877+
top_module = "ZstdDecoder",
878+
deps = [
879+
":zstd_dec_verilog_lib",
880+
],
881+
)
882+
883+
benchmark_synth(
884+
name = "zstd_dec_benchmark_synth",
885+
synth_target = ":zstd_dec_synth_asap7",
886+
)
887+
888+
place_and_route(
889+
name = "zstd_dec_place_and_route",
890+
clock_period = "750",
891+
core_padding_microns = 2,
892+
min_pin_distance = "0.5",
893+
placement_density = "0.30",
894+
skip_detailed_routing = True,
895+
synthesized_rtl = ":zstd_dec_synth_asap7",
896+
target_die_utilization_percentage = "10",
897+
)

xls/modules/zstd/common.x

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub const BLOCK_SIZE_WIDTH = u32:21;
1919
pub const HISTORY_BUFFER_SIZE_KB = u32:64;
2020
pub const OFFSET_WIDTH = u32:22;
2121
pub const LENGTH_WIDTH = u32:22;
22+
pub const BUFFER_WIDTH = u32:128;
2223

2324
pub type BlockData = bits[DATA_WIDTH];
2425
pub type BlockPacketLength = u32;

xls/modules/zstd/data_generator.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,22 @@ absl::StatusOr<std::vector<uint8_t>> GenerateFrameHeader(int seed, bool magic) {
107107
return raw_data;
108108
}
109109

110+
absl::StatusOr<std::vector<uint8_t>> GenerateFrame(int seed, BlockType btype) {
111+
std::vector<std::string> args;
112+
args.push_back("-s" + std::to_string(seed));
113+
std::filesystem::path output_path =
114+
std::filesystem::temp_directory_path() /
115+
std::filesystem::path(
116+
CreateNameForGeneratedFile(absl::MakeSpan(args), ".zstd", "fh"));
117+
args.push_back("-p" + std::string(output_path));
118+
if (btype != BlockType::RANDOM)
119+
args.push_back("--block-type=" + std::to_string(btype));
120+
if (btype == BlockType::RLE) args.push_back("--content-size");
121+
122+
XLS_ASSIGN_OR_RETURN(auto result, CallDecodecorpus(args));
123+
auto raw_data = ReadFileAsRawData(output_path);
124+
std::remove(output_path.c_str());
125+
return raw_data;
126+
}
127+
110128
} // namespace xls::zstd

xls/modules/zstd/data_generator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@
3535

3636
namespace xls::zstd {
3737

38+
enum BlockType {
39+
RAW,
40+
RLE,
41+
COMPRESSED,
42+
RANDOM,
43+
};
44+
3845
absl::StatusOr<std::vector<uint8_t>> GenerateFrameHeader(int seed, bool magic);
46+
absl::StatusOr<std::vector<uint8_t>> GenerateFrame(int seed, BlockType btype);
3947

4048
} // namespace xls::zstd
4149

xls/modules/zstd/dec_demux.x

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub proc DecoderDemux {
109109
)}
110110

111111
next (tok: token, state: DecoderDemuxState) {
112+
trace_fmt!("DecDemux: next: state: {:#x}", state);
112113
let (tok, data) = recv_if(tok, input_r, !state.last_packet.last, ZERO_DATA);
113114
let (send_raw, send_rle, send_cmp, new_state) = match state.status {
114115
DecoderDemuxStatus::IDLE =>
@@ -166,7 +167,7 @@ pub proc DecoderDemux {
166167
};
167168
let tok = send_if(tok, rle_s, send_rle, rle_data);
168169
let tok = send_if(tok, cmp_s, send_cmp, data_to_send);
169-
if (new_state.send_data == new_state.byte_to_pass) {
170+
let end_state = if (new_state.send_data == new_state.byte_to_pass) {
170171
let next_id = if (state.last_packet.last && state.last_packet.last_block) {
171172
u32: 0
172173
} else {
@@ -181,7 +182,10 @@ pub proc DecoderDemux {
181182
}
182183
} else {
183184
new_state
184-
}
185+
};
186+
trace_fmt!("DecDemux: next: end_state: {:#x}", end_state);
187+
188+
end_state
185189
}
186190
}
187191

xls/modules/zstd/dec_mux.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub proc DecoderMux {
6262
) {(raw_r, rle_r, cmp_r, output_s)}
6363

6464
next (tok: token, state: DecoderMuxState) {
65+
trace_fmt!("DecMux: next: state: {:#x}", state);
6566
let (tok, raw_data, raw_data_valid) = recv_if_non_blocking(
6667
tok, raw_r, !state.raw_data_valid, zero!<ExtendedBlockDataPacket>());
6768
let state = if (raw_data_valid) {
@@ -159,6 +160,8 @@ pub proc DecoderMux {
159160
if (do_send) {
160161
trace_fmt!("sent {:#x}", data_to_send);
161162
} else {()};
163+
trace_fmt!("DecMux: next: end_state: {:#x}", state);
164+
162165
state
163166
}
164167
}

xls/modules/zstd/rle_block_dec.x

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ proc BatchPacker {
186186
init { (BatchState { prev_last: true, ..ZERO_BATCH_STATE }) }
187187

188188
next(tok: token, state: BatchState) {
189+
trace_fmt!("BatchPacker: next: state: {:#x}", state);
189190
let (tok, decoded_data) = recv(tok, rle_data_r);
190191

191192
let symbols_in_batch = state.symbols_in_batch;
@@ -218,13 +219,16 @@ proc BatchPacker {
218219
let new_symbols_in_batch =
219220
if do_send_batch { BlockPacketLength:0 } else { symbols_in_batch };
220221
let new_batch = if do_send_batch { BlockData:0 } else { batch };
221-
BatchState {
222+
let end_state = BatchState {
222223
batch: new_batch,
223224
symbols_in_batch: new_symbols_in_batch,
224225
prev_last: decoded_data.last,
225226
prev_last_block: sync_data.last_block,
226227
prev_id: sync_data.id
227-
}
228+
};
229+
trace_fmt!("BatchPacker: next: end_state: {:#x}", end_state);
230+
231+
end_state
228232
}
229233
}
230234

0 commit comments

Comments
 (0)