#!/usr/bin/env python
#
# Copyright 2011-2011 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
TMPL_TEXT = """
#import time
/***********************************************************************
* This file was generated by $file on $time.strftime("%c")
**********************************************************************/
\#include
\#include
\#include
\#include
\#include
\#include
\#include
typedef size_t pred_type;
typedef std::vector pred_vector_type;
enum dir_type{
DIR_OTW_TO_CPU = 0,
DIR_CPU_TO_OTW = 1
};
struct pred_error : std::runtime_error{
pred_error(const std::string &what)
:std::runtime_error("convert::make_pred: " + what){
/* NOP */
}
};
pred_type make_pred(const std::string &markup, dir_type &dir){
pred_type pred = 0;
try{
boost::tokenizer > tokenizer(markup, boost::char_separator("_"));
std::vector tokens(tokenizer.begin(), tokenizer.end());
//token 0 is
std::string inp_type = tokens.at(1);
std::string num_inps = tokens.at(2);
//token 3 is
std::string out_type = tokens.at(4);
std::string num_outs = tokens.at(5);
std::string swap_type = tokens.at(6);
std::string cpu_type, otw_type;
if (inp_type.find("item") == std::string::npos){
cpu_type = inp_type;
otw_type = out_type;
dir = DIR_CPU_TO_OTW;
}
else{
cpu_type = out_type;
otw_type = inp_type;
dir = DIR_OTW_TO_CPU;
}
if (cpu_type == "fc64") pred |= $ph.fc64_p;
else if (cpu_type == "fc32") pred |= $ph.fc32_p;
else if (cpu_type == "sc16") pred |= $ph.sc16_p;
else if (cpu_type == "sc8") pred |= $ph.sc8_p;
else throw pred_error("unhandled io type " + cpu_type);
if (otw_type == "item32") pred |= $ph.item32_p;
else throw pred_error("unhandled otw type " + otw_type);
int num_inputs = boost::lexical_cast(num_inps);
int num_outputs = boost::lexical_cast(num_outs);
switch(num_inputs*num_outputs){ //FIXME treated as one value
case 1: pred |= $ph.chan1_p; break;
case 2: pred |= $ph.chan2_p; break;
case 3: pred |= $ph.chan3_p; break;
case 4: pred |= $ph.chan4_p; break;
default: throw pred_error("unhandled number of channels");
}
if (swap_type == "bswap") pred |= $ph.bswap_p;
else if (swap_type == "nswap") pred |= $ph.nswap_p;
else throw pred_error("unhandled swap type");
}
catch(...){
throw pred_error("could not parse markup: " + markup);
}
return pred;
}
#define pred_table_wildcard pred_type(~0)
#define pred_table_max_size size_t(128)
#define pred_table_index(e) (pred_type(e) & 0x7f)
static pred_vector_type get_pred_byte_order_table(void){
pred_vector_type table(pred_table_max_size, pred_table_wildcard);
\#ifdef BOOST_BIG_ENDIAN
table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.nswap_p;
table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.bswap_p;
\#else
table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.bswap_p;
table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.nswap_p;
\#endif
table[pred_table_index(otw_type_t::BO_NATIVE)] = $ph.nswap_p;
return table;
}
static pred_vector_type get_pred_io_type_table(void){
pred_vector_type table(pred_table_max_size, pred_table_wildcard);
table[pred_table_index(io_type_t::COMPLEX_FLOAT64)] = $ph.fc64_p;
table[pred_table_index(io_type_t::COMPLEX_FLOAT32)] = $ph.fc32_p;
table[pred_table_index(io_type_t::COMPLEX_INT16)] = $ph.sc16_p;
return table;
}
static pred_vector_type get_pred_num_io_table(void){
pred_vector_type table(pred_table_max_size, pred_table_wildcard);
table[1] = $ph.chan1_p;
table[2] = $ph.chan2_p;
table[3] = $ph.chan3_p;
table[4] = $ph.chan4_p;
return table;
}
UHD_INLINE pred_type make_pred(
const io_type_t &io_type,
const otw_type_t &otw_type,
size_t num_inputs,
size_t num_outputs
){
pred_type pred = $ph.item32_p; //only item32 supported as of now
static const pred_vector_type pred_byte_order_table(get_pred_byte_order_table());
pred |= pred_byte_order_table[pred_table_index(otw_type.byteorder)];
static const pred_vector_type pred_io_type_table(get_pred_io_type_table());
pred |= pred_io_type_table[pred_table_index(io_type.tid)];
static const pred_vector_type pred_num_io_table(get_pred_num_io_table());
pred |= pred_num_io_table[pred_table_index(num_inputs*num_outputs)];
if (pred == pred_table_wildcard) throw pred_error(
"unhanded input combination for make_pred()"
);
return pred;
}
"""
def parse_tmpl(_tmpl_text, **kwargs):
from Cheetah.Template import Template
return str(Template(_tmpl_text, kwargs))
class ph:
bswap_p = 0b00001
nswap_p = 0b00000
item32_p = 0b00000
sc8_p = 0b00000
sc16_p = 0b00010
fc32_p = 0b00100
fc64_p = 0b00110
chan1_p = 0b00000
chan2_p = 0b01000
chan3_p = 0b10000
chan4_p = 0b11000
if __name__ == '__main__':
import sys, os
file = os.path.basename(__file__)
open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=file, ph=ph))