jedParser: add xilinx compatibility

This commit is contained in:
Gwenhael Goavec-Merou 2021-08-18 15:38:24 +02:00
parent 274d4ea2dc
commit 471fbb6a81
2 changed files with 110 additions and 47 deletions

View File

@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <algorithm>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
@ -32,8 +33,11 @@ using namespace std;
JedParser::JedParser(string filename, bool verbose): JedParser::JedParser(string filename, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_fuse_count(0), _pin_count(0), _featuresRow(0), _feabits(0), _checksum(0), _fuse_count(0), _pin_count(0), _max_vect_test(0),
_userCode(0), _security_settings(0), _default_fuse_state(0) _featuresRow(0), _feabits(0), _has_feabits(false), _checksum(0),
_compute_checksum(0),
_userCode(0), _security_settings(0), _default_fuse_state(0),
_default_test_condition(0), _arch_code(0), _pinout_code(0)
{ {
} }
@ -91,6 +95,29 @@ void JedParser::buildDataArray(const string &content, struct jed_data &jed)
data |= val << ii; data |= val << ii;
} }
tmp_buff += data; tmp_buff += data;
_compute_checksum += data;
}
jed.data.push_back(std::move(tmp_buff));
jed.len += data_len;
}
/* convert one serie ASCII 1/0 to a vector of
* unsigned char
* string must be up to 8 bits
*/
void JedParser::buildDataArray(const vector<string> &content,
struct jed_data &jed)
{
size_t data_len = 0;
string tmp_buff;
for (size_t i = 0; i < content.size(); i++) {
uint8_t data = 0;
data_len += content[i].size();
for (size_t ii = 0; ii < content[i].size(); ii++) {
uint8_t val = (content[i][ii] == '1'?1:0);
data |= val << ii;
}
tmp_buff += data;
} }
jed.data.push_back(std::move(tmp_buff)); jed.data.push_back(std::move(tmp_buff));
jed.len += data_len; jed.len += data_len;
@ -98,48 +125,57 @@ void JedParser::buildDataArray(const string &content, struct jed_data &jed)
void JedParser::displayHeader() void JedParser::displayHeader()
{ {
printf("feabits :\n"); /* only lattice jed */
printf("%04x <-> %d\n", _feabits, _feabits); if (_has_feabits) {
/* 15-14: always 0 */ printf("feabits :\n");
printf("\tBoot Mode : "); printf("%04x <-> %d\n", _feabits, _feabits);
switch ((_feabits>>11)&0x07) { /* 15-14: always 0 */
case 0: printf("\tBoot Mode : ");
printf("Single Boot from Configuration Flash\n"); switch ((_feabits>>11)&0x07) {
break; case 0:
case 1: printf("Single Boot from Configuration Flash\n");
printf("Dual Boot from Configuration Flash then External if there is a failure\n"); break;
break; case 1:
case 3: printf("Dual Boot from Configuration Flash then External if there is a failure\n");
printf("Single Boot from External Flash\n"); break;
break; case 3:
default: printf("Single Boot from External Flash\n");
printf("Error\n"); break;
} default:
printf("Error\n");
}
printf("\tMaster Mode SPI : %s\n", printf("\tMaster Mode SPI : %s\n",
(((_feabits>>11)&0x01)?"enable":"disable")); (((_feabits>>11)&0x01)?"enable":"disable"));
printf("\tI2c port : %s\n", printf("\tI2c port : %s\n",
(((_feabits>>10)&0x01)?"disable":"enable")); (((_feabits>>10)&0x01)?"disable":"enable"));
printf("\tSlave SPI port : %s\n", printf("\tSlave SPI port : %s\n",
(((_feabits>>9)&0x01)?"disable":"enable")); (((_feabits>>9)&0x01)?"disable":"enable"));
printf("\tJTAG port : %s\n", printf("\tJTAG port : %s\n",
(((_feabits>>8)&0x01)?"disable":"enable")); (((_feabits>>8)&0x01)?"disable":"enable"));
printf("\tDONE : %s\n", printf("\tDONE : %s\n",
(((_feabits>>7)&0x01)?"enable":"disable")); (((_feabits>>7)&0x01)?"enable":"disable"));
printf("\tINITN : %s\n", printf("\tINITN : %s\n",
(((_feabits>>6)&0x01)?"enable":"disable")); (((_feabits>>6)&0x01)?"enable":"disable"));
printf("\tPROGRAMN : %s\n", printf("\tPROGRAMN : %s\n",
(((_feabits>>5)&0x01)?"disable":"enable")); (((_feabits>>5)&0x01)?"disable":"enable"));
printf("\tMy_ASSP : %s\n", printf("\tMy_ASSP : %s\n",
(((_feabits>>4)&0x01)?"enable":"disable")); (((_feabits>>4)&0x01)?"enable":"disable"));
/* 3-0: always 0 */ /* 3-0: always 0 */
}
printf("Pin Count : %d\n", _pin_count); printf("Pin Count : %d\n", _pin_count);
printf("Fuse Count : %d\n", _fuse_count); printf("Fuse Count : %d\n", _fuse_count);
for (size_t i = 0; i < _data_list.size(); i++) { for (size_t i = 0; i < _data_list.size(); i++) {
printf("area[%zd] %d %d ", i, _data_list[i].offset, _data_list[i].len); printf("area[%zd] %4d %4d ", i, _data_list[i].offset, _data_list[i].len);
printf("%s\n", _data_list[i].associatedPrevNote.c_str()); printf("%ld ", _data_list[i].data.size());
for (size_t ii = 0; ii < _data_list[i].data.size(); ii++)
for (size_t iii = 0; iii < _data_list[i].data[ii].size(); iii++)
printf("%02x", (uint8_t)_data_list[i].data[ii][iii]);
printf(" %s\n", _data_list[i].associatedPrevNote.c_str());
if (_data_list[i].offset == 2656)
break;
} }
} }
@ -182,8 +218,20 @@ void JedParser::parseLField(const vector<string> &content)
std::istringstream iss(content[0]); std::istringstream iss(content[0]);
vector<string> myList((std::istream_iterator<string>(iss)), vector<string> myList((std::istream_iterator<string>(iss)),
std::istream_iterator<string>()); std::istream_iterator<string>());
myList[1].pop_back();
buildDataArray(myList[1], d); myList.erase(myList.begin());
/* merge all to compute checksum by 8bits */
std::stringstream imploded;
std::copy(myList.begin(), myList.end(),
std::ostream_iterator<std::string>(imploded, ""));
string t = imploded.str();
for (size_t i = 0; i < t.size(); i+=8)
_compute_checksum += reverseByte(std::stoi(t.substr(i, 8),
nullptr, 2));
buildDataArray(myList, d);
} }
_data_list.push_back(std::move(d)); _data_list.push_back(std::move(d));
} }
@ -246,6 +294,9 @@ int JedParser::parse()
case 'P': // pin count case 'P': // pin count
_pin_count = count; _pin_count = count;
break; break;
case 'V': // pin count
_max_vect_test = count;
break;
default: default:
cerr << "Error for 'Q' unknown qualifier " << lines[0] << endl; cerr << "Error for 'Q' unknown qualifier " << lines[0] << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
@ -257,6 +308,10 @@ int JedParser::parse()
case 'F': case 'F':
_default_fuse_state = lines[0][1] - '0'; _default_fuse_state = lines[0][1] - '0';
break; break;
case 'J':
sscanf(lines[0].c_str() + 1, "%d", &_arch_code);
sscanf(lines[0].c_str() + 3, "%d", &_pinout_code);
break;
case 'C': case 'C':
sscanf(lines[0].c_str() + 1, "%hx", &_checksum); sscanf(lines[0].c_str() + 1, "%hx", &_checksum);
break; break;
@ -266,6 +321,7 @@ int JedParser::parse()
break; break;
case 'E': case 'E':
parseEField(lines); parseEField(lines);
_has_feabits = true;
break; break;
case 'L': // fuse offset case 'L': // fuse offset
parseLField(lines); parseLField(lines);
@ -284,6 +340,9 @@ int JedParser::parse()
_userCode = ((_userCode << 1) | (lines[0][ii] - '0')); _userCode = ((_userCode << 1) | (lines[0][ii] - '0'));
} }
break; break;
case 'X': // default test condition
sscanf(lines[0].c_str() + 1, "%d", &_default_test_condition);
break;
default: default:
printf("inconnu\n"); printf("inconnu\n");
cout << lines[0]<< endl; cout << lines[0]<< endl;
@ -292,18 +351,13 @@ int JedParser::parse()
} while (lines[0][0] != 0x03); } while (lines[0][0] != 0x03);
int size = 0; int size = 0;
uint16_t checksum = 0;
for (size_t area = 0; area < _data_list.size(); area++) { for (size_t area = 0; area < _data_list.size(); area++) {
size += _data_list[area].len; size += _data_list[area].len;
for (size_t line = 0; line < _data_list[area].data.size(); line++) {
for (size_t col = 0; col < _data_list[area].data[line].size(); col++)
checksum += (uint8_t)_data_list[area].data[line][col];
}
} }
if (_verbose) if (_verbose)
printf("theorical checksum %x -> %x\n", _checksum, checksum); printf("theorical checksum %x -> %x\n", _checksum, _compute_checksum);
if (_checksum != checksum) { if (_checksum != _compute_checksum) {
printError("Error: wrong checksum"); printError("Error: wrong checksum");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -31,6 +31,7 @@ class JedParser: public ConfigBitstreamParser {
size_t nb_section() { return _data_list.size();} size_t nb_section() { return _data_list.size();}
size_t offset_for_section(int id) {return _data_list[id].offset;} size_t offset_for_section(int id) {return _data_list[id].offset;}
int len_for_section(int id) {return _data_list[id].len;}
std::vector<std::string> data_for_section(int id) { std::vector<std::string> data_for_section(int id) {
return _data_list[id].data; return _data_list[id].data;
} }
@ -42,19 +43,27 @@ class JedParser: public ConfigBitstreamParser {
std::string readline(); std::string readline();
std::vector<std::string>readJEDLine(); std::vector<std::string>readJEDLine();
void buildDataArray(const std::string &content, struct jed_data &jed); void buildDataArray(const std::string &content, struct jed_data &jed);
void buildDataArray(const std::vector<std::string> &content,
struct jed_data &jed);
void parseEField(const std::vector<std::string> &content); void parseEField(const std::vector<std::string> &content);
void parseLField(const std::vector<std::string> &content); void parseLField(const std::vector<std::string> &content);
std::vector<struct jed_data> _data_list; std::vector<struct jed_data> _data_list;
int _fuse_count; int _fuse_count;
int _pin_count; int _pin_count;
int _max_vect_test;
uint64_t _featuresRow; uint64_t _featuresRow;
uint16_t _feabits; uint16_t _feabits;
bool _has_feabits;
uint16_t _checksum; uint16_t _checksum;
uint16_t _compute_checksum;
uint32_t _userCode; uint32_t _userCode;
uint8_t _security_settings; uint8_t _security_settings;
uint8_t _default_fuse_state; uint8_t _default_fuse_state;
std::istringstream _ss; std::istringstream _ss;
int _default_test_condition;
int _arch_code;
int _pinout_code;
}; };
#endif // JEDPARSER_HPP_ #endif // JEDPARSER_HPP_