diff --git a/xls/modules/zstd/BUILD b/xls/modules/zstd/BUILD index baa54f749f..2a48621af1 100644 --- a/xls/modules/zstd/BUILD +++ b/xls/modules/zstd/BUILD @@ -1185,3 +1185,20 @@ xls_dslx_test( dslx_test_args = {"compare": "none"}, library = ":fse_table_iterator_dslx", ) + +xls_dslx_library( + name = "fse_table_creator_dslx", + srcs = ["fse_table_creator.x"], + deps = [ + ":common_dslx", + ":fse_common_dslx", + ":ram_wr_handler_dslx", + "//xls/examples:ram_dslx", + ], +) + +xls_dslx_test( + name = "fse_table_creator_dslx_test", + dslx_test_args = {"compare": "none"}, + library = ":fse_table_creator_dslx", +) diff --git a/xls/modules/zstd/fse_table_creator.x b/xls/modules/zstd/fse_table_creator.x new file mode 100644 index 0000000000..862a66552a --- /dev/null +++ b/xls/modules/zstd/fse_table_creator.x @@ -0,0 +1,169 @@ +// Copyright 2024 The XLS Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import std; +import xls.examples.ram; +import xls.modules.zstd.common; +import xls.modules.zstd.ram_wr_handler as ram_wr; +import xls.modules.zstd.fse_common as fse; + +type DecoderCtrl = fse::FSEProbaFreqDecoderCtrl; + +enum FSETableIteratorStatus: u1 { + CONFIGURE = 0, + SEND = 1, +} + +struct FSETableCreatorCtrl { + accuracy_log: u32, + negative_proba_count: u32, +} + +proc FSETableIteratorState { + status: FSETableIteratorStatus, + ctrl: FSETableIteratorCtrl +} + +proc FSETableIterator { + type Status = FSETableIteratorStatus; + type State = FSETableIteratorState; + struct Ctrl = FSETableCreatorCtrl; + + type Reset = bool; + type Index = u32; + + ctrl_r: chan in; + resp_s: chan out; + + config( + req_r: chan in; + resp_s: chan out; + ) { (req_r, resp_s) } + + next(tok0: token, state: State) { + let do_recv_ctrl = state.status == Status::CONFIGURE; + let (tok, ctrl) = recv_if(tok, ctrl_r, do_recv_ctrl, zero!()); + + let new_state = match (state.status) { + Status::CONFIGURE => { + State { ctrl, status: Status::SEND } + }, + Status::SEND => { + state + }, + _ => { + fail!("incorrect_state", zero!); + }, + } + + new_state + } +} + +struct FSETableCreatorState { + rd_cnt: u32, + wr_cnt: u32, +} + + +proc FSETableCreator< + RAM_DATA_WIDTH: u32, + RAM_SIZE: u32, + RAM_WORD_PARTITION_SIZE: u32, + RAM_ADDR_WIDTH: u32 = {std::clog2(RAM_SIZE)}, + RAM_NUM_PARTITIONS: u32 = {ram::num_partitions(RAM_WORD_PARTITION_SIZE, RAM_DATA_WIDTH)}, +> { + type State = FSETableCreatorState; + + type RamWriteReq = ram::WriteReq; + type RamWriteResp = ram::WriteResp; + type RamReadReq = ram::ReadReq; + type RamReadResp = ram::ReadResp; + type RamAddr = bits[RAM_ADDR_WIDTH]; + type RamData = bits[RAM_DATA_WIDTH]; + + resp_in_s: chan out; + resp_out_r: chan in; + + rd_req_s: chan out; + rd_resp_r: chan in; + wr_req_s: chan out; + wr_resp_r: chan in; + + config( + rd_req_s: chan out, + rd_resp_r: chan in, + wr_req_s: chan out, + wr_resp_r: chan in) { + + let (resp_in_s, resp_in_r) = chan; + let (resp_out_s, resp_out_r) = chan; + + spawn ram_wr::RamWrRespHandler(resp_in_r, resp_out_s, wr_resp_r); + ( + resp_in_s, resp_out_r, + rd_req_s, rd_resp_r, wr_req_s, wr_resp_r, + ) + } + + init { zero!() } + + next(tok0: token, state: State) { + state + } +} + +const TEST_RAM_DATA_WIDTH = u32:8; +const TEST_RAM_SIZE = u32:256; +const TEST_RAM_ADDR_WIDTH = std::clog2(TEST_RAM_SIZE); +const TEST_RAM_WORD_PARTITION_SIZE = TEST_RAM_DATA_WIDTH; +const TEST_RAM_NUM_PARTITIONS = ram::num_partitions(TEST_RAM_WORD_PARTITION_SIZE, TEST_RAM_DATA_WIDTH); + +#[test_proc] +proc FSETableCreatorTest { + type ReadReq = ram::ReadReq; + type ReadResp = ram::ReadResp; + type WriteReq = ram::WriteReq; + type WriteResp = ram::WriteResp; + + terminator: chan out; + + rd_req_s: chan out; + rd_resp_r: chan in; + wr_req_s: chan out; + wr_resp_r: chan in; + + config(terminator: chan out) { + let (rd_req_s, rd_req_r) = chan; + let (rd_resp_s, rd_resp_r) = chan; + let (wr_req_s, wr_req_r) = chan; + let (wr_resp_s, wr_resp_r) = chan; + + spawn FSETableCreator( + rd_req_s, rd_resp_r, wr_req_s, wr_resp_r); + + spawn ram::RamModel( + rd_req_r, rd_resp_s, wr_req_r, wr_resp_s); + + ( terminator, + rd_req_s, rd_resp_r, wr_req_s, wr_resp_r + ) + } + + init { } + + next(tok: token, state: ()) { + let tok = send(tok, terminator, true); + } +}