Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Start towards OFDM blocks #236

Closed
wants to merge 17 commits into from
1 change: 1 addition & 0 deletions blocklib/digital/chunks_to_symbols/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
meson.build
68 changes: 68 additions & 0 deletions blocklib/digital/chunks_to_symbols/chunks_to_symbols.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module: digital
block: chunks_to_symbols
label: Chunks to Symbols
blocktype: block

doc:
brief: |-
Map a stream of unpacked symbol indexes to stream of
float or complex constellation points in D dimensions (D = 1 by
default)
detail: |-
\li input: stream of IN_T
\li output: stream of OUT_T
\li out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
The combination of gr::blocks::packed_to_unpacked_XX followed
by gr::digital::chunks_to_symbols_XY handles the general case
of mapping from a stream of bytes or shorts into arbitrary
float or complex symbols.

typekeys:
- id: IN_T
type: class
options:
- ru8
- ru16
- ru32
- id: OUT_T
type: class
options:
- cf32
- rf32

parameters:
- id: symbol_table
label: Symbol Table
dtype: OUT_T
settable: true
container: vector
- id: D
label: Dimension
dtype: size_t
settable: false
default: 1

# - id: num_ports
# label: Num Ports
# dtype: size_t
# default: 1
# grc:
# hide: part

# Example Ports
ports:
- domain: stream
id: in
direction: input
type: typekeys/IN_T

- domain: stream
id: out
direction: output
type: typekeys/OUT_T

implementations:
- id: cpu
# - id: cuda

file_format: 1
70 changes: 70 additions & 0 deletions blocklib/digital/chunks_to_symbols/chunks_to_symbols_cpu.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* -*- c++ -*- */
/*
* Copyright 2022 FIXME
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/

#include "chunks_to_symbols_cpu.h"
#include "chunks_to_symbols_cpu_gen.h"

namespace gr {
namespace digital {

template <class IN_T, class OUT_T>
chunks_to_symbols_cpu<IN_T, OUT_T>::chunks_to_symbols_cpu(
const typename chunks_to_symbols<IN_T, OUT_T>::block_args& args)
: INHERITED_CONSTRUCTORS(IN_T, OUT_T)
{
this->set_output_multiple(args.D);
}

template <class IN_T, class OUT_T>
work_return_code_t
chunks_to_symbols_cpu<IN_T, OUT_T>::work(std::vector<block_work_input_sptr>& work_input,
std::vector<block_work_output_sptr>& work_output)
{
auto in = work_input[0]->items<IN_T>();
auto out = work_output[0]->items<OUT_T>();

auto noutput = work_output[0]->n_items;
auto ninput = work_input[0]->n_items;

auto d_D = pmtf::get_as<size_t>(*this->param_D);

// number of inputs to consume
auto in_count = std::min(ninput, noutput / d_D);
if (in_count < 1) {
return work_return_code_t::WORK_INSUFFICIENT_OUTPUT_ITEMS;
}

auto d_symbol_table = pmtf::get_as<std::vector<OUT_T>>(*this->param_symbol_table);

if (d_D == 1) {
for (size_t i = 0; i < in_count; i++) {
auto key = static_cast<size_t>(*in);
*out = d_symbol_table[key];
++out;
++in;
}
}
else { // the multi-dimensional case
for (size_t i = 0; i < in_count; i++) {
auto key = static_cast<size_t>(*in) * d_D;
for (size_t idx = 0; idx < d_D; ++idx) {
*out = d_symbol_table[key + idx];
++out;
}
++in;
}
}

this->consume_each(in_count, work_input);
this->produce_each(in_count * d_D, work_output);
return work_return_code_t::WORK_OK;
}
} // namespace digital
} // namespace gr
33 changes: 33 additions & 0 deletions blocklib/digital/chunks_to_symbols/chunks_to_symbols_cpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* -*- c++ -*- */
/*
* Copyright 2022 FIXME
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/

#pragma once

#include <gnuradio/digital/chunks_to_symbols.h>

namespace gr {
namespace digital {

template <class IN_T, class OUT_T>
class chunks_to_symbols_cpu : public chunks_to_symbols<IN_T, OUT_T>
{
public:
chunks_to_symbols_cpu(const typename chunks_to_symbols<IN_T, OUT_T>::block_args& args);

virtual work_return_code_t work(std::vector<block_work_input_sptr>& work_input,
std::vector<block_work_output_sptr>& work_output) override;

private:
// Declare private variables here
};


} // namespace digital
} // namespace gr
1 change: 1 addition & 0 deletions blocklib/digital/crc_append/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
meson.build
61 changes: 61 additions & 0 deletions blocklib/digital/crc_append/crc_append.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module: digital
block: crc_append
label: CRC Append
blocktype: block

parameters:
- id: num_bits
label: CRC Size (bits)
dtype: size_t
grc:
default: 32
- id: poly
label: CRC Polynomial
dtype: uint64_t
grc:
default: 0x4C11DB7
- id: initial_value
label: Initial Register Value
dtype: uint64_t
grc:
default: 0xFFFFFFFF
- id: final_xor
label: Final XOR Value
dtype: uint64_t
grc:
default: 0xFFFFFFFF
- id: input_reflected
label: LSB-first Input
dtype: bool
grc:
default: True
- id: result_reflected
label: LSB-first Result
dtype: bool
grc:
default: True
- id: swap_endianness
label: LSB CRC in PDU
dtype: bool
grc:
default: False
- id: skip_header_bytes
label: Header Bytes to Skip
dtype: size_t
default: 0

ports:
- domain: message
id: in
direction: input

- domain: message
id: out
direction: output
optional: true

implementations:
- id: cpu
# - id: cuda

file_format: 1
36 changes: 36 additions & 0 deletions blocklib/digital/crc_append/crc_append_cpu.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* -*- c++ -*- */
/*
* Copyright 2022 FIXME
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/

#include "crc_append_cpu.h"
#include "crc_append_cpu_gen.h"

namespace gr {
namespace digital {

crc_append_cpu::crc_append_cpu(block_args args)
: INHERITED_CONSTRUCTORS,
d_num_bits(args.num_bits),
d_swap_endianness(args.swap_endianness),
d_crc(kernel::digital::crc(args.num_bits,
args.poly,
args.initial_value,
args.final_xor,
args.input_reflected,
args.result_reflected)),
d_header_bytes(args.skip_header_bytes)
{
if (args.num_bits % 8 != 0) {
throw std::runtime_error("CRC number of bits must be divisible by 8");
}
}


} // namespace digital
} // namespace gr
70 changes: 70 additions & 0 deletions blocklib/digital/crc_append/crc_append_cpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* -*- c++ -*- */
/*
* Copyright 2022 FIXME
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/

#pragma once

#include <gnuradio/digital/crc_append.h>

#include <pmtf/map.hpp>
#include <pmtf/vector.hpp>

#include <gnuradio/kernel/digital/crc.h>

namespace gr {
namespace digital {

class crc_append_cpu : public virtual crc_append
{
public:
crc_append_cpu(block_args args);

private:
unsigned d_num_bits;
bool d_swap_endianness;
kernel::digital::crc d_crc;
unsigned d_header_bytes;

virtual void handle_msg_in(pmtf::pmt msg) override
{
auto meta = pmtf::get_as<std::map<std::string, pmtf::pmt>>(
pmtf::map(msg)["meta"]);
auto samples = pmtf::get_as<std::vector<uint8_t>>(
pmtf::map(msg)["data"]);

const auto size = samples.size();
if (size <= d_header_bytes) {
d_logger->warn("PDU too short; dropping");
return;
}

uint64_t crc = d_crc.compute(&samples[d_header_bytes], size - d_header_bytes);

unsigned num_bytes = d_num_bits / 8;
if (d_swap_endianness) {
for (unsigned i = 0; i < num_bytes; ++i) {
samples.push_back(crc & 0xff);
crc >>= 8;
}
}
else {
for (unsigned i = 0; i < num_bytes; ++i) {
samples.push_back((crc >> (d_num_bits - 8 * (i + 1))) & 0xff);
}
}

meta["packet_len"] = pmtf::get_as<size_t>(meta["packet_len"]) + num_bytes;
auto pdu = pmtf::map({ { "data", samples }, { "meta", meta } });

this->get_message_port("out")->post(pdu);
}
};

} // namespace digital
} // namespace gr
Loading