1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
#ifndef LIBTRELLIS_BITSTREAM_H
#define LIBTRELLIS_BITSTREAM_H
#include <cstdint>
#include <memory>
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <map>
#include <boost/optional.hpp>
using namespace std;
namespace Trellis {
enum class BitstreamCommand : uint8_t {
SPI_MODE = 0b01111001,
JUMP = 0b01111110,
LSC_RESET_CRC = 0b00111011,
VERIFY_ID = 0b11100010,
LSC_WRITE_COMP_DIC = 0b00000010,
LSC_PROG_CNTRL0 = 0b00100010,
LSC_PROG_CNTRL1 = 0b00100011,
LSC_INIT_ADDRESS = 0b01000110,
LSC_WRITE_ADDRESS = 0b10110100,
LSC_PROG_INCR_CMP = 0b10111000,
LSC_PROG_INCR_RTI = 0b10000010,
LSC_PROG_SED_CRC = 0b10100010,
ISC_PROGRAM_SECURITY = 0b11001110,
ISC_PROGRAM_USERCODE = 0b11000010,
LSC_EBR_ADDRESS = 0b11110110,
LSC_EBR_WRITE = 0b10110010,
ISC_PROGRAM_DONE = 0b01011110,
LSC_PROG_CNTRL0_2 = 0b11000100,
ISC_PROGRAM_USERCODE_2 = 0b11000011,
ISC_PROGRAM_DONE_2 = 0b01111010,
WRITE_INC_FRAME = 0b01000001,
DUMMY = 0b11111111,
};
class Chip;
// This represents a low level bitstream, as nothing more than an
// array of bytes and helper functions for common tasks
class Bitstream {
public:
// Read a Lattice .bit file (metadata + bitstream)
// Note that string variants take a filename, for ease of Python binding
static Bitstream read_bit(istream &in);
// Python variant of the above, takes filename instead of istream
static Bitstream read_bit_py(string file);
// Serialise a Chip back to a bitstream
static Bitstream serialise_chip(const Chip &chip, const map<string, string> options);
static Bitstream serialise_chip_partial(const Chip &chip, const vector<uint32_t> &frames, const map<string, string> options);
static Bitstream generate_jump(uint32_t address);
static Bitstream serialise_chip_py(const Chip &chip);
static Bitstream serialise_chip_delta_py(const Chip &chip1, const Chip &chip2);
// Deserialise a bitstream to a Chip
Chip deserialise_chip();
Chip deserialise_chip(boost::optional<uint32_t> idcode = boost::optional<uint32_t>());
// Write a Lattice .bit file (metadata + bitstream)
void write_bit(ostream &out);
// Python variant of the above, takes filename instead of ostream
void write_bit_py(string file);
// Write bitstream as a vector of bytes
vector<uint8_t> get_bytes();
// Write a Lattice .bin file (bitstream only, for flash prog.)
void write_bin(ostream &out);
// Raw bitstream data
vector<uint8_t> data;
// Lattice BIT file metadata
vector<string> metadata;
// Lattice LSCC file preamble
bool have_lscc_preamble;
private:
// Private constructor
Bitstream(const vector<uint8_t> &data, const vector<string> &metadata, bool have_lscc_preamble);
// Serialization of MachXO bitstream
static Bitstream serialise_chip_machxo(const Chip &chip, const map<string, string> options);
};
// Represents an error that occurs while parsing the bitstream
class BitstreamParseError : runtime_error {
public:
explicit BitstreamParseError(const string &desc);
BitstreamParseError(const string &desc, size_t offset);
const char *what() const noexcept override;
private:
string desc;
int offset;
};
}
#endif //LIBTRELLIS_BITSTREAM_H
|