| #ifndef LIBTRELLIS_CRAM_HPP |
| #define LIBTRELLIS_CRAM_HPP |
| |
| #include <cstdint> |
| #include <memory> |
| #include <vector> |
| |
| using namespace std; |
| namespace Trellis { |
| // This represents the difference between two CRAMViews |
| struct ChangedBit { |
| int frame; |
| int bit; |
| int delta; // -1, 0 or +1 (false-true, equal, true-false) |
| inline bool operator==(const ChangedBit &other) { |
| return (frame == other.frame) && (bit == other.bit) && (delta == other.delta); |
| } |
| }; |
| |
| typedef vector<ChangedBit> CRAMDelta; |
| |
| // This represents a view into the configuration memory, typically used to represent a tile |
| class CRAMView { |
| public: |
| // Access a bit inside the CRAM view by frame and bit offset within the view |
| char &bit(int frame, int bit) const; |
| |
| // Primarily for Python use |
| bool get_bit(int frame, int biti) const; |
| |
| void set_bit(int frame, int biti, bool value); |
| |
| // Return the number of frames inside the view |
| int frames() const; |
| |
| // Return the number of bits inside the view |
| int bits() const; |
| |
| // Clear the CRAM region |
| void clear(); |
| |
| friend CRAMDelta operator-(const CRAMView &a, const CRAMView &b); |
| |
| private: |
| // Private constructor, CRAM::make_view should always be used |
| CRAMView(shared_ptr<vector<vector<char>>> data, int frame_offset, int bit_offset, int frame_count, int bit_count); |
| |
| int frame_offset; |
| int bit_offset; |
| int frame_count; |
| int bit_count; |
| |
| friend class CRAM; |
| |
| shared_ptr<vector<vector<char>>> cram_data; |
| }; |
| |
| CRAMDelta operator-(const CRAMView &a, const CRAMView &b); |
| |
| // This represents the chip configuration RAM, and allows views of it to be made (for tile accesses) |
| // N.B. all accesses are in the format (frame, bit) |
| class CRAM { |
| public: |
| // Construct empty CRAM given size |
| CRAM(int frames, int bits); |
| |
| // Access a bit in the CRAM given frame and bit offset |
| char &bit(int frame, int bit) const; |
| |
| // Primarily for Python use |
| bool get_bit(int frame, int biti) const; |
| |
| void set_bit(int frame, int biti, bool value); |
| |
| // Return number of frames in CRAM |
| int frames() const; |
| |
| // Return number of bits per frame in CRAM |
| int bits() const; |
| |
| // Make a view to the CRAM given frame and bit offset; and frames and bits per frame in the view |
| CRAMView make_view(int frame_offset, int bit_offset, int frame_count, int bit_count); |
| |
| // Using a shared_ptr so views are not invalidated even if the CRAM itself is deleted |
| // A vector of type char is used as the optimisations in vector<bool> are not worth the loss of bool& etc |
| shared_ptr<vector<vector<char>>> data; |
| }; |
| } |
| #endif //LIBTRELLIS_CRAM_HPP |