jedParser: add xilinx compatibility
This commit is contained in:
parent
274d4ea2dc
commit
471fbb6a81
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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_
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue