@@ -51,6 +51,16 @@ uint32_t get_num_config_fuses(Trellis::ChipInfo &ci) {
5151 }
5252}
5353
54+ int num_digits (uint32_t num) {
55+ int count = 0 ;
56+ do {
57+ num /= 10 ;
58+ count++;
59+ } while (num != 0 );
60+
61+ return count;
62+ }
63+
5464int main (int argc, char *argv[])
5565{
5666 using namespace Trellis ;
@@ -68,6 +78,7 @@ int main(int argc, char *argv[])
6878 options.add_options ()(" svf" , po::value<std::string>(), " output SVF file" );
6979 options.add_options ()(" svf-rowsize" , po::value<int >(), " SVF row size in bits (default 8000)" );
7080 options.add_options ()(" jed" , po::value<std::string>(), " output JED file" );
81+ options.add_options ()(" jed-note" , po::value<vector<std::string>>(), " emit NOTE field in JED file" );
7182 options.add_options ()(" compress" , " compress bitstream to reduce size" );
7283 options.add_options ()(" spimode" , po::value<std::string>(), " SPI Mode to use (fast-read, dual-spi, qspi)" );
7384 options.add_options ()(" background" , " enable background reconfiguration in bitstream" );
@@ -377,8 +388,15 @@ int main(int argc, char *argv[])
377388
378389 jed_file << " \x02 *" << endl; // STX plus "design specification" (not filled in).
379390 full_checksum += calc_checksum (" \x02 *\n " );
380- // jed_file << "\x03" << hex << uppercase << setw(4) << full_checksum << endl;
381- // return 0;
391+
392+ if (vm.count (" jed-note" )) {
393+ ostringstream note_field;
394+ for (auto &n: vm[" jed-note" ].as <vector<string>>()) {
395+ note_field << " NOTE " << n << " *" << endl;
396+ full_checksum += calc_checksum (note_field.str ());
397+ jed_file << note_field.str ();
398+ }
399+ }
382400
383401 ostringstream fusecnt_field;
384402 uint32_t fusecnt;
@@ -389,6 +407,7 @@ int main(int argc, char *argv[])
389407 return 1 ;
390408 }
391409
410+ // TODO: QP (package information not implied in textual representation).
392411 fusecnt_field << " QF" << fusecnt << ' *' << endl;
393412 full_checksum += calc_checksum (fusecnt_field.str ());
394413 jed_file << fusecnt_field.str ();
@@ -397,19 +416,36 @@ int main(int argc, char *argv[])
397416 full_checksum += calc_checksum (" G0*\n " );
398417 jed_file << " F0*" << endl; // Default fuse value.
399418 full_checksum += calc_checksum (" F0*\n " );
400- jed_file << " L0" << endl;
401- full_checksum += calc_checksum (" L0\n " );
402419
420+ // The JEDEC spec says leading 0s are optional. My own experience is
421+ // that some programmers require leading 0s.
422+ ostringstream list_field;
423+ list_field << " L" << setw (num_digits (fusecnt)) << setfill (' 0' ) << 0 << endl;
424+ full_checksum += calc_checksum (list_field.str ());
425+ jed_file << list_field.str ();
426+
427+ // Strip the leading comment- it wastes precious fuse space and
428+ // some programmers (e.g STEP-MXO2) even rely on the preamble being
429+ // the first bytes.
430+ vector<uint8_t > preamble = {0xFF , 0xFF , 0xBD , 0xB3 , 0xFF , 0xFF };
431+ auto start_iter = search (begin (bitstream), end (bitstream), begin (preamble), end (preamble));
432+
433+ if (start_iter == end (bitstream)) {
434+ cerr << " Could not extract preamble from bitstream" << endl;
435+ return 1 ;
436+ }
437+
438+ auto start_offs = start_iter - bitstream.begin ();
403439
404440 size_t i = 0 ;
405441 while (i < fusecnt/8 ) {
406442 if (i < bitstream.size ()) {
407443 size_t len = min (size_t (16 ), bitstream.size () - i);
408444
409445 for (unsigned int j = 0 ; j < len; j++) {
410- uint8_t byte = uint8_t (bitstream[j + i]);
446+ uint8_t byte = uint8_t (bitstream[j + i + start_offs ]);
411447 checksum += reverse_byte (byte);
412- full_checksum += calc_checksum (std:: bitset<8 >{byte}.to_string ());
448+ full_checksum += calc_checksum (bitset<8 >{byte}.to_string ());
413449 jed_file << std::bitset<8 >{byte};
414450 }
415451
@@ -442,10 +478,10 @@ int main(int argc, char *argv[])
442478 jed_file << " *" << endl;
443479 full_checksum += calc_checksum (" *\n " );
444480
445- ostringstream oss ;
446- oss << " C" << hex << uppercase << setfill (' 0' ) << setw (4 ) << checksum << ' *' << endl;
447- full_checksum += calc_checksum (oss .str ());
448- jed_file << oss .str ();
481+ ostringstream checksum_field ;
482+ checksum_field << " C" << hex << uppercase << setfill (' 0' ) << setw (4 ) << checksum << ' *' << endl;
483+ full_checksum += calc_checksum (checksum_field .str ());
484+ jed_file << checksum_field .str ();
449485
450486 full_checksum += calc_checksum (" \x03 " );
451487 jed_file << " \x03 " << hex << uppercase << setw (4 ) << setfill (' 0' ) << full_checksum << endl;
0 commit comments