// // srecord - manipulate eprom load files // Copyright (C) 2000 Hendrik De Vloed - hendrik.devloed@rug.ac.be // Copyright (C) 2006, 2007 Peter Miller // // 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 // . // #include #include #include #include #include srec_output_file_vhdl::srec_output_file_vhdl(const string &a_file_name) : srec_output_file(a_file_name), bytes_per_word(1), prefix("eprom"), header_done(false) { } void srec_output_file_vhdl::command_line(srec_arglex *cmdln) { if (cmdln->token_cur() == arglex::token_number) { int a1 = cmdln->value_number(); cmdln->token_next(); if (a1 > 0) { unsigned a2 = (unsigned)a1; if (a2 > sizeof(unsigned long)) a2 = sizeof(unsigned long); bytes_per_word = a2; } } if (cmdln->token_cur() == arglex::token_string) { prefix = cmdln->value_string(); cmdln->token_next(); } } void srec_output_file_vhdl::emit_header() { if (header_done) return; if (!data_only_flag) { put_stringf ( "--\n" "-- Generated automatically by %s -VHDL - do not edit\n" "--\n", progname_get() ); put_stringf ( "library IEEE;\n" "use IEEE.numeric_std.all;\n" "use work.%s_defs_pack.all;\n\n", prefix.c_str() ); put_stringf("package %s_pack is\n", prefix.c_str()); put_stringf ( " constant %s_rom : %s_rom_array;\n", prefix.c_str(), prefix.c_str() ); put_stringf("end package %s_pack;\n\n", prefix.c_str()); put_stringf("package body %s_pack is\n", prefix.c_str()); } put_stringf ( " constant %s_rom : %s_rom_array := %s_rom_array'(\n", prefix.c_str(), prefix.c_str(), prefix.c_str() ); header_done = true; } srec_output_file_vhdl::~srec_output_file_vhdl() { emit_header(); put_stringf(" others => %s_dont_care\n" " );\n", prefix.c_str()); if (!data_only_flag) { put_stringf("end package body %s_pack;\n", prefix.c_str()); } } void srec_output_file_vhdl::write(const srec_record &record) { switch (record.get_type()) { case srec_record::type_unknown: // Ignore. break; case srec_record::type_header: if (!data_only_flag && record.get_length() > 0) { // // Output the header record as a comment. // put_string("-- "); if (record.get_address() != 0) put_stringf("%08lX: ", record.get_address()); const unsigned char *cp = record.get_data(); const unsigned char *ep = cp + record.get_length(); while (cp < ep) { unsigned char c = *cp++; if (c == '\n') { put_string("\n-- "); continue; } if (!isprint(c)) c = ' '; put_char(c); } put_char('\n'); } break; case srec_record::type_data: // // Make sure the data is aligned. // if ( bytes_per_word > 1 && ( (record.get_address() % bytes_per_word) || (record.get_length() % bytes_per_word) ) ) { fatal_alignment_error(bytes_per_word); } emit_header(); for (int j = 0; j < record.get_length(); j += bytes_per_word) { unsigned long current_word = 0; for (unsigned k = 0; k < bytes_per_word; ++k) current_word = (current_word << 8) + record.get_data(j + k); put_stringf ( " %lu => %s_entry(%lu),\n", (record.get_address() + j) / bytes_per_word, prefix.c_str(), current_word ); } break; case srec_record::type_data_count: // Ignore. break; case srec_record::type_start_address: // Ignore. break; } } void srec_output_file_vhdl::line_length_set(int) { // ignore } void srec_output_file_vhdl::address_length_set(int) { // ignore } int srec_output_file_vhdl::preferred_block_size_get() const { // // Use the largest we can get, but it has to be a multiple of our // word size. // int n = srec_record::max_data_length; if (bytes_per_word > 1) n -= (n % bytes_per_word); return n; } const char * srec_output_file_vhdl::format_name() const { return "VHDL"; }