diff --git a/simulator/include/assembler.h b/simulator/include/assembler.h index 106018831..3abe00e69 100644 --- a/simulator/include/assembler.h +++ b/simulator/include/assembler.h @@ -30,12 +30,6 @@ policies, either expressed or implied, of the copyright holder. */ -// -// This is a tiny assembler based on the boost::spirit parser, which can parse -// single lines of Patmos assembly code and return the corresponding instruction -// words. -// - #ifndef PATMOS_ASSEMBLER_H #define PATMOS_ASSEMBLER_H @@ -55,55 +49,55 @@ namespace patmos class lexer_t { private: std::string Line; - + std::vector Positions; - + std::string Token; - + unsigned skip_space(unsigned pos); - + bool is_name_start(char c) const { return isalpha(c) || c == '.' || c == '_'; } - + public: lexer_t(std::string& line); - + void reset(); - + /// @return the number of tokens read so far unsigned tokens() { return Positions.size() - 1; } - + /// @return true when the current token is the last before EOL bool last() { return Positions.back() == Line.size(); } - + /// @return true when the current token is EOL bool end() { return Positions.back() == (size_t)-1; } - + std::string tok() const { return Token; } - + size_t pos() const; - + bool get_value(word_t &value, bool negate) const; - + bool is_name() const; - + bool is_digit() const; - + /// Push the given number of tokens back, reset to the n'th token before /// the current one. bool push_back(unsigned count = 1); - + /// @return false when the next token is EOL. bool next(); }; - + class line_assembler_t; - + class line_parser_t { private: lexer_t Lexer; - + // For error messages line_assembler_t &Assembler; @@ -112,31 +106,31 @@ namespace patmos /// @param maxregs the maximum number of registers (at most 100) /// @param regno the result /// @result true on success. - bool parse_register_number(const std::string &name, unsigned maxregs, + bool parse_register_number(const std::string &name, unsigned maxregs, unsigned ®no) const; - + public: line_parser_t(line_assembler_t &assembler, std::string line); - + lexer_t &get_lexer() { return Lexer; } - + void set_error(const std::string &msg); - - - bool parse_expression(word_t &value, reloc_info_t &reloc, + + + bool parse_expression(word_t &value, reloc_info_t &reloc, bool require_paren); - + bool parse_GPR(GPR_e ®); - + bool parse_SPR(SPR_e ®); - + bool parse_PRR(PRR_e &pred, bool may_negate); - + bool match_token(const std::string &tok); - + bool match_stmt_end(); }; - + /// Interface to parse a individual lines of Patmos assembly code and /// returning the corresponding instruction words. class line_assembler_t @@ -144,44 +138,44 @@ namespace patmos private: typedef std::multimap instructions_t; instructions_t Instructions; - + unsigned NOP_ID; - + typedef std::vector > relocations_t; relocations_t Relocations; - + symbol_map_t SymTab; - + std::vector Code; - + int Error_pos; - + std::string Error_msg; - + void initialize(); - + void add_relocation(unsigned index, reloc_info_t &reloc); - - bool parse_instruction(line_parser_t &parser, udword_t &encoded, + + bool parse_instruction(line_parser_t &parser, udword_t &encoded, reloc_info_t &reloc, bool &is_long); - + void set_error(line_parser_t &parser); - + public: /// Construct a line assembler. line_assembler_t(); - - + + void set_error(size_t pos, const std::string &msg); - + bool has_error() const { return Error_pos >= 0; } - + int get_error_pos() const { return Error_pos; } - + std::string get_error_msg() const { return Error_msg; } - + void print_error(std::ostream &out, unsigned offset); - + /// Parse a line of assembly code and return the corresponding instruction /// word. diff --git a/simulator/include/binary-format.h b/simulator/include/binary-format.h index 9545d6d37..21d3669d3 100644 --- a/simulator/include/binary-format.h +++ b/simulator/include/binary-format.h @@ -41,8 +41,6 @@ #include "basic-types.h" -#include - #include #include @@ -109,17 +107,17 @@ namespace patmos /// @param opcode the parsed mnemonic of this instruction. /// @param instr the instruction data to fill. /// @param reloc relocation info for this instruction. - /// @return true if the instruction requires reolcation. + /// @return true if the instruction requires reolcation. virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const = 0; - + /// Encode an instruction to its binary representation. /// @param opcode the parsed mnemonic of this instruction. /// @param instr the instruction data to encode. - virtual udword_t encode(std::string mnemonic, + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const = 0; - + /// Check whether the instruction word matches the instruction format, i.e., /// check whether the format's bit pattern matches its bit mask. /// Furthermore, verify that the instruction appears on a legal position diff --git a/simulator/include/binary-formats.h b/simulator/include/binary-formats.h index 556804137..8004ce8e9 100644 --- a/simulator/include/binary-formats.h +++ b/simulator/include/binary-formats.h @@ -57,8 +57,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -76,8 +76,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -95,8 +95,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -114,8 +114,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -133,8 +133,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -152,8 +152,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -171,8 +171,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -190,8 +190,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -209,8 +209,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -228,8 +228,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -250,8 +250,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -272,8 +272,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -291,8 +291,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -310,8 +310,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -329,8 +329,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -348,8 +348,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -373,8 +373,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; @@ -392,8 +392,8 @@ namespace patmos virtual bool parse_operands(line_parser_t &parser, std::string mnemonic, instruction_data_t &instr, reloc_info_t &reloc) const; - - virtual udword_t encode(std::string mnemonic, + + virtual udword_t encode(std::string mnemonic, const instruction_data_t &instr) const; }; diff --git a/simulator/include/command-line.h b/simulator/include/command-line.h index 1cd679ead..1f4ee8cbc 100755 --- a/simulator/include/command-line.h +++ b/simulator/include/command-line.h @@ -31,7 +31,7 @@ */ // -// Helper to parse and print command-line options, e.g., for memory/cache sizes +// Helper to parse and print command-line options, e.g., for memory/cache sizes // using unit prefixes. // @@ -81,7 +81,7 @@ namespace patmos DC_MISS, DC_ALL }; - + /// Parse a debug output format from a string in a stream /// @param in An input stream to read from. /// @param df The debug format. @@ -248,13 +248,13 @@ namespace patmos /// @param os An output stream. /// @param bs The size in bytes. std::ostream &operator <<(std::ostream &os, const byte_size_t &bs); - + /// Parsing addresses as command-line options. class address_t { private: unsigned int V; - + std::string symbol; public: @@ -267,14 +267,14 @@ namespace patmos void set_symbol(const std::string &sym) { symbol = sym; } - + /// Return the value of the address object. /// @return The value of the address object. unsigned int value() const { return V; } - + unsigned int parse(symbol_map_t &symbols) { if (V) return V; diff --git a/simulator/include/data-cache.h b/simulator/include/data-cache.h index 3d808be4d..3350cc74a 100644 --- a/simulator/include/data-cache.h +++ b/simulator/include/data-cache.h @@ -46,7 +46,7 @@ namespace patmos { public: virtual ~data_cache_t() {} - + virtual void flush_cache() = 0; }; @@ -131,14 +131,14 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) { // nothing to be done here } - + virtual void reset_stats() {} - + virtual void flush_cache() {} }; @@ -224,7 +224,7 @@ namespace patmos /// Number of stall cycles caused by method cache misses. unsigned int Num_stall_cycles; - + /// Number of cache read hits unsigned int Num_read_hits; @@ -258,8 +258,8 @@ namespace patmos /// Construct a new data cache instance. /// @param memory The memory that is accessed through the cache. /// @param num_blocks The size of the cache in blocks. - set_assoc_data_cache_t(memory_t &memory, unsigned int associativity, - unsigned int num_blocks, + set_assoc_data_cache_t(memory_t &memory, unsigned int associativity, + unsigned int num_blocks, unsigned int num_block_bytes); virtual ~set_assoc_data_cache_t(); @@ -291,7 +291,7 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); virtual void reset_stats(); diff --git a/simulator/include/dbgstack.h b/simulator/include/dbgstack.h index 09532b484..9e0409d6f 100644 --- a/simulator/include/dbgstack.h +++ b/simulator/include/dbgstack.h @@ -57,13 +57,13 @@ namespace patmos bool instruction_stats; bool profiling_stats; bool hitmiss_stats; - + debug_cache_e debug_cache; - + std::ostream *debug_out; }; - - + + /// Profiling information for functions. /// TODO we should rename that to debug_manager_t or something. class dbgstack_t @@ -74,7 +74,7 @@ namespace patmos class dbgstack_frame_t { public: // constructor - dbgstack_frame_t(simulator_t &sim, uword_t ret_base, uword_t ret_offset, + dbgstack_frame_t(simulator_t &sim, uword_t ret_base, uword_t ret_offset, uword_t function); uword_t function; @@ -82,7 +82,7 @@ namespace patmos uword_t ret_offs; uword_t caller_tos_stackcache; uword_t caller_tos_shadowstack; - + // Should we print statistics when returning from this function? bool print_stats; }; @@ -91,15 +91,15 @@ namespace patmos std::vector stack; simulator_t ∼ - + std::ostream *debug_out; - + /// Address of function to print stats for, or UINT_MAX. uword_t print_function; - + /// Options for statistics output stats_options_t stats_options; - + /// True if we are currently collecting stats bool found_print_function; @@ -110,18 +110,18 @@ namespace patmos const dbgstack_frame_t *callee) const; public: /// Constructor - dbgstack_t(simulator_t &s) : sim(s), debug_out(0), + dbgstack_t(simulator_t &s) : sim(s), debug_out(0), print_function(std::numeric_limits::max()), found_print_function(false) { } stats_options_t& get_stats_options() { return stats_options; } - + const stats_options_t& get_stats_options() const { return stats_options; } - + void print_function_stats(uword_t address, std::ostream &debug_out); - + /// initialize - Initialize the debug stack. void initialize(uword_t entry); @@ -129,10 +129,10 @@ namespace patmos void finalize(void); unsigned size() const { return stack.size(); } - + /// Return true if we are debug printing is currently enabled. bool is_printing() const; - + /// is_active_frame - Returns true if a given frame is currently active. /// @param frame the frame to check bool is_active_frame(const dbgstack_frame_t &frame) const; diff --git a/simulator/include/decoder.h b/simulator/include/decoder.h index da0927f8c..ece58be8d 100644 --- a/simulator/include/decoder.h +++ b/simulator/include/decoder.h @@ -53,20 +53,20 @@ namespace patmos class symbol_map_t; class section_info_t; - class decoder_callback_t + class decoder_callback_t { public: - + /// Called when a bundle has been decoded. /// @param addr the current address of the bundle /// @param bundle the decoded bundle /// @param size the size of the bundle in operations, 0 if decoding failed. /// @param sym the symbol table /// @return 0 on success, anything else on error. - virtual int process_bundle(uword_t addr, instruction_data_t *bundle, + virtual int process_bundle(uword_t addr, instruction_data_t *bundle, unsigned slots, symbol_map_t &sym) = 0; }; - + /// Interface to decoder Patmos instructions. class decoder_t { @@ -83,10 +83,10 @@ namespace patmos /// ID of the instruction used to encode NOPs static int NOP_ID; - + /// Initialize the simulation functions and binary formats. static void initialize_instructions(); - + /// Decode a binary encoded instruction. /// @param iw The instruction word to decode. /// @param imm The optional long immediate operand. @@ -115,24 +115,24 @@ namespace patmos /// @return 0 on success, or any error code returned by the callback handler int decode(loader_t &loader, section_info_t §ion, symbol_map_t &sym, decoder_callback_t &cb); - + /// Return the number of instructions known to the decoder. /// @return The number of instructions known to the decoder static unsigned int get_num_instructions() { return Instructions.size(); } - + /// Test if an instruction is a NOP instruction. bool is_NOP(instruction_data_t *data) const; - + /// @return the ID of the instruction used for NOPs, i.e., SUBi. static unsigned int get_noop_id() { return NOP_ID; } /// Return instruction by ID. /// @return The instruction having the given ID. static instruction_t &get_instruction(int ID); - }; + }; } #endif // PATMOS_DECODER_H diff --git a/simulator/include/exception.h b/simulator/include/exception.h index 22cc22b26..3b20b69c2 100644 --- a/simulator/include/exception.h +++ b/simulator/include/exception.h @@ -70,7 +70,7 @@ namespace patmos /// An illegal memory address has been accessed. ILLEGAL_ACCESS, - + /// A stack operation exceeded the stack size. STACK_EXCEEDED, @@ -97,7 +97,7 @@ namespace patmos /// The value of the cycle counter when the exception was raised. unsigned int Cycle; - + /// An optional error message. std::string Message; @@ -109,19 +109,19 @@ namespace patmos unsigned int cycle = 0) : Kind(kind), Info(info), PC(pc), Cycle(cycle), Message("") {} - - simulation_exception_t(kind_t kind, std::string msg, uword_t pc = 0, + + simulation_exception_t(kind_t kind, std::string msg, uword_t pc = 0, unsigned int cycle = 0) : Kind(kind), Info(0), PC(pc), Cycle(cycle), Message(msg) {} public: - void set_cycle(unsigned int cycle, uword_t pc) + void set_cycle(unsigned int cycle, uword_t pc) { Cycle = cycle; PC = pc; } - + /// Return the kind of the simulation exception. /// @return The kind of the simulation exception. kind_t get_kind() const @@ -135,7 +135,7 @@ namespace patmos { return Info; } - + std::string get_message() const { if (Message.empty()) { @@ -146,7 +146,7 @@ namespace patmos return Message; } } - + std::string to_string(symbol_map_t &sym) const { std::string kind_msg; switch (Kind) { @@ -233,14 +233,14 @@ namespace patmos { throw simulation_exception_t(ILLEGAL_ACCESS, address); } - + /// Throw an illegal access simulation exception. /// @param address The unmapped address. static void illegal_access(std::string msg) __attribute__ ((noreturn)) { throw simulation_exception_t(ILLEGAL_ACCESS, msg); } - + /// Throw a stack-cache-size-exceeded simulation exception. static void stack_exceeded(std::string msg) __attribute__ ((noreturn)) { @@ -264,7 +264,7 @@ namespace patmos { throw simulation_exception_t(ILLEGAL_PC, msg); } - + /// Throw a unaligned simulation exception. static void unaligned(uword_t address) __attribute__ ((noreturn)) { diff --git a/simulator/include/excunit.h b/simulator/include/excunit.h index 2680132f5..48d9c31f0 100644 --- a/simulator/include/excunit.h +++ b/simulator/include/excunit.h @@ -40,7 +40,7 @@ #include "basic-types.h" #include "memory-map.h" -namespace patmos +namespace patmos { /// Enumeration for interrupt types @@ -77,25 +77,25 @@ namespace patmos ET_INTR_12, ET_INTR_13, ET_INTR_14, - ET_INTR_15, + ET_INTR_15, NUM_EXCEPTIONS }; - /// Structure wrapping all information needed + /// Structure wrapping all information needed /// to handle an exception struct exception_t { // interrupt identifier exception_e Type; - + // ISR address for the interrupt uword_t Address; - + exception_t() : Type(ET_ILLEGAL_OPERATION), Address(0) {} - + // interrupt constructor - exception_t(exception_e mType, uword_t mAddress) + exception_t(exception_e mType, uword_t mAddress) : Type(mType), Address(mAddress) {} }; @@ -106,25 +106,25 @@ namespace patmos private: static const uword_t NO_ISR_ADDR = ~0u; - + // Enable interrupts bool Enable_interrupts; - + // Print out status changes bool Enable_debug; - + // Status flags for enabling interrupts uword_t Status; - + // Mask of enabled interrupts uword_t Mask; - + // Pending interrupts mask uword_t Pending; - + // Next interrupt that is going to be served (-1 if no pending interrupts) uword_t Source; - + /// Vector of ISR addresses uword_t Exception_vector[NUM_EXCEPTIONS]; @@ -135,11 +135,11 @@ namespace patmos /// Check if we should handle an interrupt or exception via an ISR. bool may_fire(exception_e exc); - + /// Check if an exception vector has been enabled, i.e. its mask bit is set. /// Does not check if throwing interrupts has been disabled. bool enabled(exception_e exc); - + /// Returns true if we are in privileged mode bool privileged(); @@ -148,7 +148,7 @@ namespace patmos /// Gets the next enqued interrupt exception_t next(); - + /// Check if we can trap the given exception, and return the ISR address /// if true. This sets up Source to the exception number, but does not /// call the exception handler. @@ -159,28 +159,28 @@ namespace patmos /// Get the ISR address for an exception entry. Does not modify the state exception_t get(exception_e exc) const; - + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size); - + virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); - + virtual void tick(simulator_t &s); - + /// Enables firing of interupts and exception handler ISRs. Does not disable /// traps. void enable_interrupts(bool enabled); /// Enable debug printing void enable_debug(bool debug); - + /// Make an exception pending. Never throws a simulator-exception directly. /// If the exception unit is disabled, the exception is effectively ignored. /// If the exception unit is enabled but the ISR is not installed, /// an illegal PC exception is triggered later. /// To throw a fault, use one of the specialized functions of this class. - void fire_exception(exception_e exctype); + void fire_exception(exception_e exctype); + - /// Throw an illegal instruction exception. /// @param iw The instruction word void illegal(uword_t iw); @@ -188,7 +188,7 @@ namespace patmos /// Throw an illegal instruction exception. /// @param msg The error message void illegal(std::string msg); - + /// Throw an unmapped address exception. /// @param address The unmapped address. void unmapped(uword_t address); @@ -196,7 +196,7 @@ namespace patmos /// Throw an illegal access exception. /// @param address The unmapped address. void illegal_access(uword_t address); - + /// Throw a stack-cache-size-exceeded exception. void stack_exceeded(std::string msg); @@ -208,7 +208,7 @@ namespace patmos /// Thow a PC-outsize-method exception. void illegal_pc(std::string msg); - + /// Throw a unaligned exception. void unaligned(uword_t address); diff --git a/simulator/include/instr-cache.h b/simulator/include/instr-cache.h index 317d5a4fe..0b6c8991a 100755 --- a/simulator/include/instr-cache.h +++ b/simulator/include/instr-cache.h @@ -43,7 +43,7 @@ #include "simulation-core.h" namespace patmos -{ +{ /// Basic interface for instruction-caches implementations. class instr_cache_t { @@ -85,16 +85,16 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) = 0; - + /// Reset statistics. virtual void reset_stats() = 0; - + /// Flush the cache. virtual void flush_cache() = 0; }; - + class no_instr_cache_t : public instr_cache_t { @@ -104,31 +104,31 @@ namespace patmos /// Number of words fetched so far for the current fetch request. uword_t Fetched; - + /// Words fetched so far for the current fetch request. word_t Fetch_cache[NUM_SLOTS]; - + /// Was the current slot access a miss? bool Is_miss[NUM_SLOTS]; - + /// Number of fetch requests with only misses uint64_t Num_all_miss; - + /// Number of fetch requests with a single miss in the first slot uint64_t Num_first_miss; - + /// Number of fetch requests with a single miss not in the first slot uint64_t Num_succ_miss; - + /// Number of fetch requests without misses uint64_t Num_hits; - + public: /// Construct a new instruction cache instance. /// The memory passed to this cache is not owned by this cache and must be /// managed externally. /// @param memory The memory that is accessed through the cache. - no_instr_cache_t(memory_t &memory) + no_instr_cache_t(memory_t &memory) : Memory(&memory), Fetched(0), Num_all_miss(0), Num_first_miss(0), Num_succ_miss(0), Num_hits(0) { @@ -136,7 +136,7 @@ namespace patmos Is_miss[i] = false; } } - + virtual void initialize(simulator_t &s, uword_t address) {} virtual bool fetch(simulator_t &s, uword_t base, uword_t address, word_t iw[NUM_SLOTS]); @@ -144,20 +144,20 @@ namespace patmos virtual bool load_method(simulator_t &s, uword_t address, word_t offset); virtual bool is_available(simulator_t &s, uword_t address); - + virtual void tick(simulator_t &s) {} virtual void print(const simulator_t &s, std::ostream &os) {} virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); - + virtual void reset_stats(); - + virtual void flush_cache() {} }; - - + + /// An instuction cache using a backing data cache. /// @param owning_cache set to true if this cache should own the given memory. template @@ -166,11 +166,11 @@ namespace patmos private: /// The global memory or backing cache. data_cache_t *Backing_cache; - + public: /// Construct a new instruction cache instance. /// @param memory The memory that is accessed through the cache. - instr_cache_wrapper_t(data_cache_t *data_cache) + instr_cache_wrapper_t(data_cache_t *data_cache) : no_instr_cache_t(*data_cache), Backing_cache(data_cache) { } @@ -186,7 +186,7 @@ namespace patmos if (IS_OWNING_CACHE) { Backing_cache->tick(s); } - + no_instr_cache_t::tick(s); } @@ -198,13 +198,13 @@ namespace patmos Backing_cache->print(s, os); os << "\n"; } - + no_instr_cache_t::print(s, os);; } /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) { if (IS_OWNING_CACHE) { @@ -214,14 +214,14 @@ namespace patmos no_instr_cache_t::print_stats(s, os, options); } - + virtual void reset_stats() { if (IS_OWNING_CACHE) { Backing_cache->reset_stats(); } no_instr_cache_t::reset_stats(); } - + virtual void flush_cache() { Backing_cache->flush_cache(); } diff --git a/simulator/include/instr-spm.h b/simulator/include/instr-spm.h index c0311db13..180d4fb14 100755 --- a/simulator/include/instr-spm.h +++ b/simulator/include/instr-spm.h @@ -33,7 +33,7 @@ // // Instruction scratchpad interface. // -// The I-SPM is implemented as a wrapper for a backing instruction cache. +// The I-SPM is implemented as a wrapper for a backing instruction cache. // #ifndef PATMOS_INSTR_SPM_H @@ -44,14 +44,14 @@ #include "simulation-core.h" namespace patmos -{ +{ class instr_spm_t : public instr_cache_t { private: - + /// A map of function addresses to access counters per function. typedef std::map method_stats_t; - + /// The backing memory. memory_t *Memory; @@ -60,12 +60,12 @@ namespace patmos /// The size of the I-SPM. uword_t Size; - + /// Number of load requests for the SPM. uint64_t Num_loads; - + method_stats_t Method_stats; - + public: /// Construct a new instruction SPM instance. /// The memory passed to this SPM is not owned by this cache and must be @@ -73,18 +73,18 @@ namespace patmos /// @param memory The memory that is accessed through the SPM. /// @param cache the cache to use for non-SPM accesses. /// @param size the size of the SPM. It will be mapped to [0..size). - instr_spm_t(memory_t &memory, instr_cache_t *icache, word_t size) + instr_spm_t(memory_t &memory, instr_cache_t *icache, word_t size) : Memory(&memory), Cache(icache), Size(size), Num_loads(0) { } - + virtual ~instr_spm_t() { if (Cache) delete Cache; } - virtual void initialize(simulator_t &s, uword_t address) { - Cache->initialize(s, address); + virtual void initialize(simulator_t &s, uword_t address) { + Cache->initialize(s, address); } virtual bool fetch(simulator_t &s, uword_t base, uword_t address, word_t iw[NUM_SLOTS]); @@ -92,18 +92,18 @@ namespace patmos virtual bool load_method(simulator_t &s, uword_t address, word_t offset); virtual bool is_available(simulator_t &s, uword_t address); - + virtual void tick(simulator_t &s) { Cache->tick(s); } - virtual void print(const simulator_t &s, std::ostream &os) { + virtual void print(const simulator_t &s, std::ostream &os) { Cache->print(s, os); } virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); - + virtual void reset_stats(); - + virtual void flush_cache(); }; diff --git a/simulator/include/instruction.h b/simulator/include/instruction.h index d80e7c133..d17a6fc8b 100644 --- a/simulator/include/instruction.h +++ b/simulator/include/instruction.h @@ -85,31 +85,31 @@ namespace patmos virtual bool is_flow_control() const = 0; virtual bool is_call() const { return false; } - + virtual bool is_return() const { return false; } - + virtual bool is_load() const { return false; } - + virtual bool is_store() const { return false; } - + /// Returns the number of delay slot cycles of this instruction virtual unsigned get_delay_slots(const instruction_data_t &ops) const = 0; /// Returns the number of delay slots for interrupt triggering virtual unsigned get_intr_delay_slots(const instruction_data_t &ops) const = 0; - + /// Returns the destination register of the instruction, or r0 if no destination. - virtual GPR_e get_dst_reg(const instruction_data_t &ops) const { + virtual GPR_e get_dst_reg(const instruction_data_t &ops) const { return r0; } - + /// Returns the first source register, or r0 if no source registers. - virtual GPR_e get_src1_reg(const instruction_data_t &ops) const { + virtual GPR_e get_src1_reg(const instruction_data_t &ops) const { return r0; } - + /// Return the second source register, or r0 if operation has less than two operands. - virtual GPR_e get_src2_reg(const instruction_data_t &ops) const { + virtual GPR_e get_src2_reg(const instruction_data_t &ops) const { return r0; } @@ -328,10 +328,10 @@ namespace patmos /// New stack spill pointer from EX stage. word_t EX_Ss; - + /// New stack top pointer from EX stage. word_t EX_St; - + /// Result register operand from EX stage. GPR_by_pass_t GPR_EX_Rd; @@ -350,7 +350,7 @@ namespace patmos // -------------------------- MW ------------------------------------------- /// Discard instructions in MW stage (stalling). word_t MW_Discard; - + /// Keep track if this is the first cycle in the MW stage. word_t MW_Initialized; @@ -561,7 +561,7 @@ namespace patmos /// Print the instruction's operands to an output stream. /// @param os The output stream to print to. /// @param symbols A mapping of addresses to symbols. - void print_operands(const simulator_t &s, std::ostream &os, + void print_operands(const simulator_t &s, std::ostream &os, const symbol_map_t &symbols) const { if (I) { diff --git a/simulator/include/loader.h b/simulator/include/loader.h index 0b47ead5b..f5b8842ce 100644 --- a/simulator/include/loader.h +++ b/simulator/include/loader.h @@ -46,96 +46,94 @@ #include -#include - namespace patmos { class simulator_t; - - struct section_info_t + + struct section_info_t { /// Offset in the binary of the section uword_t offset; - + /// Address in memory of the section uword_t addr; - + /// Size of the section uword_t size; - - section_info_t(uword_t offset, uword_t addr, uword_t size) - : offset(offset), addr(addr), size(size) + + section_info_t(uword_t offset, uword_t addr, uword_t size) + : offset(offset), addr(addr), size(size) {} }; - - /// List of sections as (start-address, end-address) pairs. End-address is + + /// List of sections as (start-address, end-address) pairs. End-address is /// the next address after the last valid address in the section. typedef std::vector section_list_t; - - class loader_t + + class loader_t { private: bool Is_ELF; - + protected: std::vector buf; - + loader_t(std::istream &is, bool elf); - + public: virtual ~loader_t() {} - + bool is_ELF() { return Is_ELF; } - + uword_t get_binary_size() { return buf.size(); } - + /// @return The entry point of the elf executable. virtual uword_t get_program_entry() = 0; - + /// @param symbols Map to store symbol information, if available. /// @param text List of text sections in memory. virtual void load_symbols(symbol_map_t &sym, section_list_t &text) = 0; - + /// @param m The main memory to load to. virtual void load_to_memory(simulator_t &s, memory_t &m) = 0; - + /// Read a word from the binary and convert it to big-endian. /// @param offset the offset in the binary file to read from. virtual uword_t read_word(uword_t offset); }; - - class elf_loader_t : public loader_t + + class elf_loader_t : public loader_t { private: Elf *elf; - + uword_t entry; - + public: explicit elf_loader_t(std::istream &is); virtual ~elf_loader_t(); - + virtual uword_t get_program_entry() { return entry; } - + virtual void load_symbols(symbol_map_t &sym, section_list_t &text); - - virtual void load_to_memory(simulator_t &s, memory_t &m); + + virtual void load_to_memory(simulator_t &s, memory_t &m); }; - + class bin_loader_t : public loader_t { public: explicit bin_loader_t(std::istream &is) : loader_t(is, false) {} - + virtual uword_t get_program_entry() { return 0x4; } - + virtual void load_symbols(symbol_map_t &sym, section_list_t &text); - + virtual void load_to_memory(simulator_t &s, memory_t &m); }; - + bool is_elf(std::istream &is); - + /// Create a new file loader from a stream. /// @param is The input stream to read from. loader_t *create_loader(std::istream &is); diff --git a/simulator/include/memory-map.h b/simulator/include/memory-map.h index b4a1711e7..238938d89 100644 --- a/simulator/include/memory-map.h +++ b/simulator/include/memory-map.h @@ -46,7 +46,7 @@ namespace patmos { class simulator_t; class excunit_t; - + /// Default address of the UART status register. static const uword_t IOMAP_BASE_ADDRESS = 0xF0000000; @@ -55,34 +55,34 @@ namespace patmos /// Offset from IO base address for the CPU info. static const uword_t CPUINFO_OFFSET = 0x00000; - + /// Number of bytes mapped to the CPU Info. static const uword_t CPUINFO_MAP_SIZE = 0x000C; - + /// Offset from IO base address for the exception unit. static const uword_t EXCUNIT_OFFSET = 0x10000; - + /// Number of bytes mapped to the exception unit. static const uword_t EXCUNIT_MAP_SIZE = 0x0100; /// Offset from IO base address for the timer device. static const uword_t TIMER_OFFSET = 0x20000; - + /// Number of bytes mapped to the timer device. static const uword_t TIMER_MAP_SIZE = 0x0018; /// Offset from IO base address for the performance counters device. static const uword_t PERFCOUNTERS_OFFSET = 0x30000; - + /// Number of bytes mapped to the performance counters device. static const uword_t PERFCOUNTERS_MAP_SIZE = 0x0028; /// Offset from IO base address for the memory management unit. static const uword_t MMU_OFFSET = 0x70000; - + /// Number of bytes mapped to the memory management unit. static const uword_t MMU_MAP_SIZE = 0x0040; - + /// Offset from IO base address for UART device. static const uword_t UART_OFFSET = 0x80000; @@ -91,56 +91,56 @@ namespace patmos /// Offset from IO base address for the LED device. static const uword_t LED_OFFSET = 0x90000; - + /// Number of bytes mapped to the LED device. static const uword_t LED_MAP_SIZE = 0x0004; /// Offset from IO base address for the EthMac device. static const uword_t ETHMAC_OFFSET = 0xb0000; - + /// Number of bytes mapped to the EthMac device. static const uword_t ETHMAC_MAP_SIZE = 0x10000; - + class mapped_device_t { protected: /// Base address of this device uword_t Base_address; - + // Number of bytes mapped to this device uword_t Mapped_bytes; - + public: - - mapped_device_t(uword_t base_address, uword_t mapped_bytes) + + mapped_device_t(uword_t base_address, uword_t mapped_bytes) : Base_address(base_address), Mapped_bytes(mapped_bytes) {} - + virtual ~mapped_device_t() {} - + /// Check if the address is a word access to this device. /// @param address the memory address to check for a match. /// @param size the requested size of the access /// @param offset the offset to the base address to check with. bool is_word_access(uword_t address, uword_t size, uword_t offset); - + /// Read a word from memory pointer /// @param value the pointer to the data to read /// @param size the size of the value to read in bytes /// @return the read value uword_t get_word(byte_t *value, uword_t size); - + /// Write a word to a memory pointer /// @param value the pointer to the data to write /// @param size the size of the value to write in bytes /// @param data the word to write void set_word(byte_t *value, uword_t size, uword_t data); - + /// Get the base address of this device. virtual uword_t get_base_address() const { return Base_address; } - + /// Get the number of bytes that are mapped to this device. virtual uword_t get_num_mapped_bytes() const { return Mapped_bytes; } - + /// A simulated access to a read port. /// @param address The memory address to read from. /// @param value A pointer to a destination to store the value read from @@ -157,7 +157,7 @@ namespace patmos /// otherwise. virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size) = 0; - /// A simulated access to a read port. Does not update the device state or + /// A simulated access to a read port. Does not update the device state or /// simulate timing, just reads the value. /// @param address The memory address to read from. /// @param value A pointer to a destination to store the value read from @@ -178,27 +178,27 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) { } - + /// Reset the statistics. virtual void reset_stats() { } }; - - - class cpuinfo_t : public mapped_device_t + + + class cpuinfo_t : public mapped_device_t { // The CPU ID uword_t Cpu_id; - + // The CPU frequency (Hz) uword_t Cpu_freq; - + // The number of cores uword_t Cpu_cnt; public: - + /// @param freq The CPU frequency in Mhz cpuinfo_t(uword_t base_address, uword_t cpuid, double freq, uword_t cpucnt) : mapped_device_t(base_address, CPUINFO_MAP_SIZE), @@ -206,22 +206,22 @@ namespace patmos Cpu_freq(freq * 1000000), Cpu_cnt(cpucnt) {} - + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size); virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); - + virtual void peek(simulator_t &s, uword_t address, byte_t *value, uword_t size); }; - class perfcounters_t : public mapped_device_t + class perfcounters_t : public mapped_device_t { public: - + perfcounters_t(uword_t base_address) : mapped_device_t(base_address, PERFCOUNTERS_MAP_SIZE) {} - + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size); virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); @@ -256,17 +256,17 @@ namespace patmos } } - virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size); + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size); virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); virtual uword_t xlate(uword_t address, mmu_op_t op); }; - - class led_t : public mapped_device_t + + class led_t : public mapped_device_t { /// Stream to write LED status to std::ostream &Out_stream; - + uword_t Curr_state; public: led_t(uword_t base_address, std::ostream &os) @@ -278,7 +278,7 @@ namespace patmos virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); }; - class ethmac_t : public mapped_device_t + class ethmac_t : public mapped_device_t { private: byte_t buffer [0xf000]; @@ -307,7 +307,7 @@ namespace patmos virtual void tick(simulator_t &s); }; - + /// Map several devices into the address space of another memory device class memory_map_t : public memory_t { @@ -317,30 +317,30 @@ namespace patmos typedef std::vector DeviceList; typedef std::vector > AddressList; - + DeviceList Devices; - + /// List of start-address,high-address pairs per device AddressList Device_map; - + uword_t Base_address; - + uword_t High_address; - + protected: mapped_device_t& find_device(uword_t address); - + public: /// Construct a new memory map. /// @param memory The memory onto which the devices are memory mapped. /// @param base_address The start address of the mapped address range. /// @param high_address The highest address of the mapped address range. - memory_map_t(memory_t &memory, uword_t base_address, uword_t high_address) - : Memory(memory), Base_address(base_address), High_address(high_address) + memory_map_t(memory_t &memory, uword_t base_address, uword_t high_address) + : Memory(memory), Base_address(base_address), High_address(high_address) {} void add_device(mapped_device_t &device); - + /// A simulated access to a read port. /// @param address The memory address to read from. /// @param value A pointer to a destination to store the value read from @@ -384,9 +384,9 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); - + virtual void reset_stats(); }; } diff --git a/simulator/include/memory.h b/simulator/include/memory.h index bab7f13dc..97da62022 100644 --- a/simulator/include/memory.h +++ b/simulator/include/memory.h @@ -64,7 +64,7 @@ namespace patmos memory_t() : Mmu(NULL) {} virtual ~memory_t() {} - + /// A simulated access to a read port. /// @param s The core performing the access /// @param address The memory address to read from. @@ -122,7 +122,7 @@ namespace patmos /// @param size The number of bytes to write. virtual void write_peek(simulator_t &s, uword_t address, byte_t *value, uword_t size) = 0; - + /// Read some values of a fixed size from the memory -- DO NOT SIMULATE TIMING, just read. /// @param address The memory address to read from. /// @param value A pointer to a destination to store the value read from @@ -154,7 +154,7 @@ namespace patmos void set_mmu(mmu_t *mmu) { Mmu = mmu; } - + /// Reset statistics. virtual void reset_stats() = 0; }; @@ -171,39 +171,39 @@ namespace patmos /// The content of the memory. byte_t *Content; - + /// Optional vector of flags indicating whether a byte has been initialized. byte_t *Init_vector; bool Randomize; - + mem_check_e Mem_check; - + /// Ensure that the content is initialize up to the given address. /// @param address The address that should be accessed. /// @param size The access size. /// @param is_write Access is a write or a read /// @param ignore_errors Do not throw any exceptions on access errors - void check_initialize_content(simulator_t &s, uword_t address, uword_t size, + void check_initialize_content(simulator_t &s, uword_t address, uword_t size, bool is_read, bool ignore_errors = false); - + public: /// Construct a new memory instance. /// @param memory_size The size of the memory in bytes. - ideal_memory_t(unsigned int memory_size, bool randomize, - mem_check_e memchk) - : Memory_size(memory_size), Initialized_offset(0), + ideal_memory_t(unsigned int memory_size, bool randomize, + mem_check_e memchk) + : Memory_size(memory_size), Initialized_offset(0), Randomize(randomize), Mem_check(memchk) { Content = new byte_t[memory_size]; - + if (memchk != MCK_NONE) { Init_vector = new byte_t[memory_size]; } else { Init_vector = NULL; } } - + ~ideal_memory_t() { if (Content) delete[] Content; if (Init_vector) delete[] Init_vector; @@ -262,12 +262,12 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) { // nothing to be done here } - + virtual void reset_stats() {} }; @@ -286,13 +286,13 @@ namespace patmos /// If true, do not wait for the request to be retrieved, but delete it. bool Is_posted; - + /// Number of ticks remaining until the request completes. unsigned int Num_ticks_remaining; }; /// A memory with fixed access times to transfer fixed-sized blocks. - /// Memory accesses are performed in blocks (NUM_BLOCK_BYTES) with a fixed + /// Memory accesses are performed in blocks (NUM_BLOCK_BYTES) with a fixed /// access delay (Num_ticks_per_block). class fixed_delay_memory_t : public ideal_memory_t { @@ -301,75 +301,75 @@ namespace patmos typedef std::vector requests_t; typedef std::map request_size_map_t; - + /// Memory access time per block in cycles. unsigned int Num_ticks_per_burst; /// Block transfer size unsigned int Num_bytes_per_burst; - + /// Enable posted writes. unsigned int Num_posted_writes; - + /// Number of initial read delay ticks. unsigned int Num_read_delay_ticks; - + /// Outstanding requests to the memory. requests_t Requests; private: // ------------- Statistics ------------- - + /// End address of last request uword_t Last_address; - + /// Last request was a load? bool Last_is_load; - + /// Maximum size of the queue unsigned Num_max_queue_size; - + /// Number of read requests uint64_t Num_reads; - + /// Number of write requests uint64_t Num_writes; - + /// Total number of bytes read uint64_t Num_bytes_read; - + /// Total number of bytes written uint64_t Num_bytes_written; - + /// Actual number of bytes transferred for reads uint64_t Num_bytes_read_transferred; /// Actual number of bytes transferred for writes uint64_t Num_bytes_write_transferred; - + /// Number of consecutive memory requests uint64_t Num_consecutive_requests; - + /// Number of cycles the memory interface was busy. uint64_t Num_busy_cycles; - + /// Number of cycles hidden by posted writes. uint64_t Num_posted_write_cycles; - + /// Track number of requests per request size. request_size_map_t Num_requests_per_size; - - protected: - virtual uword_t get_aligned_size(uword_t address, uword_t size, + + protected: + virtual uword_t get_aligned_size(uword_t address, uword_t size, uword_t &aligned_address); - + virtual unsigned int get_transfer_ticks(uword_t aligned_address, - uword_t aligned_size, bool is_load, + uword_t aligned_size, bool is_load, bool is_posted); - + /// Let one tick pass for the given request. virtual void tick_request(request_info_t &req); - + /// Find or create a request given an address, size, and load/store flag. /// @param address The address of the request. /// @param size The number of bytes request by the access. @@ -377,35 +377,35 @@ namespace patmos /// @param is_posted A flag indicating whether the store is posted or not. /// @return An existing or newly created request info object. /// \see request_info_t - const request_info_t &find_or_create_request(simulator_t &s, + const request_info_t &find_or_create_request(simulator_t &s, uword_t address, uword_t size, bool is_load, bool is_fetch, bool is_posted = false); - + public: /// Construct a new memory instance. /// @param memory_size The size of the memory in bytes. /// @param num_bytes_per_burst Memory block size. - /// @param num_posted_writes Enable posted writes, sets the max size + /// @param num_posted_writes Enable posted writes, sets the max size /// of the request queue. /// @param num_ticks_per_burst Memory access time per block in cycles. - /// @param Num_read_delay_ticks Number of ticks until a response to a + /// @param Num_read_delay_ticks Number of ticks until a response to a /// request is received fixed_delay_memory_t(unsigned int memory_size, unsigned int num_bytes_per_burst, unsigned int num_posted_writes, - unsigned int num_ticks_per_burst, + unsigned int num_ticks_per_burst, unsigned int num_read_delay_ticks, bool randomize, mem_check_e memchk) : ideal_memory_t(memory_size, randomize, memchk), Num_ticks_per_burst(num_ticks_per_burst), Num_bytes_per_burst(num_bytes_per_burst), Num_posted_writes(num_posted_writes), - Num_read_delay_ticks(num_read_delay_ticks), Last_address(0), + Num_read_delay_ticks(num_read_delay_ticks), Last_address(0), Last_is_load(false), Num_max_queue_size(0), Num_reads(0), Num_writes(0), Num_bytes_read(0), Num_bytes_written(0), - Num_bytes_read_transferred(0), Num_bytes_write_transferred(0), - Num_consecutive_requests(0), Num_busy_cycles(0), + Num_bytes_read_transferred(0), Num_bytes_write_transferred(0), + Num_consecutive_requests(0), Num_busy_cycles(0), Num_posted_write_cycles(0) { } @@ -440,9 +440,9 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); - + virtual void reset_stats(); }; @@ -451,47 +451,47 @@ namespace patmos { private: unsigned int Num_bytes_per_page; - + protected: virtual unsigned int get_transfer_ticks(uword_t aligned_address, - uword_t aligned_size, bool is_load, + uword_t aligned_size, bool is_load, bool is_posted); public: - variable_burst_memory_t(unsigned int memory_size, + variable_burst_memory_t(unsigned int memory_size, unsigned int num_min_bytes_per_burst, unsigned int num_bytes_per_page, unsigned int num_posted_writes, unsigned int num_min_ticks_per_burst, unsigned int num_read_delay_ticks, bool randomize, mem_check_e memchk) - : fixed_delay_memory_t(memory_size, num_min_bytes_per_burst, - num_posted_writes, + : fixed_delay_memory_t(memory_size, num_min_bytes_per_burst, + num_posted_writes, num_min_ticks_per_burst, num_read_delay_ticks, randomize, memchk), Num_bytes_per_page(num_bytes_per_page) {} }; - - class tdm_memory_t : public fixed_delay_memory_t + + class tdm_memory_t : public fixed_delay_memory_t { private: uword_t Round_length; - + uword_t Round_start; - + uword_t Round_counter; - + /// True if we are currently sending a request over the NOC bool Is_Transferring; - + protected: virtual unsigned int get_transfer_ticks(uword_t aligned_address, - uword_t aligned_size, bool is_load, + uword_t aligned_size, bool is_load, bool is_posted); virtual void tick_request(request_info_t &req); - + public: tdm_memory_t(unsigned int memory_size, unsigned int num_bytes_per_burst, unsigned int num_posted_writes, @@ -499,9 +499,9 @@ namespace patmos unsigned int cpu_id, unsigned int num_ticks_per_burst, unsigned int num_read_delay_ticks, - unsigned int num_refresh_ticks_per_round, + unsigned int num_refresh_ticks_per_round, bool randomize, mem_check_e memchk); - + virtual void tick(simulator_t &s); }; diff --git a/simulator/include/method-cache.h b/simulator/include/method-cache.h index 2513b4e9c..7b217845a 100755 --- a/simulator/include/method-cache.h +++ b/simulator/include/method-cache.h @@ -102,11 +102,11 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. /// @param symbols A mapping of addresses to symbols. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); - + virtual void reset_stats() {} - + virtual void flush_cache() {} }; @@ -127,25 +127,25 @@ namespace patmos public: /// Number of bytes transferred for this method. unsigned int Num_method_bytes; - + /// Number of blocks required for this method. unsigned int Num_blocks_allocated; - + /// Number of cache hits for the method. offset_stats_t Accesses; /// Minimum utilization of the cache entry for this method in words. float Min_utilization; - + /// Maximum utilization of the cache entry for this method in words. float Max_utilization; /// Keep track how often this method was evicted by some other method. eviction_stats_t Evictions; - + /// Initialize the method statistics. method_stats_info_t() : Num_method_bytes(0), Num_blocks_allocated(0), - Min_utilization(std::numeric_limits::max()), + Min_utilization(std::numeric_limits::max()), Max_utilization(0) { } @@ -183,10 +183,10 @@ namespace patmos uword_t Num_bytes; std::vector Utilization; - + /// Construct a method lru info object. All data is initialized to zero. /// @param instructions Pointer to the method's instructions. - method_info_t() + method_info_t() : Address(0), Num_blocks(0), Num_bytes(0) { } @@ -197,9 +197,9 @@ namespace patmos /// @param num_bytes The number of valid instruction bytes of the method. void update(uword_t address, uword_t num_blocks, uword_t num_bytes); - + void reset_utilization(); - + unsigned int get_utilized_bytes(); }; @@ -217,7 +217,7 @@ namespace patmos /// Maximum number of active functions allowed in the cache. unsigned int Num_max_methods; - + /// Currently active phase to fetch a method from memory. phase_e Phase; @@ -255,10 +255,10 @@ namespace patmos /// Number of bytes fetched from the cache. unsigned int Num_bytes_fetched; - + /// Maximum number of methods allocated in the cache. unsigned int Num_max_active_methods; - + /// Number of cache hits. unsigned int Num_hits; @@ -279,13 +279,13 @@ namespace patmos /// Number of bytes used in evicted methods. unsigned int Num_bytes_utilized; - + /// Total Number of blocks evicted but not immediately allocated. unsigned int Num_blocks_freed; - + /// Maximum number of blocks evicted but not immediately allocated. unsigned int Max_blocks_freed; - + /// Cache statistics of individual method. method_stats_t Method_stats; @@ -305,23 +305,23 @@ namespace patmos virtual size_t get_active_method() const; - void print_cache_state(simulator_t &s, std::ostream &dout, + void print_cache_state(simulator_t &s, std::ostream &dout, size_t active_method) const; - + void print_hit(simulator_t &s, std::ostream &dout, uword_t address) const; - + void print_miss(simulator_t &s, std::ostream &dout, uword_t address, - uword_t evicted_methods, uword_t evicted_blocks, + uword_t evicted_methods, uword_t evicted_blocks, uword_t blocks_freed, bool capacity_miss) const; - + enum eviction_type_e { EVICT_CAPACITY, EVICT_TAG, EVICT_FLUSH }; - + /// Evict a given method, updating the cache state, and various statics. /// Also updates the utilization stats. /// @param method The method to be evicted. /// @param new_method the address of the new method causing the eviction /// @param capacity_miss true if the method is evicted due to a capacity miss - void update_evict_stats(method_info_t &method, uword_t new_method, + void update_evict_stats(method_info_t &method, uword_t new_method, eviction_type_e type); bool read_function_size(simulator_t &s, word_t function_base, uword_t *result_size); @@ -331,17 +331,17 @@ namespace patmos uword_t get_num_blocks_for_bytes(uword_t num_bytes); uword_t get_transfer_start(uword_t address); - + uword_t get_transfer_size(); - + public: /// Construct an LRU-based method cache. /// @param memory The memory to fetch instructions from on a cache miss. /// @param num_blocks The size of the cache in blocks. /// @param num_block_bytes The size of a single block in bytes /// @param max_active_methods The max number of active methods - lru_method_cache_t(memory_t &memory, unsigned int num_blocks, - unsigned int num_block_bytes, + lru_method_cache_t(memory_t &memory, unsigned int num_blocks, + unsigned int num_block_bytes, unsigned int max_active_methods = 0); /// Initialize the cache before executing the first instruction. @@ -381,13 +381,13 @@ namespace patmos /// Print statistics to an output stream. /// @param os The output stream to print to. /// @param symbols A mapping of addresses to symbols. - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); virtual void reset_stats(); - + virtual void flush_cache(); - + /// free dynamically allocated cache memory. virtual ~lru_method_cache_t(); }; @@ -407,7 +407,7 @@ namespace patmos virtual bool lookup(simulator_t &s, uword_t address); virtual size_t get_active_method() const; - + public: /// Construct an FIFO-based method cache. @@ -415,10 +415,10 @@ namespace patmos /// @param num_blocks The size of the cache in blocks. /// @param num_block_bytes The size of a single block in bytes /// @param max_active_methods The max number of active methods - fifo_method_cache_t(memory_t &memory, unsigned int num_blocks, + fifo_method_cache_t(memory_t &memory, unsigned int num_blocks, unsigned int num_block_bytes, unsigned int max_active_methods = 0) : - lru_method_cache_t(memory, num_blocks, num_block_bytes, + lru_method_cache_t(memory, num_blocks, num_block_bytes, max_active_methods) { active_method = base_t::Num_blocks - 1; @@ -442,7 +442,7 @@ namespace patmos virtual bool fetch(simulator_t &s, uword_t base, uword_t address, word_t iw[2]); virtual void flush_cache(); - + }; } diff --git a/simulator/include/profiling.h b/simulator/include/profiling.h index 1894612c3..960dd1b07 100644 --- a/simulator/include/profiling.h +++ b/simulator/include/profiling.h @@ -46,7 +46,7 @@ namespace patmos { struct stats_options_t; - + /// Profiling information for functions. class profiling_t { @@ -68,7 +68,7 @@ namespace patmos uword_t entry; typedef std::map cycles_map_t; - + /// cycles_map - Map of function addr -> cycle count. cycles_map_t cycles_map; @@ -77,8 +77,8 @@ namespace patmos /// last_cycle - Value of the cycle counter on last update. uint64_t last_cycle; - - /// reset_cycle - Value of the cycle counter on last reset or + + /// reset_cycle - Value of the cycle counter on last reset or /// initialization. uint64_t reset_cycle; @@ -105,9 +105,9 @@ namespace patmos /// print - Print profiling information to a given stream, using /// given symbols. - std::ostream &print(std::ostream &os, symbol_map_t &sym, + std::ostream &print(std::ostream &os, symbol_map_t &sym, const stats_options_t& options) const; - + void reset_stats(uint64_t cycle); }; diff --git a/simulator/include/rtc.h b/simulator/include/rtc.h index ce01effce..9d972e5f7 100644 --- a/simulator/include/rtc.h +++ b/simulator/include/rtc.h @@ -56,28 +56,28 @@ namespace patmos // Frequency of the CPU in MHz. double Frequency; - + /// Latched high word of clock counter uword_t High_clock; - + /// Latched high word of usec counter uword_t High_usec; /// Remember the last usec value to trigger only when it changed uint64_t Last_usec; - + /// Latched low word of interrupt register value uword_t Low_interrupt_clock; - + /// Latched low word of usec interrupt register value uword_t Low_interrupt_usec; - + /// Cycle interrupt register value uint64_t Interrupt_clock; /// usec interrupt register value uint64_t Interrupt_usec; - + /// Print debug messages bool Enable_debug; public: @@ -87,7 +87,7 @@ namespace patmos Simulator(s), Frequency(frequency), High_clock(0), High_usec(0), Last_usec(0), Low_interrupt_clock(0), Low_interrupt_usec(0), - Interrupt_clock(std::numeric_limits::max()), + Interrupt_clock(std::numeric_limits::max()), Interrupt_usec(std::numeric_limits::max()), Enable_debug(false) { @@ -97,16 +97,16 @@ namespace patmos void enable_debug(bool debug) { Enable_debug = debug; } - + uint64_t getCycle() { return Simulator.Cycle; } - + uint64_t getUSec() { // TODO if Frequency == 0, use wall clock for usec return (uint64_t)((double)Simulator.Cycle / Frequency); } - + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size) { if (is_word_access(address, size, 0x00)) { // read latched high word of cycle counter @@ -141,9 +141,9 @@ namespace patmos // set the clock interrupt timer uword_t high_clock = get_word(value, size); Interrupt_clock = ((uint64_t)high_clock)<<32 | Low_interrupt_clock; - + if (Enable_debug) { - std::cerr << "*** RTC: Set next cycle interrupt to " << Interrupt_clock + std::cerr << "*** RTC: Set next cycle interrupt to " << Interrupt_clock << ", current cycle: " << getCycle() << "\n"; } } @@ -155,9 +155,9 @@ namespace patmos // set the usec interrupt timer uword_t high_usec = get_word(value, size); Interrupt_usec = ((uint64_t)high_usec)<<32 | Low_interrupt_usec; - + if (Enable_debug) { - std::cerr << "*** RTC: Set next usec interrupt to " << Interrupt_usec + std::cerr << "*** RTC: Set next usec interrupt to " << Interrupt_usec << ", current usec: " << getUSec() << ", cycle: " << getCycle() << "\n"; } } diff --git a/simulator/include/simulation-core.h b/simulator/include/simulation-core.h index 77b8bb382..4052d2d8c 100644 --- a/simulator/include/simulation-core.h +++ b/simulator/include/simulation-core.h @@ -68,8 +68,8 @@ namespace patmos /// Define the number of cycles for a single memory transfer. static const unsigned int NUM_MEMORY_TRANSFER_LATENCY = 21; - - /// Define the number of bytes in a block transferred on an access to the + + /// Define the number of bytes in a block transferred on an access to the /// global main memory. static const unsigned int NUM_MEMORY_BLOCK_BYTES = 16; @@ -90,10 +90,10 @@ namespace patmos /// Define the maximum number of methods that can be cached in the method cache. static const unsigned int NUM_METHOD_CACHE_MAX_METHODS = 16; - + /// Define the number of bytes in a block of the method cache. static const unsigned int NUM_METHOD_CACHE_BLOCK_BYTES = 8; - + /// General-purpose register holding the program's exit code when terminating. static const GPR_e GPR_EXIT_CODE_INDEX = r1; @@ -133,7 +133,7 @@ namespace patmos /// Number of times an instruction of the instruction class was retired /// (s.t. the predicate evaluated to false) unsigned int Num_discarded; - + void reset() { Num_fetched = Num_retired = Num_discarded = 0; } @@ -195,7 +195,7 @@ namespace patmos /// The next value for program counter register. uword_t nPC; - + /// Old value of the program counter, for debugging purposes only. uword_t Debug_last_PC; @@ -213,10 +213,10 @@ namespace patmos /// Signal to disable the IF stage. bool Disable_IF; - + /// Interrupt instruction instruction_t *Instr_INTR; - + /// Halt pseudo instruction. instruction_t *Instr_HALT; @@ -225,10 +225,10 @@ namespace patmos /// Keep track of delays for interrupt triggering unsigned int Delay_counter; - + /// If set to true, flush the pipeline and halt the simulation. bool Halt; - + /// Delay decoder when an interrupt has been executed int Exception_handling_counter; @@ -237,7 +237,7 @@ namespace patmos /// Cycle of the last reset_stats() call. uint64_t Stats_Start_Cycle; - + /// Debug accesses to those addresses. std::set Debug_mem_address; @@ -246,7 +246,7 @@ namespace patmos /// Instruction counter for trace analysis uint64_t Traced_instructions; - + /// Runtime statistics on all instructions, per pipeline instruction_stats_t Instruction_stats[NUM_SLOTS]; @@ -258,16 +258,16 @@ namespace patmos /// Number of NOPs executed uint64_t Num_NOPs; - + /// Profiling information for function profiling profiling_t Profiling; - /// Print the internal register state of the simulator to an output stream + /// Print the internal register state of the simulator to an output stream /// (excluding memories and caches) /// @param os An output stream. /// @param debug_fmt The selected output format. /// @param nopc skip printing cycles and PC - void print_registers(std::ostream &os, debug_format_e debug_fmt, + void print_registers(std::ostream &os, debug_format_e debug_fmt, bool nopc = false) const; /// Perform a step of the simulation for a given pipeline. @@ -294,13 +294,13 @@ namespace patmos /// itself or any following stage. bool is_stalling(Pipeline_t pst) const; - /// Halt the simulation. All instructions currently in flight will be + /// Halt the simulation. All instructions currently in flight will be /// completed first. void halt(); - + /// Check if the simulator has been requested to halt. bool is_halting() const; - + /// Track retiring instructions for stats. void track_retiring_instructions(); @@ -328,13 +328,13 @@ namespace patmos /// Flush all data caches when reaching the given program counter. void flush_caches_at(uword_t address) { Flush_Cache_PC = address; } - + /// Read a file containing watchpoints for the trace analysis. void read_watchpoint_file(std::string wpfilename); - - /// Print accesses to a + + /// Print accesses to a void debug_mem_address(uword_t address) { Debug_mem_address.insert(address); } - + /// Run the simulator. /// @param entry Initialize the method cache, PC, etc. to start execution /// from this entry address. @@ -376,7 +376,7 @@ namespace patmos /// Reset all simulation statistics. void reset_stats(); - + /// Flush all caches. void flush_caches(); }; diff --git a/simulator/include/stack-cache.h b/simulator/include/stack-cache.h index a456988da..7e44ee222 100755 --- a/simulator/include/stack-cache.h +++ b/simulator/include/stack-cache.h @@ -45,7 +45,7 @@ namespace patmos { class simulator_t; - + /// Base class for all stack cache implementations. class stack_cache_t : public memory_t { @@ -55,60 +55,60 @@ namespace patmos /// @param value The value to be written to the memory. /// @param size The number of bytes to write. virtual void write_peek(simulator_t &s, uword_t address, byte_t *value, uword_t size); - + /// Check if the memory is busy handling some request. /// @return False in case the memory is currently handling some request, /// otherwise true. virtual bool is_ready(); - + public: virtual ~stack_cache_t() {} - /// Prepare for reserveing a given number of bytes, and update the stack + /// Prepare for reserveing a given number of bytes, and update the stack /// pointers. /// @param size The number of bytes to be reserved. - /// @param stack_spill Reference to the current value of the stack spill + /// @param stack_spill Reference to the current value of the stack spill /// pointer (might be updated). /// @param stack_top Reference to the current value of the stack top /// pointer (might be updated). /// @return the number of bytes to be spilled. - virtual word_t prepare_reserve(simulator_t &s, uword_t size, + virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top) = 0; /// Prepare for freeing a given number of bytes on the stack, and update /// update the stack pointers. /// @param size The number of bytes to be freed. - /// @param stack_spill Reference to the current value of the stack spill + /// @param stack_spill Reference to the current value of the stack spill /// pointer (might be updated). /// @param stack_top Reference to the current value of the stack top /// pointer (might be updated). /// @return the number of bytes to be spilled or filled. - virtual word_t prepare_free(simulator_t &s, uword_t size, + virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top) = 0; - /// Prepare for ensuring that a given number of bytes are actually + /// Prepare for ensuring that a given number of bytes are actually /// on the stack, and update the stack pointers. /// @param size The number of bytes that have to be available. - /// @param stack_spill Reference to the current value of the stack spill + /// @param stack_spill Reference to the current value of the stack spill /// pointer (might be updated). /// @param stack_top Reference to the current value of the stack top /// pointer (might be updated). /// @return the number of bytes to be filled. - virtual word_t prepare_ensure(simulator_t &s, uword_t size, + virtual word_t prepare_ensure(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top) = 0; - /// Prepare for spilling the given number of bytes from the stack, and + /// Prepare for spilling the given number of bytes from the stack, and /// update the stack pointers. /// @param size The number of bytes that have to be spilled. - /// @param stack_spill Reference to the current value of the stack spill + /// @param stack_spill Reference to the current value of the stack spill /// pointer (might be updated). /// @param stack_top Reference to the current value of the stack top /// pointer (might be updated). - /// @return the number of bytes to be spilled. - virtual word_t prepare_spill(simulator_t &s, uword_t size, + /// @return the number of bytes to be spilled. + virtual word_t prepare_spill(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top) = 0; - + /// Reserve a given number of bytes, potentially spilling stack data to some /// memory. /// @param size The number of bytes to be reserved. @@ -171,18 +171,18 @@ namespace patmos public: ideal_stack_cache_t(memory_t &memory) : Memory(memory) {} - virtual word_t prepare_reserve(simulator_t &s, uword_t size, + virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - - virtual word_t prepare_free(simulator_t &s, uword_t size, + + virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - virtual word_t prepare_ensure(simulator_t &s, uword_t size, + virtual word_t prepare_ensure(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - virtual word_t prepare_spill(simulator_t &s, uword_t size, + virtual word_t prepare_spill(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - + virtual bool reserve(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top); @@ -194,8 +194,8 @@ namespace patmos virtual bool spill(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top); - - + + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size, bool is_fetch); virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); @@ -204,12 +204,12 @@ namespace patmos virtual void tick(simulator_t &s) {} - + /// Print the internal state of the stack cache to an output stream. /// @param os The output stream to print to. virtual void print(const simulator_t &s, std::ostream &os) const; - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options) {} virtual void reset_stats() {} @@ -227,14 +227,14 @@ namespace patmos /// Note that this can be different from $st when $st is set explicitly /// via MTS until the next STC instruction. uword_t stack_top; - + public: - proxy_stack_cache_t(memory_t& memory) - : ideal_stack_cache_t(memory), stack_top(0) + proxy_stack_cache_t(memory_t& memory) + : ideal_stack_cache_t(memory), stack_top(0) {} - + virtual bool reserve(simulator_t &s, uword_t size, word_t delta, - uword_t new_spill, uword_t new_top) + uword_t new_spill, uword_t new_top) { stack_top = new_top; return true; } virtual bool free(simulator_t &s, uword_t size, word_t delta, @@ -248,7 +248,7 @@ namespace patmos virtual bool spill(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top) { stack_top = new_top; return true; } - + virtual bool read(simulator_t &s, uword_t address, byte_t *value, uword_t size, bool is_fetch); virtual bool write(simulator_t &s, uword_t address, byte_t *value, uword_t size); @@ -256,7 +256,7 @@ namespace patmos virtual void read_peek(simulator_t &s, uword_t address, byte_t *value, uword_t size, bool is_fetch); }; - + /// A stack cache organized in blocks. /// The cache is organized in blocks (Num_blocks) each a fixed size in bytes /// Num_block_bytes. Spills and fills are performed automatically during the @@ -280,7 +280,7 @@ namespace patmos /// Size of blocks in bytes. unsigned int Num_block_bytes; - + /// Store currently ongoing transfer. phase_e Phase; @@ -339,24 +339,24 @@ namespace patmos /// Construct a block-based stack cache. /// @param memory The memory to spill/fill. /// @param num_blocks Size of the stack cache in blocks. - block_stack_cache_t(memory_t &memory, unsigned int num_blocks, + block_stack_cache_t(memory_t &memory, unsigned int num_blocks, unsigned int num_block_bytes); virtual ~block_stack_cache_t(); - - virtual word_t prepare_reserve(simulator_t &s, uword_t size, + + virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - - virtual word_t prepare_free(simulator_t &s, uword_t size, + + virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - virtual word_t prepare_ensure(simulator_t &s, uword_t size, + virtual word_t prepare_ensure(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - virtual word_t prepare_spill(simulator_t &s, uword_t size, + virtual word_t prepare_spill(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - + virtual bool reserve(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top); @@ -377,25 +377,25 @@ namespace patmos virtual void print(const simulator_t &s, std::ostream &os) const; - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); virtual void reset_stats(); }; - /// A stack cache generating only aligned memory transfers, given a - /// pre-defined block size, while preserving the impression that the stack - /// cache operates on blocks of 4 bytes (words) for the instruction set + /// A stack cache generating only aligned memory transfers, given a + /// pre-defined block size, while preserving the impression that the stack + /// cache operates on blocks of 4 bytes (words) for the instruction set /// architecture. - /// - /// The main idea is to reserve one block of the stack cache as a sort of - /// alignment buffer, reducing the effective size of the maximal reservable - /// space (which has to be respected by the compiler). This allows the stack + /// + /// The main idea is to reserve one block of the stack cache as a sort of + /// alignment buffer, reducing the effective size of the maximal reservable + /// space (which has to be respected by the compiler). This allows the stack /// cache to spill/fill entire blocks that are properly aligned. - /// + /// /// In addition, free instructions need some special care. Whenever the free - /// empties the stack cache a single block needs to be filled in order to - /// ensure proper alignment of the memory top pointer and matching content of + /// empties the stack cache a single block needs to be filled in order to + /// ensure proper alignment of the memory top pointer and matching content of /// the stack cache. class block_aligned_stack_cache_t : public block_stack_cache_t { @@ -406,52 +406,52 @@ namespace patmos /// Total number of words additionally transferred to main (spill) memory. unsigned int Num_words_spilled; - /// Maximal number of blocks additionally transferred to main at once + /// Maximal number of blocks additionally transferred to main at once /// (spill) memory. unsigned int Max_words_spilled; - /// Total number of words additionally transferred from main (fill) + /// Total number of words additionally transferred from main (fill) /// memory. unsigned int Num_words_filled; - /// Maximal number of blocks additionally transferred from main at once + /// Maximal number of blocks additionally transferred from main at once /// (fill) memory. unsigned int Max_words_filled; - /// Total number of words additionally transferred from main (free) + /// Total number of words additionally transferred from main (free) /// memory. unsigned int Num_words_free_filled; - /// Maximal number of blocks additionally transferred from main at once + /// Maximal number of blocks additionally transferred from main at once /// (fill) memory. unsigned int Max_words_free_filled; public: /// Construct an aligned block-based stack cache. /// @param memory The memory to spill/fill. /// @param num_blocks Size of the stack cache in blocks. - block_aligned_stack_cache_t(memory_t &memory, unsigned int num_blocks, + block_aligned_stack_cache_t(memory_t &memory, unsigned int num_blocks, unsigned int num_block_bytes); - /// Override the original prepare reserve function and align the stack + /// Override the original prepare reserve function and align the stack /// spill pointer / transfer size. - virtual word_t prepare_reserve(simulator_t &s, uword_t size, + virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); // Override the original prepare ensure function and align the stack spill // pointer / transfer size. - virtual word_t prepare_ensure(simulator_t &s, uword_t size, + virtual word_t prepare_ensure(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); // Override the original prepare free function and align the stack spill // pointer and potentially trigger a one-block fill. - virtual word_t prepare_free(simulator_t &s, uword_t size, + virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); // Behave as a normal free, but if needed execute a one-block fill. virtual bool free(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top); - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); void reset_stats(); @@ -459,47 +459,47 @@ namespace patmos class block_lazy_stack_cache_t : public block_stack_cache_t { - private: - /// Pointer relative to stack top stack tracking data that has been + private: + /// Pointer relative to stack top stack tracking data that has been /// modified. uword_t Lazy_pointer; /// Updated next value of the Lazy_pointer. /// \see Lazy_pointer uword_t Next_Lazy_pointer; - - /// Number of blocks that should be evicted but not spilled by the next + + /// Number of blocks that should be evicted but not spilled by the next /// reserve uword_t Num_blocks_to_evict; - - /// Statistic counter, measuring the number of blocks that were not + + /// Statistic counter, measuring the number of blocks that were not /// spilled due to lazy spilling. unsigned int Num_blocks_not_spilled; - - /// Statistic counter, measuring the maximum number of blocks that were + + /// Statistic counter, measuring the maximum number of blocks that were /// not spilled due to lazy spilling. - unsigned int Max_blocks_not_spilled; + unsigned int Max_blocks_not_spilled; public: /// Construct a lazy block-based stack cache. /// @param memory The memory to spill/fill. /// @param num_blocks Size of the stack cache in blocks. - block_lazy_stack_cache_t(memory_t &memory, unsigned int num_blocks, + block_lazy_stack_cache_t(memory_t &memory, unsigned int num_blocks, unsigned int num_block_bytes); - virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, + virtual word_t prepare_reserve(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); - - virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, + + virtual word_t prepare_free(simulator_t &s, uword_t size, uword_t &stack_spill, uword_t &stack_top); /// Free a given number of bytes on the stack. /// @param size The number of bytes to be freed. - /// @param delta The value returned by prepare, i.e., the number of bytes + /// @param delta The value returned by prepare, i.e., the number of bytes /// to be spilled or filled. /// @param new_spill The new value of the stack spill pointer. /// @param new_top The new value of the stack top pointer. - /// @return True when the stack space is actually freed in the cache, + /// @return True when the stack space is actually freed in the cache, /// false otherwise. virtual bool free(simulator_t &s, uword_t size, word_t delta, uword_t new_spill, uword_t new_top); @@ -520,7 +520,7 @@ namespace patmos virtual void print(const simulator_t &s, std::ostream &os) const; - virtual void print_stats(const simulator_t &s, std::ostream &os, + virtual void print_stats(const simulator_t &s, std::ostream &os, const stats_options_t& options); void reset_stats(); diff --git a/simulator/include/streams.h b/simulator/include/streams.h index 41353e482..4a2f10c6c 100644 --- a/simulator/include/streams.h +++ b/simulator/include/streams.h @@ -42,7 +42,7 @@ namespace patmos { - + template< class T > struct StandardStream { @@ -52,12 +52,12 @@ namespace patmos struct StandardStream< std::basic_istream > { static std::istream *stream() { return &std::cin; } - + static bool isIOStream(std::basic_istream *stream) { return stream == &std::cin; } }; - + template<> struct StandardStream< std::basic_ostream > { @@ -68,7 +68,7 @@ namespace patmos } }; - + /// Open a file stream, or use the given default. /// @param str File name or "-". /// @param default_stream A default stream. @@ -79,7 +79,7 @@ namespace patmos { if (str == "") return &default_stream; - else if (str == "-") + else if (str == "-") return StandardStream::stream(); else { diff --git a/simulator/include/symbol.h b/simulator/include/symbol.h index fbdc826b9..632aa9264 100644 --- a/simulator/include/symbol.h +++ b/simulator/include/symbol.h @@ -41,12 +41,10 @@ #include -#include - namespace patmos { class symbol_map_t; - + struct reloc_info_t { std::string SymA; // If not empty, the result of the relocation is A - B. @@ -61,33 +59,33 @@ namespace patmos unsigned Shift; // Relative to PC? bool Relative; - + reloc_info_t() : Addend(0), Size(0), Offset(0), Shift(0), Relative(false) {} - - void set_format(unsigned size, unsigned offset = 0, unsigned shift = 0, + + void set_format(unsigned size, unsigned offset = 0, unsigned shift = 0, bool relative = false) { - Size = size; - Offset = offset; - Shift = shift; - Relative = relative; + Size = size; + Offset = offset; + Shift = shift; + Relative = relative; } - - void set_PCRel_format(unsigned size) + + void set_PCRel_format(unsigned size) { set_format(size, 0, 2, true); } - + void set_word_format(unsigned size) { set_format(size, 0, 2, false); } - + bool get_value(symbol_map_t &symbols, word_t &value, word_t PC = 0) const; }; - - + + /// Symbol information, start address, size struct symbol_info_t { @@ -150,15 +148,15 @@ namespace patmos /// @param symbol the name of the symbol. /// @return True if the map contains at least one symbol with that name. bool contains(std::string symbol) const; - + /// Check if a symbol at a given address covers the given address, i.e, - /// if there is a symbol at address @symbol and @addess is in + /// if there is a symbol at address @symbol and @addess is in /// [@symbol,@symbol+@symbol.size) /// @param symbol an address of a symbol /// @param address the address to check /// @return True if the a symbol at @symbol has a size attribute and covers @address bool covers(word_t symbol, word_t address) const; - + /// Find a symbol given a specific address. /// \see print /// @param address The address for which symbol information should be @@ -169,7 +167,7 @@ namespace patmos /// Find an address by symbol name. /// @return -1 if not found, the address of the symbol otherwise. word_t find(std::string symbol) const; - + /// Print symbol information given a specific address to a stream. /// The symbol table is searched for the symbol covering the address and the /// name of the symbol is returned. In case labels of basic blocks within diff --git a/simulator/include/uart.h b/simulator/include/uart.h index 07042cf75..b65798cd8 100644 --- a/simulator/include/uart.h +++ b/simulator/include/uart.h @@ -60,7 +60,7 @@ namespace patmos std::istream &In_stream; /// Flag indicating whether the input stream is a tty. - /// When true, this disables the signaling of EOF when the stream's buffer + /// When true, this disables the signaling of EOF when the stream's buffer /// becomes empty. bool IsTTY; @@ -75,7 +75,7 @@ namespace patmos /// bit position of the transmit-ready bit (TRE). static const uword_t TRE = 0; - + protected: /// A simulated access to the UART's status register. /// @param value A pointer to a destination to store the value read from @@ -83,7 +83,7 @@ namespace patmos /// @return True when the data is available from the UART. virtual bool read_status(byte_t *value) { - // always accept data for transmission (TRE = 1), but data is only + // always accept data for transmission (TRE = 1), but data is only // available when there is something in the stream (DAV=0 or 1). // when the input stream reaches the end-of-file (EOF), signal a parity // error, i.e., PAE = 1. @@ -105,7 +105,7 @@ namespace patmos { return true; } - + /// A simulated access to the UART's data register. /// @param value A pointer to a destination to store the value read from /// the UART. @@ -115,7 +115,7 @@ namespace patmos In_stream.read(reinterpret_cast(value), sizeof(byte_t)); std::streamsize num = In_stream.gcount(); if (num == 0) return false; - + assert(num == sizeof(byte_t)); return true; } @@ -176,7 +176,7 @@ namespace patmos return true; } - /// A simulated access to a read port. Does not update the device state or + /// A simulated access to a read port. Does not update the device state or /// simulate timing, just reads the value. /// @param address The memory address to read from. /// @param value A pointer to a destination to store the value read from diff --git a/simulator/src/assembler.cc b/simulator/src/assembler.cc index 34da7755a..76a1a5eb8 100644 --- a/simulator/src/assembler.cc +++ b/simulator/src/assembler.cc @@ -35,8 +35,6 @@ // allows to write small test programs. // -// #define BOOST_SPIRIT_DEBUG 1 - #include "assembler.h" #include "binary-formats.h" #include "instruction.h" @@ -48,7 +46,6 @@ #include #include #include -#include namespace patmos { @@ -56,7 +53,7 @@ namespace patmos { reset(); } - + unsigned lexer_t::skip_space(unsigned position) { unsigned pos = position; while (pos < Line.size() && isspace(Line[pos])) { @@ -64,14 +61,14 @@ namespace patmos } return pos; } - + void lexer_t::reset() { Positions.clear(); Positions.push_back(skip_space(0)); Token = ""; - + } - + size_t lexer_t::pos() const { if (Positions.size() < 2) { return 0; @@ -79,34 +76,34 @@ namespace patmos return Positions[Positions.size() - 2]; } } - + bool lexer_t::get_value(word_t &value, bool negate) const { if (!is_digit()) return false; char *nptr; value = strtol(Token.c_str(), &nptr, 0); - + if (*nptr != '\0') { return false; } - + if (negate) { value = -value; } return true; } - + bool lexer_t::is_name() const { return !Token.empty() && is_name_start(Token[0]); } - + bool lexer_t::is_digit() const { return !Token.empty() && isdigit(Token[0]); } - - bool lexer_t::push_back(unsigned count) { - for (unsigned i = 0; i < count; i++) { + + bool lexer_t::push_back(unsigned count) { + for (unsigned i = 0; i < count; i++) { Positions.pop_back(); } Positions.pop_back(); @@ -117,8 +114,8 @@ namespace patmos } return true; } - - bool lexer_t::next() + + bool lexer_t::next() { if (end()) { return false; @@ -128,17 +125,17 @@ namespace patmos Positions.push_back(-1); return false; } - + unsigned pos = Positions.back(); - + size_t first = pos; size_t last = pos; - + // Eat a full word while (last < Line.size()) { char c = Line[last]; - - // TODO we could check here if we are parsing a name or a digit and + + // TODO we could check here if we are parsing a name or a digit and // throw an error on malformed numbers if (isalnum(c) || c == '.' || c == '_') { last++; @@ -146,52 +143,52 @@ namespace patmos break; } } - + // include at least one (special) character in the next token if (last == first) last++; // special handling of || separator as one token if (Line[first] == '|' && last < Line.size() && Line[last] == '|') last++; - + // go to the beginning of the next token Positions.push_back(skip_space(last)); - + Token = Line.substr(first, last - first); - + return true; } - + line_parser_t::line_parser_t(line_assembler_t &assembler, std::string line) : Lexer(line), Assembler(assembler) {} - - bool line_parser_t::parse_register_number(const std::string &name, - unsigned maxregs, + + bool line_parser_t::parse_register_number(const std::string &name, + unsigned maxregs, unsigned ®no) const { unsigned length = name.size(); if (length < 2 || length > 3) return false; if (!isdigit(name[1]) || (length == 3 && !isdigit(name[2]))) return false; - - // using scanf or atoi or strtol for a 2 digit number has quite some - // overhead and the error handling code to reject stuff like 'r+1z' + + // using scanf or atoi or strtol for a 2 digit number has quite some + // overhead and the error handling code to reject stuff like 'r+1z' // as valid name would be larger than a simple switch over all names. unsigned value = name[1] - '0'; if (length == 3) { value = value * 10 + (name[2] - '0'); } - + regno = value; - + return value < maxregs; } - + void line_parser_t::set_error(const std::string &msg) { Assembler.set_error(Lexer.pos(), msg); } - - bool line_parser_t::parse_expression(word_t &value, reloc_info_t &reloc, + + bool line_parser_t::parse_expression(word_t &value, reloc_info_t &reloc, bool require_paren) { bool has_paren = false; @@ -202,13 +199,13 @@ namespace patmos return false; } } - - if (Lexer.is_name()) { + + if (Lexer.is_name()) { reloc.SymA = Lexer.tok(); value = 0; } else { bool negate = match_token("-"); - + if (!Lexer.get_value(value, false)) { set_error("Error parsing number."); return false; @@ -224,16 +221,16 @@ namespace patmos } return !has_paren; } - + if (!reloc.SymA.empty()) { // TODO allow for 'SymA - SymB +|- Addend', 'SymA +|- Addend' - + if (Lexer.tok() == "-") { if (require_paren && !has_paren) { set_error("parenthesis required for expressions."); return false; } - + if (!Lexer.next()) { set_error("missing symbol or value."); return false; @@ -253,7 +250,7 @@ namespace patmos } } } - + if (has_paren) { if (Lexer.tok() == ")") { Lexer.next(); @@ -264,10 +261,10 @@ namespace patmos return false; } } - + return true; } - + bool line_parser_t::parse_GPR(GPR_e ®) { std::string name = Lexer.tok(); @@ -292,7 +289,7 @@ namespace patmos Lexer.next(); return true; } - + bool line_parser_t::parse_SPR(SPR_e ®) { std::string name = Lexer.tok(); @@ -327,7 +324,7 @@ namespace patmos Lexer.next(); return true; } - + bool line_parser_t::parse_PRR(PRR_e &pred, bool may_negate) { bool negated = false; @@ -366,7 +363,7 @@ namespace patmos Lexer.next(); return true; } - + bool line_parser_t::match_token(const std::string &tok) { if (Lexer.tok() == tok) { @@ -376,7 +373,7 @@ namespace patmos set_error(std::string("expected token '") + tok + "'"); return false; } - + bool line_parser_t::match_stmt_end() { // skip semicolon @@ -391,14 +388,14 @@ namespace patmos return false; } - - + + line_assembler_t::line_assembler_t() : NOP_ID(0), Error_pos(-1) { initialize(); } - - line_assembler_t::~line_assembler_t() + + line_assembler_t::~line_assembler_t() { } @@ -406,19 +403,19 @@ namespace patmos Error_pos = pos; Error_msg = msg; } - - void line_assembler_t::print_error(std::ostream &out, unsigned offset) + + void line_assembler_t::print_error(std::ostream &out, unsigned offset) { if (Error_pos < 0) return; - + for (unsigned i = 0; i < offset + Error_pos; i++) { out << " "; } out << "^ " << Error_msg << "\n"; } - - void line_assembler_t::initialize() - { + + void line_assembler_t::initialize() + { // initialization already done? if (!Instructions.empty()) return; @@ -463,7 +460,7 @@ namespace patmos #include "instructions.inc" } - + void line_assembler_t::add_relocation(unsigned index, reloc_info_t &reloc) { if (reloc.SymA.empty()) { @@ -471,17 +468,17 @@ namespace patmos } Relocations.push_back(std::pair(index, reloc)); } - - bool line_assembler_t::parse_instruction(line_parser_t &parser, - udword_t &encoded, - reloc_info_t &reloc, bool &is_long) + + bool line_assembler_t::parse_instruction(line_parser_t &parser, + udword_t &encoded, + reloc_info_t &reloc, bool &is_long) { lexer_t &lexer = parser.get_lexer(); - + instruction_data_t instr; instr.Address = Code.size() * 4; instr.Pred = p0; - + // parse guard // [ '(' ['!'] ')' ] if (lexer.tok() == "(") { @@ -489,7 +486,7 @@ namespace patmos parser.set_error("missing guard name."); return false; } - if (!parser.parse_PRR(instr.Pred, true)) { + if (!parser.parse_PRR(instr.Pred, true)) { return false; } if (lexer.tok() != ")") { @@ -501,7 +498,7 @@ namespace patmos return false; } } - + // parse instruction if (!lexer.is_name()) { parser.set_error("expect instruction opcode."); @@ -517,7 +514,7 @@ namespace patmos instr.OPS.ALUil.Rd = r0; instr.OPS.ALUil.Rs1 = r0; instr.OPS.ALUil.Imm2 = 0; - } + } else if (opcode == "halt") { skip_operands = true; opcode = "brcf"; @@ -525,22 +522,22 @@ namespace patmos instr.OPS.CFLrt.Rs1 = r0; instr.OPS.CFLrt.Rs2 = r0; } - + // get the instruction format, parse operands. instructions_t::iterator it = Instructions.find(opcode); if (it == Instructions.end()) { parser.set_error("unknown opcode."); return false; } - + lexer.next(); - + unsigned tokens = lexer.tokens(); - + // iterate over all instruction formats for the same mnemonic while (it != Instructions.end() && it->first == opcode) { binary_format_t *bfmt = it->second; - + if (!skip_operands) { if (!bfmt->parse_operands(parser, opcode, instr, reloc)) { // reset the lexer @@ -550,49 +547,49 @@ namespace patmos continue; } } - + is_long = bfmt->is_long(); - + encoded = bfmt->encode(opcode, instr); - + return true; } return false; } - + bool line_assembler_t::parse_line(const std::string &line, dword_t &iw) { // [