14 #define TRG_SHORT_NAMES
15 #define TRGCDC_SHORT_NAMES
18 #include "trg/cdc/JLUT.h"
19 #include "trg/cdc/FpgaUtility.h"
20 #include "trg/cdc/JSignal.h"
21 #include "trg/cdc/JSignalData.h"
24 #include "FpgaUtility.h"
26 #include "JSignalData.h"
43 std::string TRGCDCJLUT::version(
void)
const
45 return string(
"TRGCDCJLUT 0.00");
48 TRGCDCJLUT::TRGCDCJLUT(
const string& name)
50 m_outputFlag(0), m_inputBitsize(0), m_outputBitsize(0),
51 m_inputOffset(0), m_outputOffset(0), m_outputIntMax(0),
52 m_inputToReal(0), m_toReal(0), m_inputShiftBits(0),
53 m_outputType(0), m_outputNBitsWithOffset(0)
59 : m_const(in.m_const),
61 m_fileName(in.m_fileName),
62 m_function(in.m_function),
63 m_floatFunction(in.m_floatFunction),
64 m_inputMin(in.m_inputMin),
65 m_inputMax(in.m_inputMax),
66 m_shiftOutputMin(in.m_shiftOutputMin),
67 m_shiftOffsetOutputMax(in.m_shiftOffsetOutputMax)
87 void TRGCDCJLUT::setData(
int inputBitsize,
int outputBitsize,
const string& filename,
bool twosComplement)
90 coeFile.open(filename.c_str());
92 cout <<
"TRGCDCJLUT !!! can not open file : " << filename << endl;
93 cout <<
" LUT is not initialized yet" << endl;
101 int inputSize = pow(2, inputBitsize);
105 stringstream reformatCoeFile;
107 while (getline(coeFile, t_line)) {
109 t_line.erase(remove_if(t_line.begin(), t_line.end(), ::isspace), t_line.end());
111 if (t_line.size() == 0)
continue;
113 size_t t_iFind = t_line.find(
";");
114 if (t_iFind != string::npos) {
115 t_line.erase(t_iFind + 1, string::npos);
118 if (t_line ==
";")
continue;
120 if (t_line.find(
";") == string::npos) reformatCoeFile << t_line;
122 else reformatCoeFile << t_line.substr(0, t_line.size() - 1) << endl;
127 vector<string> t_rawData;
128 while (getline(reformatCoeFile, t_line)) {
131 size_t t_iFind = t_line.find(
"=");
132 if (t_iFind != string::npos) {
135 if (t_line.substr(0, t_iFind) ==
"memory_initialization_radix") {
136 t_radix = atoi(t_line.substr(t_iFind + 1, string::npos).c_str());
137 }
else if (t_line.substr(0, t_iFind) ==
"memory_initialization_vector") {
139 string t_dataLine = t_line.substr(t_iFind + 1, string::npos);
141 t_iFind = t_dataLine.find(
",");
142 if (t_iFind != string::npos) {
143 t_rawData.push_back(t_dataLine.substr(0, t_iFind));
144 t_dataLine.erase(0, t_iFind + 1);
147 t_rawData.push_back(t_dataLine);
152 cout <<
"[Error] TRGCDCJLUT::setData() => .coe format keyword is wrong. Aborting" << endl;
156 cout <<
"[Error] TRGCDCJLUT::setData() => .coe format is wrong. Needs keywords. Aborting" << endl;
164 if (!twosComplement) {
165 for (
int iData = 0; iData < int(t_rawData.size()); iData++) {
171 int nBits = t_rawData[0].size();
173 int t_max = pow(t_radix, nBits) - 1;
175 nBits = floor(log(t_max) / log(2)) + 1;
176 for (
int iData = 0; iData < int(t_rawData.size()); iData++) {
186 cout <<
"LUT(" <<
m_name <<
") data" << endl;
187 for (
int iData = 0; iData < int(
m_data.size()); iData++) {
188 cout <<
"[" << iData <<
"] " <<
m_data[iData] << endl;
190 cout <<
"TTRGCDCJLUT ... LUT(" <<
m_name <<
") initilized with " << filename << endl;
205 int lutInputBitwidth,
int lutOutputBitwidth)
208 signed long long t_int;
218 t_int = input.getMinInt();
219 t_toReal = input.getToReal();;
220 t_actual = input.getMinActual();
221 t_commonData = input.getCommonData();
223 t_int = input.getMaxInt();
224 t_actual = input.getMaxActual();
243 double t_outputRealMinInt =
function(minInv.
getRealInt());
244 double t_outputRealMaxInt =
function(maxInv.
getRealInt());
245 if (std::isnan(t_outputRealMinInt)) {
246 cout <<
"[Error] TRGCDCJLUT::setFloatFunction() => t_outputRealMinInt is nan. Please change minInv signal so that function(minInv.getRealInt()) does not give nan."
249 if (std::isnan(t_outputRealMaxInt)) {
250 cout <<
"[Error] TRGCDCJLUT::setFloatFunction() => t_outputRealMaxInt is nan. Please change maxInv so that function(maxInv.getRealInt()) does not give nan"
253 if (t_outputRealMaxInt < t_outputRealMinInt) {
254 cout <<
"[Error] TRGCDCJLUT::setFloatFunction() => t_outputRealMaxInt is smaller than t_outputRealMinInt." << endl;
257 double t_outputMinActual =
function(minInv.
getActual());
258 double t_outputMaxActual =
function(maxInv.
getActual());
259 double t_outputToReal;
260 t_outputToReal = outputToReal;
261 double tt_factor = log((max(t_outputRealMaxInt, abs(t_outputRealMinInt)) - t_outputRealMinInt) / ((pow(2,
262 lutOutputBitwidth) - 0.5) * t_outputToReal)) / log(2);
263 tt_factor = ceil(tt_factor);
268 t_toReal = t_outputToReal * pow(2, tt_factor);
269 t_actual = t_outputMinActual;
279 t_actual = t_outputMaxActual - t_shiftOutputMin.
getActual();
308 if (
m_write != 1) cout <<
"[Warning] TRGCDCJLUT::m_function => input is smaller then 0. Changed to 0." << endl;
329 cout <<
"[Warning] TRGCDCJLUT::m_function => output is smaller then 0. Changed to 0." << endl;
330 cout <<
"Could happen if invY_min and invY_max are inside x range." << endl;
336 cout <<
"[Warning] TRGCDCJLUT::m_function => output is larger then allowed max value. Changed to " <<
338 cout <<
"Could happen if invY_min and invY_max are inside x range." << endl;
416 cout <<
"<<<[LUT] " <<
m_name <<
">>>" << endl;
422 cout <<
"<<<[LUT] " <<
m_name <<
">>>" << endl;
431 cout <<
"[Error] TRGCDCJLUT::makeCOE() => m_function is not set. Aborting." << endl;
436 cout <<
"[Error] TRGCDCJLUT::makeCOE() => inputBitSize is not set. Aborting." << endl;
441 if (fileName !=
"") t_fileName = fileName;
442 else if (
name() !=
"") {
444 t_fileName +=
".coe";
445 }
else t_fileName =
"untitled.coe";
448 coeFile.open(t_fileName.c_str());
450 coeFile <<
"* [Information for COE " << fileName <<
" ]" << endl;
461 coeFile <<
"memory_initialization_radix=10;" << endl;
462 coeFile <<
"memory_initialization_vector=" << endl;
464 for (
unsigned index = 0; index < pow(2,
m_inputBitsize) - 1; index++) {
476 string TRGCDCJLUT::operate(std::string out, std::string in, std::map<std::string, std::map<std::string, double>* >& m_intStorage)
478 double floatInput = (*m_intStorage[
"int"])[in] +
m_inputOffset;
481 stringstream t_offsetName;
483 (*m_intStorage[
"type"])[t_offsetName.str()] = 1;
485 (*m_intStorage[
"toReal"])[t_offsetName.str()] =
m_toReal;
487 (*m_intStorage[
"int"])[t_offsetName.str()] =
getOutput((*m_intStorage[
"int"])[in]);
488 (*m_intStorage[
"realInt"])[t_offsetName.str()] = (*m_intStorage[
"int"])[t_offsetName.str()] *
m_toReal;
492 (*m_intStorage[
"toReal"])[out] =
m_toReal;
495 (*m_intStorage[
"realInt"])[out] = (*m_intStorage[
"int"])[out] *
m_toReal;;
497 return t_offsetName.str();
514 cout <<
"[Warning] TRGCDCJLUT::operate() => Offsetted input minInt is not 0." << endl;
535 string t_shiftOffsetInputCode =
"";
539 t_shiftOffsetInputCode);
558 t_offsetOutput.
setName(
"lut_" + out.getName() +
"_out");
578 if (out.getPrintVhdl() == 1) {
579 string t_finalCode =
lutVhdlCode(t_shiftOffsetInputCode);
580 out.getCommonData()->setVhdlOutProcess(out.getCommonData()->getVhdlOutProcess() + t_finalCode);
583 map<string, vector<int> >& t_signals = out.getCommonData()->m_signals;
584 if (t_signals.find(t_offsetOutput.
getName()) == t_signals.end()) {
593 return t_offsetOutput;
600 stringstream t_vhdlCode;
601 t_vhdlCode <<
"lut_" <<
m_name <<
"_i: entity work.lut_" <<
m_name << endl;
602 t_vhdlCode <<
" port map(" << endl;
603 t_vhdlCode <<
" clka=>CLKIN, " << endl;
604 t_vhdlCode <<
" addra=>lut_" <<
m_name <<
"_in," << endl;
605 t_vhdlCode <<
" douta=>lut_" <<
m_name <<
"_out" << endl;
606 t_vhdlCode <<
");" << endl;
607 t_vhdlCode << shiftOffsetInput << endl;
608 return t_vhdlCode.str();