URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk
- from Rev 50 to Rev 51
- ↔ Reverse comparison
Rev 50 → Rev 51
/orpsocv2/bench/sysc/include/coff.h
0,0 → 1,458
|
/* This file is derived from the GAS 2.1.4 assembler control file. |
The GAS product is under the GNU Public License, version 2 or later. |
As such, this file is also under that license. |
|
If the file format changes in the COFF object, this file should be |
subsequently updated to reflect the changes. |
|
The actual loader module only uses a few of these structures. The full |
set is documented here because I received the full set. If you wish |
more information about COFF, then O'Reilly has a very excellent book. |
*/ |
|
|
#define E_SYMNMLEN 8 /* Number of characters in a symbol name */ |
#define E_FILNMLEN 14 /* Number of characters in a file name */ |
#define E_DIMNUM 4 /* Number of array dimensions in auxiliary entry */ |
|
/* |
* These defines are byte order independent. There is no alignment of fields |
* permitted in the structures. Therefore they are declared as characters |
* and the values loaded from the character positions. It also makes it |
* nice to have it "endian" independent. |
*/ |
#if !defined(WORDS_BIGENDIAN) |
/* Load a short int from the following tables with little-endian formats */ |
#define COFF_SHORT_L SWAP_ENDIAN_SHORT |
/* Load a long int from the following tables with little-endian formats */ |
#define COFF_LONG_L SWAP_ENDIAN_LONG |
/* Load a short int from the following tables with big-endian formats */ |
#define COFF_SHORT_H KEEP_ENDIAN_SHORT |
/* Load a long int from the following tables with big-endian formats */ |
#define COFF_LONG_H KEEP_ENDIAN_LONG |
#else |
#define COFF_SHORT_L KEEP_ENDIAN_SHORT |
#define COFF_LONG_L KEEP_ENDIAN_LONG |
#define COFF_SHORT_H SWAP_ENDIAN_SHORT |
#define COFF_LONG_H SWAP_ENDIAN_LONG |
#endif |
|
#define SWAP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\ |
((unsigned short)((unsigned char)ps[0])))) |
|
#define SWAP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\ |
((unsigned long)((unsigned char)ps[2])<<16) |\ |
((unsigned long)((unsigned char)ps[1])<<8) |\ |
((unsigned long)((unsigned char)ps[0]))))) |
|
#define KEEP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\ |
((unsigned short)((unsigned char)ps[1])))) |
|
#define KEEP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\ |
((unsigned long)((unsigned char)ps[1])<<16) |\ |
((unsigned long)((unsigned char)ps[2])<<8) |\ |
((unsigned long)((unsigned char)ps[3]))))) |
|
/* These may be overridden later by brain dead implementations which generate |
a big-endian header with little-endian data. In that case, generate a |
replacement macro which tests a flag and uses either of the two above |
as appropriate. */ |
|
#define COFF_LONG(v) COFF_LONG_L(v) |
#define COFF_SHORT(v) COFF_SHORT_L(v) |
|
/*** coff information for Intel 386/486. */ |
|
|
/* |
* Bits for f_flags: |
* |
* F_RELFLG relocation info stripped from file |
* F_EXEC file is executable (i.e. no unresolved external |
* references) |
* F_LNNO line numbers stripped from file |
* F_LSYMS local symbols stripped from file |
* F_MINMAL this is a minimal object file (".m") output of fextract |
* F_UPDATE this is a fully bound update file, output of ogen |
* F_SWABD this file has had its bytes swabbed (in names) |
* F_AR16WR this file has the byte ordering of an AR16WR |
* (e.g. 11/70) machine |
* F_AR32WR this file has the byte ordering of an AR32WR machine |
* (e.g. vax and iNTEL 386) |
* F_AR32W this file has the byte ordering of an AR32W machine |
* (e.g. 3b,maxi) |
* F_PATCH file contains "patch" list in optional header |
* F_NODF (minimal file only) no decision functions for |
* replaced functions |
*/ |
|
#define COFF_F_RELFLG 0000001 |
#define COFF_F_EXEC 0000002 |
#define COFF_F_LNNO 0000004 |
#define COFF_F_LSYMS 0000010 |
#define COFF_F_MINMAL 0000020 |
#define COFF_F_UPDATE 0000040 |
#define COFF_F_SWABD 0000100 |
#define COFF_F_AR16WR 0000200 |
#define COFF_F_AR32WR 0000400 |
#define COFF_F_AR32W 0001000 |
#define COFF_F_PATCH 0002000 |
#define COFF_F_NODF 0002000 |
|
#define COFF_I386MAGIC 0x14c /* Linux's system */ |
|
#if 0 /* Perhaps, someday, these formats may be used. */ |
#define COFF_I386PTXMAGIC 0x154 |
#define COFF_I386AIXMAGIC 0x175 /* IBM's AIX system */ |
#define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \ |
&& COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \ |
&& COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC) |
#else |
#define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC) |
#endif |
|
/********************** FILE HEADER **********************/ |
|
struct coff_filehdr |
{ |
char f_magic[2]; // magic number |
char f_nscns[2]; // number of sections |
char f_timdat[4]; // time & date stamp |
char f_symptr[4]; // file pointer to symtab |
char f_nsyms[4]; // number of symtab entries |
char f_opthdr[2]; // sizeof(optional hdr) |
char f_flags[2]; // flags |
}; |
|
#define COFF_FILHDR struct coff_filehdr |
#define COFF_FILHSZ sizeof(COFF_FILHDR) |
|
/********************** AOUT "OPTIONAL HEADER" **********************/ |
|
/* Linux COFF must have this "optional" header. Standard COFF has no entry |
location for the "entry" point. They normally would start with the first |
location of the .text section. This is not a good idea for linux. So, |
the use of this "optional" header is not optional. It is required. |
|
Do not be tempted to assume that the size of the optional header is |
a constant and simply index the next byte by the size of this structure. |
Use the 'f_opthdr' field in the main coff header for the size of the |
structure actually written to the file!! |
*/ |
|
//typedef struct |
struct COFF_aouthdr |
{ |
char magic[2]; /* type of file */ |
char vstamp[2]; /* version stamp */ |
char tsize[4]; /* text size in bytes, padded to FW bdry */ |
char dsize[4]; /* initialized data " " */ |
char bsize[4]; /* uninitialized data " " */ |
char entry[4]; /* entry pt. */ |
char text_start[4]; /* base of text used for this file */ |
char data_start[4]; /* base of data used for this file */ |
}; |
|
#define COFF_AOUTHDR COFF_aouthdr |
#define COFF_AOUTSZ (sizeof(COFF_AOUTHDR)) |
|
#define COFF_STMAGIC 0401 |
#define COFF_OMAGIC 0404 |
#define COFF_JMAGIC 0407 /* dirty text and data image, can't share */ |
#define COFF_DMAGIC 0410 /* dirty text segment, data aligned */ |
#define COFF_ZMAGIC 0413 /* The proper magic number for executables */ |
#define COFF_SHMAGIC 0443 /* shared library header */ |
|
/********************** STORAGE CLASSES **********************/ |
|
/* This used to be defined as -1, but now n_sclass is unsigned. */ |
#define C_EFCN 0xff /* physical end of function */ |
#define C_NULL 0 |
#define C_AUTO 1 /* automatic variable */ |
#define C_EXT 2 /* external symbol */ |
#define C_STAT 3 /* static */ |
#define C_REG 4 /* register variable */ |
#define C_EXTDEF 5 /* external definition */ |
#define C_LABEL 6 /* label */ |
#define C_ULABEL 7 /* undefined label */ |
#define C_MOS 8 /* member of structure */ |
#define C_ARG 9 /* function argument */ |
#define C_STRTAG 10 /* structure tag */ |
#define C_MOU 11 /* member of union */ |
#define C_UNTAG 12 /* union tag */ |
#define C_TPDEF 13 /* type definition */ |
#define C_USTATIC 14 /* undefined static */ |
#define C_ENTAG 15 /* enumeration tag */ |
#define C_MOE 16 /* member of enumeration */ |
#define C_REGPARM 17 /* register parameter */ |
#define C_FIELD 18 /* bit field */ |
#define C_AUTOARG 19 /* auto argument */ |
#define C_LASTENT 20 /* dummy entry (end of block) */ |
#define C_BLOCK 100 /* ".bb" or ".eb" */ |
#define C_FCN 101 /* ".bf" or ".ef" */ |
#define C_EOS 102 /* end of structure */ |
#define C_FILE 103 /* file name */ |
#define C_LINE 104 /* line # reformatted as symbol table entry */ |
#define C_ALIAS 105 /* duplicate tag */ |
#define C_HIDDEN 106 /* ext symbol in dmert public lib */ |
|
#define C_WEAKEXT 127 /* weak symbol -- GNU extension */ |
|
/* New storage classes for TI COFF */ |
#define C_UEXT 19 /* Tentative external definition */ |
#define C_STATLAB 20 /* Static load time label */ |
#define C_EXTLAB 21 /* External load time label */ |
#define C_SYSTEM 23 /* System Wide variable */ |
|
/* New storage classes for WINDOWS_NT */ |
#define C_SECTION 104 /* section name */ |
#define C_NT_WEAK 105 /* weak external */ |
|
/* New storage classes for 80960 */ |
|
/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ |
#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */ |
|
#define C_SCALL 107 /* Procedure reachable via system call */ |
#define C_LEAFEXT 108 /* External leaf */ |
#define C_LEAFSTAT 113 /* Static leaf */ |
#define C_OPTVAR 109 /* Optimized variable */ |
#define C_DEFINE 110 /* Preprocessor #define */ |
#define C_PRAGMA 111 /* Advice to compiler or linker */ |
#define C_SEGMENT 112 /* 80960 segment name */ |
|
/* Storage classes for m88k */ |
#define C_SHADOW 107 /* shadow symbol */ |
#define C_VERSION 108 /* coff version symbol */ |
|
/* New storage classes for RS/6000 */ |
#define C_HIDEXT 107 /* Un-named external symbol */ |
#define C_BINCL 108 /* Marks beginning of include file */ |
#define C_EINCL 109 /* Marks ending of include file */ |
|
/* storage classes for stab symbols for RS/6000 */ |
#define C_GSYM (0x80) |
#define C_LSYM (0x81) |
#define C_PSYM (0x82) |
#define C_RSYM (0x83) |
#define C_RPSYM (0x84) |
#define C_STSYM (0x85) |
#define C_TCSYM (0x86) |
#define C_BCOMM (0x87) |
#define C_ECOML (0x88) |
#define C_ECOMM (0x89) |
#define C_DECL (0x8c) |
#define C_ENTRY (0x8d) |
#define C_FUN (0x8e) |
#define C_BSTAT (0x8f) |
#define C_ESTAT (0x90) |
|
/* Storage classes for Thumb symbols */ |
#define C_THUMBEXT (128 + C_EXT) /* 130 */ |
#define C_THUMBSTAT (128 + C_STAT) /* 131 */ |
#define C_THUMBLABEL (128 + C_LABEL) /* 134 */ |
#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ |
#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ |
|
/********************** SECTION HEADER **********************/ |
|
struct COFF_scnhdr { |
char s_name[8]; /* section name */ |
char s_paddr[4]; /* physical address, aliased s_nlib */ |
char s_vaddr[4]; /* virtual address */ |
char s_size[4]; /* section size */ |
char s_scnptr[4]; /* file ptr to raw data for section */ |
char s_relptr[4]; /* file ptr to relocation */ |
char s_lnnoptr[4]; /* file ptr to line numbers */ |
char s_nreloc[2]; /* number of relocation entries */ |
char s_nlnno[2]; /* number of line number entries */ |
char s_flags[4]; /* flags */ |
}; |
|
#define COFF_SCNHDR struct COFF_scnhdr |
#define COFF_SCNHSZ sizeof(COFF_SCNHDR) |
|
/* |
* names of "special" sections |
*/ |
|
#define COFF_TEXT ".text" |
#define COFF_DATA ".data" |
#define COFF_BSS ".bss" |
#define COFF_COMMENT ".comment" |
#define COFF_LIB ".lib" |
|
#define COFF_SECT_TEXT 0 /* Section for instruction code */ |
#define COFF_SECT_DATA 1 /* Section for initialized globals */ |
#define COFF_SECT_BSS 2 /* Section for un-initialized globals */ |
#define COFF_SECT_REQD 3 /* Minimum number of sections for good file */ |
|
#define COFF_STYP_REG 0x00 /* regular segment */ |
#define COFF_STYP_DSECT 0x01 /* dummy segment */ |
#define COFF_STYP_NOLOAD 0x02 /* no-load segment */ |
#define COFF_STYP_GROUP 0x04 /* group segment */ |
#define COFF_STYP_PAD 0x08 /* .pad segment */ |
#define COFF_STYP_COPY 0x10 /* copy section */ |
#define COFF_STYP_TEXT 0x20 /* .text segment */ |
#define COFF_STYP_DATA 0x40 /* .data segment */ |
#define COFF_STYP_BSS 0x80 /* .bss segment */ |
#define COFF_STYP_INFO 0x200 /* .comment section */ |
#define COFF_STYP_OVER 0x400 /* overlay section */ |
#define COFF_STYP_LIB 0x800 /* library section */ |
|
/* |
* Shared libraries have the following section header in the data field for |
* each library. |
*/ |
|
struct COFF_slib { |
char sl_entsz[4]; /* Size of this entry */ |
char sl_pathndx[4]; /* size of the header field */ |
}; |
|
#define COFF_SLIBHD struct COFF_slib |
#define COFF_SLIBSZ sizeof(COFF_SLIBHD) |
|
/********************** LINE NUMBERS **********************/ |
|
/* 1 line number entry for every "breakpointable" source line in a section. |
* Line numbers are grouped on a per function basis; first entry in a function |
* grouping will have l_lnno = 0 and in place of physical address will be the |
* symbol table index of the function name. |
*/ |
|
struct COFF_lineno { |
union { |
char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ |
char l_paddr[4]; /* (physical) address of line number */ |
} l_addr; |
char l_lnno[2]; /* line number */ |
}; |
|
#define COFF_LINENO struct COFF_lineno |
#define COFF_LINESZ 6 |
|
/********************** SYMBOLS **********************/ |
|
#define COFF_E_SYMNMLEN 8 /* # characters in a short symbol name */ |
#define COFF_E_FILNMLEN 14 /* # characters in a file name */ |
#define COFF_E_DIMNUM 4 /* # array dimensions in auxiliary entry */ |
|
/* |
* All symbols and sections have the following definition |
*/ |
|
struct COFF_syment |
{ |
union { |
char e_name[E_SYMNMLEN]; /* Symbol name (first 8 characters) */ |
struct { |
char e_zeroes[4]; /* Leading zeros */ |
char e_offset[4]; /* Offset if this is a header section */ |
} e; |
} e; |
|
char e_value[4]; /* Value (address) of the segment */ |
char e_scnum[2]; /* Section number */ |
char e_type[2]; /* Type of section */ |
char e_sclass[1]; /* Loader class */ |
char e_numaux[1]; /* Number of auxiliary entries which follow */ |
}; |
|
#define COFF_N_BTMASK (0xf) /* Mask for important class bits */ |
#define COFF_N_TMASK (0x30) /* Mask for important type bits */ |
#define COFF_N_BTSHFT (4) /* # bits to shift class field */ |
#define COFF_N_TSHIFT (2) /* # bits to shift type field */ |
|
/* |
* Auxiliary entries because the main table is too limiting. |
*/ |
|
union COFF_auxent { |
|
/* |
* Debugger information |
*/ |
|
struct { |
char x_tagndx[4]; /* str, un, or enum tag indx */ |
union { |
struct { |
char x_lnno[2]; /* declaration line number */ |
char x_size[2]; /* str/union/array size */ |
} x_lnsz; |
char x_fsize[4]; /* size of function */ |
} x_misc; |
|
union { |
struct { /* if ISFCN, tag, or .bb */ |
char x_lnnoptr[4]; /* ptr to fcn line # */ |
char x_endndx[4]; /* entry ndx past block end */ |
} x_fcn; |
|
struct { /* if ISARY, up to 4 dimen. */ |
char x_dimen[E_DIMNUM][2]; |
} x_ary; |
} x_fcnary; |
|
char x_tvndx[2]; /* tv index */ |
} x_sym; |
|
/* |
* Source file names (debugger information) |
*/ |
|
union { |
char x_fname[E_FILNMLEN]; |
struct { |
char x_zeroes[4]; |
char x_offset[4]; |
} x_n; |
} x_file; |
|
/* |
* Section information |
*/ |
|
struct { |
char x_scnlen[4]; /* section length */ |
char x_nreloc[2]; /* # relocation entries */ |
char x_nlinno[2]; /* # line numbers */ |
} x_scn; |
|
/* |
* Transfer vector (branch table) |
*/ |
|
struct { |
char x_tvfill[4]; /* tv fill value */ |
char x_tvlen[2]; /* length of .tv */ |
char x_tvran[2][2]; /* tv range */ |
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */ |
}; |
|
#define COFF_SYMENT struct COFF_syment |
#define COFF_SYMESZ 18 |
#define COFF_AUXENT union COFF_auxent |
#define COFF_AUXESZ 18 |
|
#define COFF_ETEXT "etext" |
|
/********************** RELOCATION DIRECTIVES **********************/ |
|
struct COFF_reloc { |
char r_vaddr[4]; /* Virtual address of item */ |
char r_symndx[4]; /* Symbol index in the symtab */ |
char r_type[2]; /* Relocation type */ |
}; |
|
#define COFF_RELOC struct COFF_reloc |
#define COFF_RELSZ 10 |
|
#define COFF_DEF_DATA_SECTION_ALIGNMENT 4 |
#define COFF_DEF_BSS_SECTION_ALIGNMENT 4 |
#define COFF_DEF_TEXT_SECTION_ALIGNMENT 4 |
|
/* For new sections we haven't heard of before */ |
#define COFF_DEF_SECTION_ALIGNMENT 4 |
/orpsocv2/bench/sysc/include/Or1200MonitorSC.h
25,7 → 25,7
|
// ---------------------------------------------------------------------------- |
|
// $Id: Or1200MonitorSC.h 288 2009-02-03 15:08:00Z jeremy $ |
// $Id$ |
|
#ifndef OR1200_MONITOR_SC__H |
#define OR1200_MONITOR_SC__H |
36,8 → 36,8
#include "systemc.h" |
|
#include "OrpsocAccess.h" |
#include "MemoryLoad.h" |
|
|
//! Monitor for special l.nop instructions |
|
//! This class is based on the or1200_monitor.v of the Verilog test bench. It |
52,6 → 52,7
// Constructor |
Or1200MonitorSC (sc_core::sc_module_name name, |
OrpsocAccess *_accessor, |
MemoryLoad *_memoryload, |
int argc, |
char *argv[]); |
|
61,13 → 62,16
// Methods to setup and output state of processor to a file |
void displayState(); |
|
// Function to calculate performance of the sim |
// Methods to generate the call and return list during execution |
void callLog(); |
|
// Method to calculate performance of the sim |
void perfSummary(); |
|
// Print out the command-line switches for this module's options |
// Method to print out the command-line switches for this module's options |
void printSwitches(); |
|
// Print out the usage for each option |
// Method to print out the usage for each option |
void printUsage(); |
|
// The ports |
75,6 → 79,8
|
private: |
|
#define DEFAULT_PROF_FILE "sim.profile" |
|
// Special NOP instructions |
static const uint32_t NOP_NOP = 0x15000000; //!< Normal nop instruction |
static const uint32_t NOP_EXIT = 0x15000001; //!< End of simulation |
84,16 → 90,21
|
// Variables for processor status output |
ofstream statusFile; |
ofstream profileFile; |
int logging_enabled; |
int exit_perf_summary_enabled; |
int insn_count; |
long long cycle_count; |
|
// Time measurement variables - for calculating performance of the sim |
//! Time measurement variable - for calculating performance of the sim |
clock_t start; |
|
//! The accessor for the Orpsoc instance |
OrpsocAccess *accessor; |
|
//! The memory loading object |
MemoryLoad *memoryload; |
|
}; // Or1200MonitorSC () |
|
#endif // OR1200_MONITOR_SC__H |
/orpsocv2/bench/sysc/include/elf.h
0,0 → 1,447
#ifndef _LINUX_ELF_H |
#define _LINUX_ELF_H |
|
/*#if HAVE_CONFIG_H |
#include <config.h> |
#endif*/ |
|
#ifdef WORDS_BIGENDIAN |
#define ELF_SHORT_H |
#define ELF_LONG_H |
#else |
/* Load a short int from the following tables with big-endian formats */ |
#define ELF_SHORT_H(ps) ((((unsigned short)(ps) >> 8) & 0xff) |\ |
(((unsigned short)(ps) << 8) & 0xff00)) |
|
/* Load a long int from the following tables with big-endian formats */ |
#define ELF_LONG_H(ps) ((((unsigned long)(ps) >> 24) & 0xff) |\ |
(((unsigned long)(ps) >> 8) & 0xff00)|\ |
(((unsigned long)(ps) << 8) & 0xff0000)|\ |
(((unsigned long)(ps) << 24) & 0xff000000)) |
#endif |
|
#ifdef OR32_TYPES |
typedef uint32_t Elf32_Addr; |
typedef uint16_t Elf32_Half; |
typedef uint32_t Elf32_Off; |
typedef int32_t Elf32_Sword; |
typedef uint32_t Elf32_Word; |
#else |
typedef unsigned long Elf32_Addr; |
typedef unsigned short Elf32_Half; |
typedef unsigned long Elf32_Off; |
typedef long Elf32_Sword; |
typedef unsigned long Elf32_Word; |
#endif |
|
/* These constants are for the segment types stored in the image headers */ |
#define PT_NULL 0 |
#define PT_LOAD 1 |
#define PT_DYNAMIC 2 |
#define PT_INTERP 3 |
#define PT_NOTE 4 |
#define PT_SHLIB 5 |
#define PT_PHDR 6 |
#define PT_LOPROC 0x70000000 |
#define PT_HIPROC 0x7fffffff |
|
/* These constants define the different elf file types */ |
#define ET_NONE 0 |
#define ET_REL 1 |
#define ET_EXEC 2 |
#define ET_DYN 3 |
#define ET_CORE 4 |
#define ET_LOPROC 5 |
#define ET_HIPROC 6 |
|
/* These constants define the various ELF target machines */ |
#define EM_NONE 0 |
#define EM_M32 1 |
#define EM_SPARC 2 |
#define EM_386 3 |
#define EM_68K 4 |
#define EM_88K 5 |
#define EM_486 6 /* Perhaps disused */ |
#define EM_860 7 |
|
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ |
|
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ |
|
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ |
|
#define EM_PARISC 15 /* HPPA */ |
|
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ |
|
#define EM_PPC 20 /* PowerPC */ |
|
/* |
* This is an interim value that we will use until the committee comes |
* up with a final number. |
*/ |
#define EM_ALPHA 0x9026 |
|
|
/* This is the info that is needed to parse the dynamic section of the file */ |
#define DT_NULL 0 |
#define DT_NEEDED 1 |
#define DT_PLTRELSZ 2 |
#define DT_PLTGOT 3 |
#define DT_HASH 4 |
#define DT_STRTAB 5 |
#define DT_SYMTAB 6 |
#define DT_RELA 7 |
#define DT_RELASZ 8 |
#define DT_RELAENT 9 |
#define DT_STRSZ 10 |
#define DT_SYMENT 11 |
#define DT_INIT 12 |
#define DT_FINI 13 |
#define DT_SONAME 14 |
#define DT_RPATH 15 |
#define DT_SYMBOLIC 16 |
#define DT_REL 17 |
#define DT_RELSZ 18 |
#define DT_RELENT 19 |
#define DT_PLTREL 20 |
#define DT_DEBUG 21 |
#define DT_TEXTREL 22 |
#define DT_JMPREL 23 |
#define DT_LOPROC 0x70000000 |
#define DT_HIPROC 0x7fffffff |
|
/* This info is needed when parsing the symbol table */ |
#define STB_LOCAL 0 |
#define STB_GLOBAL 1 |
#define STB_WEAK 2 |
|
#define STT_NOTYPE 0 |
#define STT_OBJECT 1 |
#define STT_FUNC 2 |
#define STT_SECTION 3 |
#define STT_FILE 4 |
|
#define ELF32_ST_BIND(x) ((x) >> 4) |
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) |
|
/* Symbolic values for the entries in the auxiliary table |
put on the initial stack */ |
#define AT_NULL 0 /* end of vector */ |
#define AT_IGNORE 1 /* entry should be ignored */ |
#define AT_EXECFD 2 /* file descriptor of program */ |
#define AT_PHDR 3 /* program headers for program */ |
#define AT_PHENT 4 /* size of program header entry */ |
#define AT_PHNUM 5 /* number of program headers */ |
#define AT_PAGESZ 6 /* system page size */ |
#define AT_BASE 7 /* base address of interpreter */ |
#define AT_FLAGS 8 /* flags */ |
#define AT_ENTRY 9 /* entry point of program */ |
#define AT_NOTELF 10 /* program is not ELF */ |
#define AT_UID 11 /* real uid */ |
#define AT_EUID 12 /* effective uid */ |
#define AT_GID 13 /* real gid */ |
#define AT_EGID 14 /* effective gid */ |
|
|
typedef struct dynamic{ |
Elf32_Sword d_tag; |
union{ |
Elf32_Sword d_val; |
Elf32_Addr d_ptr; |
} d_un; |
} Elf32_Dyn; |
|
typedef struct { |
unsigned long long d_tag; /* entry tag value */ |
union { |
unsigned long long d_val; |
unsigned long long d_ptr; |
} d_un; |
} Elf64_Dyn; |
|
/* The following are used with relocations */ |
#define ELF32_R_SYM(x) ((x) >> 8) |
#define ELF32_R_TYPE(x) ((x) & 0xff) |
|
#define R_386_NONE 0 |
#define R_386_32 1 |
#define R_386_PC32 2 |
#define R_386_GOT32 3 |
#define R_386_PLT32 4 |
#define R_386_COPY 5 |
#define R_386_GLOB_DAT 6 |
#define R_386_JMP_SLOT 7 |
#define R_386_RELATIVE 8 |
#define R_386_GOTOFF 9 |
#define R_386_GOTPC 10 |
#define R_386_NUM 11 |
|
#define R_68K_NONE 0 |
#define R_68K_32 1 |
#define R_68K_16 2 |
#define R_68K_8 3 |
#define R_68K_PC32 4 |
#define R_68K_PC16 5 |
#define R_68K_PC8 6 |
#define R_68K_GOT32 7 |
#define R_68K_GOT16 8 |
#define R_68K_GOT8 9 |
#define R_68K_GOT32O 10 |
#define R_68K_GOT16O 11 |
#define R_68K_GOT8O 12 |
#define R_68K_PLT32 13 |
#define R_68K_PLT16 14 |
#define R_68K_PLT8 15 |
#define R_68K_PLT32O 16 |
#define R_68K_PLT16O 17 |
#define R_68K_PLT8O 18 |
#define R_68K_COPY 19 |
#define R_68K_GLOB_DAT 20 |
#define R_68K_JMP_SLOT 21 |
#define R_68K_RELATIVE 22 |
|
typedef struct elf32_rel { |
Elf32_Addr r_offset; |
Elf32_Word r_info; |
} Elf32_Rel; |
|
typedef struct elf64_rel { |
unsigned long long r_offset; /* Location at which to apply the action */ |
unsigned long long r_info; /* index and type of relocation */ |
} Elf64_Rel; |
|
typedef struct elf32_rela{ |
Elf32_Addr r_offset; |
Elf32_Word r_info; |
Elf32_Sword r_addend; |
} Elf32_Rela; |
|
typedef struct elf64_rela { |
unsigned long long r_offset; /* Location at which to apply the action */ |
unsigned long long r_info; /* index and type of relocation */ |
unsigned long long r_addend; /* Constant addend used to compute value */ |
} Elf64_Rela; |
|
typedef struct elf32_sym{ |
Elf32_Word st_name; |
Elf32_Addr st_value; |
Elf32_Word st_size; |
unsigned char st_info; |
unsigned char st_other; |
Elf32_Half st_shndx; |
} Elf32_Sym; |
|
typedef struct elf64_sym { |
unsigned int st_name; /* Symbol name, index in string tbl */ |
unsigned char st_info; /* Type and binding attributes */ |
unsigned char st_other; /* No defined meaning, 0 */ |
unsigned short st_shndx; /* Associated section index */ |
unsigned long long st_value; /* Value of the symbol */ |
unsigned long long st_size; /* Associated symbol size */ |
} Elf64_Sym; |
|
|
#define EI_NIDENT 16 |
|
typedef struct elf32_hdr{ |
unsigned char e_ident[EI_NIDENT]; |
Elf32_Half e_type; |
Elf32_Half e_machine; |
Elf32_Word e_version; |
Elf32_Addr e_entry; /* Entry point */ |
Elf32_Off e_phoff; |
Elf32_Off e_shoff; |
Elf32_Word e_flags; |
Elf32_Half e_ehsize; |
Elf32_Half e_phentsize; |
Elf32_Half e_phnum; |
Elf32_Half e_shentsize; |
Elf32_Half e_shnum; |
Elf32_Half e_shstrndx; |
} Elf32_Ehdr; |
|
typedef struct elf64_hdr { |
unsigned char e_ident[16]; /* ELF "magic number" */ |
short int e_type; |
short unsigned int e_machine; |
int e_version; |
unsigned long long e_entry; /* Entry point virtual address */ |
unsigned long long e_phoff; /* Program header table file offset */ |
unsigned long long e_shoff; /* Section header table file offset */ |
int e_flags; |
short int e_ehsize; |
short int e_phentsize; |
short int e_phnum; |
short int e_shentsize; |
short int e_shnum; |
short int e_shstrndx; |
} Elf64_Ehdr; |
|
/* These constants define the permissions on sections in the program |
header, p_flags. */ |
#define PF_R 0x4 |
#define PF_W 0x2 |
#define PF_X 0x1 |
|
typedef struct elf32_phdr{ |
Elf32_Word p_type; |
Elf32_Off p_offset; |
Elf32_Addr p_vaddr; |
Elf32_Addr p_paddr; |
Elf32_Word p_filesz; |
Elf32_Word p_memsz; |
Elf32_Word p_flags; |
Elf32_Word p_align; |
} Elf32_Phdr; |
|
typedef struct elf64_phdr { |
int p_type; |
int p_flags; |
unsigned long long p_offset; /* Segment file offset */ |
unsigned long long p_vaddr; /* Segment virtual address */ |
unsigned long long p_paddr; /* Segment physical address */ |
unsigned long long p_filesz; /* Segment size in file */ |
unsigned long long p_memsz; /* Segment size in memory */ |
unsigned long long p_align; /* Segment alignment, file & memory */ |
} Elf64_Phdr; |
|
/* sh_type */ |
#define SHT_NULL 0 |
#define SHT_PROGBITS 1 |
#define SHT_SYMTAB 2 |
#define SHT_STRTAB 3 |
#define SHT_RELA 4 |
#define SHT_HASH 5 |
#define SHT_DYNAMIC 6 |
#define SHT_NOTE 7 |
#define SHT_NOBITS 8 |
#define SHT_REL 9 |
#define SHT_SHLIB 10 |
#define SHT_DYNSYM 11 |
#define SHT_NUM 12 |
#define SHT_LOPROC 0x70000000 |
#define SHT_HIPROC 0x7fffffff |
#define SHT_LOUSER 0x80000000 |
#define SHT_HIUSER 0xffffffff |
|
/* sh_flags */ |
#define SHF_WRITE 0x1 |
#define SHF_ALLOC 0x2 |
#define SHF_EXECINSTR 0x4 |
#define SHF_MASKPROC 0xf0000000 |
|
/* special section indexes */ |
#define SHN_UNDEF 0 |
#define SHN_LORESERVE 0xff00 |
#define SHN_LOPROC 0xff00 |
#define SHN_HIPROC 0xff1f |
#define SHN_ABS 0xfff1 |
#define SHN_COMMON 0xfff2 |
#define SHN_HIRESERVE 0xffff |
|
typedef struct elf32_shdr { |
Elf32_Word sh_name; |
Elf32_Word sh_type; |
Elf32_Word sh_flags; |
Elf32_Addr sh_addr; |
Elf32_Off sh_offset; |
Elf32_Word sh_size; |
Elf32_Word sh_link; |
Elf32_Word sh_info; |
Elf32_Word sh_addralign; |
Elf32_Word sh_entsize; |
} Elf32_Shdr; |
|
typedef struct elf64_shdr { |
unsigned int sh_name; /* Section name, index in string tbl */ |
unsigned int sh_type; /* Type of section */ |
unsigned long long sh_flags; /* Miscellaneous section attributes */ |
unsigned long long sh_addr; /* Section virtual addr at execution */ |
unsigned long long sh_offset; /* Section file offset */ |
unsigned long long sh_size; /* Size of section in bytes */ |
unsigned int sh_link; /* Index of another section */ |
unsigned int sh_info; /* Additional section information */ |
unsigned long long sh_addralign; /* Section alignment */ |
unsigned long long sh_entsize; /* Entry size if section holds table */ |
} Elf64_Shdr; |
|
#define EI_MAG0 0 /* e_ident[] indexes */ |
#define EI_MAG1 1 |
#define EI_MAG2 2 |
#define EI_MAG3 3 |
#define EI_CLASS 4 |
#define EI_DATA 5 |
#define EI_VERSION 6 |
#define EI_PAD 7 |
|
#define ELFMAG0 0x7f /* EI_MAG */ |
#define ELFMAG1 'E' |
#define ELFMAG2 'L' |
#define ELFMAG3 'F' |
#define ELFMAG "\177ELF" |
#define SELFMAG 4 |
|
#define ELFCLASSNONE 0 /* EI_CLASS */ |
#define ELFCLASS32 1 |
#define ELFCLASS64 2 |
#define ELFCLASSNUM 3 |
|
#define ELFDATANONE 0 /* e_ident[EI_DATA] */ |
#define ELFDATA2LSB 1 |
#define ELFDATA2MSB 2 |
|
#define EV_NONE 0 /* e_version, EI_VERSION */ |
#define EV_CURRENT 1 |
#define EV_NUM 2 |
|
/* Notes used in ET_CORE */ |
#define NT_PRSTATUS 1 |
#define NT_PRFPREG 2 |
#define NT_PRPSINFO 3 |
#define NT_TASKSTRUCT 4 |
|
/* Note header in a PT_NOTE section */ |
typedef struct elf32_note { |
Elf32_Word n_namesz; /* Name size */ |
Elf32_Word n_descsz; /* Content size */ |
Elf32_Word n_type; /* Content type */ |
} Elf32_Nhdr; |
|
/* Note header in a PT_NOTE section */ |
/* |
* For now we use the 32 bit version of the structure until we figure |
* out whether we need anything better. Note - on the Alpha, "unsigned int" |
* is only 32 bits. |
*/ |
typedef struct elf64_note { |
unsigned int n_namesz; /* Name size */ |
unsigned int n_descsz; /* Content size */ |
unsigned int n_type; /* Content type */ |
} Elf64_Nhdr; |
|
#ifdef __mc68000__ |
#define ELF_START_MMAP 0xC0000000 |
#endif |
#ifdef __i386__ |
#define ELF_START_MMAP 0x80000000 |
#endif |
|
#if ELF_CLASS == ELFCLASS32 |
|
extern Elf32_Dyn _DYNAMIC []; |
#define elfhdr elf32_hdr |
#define elf_phdr elf32_phdr |
#define elf_note elf32_note |
|
#else |
|
extern Elf64_Dyn _DYNAMIC []; |
#define elfhdr elf64_hdr |
#define elf_phdr elf64_phdr |
#define elf_note elf64_note |
|
#endif |
|
|
#endif /* _LINUX_ELF_H */ |
/orpsocv2/bench/sysc/include/OrpsocAccess.h
38,6 → 38,7
class Vorpsoc_top_or1200_except; |
class Vorpsoc_top_or1200_sprs; |
class Vorpsoc_top_or1200_dpram; |
class Vorpsoc_top_ram_wb_sc_sw__D20_A18_M800000; |
|
|
//! Access functions to the Verilator model |
53,13 → 54,17
OrpsocAccess (Vorpsoc_top *orpsoc_top); |
|
// Accessor functions |
bool getExFreeze (); |
bool getWbFreeze (); |
uint32_t getWbInsn (); |
uint32_t getIdInsn (); |
uint32_t getExInsn (); |
uint32_t getWbPC (); |
uint32_t getIdPC (); |
uint32_t getExPC (); |
bool getExceptFlushpipe (); |
bool getExDslot (); |
uint32_t getExceptType(); |
// Get a specific GPR from the register file |
uint32_t getGpr (uint32_t regNum); |
//SPR accessessors |
68,6 → 73,12
uint32_t getSprEear (); |
uint32_t getSprEsr (); |
|
// Wishbone SRAM accessor functions |
uint32_t get_mem (uint32_t addr); |
void set_mem (uint32_t addr, uint32_t data); |
// Trigger a $readmemh for the RAM array |
void do_ram_readmemh (void); |
|
private: |
|
// Pointers to modules with accessor functions |
75,6 → 86,7
Vorpsoc_top_or1200_except *or1200_except; |
Vorpsoc_top_or1200_sprs *or1200_sprs; |
Vorpsoc_top_or1200_dpram *rf_a; |
/*Vorpsoc_top_ram_wb_sc_sw*/Vorpsoc_top_ram_wb_sc_sw__D20_A18_M800000 *ram_wb_sc_sw; |
|
}; // OrpsocAccess () |
|
/orpsocv2/bench/sysc/include/MemoryLoad.h
0,0 → 1,203
/* MemoryLoad.h -- Header file for parse.c |
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
Copyright (C) 2008 Embecosm Limited |
Copyright (C) 2009 Julius Baxter, julius@orsoc.se |
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
|
This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. |
|
This program is free software; you can redistribute it and/or modify it |
under the terms of the GNU General Public License as published by the Free |
Software Foundation; either version 3 of the License, or (at your option) |
any later version. |
|
This program is distributed in the hope that it will be useful, but WITHOUT |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
more details. |
|
You should have received a copy of the GNU General Public License along |
with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* Here we define some often used caharcters in assembly files. This wil |
probably go into architecture dependent directory. */ |
|
|
#ifndef MEMORYLOAD__H |
#define MEMORYLOAD__H |
|
/* Package includes */ |
//#include "sim-config.h" |
#include <stdint.h> |
|
#include "coff.h" |
#include "elf.h" |
|
#include "OrpsocAccess.h" |
|
//#define PRINTF(x...) fprintf(stdout,x) |
#define PRINTF(x...) |
|
/* Basic types for openrisc */ |
typedef uint32_t oraddr_t; /*!< Address as addressed by openrisc */ |
typedef uint32_t uorreg_t; /*!< An unsigned register of openrisc */ |
typedef int32_t orreg_t; /*!< A signed register of openrisc */ |
|
/* From abstract.h */ |
#define DEFAULT_MEMORY_START 0 |
#define DEFAULT_MEMORY_LEN 0x800000 |
#define STACK_SIZE 20 |
#define LABELNAME_LEN 50 |
#define INSNAME_LEN 15 |
#define OPERANDNAME_LEN 50 |
#define MAX_OPERANDS 5 |
|
#define OP_MEM_ACCESS 0x80000000 |
|
/* Cache tag types. */ |
#define CT_NONE 0 |
#define CT_VIRTUAL 1 |
#define CT_PHYSICAL 2 |
|
/* History of execution */ |
#define HISTEXEC_LEN 200 |
|
/* Added by MM */ |
#ifndef LONGEST |
#define LONGEST long long |
#endif /* LONGEST */ |
|
#ifndef ULONGEST |
#define ULONGEST unsigned long long |
#endif /* ULONGEST */ |
|
|
|
#define PRIx32 "x" |
#define PRIx16 "hx" |
#define PRIx8 "hhx" |
#define PRId32 "d" |
|
/* Strings for printing OpenRISC types */ |
#define PRIxADDR "08" PRIx32 /*!< print an openrisc address in hex */ |
#define PRIxREG "08" PRIx32 /*!< print an openrisc register in hex */ |
#define PRIdREG PRId32 /*!< print an openrisc register in decimals */ |
|
/* Endianness convenience macros */ |
#define LE16(x) bswap_16(x) |
|
/*! Instruction queue */ |
struct iqueue_entry |
{ |
int insn_index; |
uint32_t insn; |
oraddr_t insn_addr; |
}; |
|
/*! Structure for holding one label per particular memory location */ |
struct label_entry |
{ |
char *name; |
oraddr_t addr; |
struct label_entry *next; |
}; |
|
/* from arch sim cpu/or1k/opcode/or32.h */ |
#define MAX_GPRS 32 |
#define PAGE_SIZE 8192 |
|
|
|
class MemoryLoad |
{ |
public: |
|
// Constructor |
MemoryLoad(OrpsocAccess *_accessor); |
|
// Label access function |
struct label_entry* get_label (oraddr_t addr); |
|
uint32_t loadcode (char *filename, |
oraddr_t startaddr, |
oraddr_t virtphy_transl); |
|
|
private: |
|
//! The accessor for the Orpsoc instance |
OrpsocAccess *accessor; |
|
#define MEMORY_LEN 0x100000000ULL |
|
/*!Whether to do immediate statistics. This seems to be for local debugging |
of parse.c */ |
#define IMM_STATS 0 |
|
/*!Unused mem memory marker. It is used when allocating program and data |
memory during parsing */ |
unsigned int freemem; |
|
/*!Translation table provided by microkernel. Only used if simulating |
microkernel. */ |
oraddr_t transl_table; |
|
/*!Used to signal whether during loading of programs a translation fault |
occured. */ |
uint32_t transl_error; |
|
#if IMM_STATS |
int bcnt[33][3] = { 0 }; |
int bsum[3] = { 0 }; |
uint32_t movhi = 0; |
#endif /* IMM_STATS */ |
|
// A large number, for the Linux kernel (~8000 functions) |
#define LABELS_HASH_SIZE 10000 |
/* Local list of labels (symbols) */ |
struct label_entry *label_hash[LABELS_HASH_SIZE]; |
|
|
/* Function prototypes for external use */ |
char *strstrip (char *dst, |
const char *src, |
int n); |
|
oraddr_t translate (oraddr_t laddr, |
int *breakpoint); |
|
|
int bits (uint32_t val); |
|
void check_insn (uint32_t insn); |
|
void addprogram (oraddr_t address, |
uint32_t insn, |
int *breakpoint); |
|
void readfile_coff (char *filename, |
short sections); |
|
void readsyms_coff (char *filename, |
uint32_t symptr, |
uint32_t syms); |
|
void readfile_elf (char *filename); |
|
void identifyfile (char *filename); |
|
void init_labels (); |
|
void add_label (oraddr_t addr, char *name); |
|
struct label_entry* find_label (char *name); |
oraddr_t eval_label (char *name); |
|
|
|
|
}; |
|
#endif /* MEMORYLOAD__H */ |
/orpsocv2/bench/sysc/src/Or1200MonitorSC.cpp
46,10 → 46,12
|
Or1200MonitorSC::Or1200MonitorSC (sc_core::sc_module_name name, |
OrpsocAccess *_accessor, |
MemoryLoad *_memoryload, |
int argc, |
char *argv[]) : |
sc_module (name), |
accessor (_accessor) |
accessor (_accessor), |
memoryload(_memoryload) |
{ |
|
// If not -log option, then don't log |
56,6 → 58,10
|
string logfileDefault("vlt-executed.log"); |
string logfileNameString; |
int profiling_enabled = 0; |
string profileFileName(DEFAULT_PROF_FILE); |
insn_count=0; |
cycle_count=0; |
|
exit_perf_summary_enabled = 1; // Simulation exit performance summary is |
// on by default. Turn off with "-q" on the cmd line |
72,23 → 78,44
{ |
logfileNameString = (argv[i+1]); |
cmdline_name_found=1; |
break; |
} |
} |
// Search through the command line parameters for the "-q","--no-perf-summary" option |
for(int i=1; i < argc; i++) |
{ |
if ((strcmp(argv[i], "-q")==0) || |
(strcmp(argv[i], "--quiet")==0)) |
else if ((strcmp(argv[i], "-q")==0) || |
(strcmp(argv[i], "--quiet")==0)) |
{ |
exit_perf_summary_enabled = 0; |
break; |
} |
else if ((strcmp(argv[i], "-p")==0) || |
(strcmp(argv[i], "--profile")==0)) |
{ |
profiling_enabled = 1; |
// Check for !end of command line and it's not a command |
if ((i+1 < argc)){ |
if(argv[i+1][0] != '-') |
profileFileName = (argv[i+1]); |
} |
} |
} |
} |
|
|
if (profiling_enabled) |
{ |
profileFile.open(profileFileName.c_str(), ios::out); // Open profiling log file |
if(profileFile.is_open()) |
{ |
// If the file was opened OK, then enabled logging and print a message. |
profiling_enabled = 1; |
cout << "* Execution profiling enabled. Logging to " << profileFileName << endl; |
} |
|
// Setup profiling function |
SC_METHOD (callLog); |
sensitive << clk.pos(); |
dont_initialize(); |
start = clock(); |
} |
|
|
if(cmdline_name_found==1) // No -log option specified so don't turn on logging |
{ |
|
103,13 → 130,15
} |
|
} |
if (logging_enabled) |
{ |
SC_METHOD (displayState); |
sensitive << clk.pos(); |
dont_initialize(); |
start = clock(); |
} |
|
|
SC_METHOD (displayState); |
sensitive << clk.pos(); |
dont_initialize(); |
start = clock(); |
|
|
// checkInstruction monitors the bus for special NOP instructionsl |
SC_METHOD (checkInstruction); |
124,7 → 153,7
void |
Or1200MonitorSC::printSwitches() |
{ |
printf(" [-l <file>] [-q]"); |
printf(" [-l <file>] [-q] [-p [<file>]]"); |
} |
|
//! Print usage for the options of this module |
131,6 → 160,7
void |
Or1200MonitorSC::printUsage() |
{ |
printf(" -p, --profile\t\tEnable execution profiling output to file (default "DEFAULT_PROF_FILE")\n"); |
printf(" -l, --log\t\tLog processor execution to file\n"); |
printf(" -q, --quiet\t\tDisable the performance summary at end of simulation\n"); |
} |
150,7 → 180,7
{ |
uint32_t r3; |
double ts; |
|
|
// Check the instruction when the freeze signal is low. |
if (!accessor->getWbFreeze()) |
{ |
194,11 → 224,79
} // checkInstruction() |
|
|
//! Method to log execution in terms of calls and returns |
|
void |
Or1200MonitorSC::callLog() |
{ |
uint32_t exinsn, delaypc; |
uint32_t o_a; // operand a |
uint32_t o_b; // operand b |
struct label_entry *tmp; |
|
cycle_count++; |
// Instructions should be valid when freeze is low and there are no exceptions |
//if (!accessor->getExFreeze()) |
if ((!accessor->getWbFreeze()) && (accessor->getExceptType() == 0)) |
{ |
// Increment instruction counter |
insn_count++; |
|
//exinsn = accessor->getExInsn();// & 0x3ffffff; |
exinsn = accessor->getWbInsn(); |
// Check the instruction |
switch((exinsn >> 26) & 0x3f) { // Check Opcode - top 6 bits |
case 0x1: |
/* Instruction: l.jal */ |
o_a = (exinsn >> 0) & 0x3ffffff; |
if(o_a & 0x02000000) o_a |= 0xfe000000; |
|
//delaypc = accessor->getExPC() + (o_a * 4); // PC we're jumping to |
delaypc = accessor->getWbPC() + (o_a * 4); // PC we're jumping to |
// Now we have info about where we're jumping to. Output the info, with label if possible |
// We print the PC we're jumping from + 8 which is the return address |
if ( tmp = memoryload->get_label (delaypc) ) |
profileFile << "+" << std::setfill('0') << hex << std::setw(8) << cycle_count << " " << hex << std::setw(8) << accessor->getWbPC() + 8 << " " << hex << std::setw(8) << delaypc << " " << tmp->name << endl; |
else |
profileFile << "+" << std::setfill('0') << hex << std::setw(8) << cycle_count << " " << hex << std::setw(8) << accessor->getWbPC() + 8 << " " << hex << std::setw(8) << delaypc << " @" << hex << std::setw(8) << delaypc << endl; |
|
break; |
case 0x11: |
/* Instruction: l.jr */ |
// Bits 15-11 contain register number |
o_b = (exinsn >> 11) & 0x1f; |
if (o_b == 9) // l.jr r9 is typical return |
{ |
// Now get the value in this register |
delaypc = accessor->getGpr(o_b); |
// Output this jump |
profileFile << "-" << std::setfill('0') << hex << std::setw(8) << cycle_count << " " << hex << std::setw(8) << delaypc << endl; |
} |
break; |
case 0x12: |
/* Instruction: l.jalr */ |
o_b = (exinsn >> 11) & 0x1f; |
// Now get the value in this register |
delaypc = accessor->getGpr(o_b); |
// Now we have info about where we're jumping to. Output the info, with label if possible |
// We print the PC we're jumping from + 8 which is the return address |
if ( tmp = memoryload->get_label (delaypc) ) |
profileFile << "+" << std::setfill('0') << hex << std::setw(8) << cycle_count << " " << hex << std::setw(8) << accessor->getWbPC() + 8 << " " << hex << std::setw(8) << delaypc << " " << tmp->name << endl; |
else |
profileFile << "+" << std::setfill('0') << hex << std::setw(8) << cycle_count << " " << hex << std::setw(8) << accessor->getWbPC() + 8 << " " << hex << std::setw(8) << delaypc << " @" << hex << std::setw(8) << delaypc << endl; |
|
break; |
|
} |
} |
} // checkInstruction() |
|
|
//! Method to output the state of the processor |
|
//! This function will output to a file, if enabled, the status of the processor |
//! For now, it's just the PPC and instruction. |
#define PRINT_REGS 0 |
#define PRINT_REGS 1 |
void |
Or1200MonitorSC::displayState() |
{ |
206,8 → 304,6
|
// Calculate how many instructions we've actually calculated by ignoring cycles where we're frozen, delay slots and flushpipe cycles |
if ((!accessor->getWbFreeze()) && !(accessor->getExceptFlushpipe() && accessor->getExDslot())) |
// Increment instruction counter |
insn_count++; |
|
if (logging_enabled == 0) |
return; // If we didn't inialise a file, then just return. |
215,8 → 311,8
// Output the state if we're not frozen and not flushing during a delay slot |
if ((!accessor->getWbFreeze()) && !(accessor->getExceptFlushpipe() && accessor->getExDslot())) |
{ |
// Print PC, instruction |
statusFile << "\nEXECUTED("<< std::setfill(' ') << std::setw(11) << dec << insn_count << "): " << std::setfill('0') << hex << std::setw(8) << accessor->getWbPC() << ": " << hex << accessor->getWbInsn() << endl; |
// Print PC, instruction |
statusFile << "\nEXECUTED("<< std::setfill(' ') << std::setw(11) << dec << insn_count << "): " << std::setfill('0') << hex << std::setw(8) << accessor->getWbPC() << ": " << hex << accessor->getWbInsn() << endl; |
#if PRINT_REGS |
// Print general purpose register contents |
for (int i=0; i<32; i++) |
/orpsocv2/bench/sysc/src/OrpsocAccess.cpp
39,6 → 39,10
#include "Vorpsoc_top_or1200_sprs.h" |
#include "Vorpsoc_top_or1200_rf.h" |
#include "Vorpsoc_top_or1200_dpram.h" |
//#include "Vorpsoc_top_ram_wb.h" |
//#include "Vorpsoc_top_ram_wb_sc_sw.h" |
#include "Vorpsoc_top_ram_wb__D20_A18_M800000.h" |
#include "Vorpsoc_top_ram_wb_sc_sw__D20_A18_M800000.h" |
|
//! Constructor for the ORPSoC access class |
|
53,10 → 57,21
or1200_except = orpsoc_top->v->i_or1k->i_or1200_top->or1200_cpu->or1200_except; |
or1200_sprs = orpsoc_top->v->i_or1k->i_or1200_top->or1200_cpu->or1200_sprs; |
rf_a = orpsoc_top->v->i_or1k->i_or1200_top->or1200_cpu->or1200_rf->rf_a; |
ram_wb_sc_sw = orpsoc_top->v->ram_wb0->ram0; |
|
} // OrpsocAccess () |
|
//! Access for the ex_freeze signal |
|
//! @return The value of the or1200_ctrl.ex_freeze signal |
|
bool |
OrpsocAccess::getExFreeze () |
{ |
return or1200_ctrl->ex_freeze; |
|
} // getExFreeze () |
|
//! Access for the wb_freeze signal |
|
//! @return The value of the or1200_ctrl.wb_freeze signal |
90,6 → 105,18
|
} // getExDslot () |
|
//! Access for the except_type value |
|
//! @return The value of the or1200_except.except_type register |
|
uint32_t |
OrpsocAccess::getExceptType () |
{ |
return (or1200_except->get_except_type) (); |
|
} // getExceptType () |
|
|
//! Access for the id_pc register |
|
//! @return The value of the or1200_except.id_pc register |
101,6 → 128,17
|
} // getIdPC () |
|
//! Access for the ex_pc register |
|
//! @return The value of the or1200_except.id_ex register |
|
uint32_t |
OrpsocAccess::getExPC () |
{ |
return (or1200_except->get_ex_pc) (); |
|
} // getExPC () |
|
//! Access for the wb_pc register |
|
//! @return The value of the or1200_except.wb_pc register |
112,6 → 150,29
|
} // getWbPC () |
|
//! Access for the id_insn register |
|
//! @return The value of the or1200_ctrl.wb_insn register |
|
uint32_t |
OrpsocAccess::getIdInsn () |
{ |
return (or1200_ctrl->get_id_insn) (); |
|
} // getIdInsn () |
|
//! Access for the ex_insn register |
|
//! @return The value of the or1200_ctrl.ex_insn register |
|
uint32_t |
OrpsocAccess::getExInsn () |
{ |
return (or1200_ctrl->get_ex_insn) (); |
|
} // getExInsn () |
|
|
//! Access for the wb_insn register |
|
//! @return The value of the or1200_ctrl.wb_insn register |
123,17 → 184,35
|
} // getWbInsn () |
|
//! Access for the id_insn register |
//! Access the Wishbone SRAM memory |
|
//! @return The value of the or1200_ctrl.wb_insn register |
//! @return The value of the memory word at addr |
|
uint32_t |
OrpsocAccess::getIdInsn () |
OrpsocAccess::get_mem (uint32_t addr) |
{ |
return (or1200_ctrl->get_id_insn) (); |
return (ram_wb_sc_sw->get_mem) (addr); |
|
} // getIdInsn () |
} // get_mem () |
|
//! Write value to the Wishbone SRAM memory |
|
void |
OrpsocAccess::set_mem (uint32_t addr, uint32_t data) |
{ |
(ram_wb_sc_sw->set_mem) (addr, data); |
|
} // set_mem () |
|
//! Trigger the $readmemh() system call |
|
void |
OrpsocAccess::do_ram_readmemh (void) |
{ |
(ram_wb_sc_sw->do_readmemh) (); |
|
} // do_ram_readmemh () |
|
//! Access for the OR1200 GPRs |
|
//! These are extracted from memory using the Verilog function |
/orpsocv2/bench/sysc/src/MemoryLoad.cpp
0,0 → 1,979
/* MemoryLoad.cpp -- Program load functions |
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
Copyright (C) 2008 Embecosm Limited |
Copyright (C) 2009 Julius Baxter, julius@orsoc.se |
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
|
This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. |
|
This program is free software; you can redistribute it and/or modify it |
under the terms of the GNU General Public License as published by the Free |
Software Foundation; either version 3 of the License, or (at your option) |
any later version. |
|
This program is distributed in the hope that it will be useful, but WITHOUT |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
more details. |
|
You should have received a copy of the GNU General Public License along |
with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* This program is commented throughout in a fashion suitable for processing |
with Doxygen. */ |
|
/* System includes */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
#include "MemoryLoad.h" |
#include "OrpsocMain.h" |
|
|
//! Constructor for the ORPSoC memory loader class |
|
//! Initializes various values |
|
//! @param[in] orpsoc The SystemC Verilated ORPSoC instance |
//! @param[in] accessor Accessor class for this Verilated ORPSoC model |
|
MemoryLoad::MemoryLoad |
( |
OrpsocAccess *_accessor |
) |
{ |
accessor = _accessor; |
} // MemoryAccess () |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Copy a string with null termination |
|
This function is very similar to strncpy, except it null terminates the |
string. A global function also used by the CUC. |
|
@param[in] dst The destination string |
@param[in] src The source string |
@param[in] n Number of chars to copy EXCLUDING the null terminator |
(i.e. dst had better have room for n+1 chars) |
|
@return A pointer to dst */ |
/*---------------------------------------------------------------------------*/ |
char * |
MemoryLoad::strstrip (char *dst, |
const char *src, |
int n) |
{ |
strncpy (dst, src, n); |
*(dst + n) = '\0'; |
|
return dst; |
|
} /* strstrip () */ |
|
/*---------------------------------------------------------------------------*/ |
/*!Translate logical to physical addresses for the loader |
|
Used only by the simulator loader to translate logical addresses into |
physical. If loadcode() is called with valid @c virtphy_transl pointer to |
a table of translations then translate() performs translation otherwise |
physical address is equal to logical. |
|
Currently NOT used |
|
@param[in] laddr Logical address |
@param[in] breakpoint Unused |
|
@return The physical address */ |
/*---------------------------------------------------------------------------*/ |
oraddr_t |
MemoryLoad::translate (oraddr_t laddr, |
int *breakpoint) |
{ |
/* |
int i; |
|
// No translation (i.e. when loading kernel into simulator) |
if (transl_table == 0) |
{ |
return laddr; |
} |
|
// Try to find our translation in the table. |
for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) |
{ |
if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0)) |
{ |
// Page modified |
set_direct32 (transl_table + i + 8, -2, 0, 0); |
PRINTF ("found paddr=%" PRIx32 "\n", |
eval_direct32 (transl_table + i + 4, 0, 0) | |
(laddr & (PAGE_SIZE - 1))); |
return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) | |
(laddr & (oraddr_t) (PAGE_SIZE - 1)); |
} |
} |
|
// Allocate new phy page for us. |
for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) |
{ |
if (eval_direct32 (transl_table + i + 8, 0, 0) == 0) |
{ |
// VPN |
set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0); |
// PPN |
set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0); |
// Page modified |
//set_direct32 (transl_table + i + 8, -2, 0, 0); |
PRINTF ("newly allocated ppn=%" PRIx32 "\n", |
eval_direct32 (transl_table + i + 4, 0, 0)); |
PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4); |
PRINTF ("newly allocated ofs=%" PRIxADDR "\n", |
(laddr & (PAGE_SIZE - 1))); |
PRINTF ("newly allocated paddr=%" PRIx32 "\n", |
eval_direct32 (transl_table + i + 4, 0, |
0) | (laddr & (PAGE_SIZE - 1))); |
return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) | |
(laddr & (oraddr_t) (PAGE_SIZE - 1)); |
} |
} |
|
// If we come this far then all phy memory is used and we can't find our |
page nor allocate new page. |
transl_error = 1; |
PRINTF ("can't translate %" PRIxADDR "\n", laddr); |
exit (1); |
|
return -1; |
*/ |
return 0; |
|
} /* translate() */ |
|
#if IMM_STATS |
int |
MemoryLoad::bits (uint32_t val) |
{ |
int i = 1; |
if (!val) |
return 0; |
while (val != 0 && (int32_t) val != -1) |
{ |
i++; |
val = (int32_t) val >> 1; |
} |
return i; |
} |
|
void |
MemoryLoad::check_insn (uint32_t insn) |
{ |
int insn_index = insn_decode (insn); |
struct insn_op_struct *opd = op_start[insn_index]; |
uint32_t data = 0; |
int dis = 0; |
const char *name; |
if (!insn || insn_index < 0) |
return; |
name = insn_name (insn_index); |
if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0) |
return; |
|
while (1) |
{ |
uint32_t tmp = 0 unsigned int nbits = 0; |
while (1) |
{ |
tmp |= |
((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << |
nbits; |
nbits += opd->data; |
if (opd->type & OPTYPE_OP) |
break; |
opd++; |
} |
|
/* Do we have to sign extend? */ |
if (opd->type & OPTYPE_SIG) |
{ |
int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR; |
if (tmp & (1 << sbit)) |
tmp |= 0xFFFFFFFF << sbit; |
} |
if (opd->type & OPTYPE_DIS) |
{ |
/* We have to read register later. */ |
data += tmp; |
dis = 1; |
} |
else |
{ |
if (!(opd->type & OPTYPE_REG) || dis) |
{ |
if (!dis) |
data = tmp; |
if (strcmp (name, "l.movhi") == 0) |
{ |
movhi = data << 16; |
} |
else |
{ |
data |= movhi; |
//PRINTF ("%08x %s\n", data, name); |
if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY)) |
{ |
bcnt[bits (data)][0]++; |
bsum[0]++; |
} |
else |
{ |
if (strcmp (name, "l.bf") == 0 |
|| strcmp (name, "l.bnf") == 0) |
{ |
bcnt[bits (data)][1]++; |
bsum[1]++; |
} |
else |
{ |
bcnt[bits (data)][2]++; |
bsum[2]++; |
} |
} |
} |
} |
data = 0; |
dis = 0; |
} |
if (opd->type & OPTYPE_LAST) |
{ |
return; |
} |
opd++; |
} |
} |
#endif |
|
/*---------------------------------------------------------------------------*/ |
/*!Add an instruction to the program |
|
@note insn must be in big endian format |
|
@param[in] address The address to use |
@param[in] insn The instruction to add |
@param[in] breakpoint Not used (it is passed to the translate() function, |
which also does not use it. */ |
/*---------------------------------------------------------------------------*/ |
void |
MemoryLoad::addprogram (oraddr_t address, |
uint32_t insn, |
int *breakpoint) |
{ |
|
// Memory is word addressed, not byte, so /4 the address we get |
int vaddr = (int) address/4; /*(!runtime.sim.filename) ? translate (address, breakpoint) : |
translate (freemem, breakpoint); |
-- jb |
*/ |
/* We can't have set_program32 functions since it is not gauranteed that the |
section we're loading is aligned on a 4-byte boundry */ |
/* |
set_program8 (vaddr, (insn >> 24) & 0xff); |
set_program8 (vaddr + 1, (insn >> 16) & 0xff); |
set_program8 (vaddr + 2, (insn >> 8) & 0xff); |
set_program8 (vaddr + 3, insn & 0xff); |
*/ |
/* Use the whole-word write */ |
accessor->set_mem(vaddr, insn); |
PRINTF("* addprogram: addr 0x%.8x insn: 0x%.8x (conf: 0x%.8x)\n", vaddr, insn, accessor->get_mem(vaddr)); |
|
|
#if IMM_STATS |
check_insn (insn); |
#endif |
|
//if (runtime.sim.filename) |
//{ |
//freemem += insn_len (insn_decode (insn)); |
//} |
freemem += 4; |
|
} /* addprogram () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Load big-endian COFF file |
|
@param[in] filename File to load |
@param[in] sections Number of sections in file */ |
/*---------------------------------------------------------------------------*/ |
void |
MemoryLoad::readfile_coff (char *filename, |
short sections) |
{ |
FILE *inputfs; |
char inputbuf[4]; |
uint32_t insn; |
int32_t sectsize; |
COFF_AOUTHDR coffaouthdr; |
struct COFF_scnhdr coffscnhdr; |
int len; |
int firstthree = 0; |
int breakpoint = 0; |
|
if (!(inputfs = fopen (filename, "r"))) |
{ |
perror ("readfile_coff"); |
exit (1); |
} |
|
if (fseek (inputfs, sizeof (COFF_FILHDR), SEEK_SET) == -1) |
{ |
fclose (inputfs); |
perror ("readfile_coff"); |
exit (1); |
} |
|
if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1) |
{ |
fclose (inputfs); |
perror ("readfile_coff"); |
exit (1); |
} |
|
while (sections--) |
{ |
uint32_t scnhdr_pos = |
sizeof (COFF_FILHDR) + sizeof (coffaouthdr) + |
sizeof (struct COFF_scnhdr) * firstthree; |
if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1) |
{ |
fclose (inputfs); |
perror ("readfile_coff"); |
exit (1); |
} |
if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1) |
{ |
fclose (inputfs); |
perror ("readfile_coff"); |
exit (1); |
} |
PRINTF ("Section: %s,", coffscnhdr.s_name); |
PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr)); |
PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr)); |
PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size)); |
PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr)); |
|
sectsize = COFF_LONG_H (coffscnhdr.s_size); |
++firstthree; |
|
/* loading section */ |
freemem = COFF_LONG_H (coffscnhdr.s_paddr); |
if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1) |
{ |
fclose (inputfs); |
perror ("readfile_coff"); |
exit (1); |
} |
while (sectsize > 0 |
&& (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs))) |
{ |
insn = COFF_LONG_H (inputbuf); |
//len = insn_len (insn_decode (insn)); |
len = 4; |
if (len == 2) |
{ |
fseek (inputfs, -2, SEEK_CUR); |
} |
|
addprogram (freemem, insn, &breakpoint); |
sectsize -= len; |
} |
} |
if (firstthree < 3) |
{ |
PRINTF ("One or more missing sections. At least"); |
PRINTF (" three sections expected (.text, .data, .bss).\n"); |
exit (1); |
} |
if (firstthree > 3) |
{ |
PRINTF ("Warning: one or more extra sections. These"); |
PRINTF (" sections were handled as .data sections.\n"); |
} |
|
fclose (inputfs); |
PRINTF ("Finished loading COFF.\n"); |
return; |
|
} /* readfile_coff () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Load symbols from big-endian COFF file |
|
@param[in] filename File to load |
@param[in] symptr Symbol pointer value |
@param[in] syms Symbols value */ |
/*---------------------------------------------------------------------------*/ |
|
void |
MemoryLoad::readsyms_coff (char *filename, uint32_t symptr, uint32_t syms) |
{ |
FILE *inputfs; |
struct COFF_syment coffsymhdr; |
int count = 0; |
uint32_t nsyms = syms; |
if (!(inputfs = fopen (filename, "r"))) |
{ |
perror ("readsyms_coff"); |
exit (1); |
} |
|
if (fseek (inputfs, symptr, SEEK_SET) == -1) |
{ |
fclose (inputfs); |
perror ("readsyms_coff"); |
exit (1); |
} |
|
while (syms--) |
{ |
int i, n; |
if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) |
{ |
fclose (inputfs); |
perror ("readsyms_coff"); |
exit (1); |
} |
|
n = (unsigned char) coffsymhdr.e_numaux[0]; |
|
/* check whether this symbol belongs to a section and is external |
symbol; ignore all others */ |
if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0 |
&& coffsymhdr.e_sclass[0] == C_EXT) |
{ |
if (*((uint32_t *) coffsymhdr.e.e.e_zeroes)) |
{ |
if (strlen (coffsymhdr.e.e_name) |
&& strlen (coffsymhdr.e.e_name) < 9) |
add_label (COFF_LONG_H (coffsymhdr.e_value), |
coffsymhdr.e.e_name); |
} |
else |
{ |
uint32_t fpos = ftell (inputfs); |
|
if (fseek |
(inputfs, |
symptr + nsyms * COFF_SYMESZ + |
COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0) |
{ |
char tmp[33], *s = &tmp[0]; |
while (s != &tmp[32]) |
if ((*(s++) = fgetc (inputfs)) == 0) |
break; |
tmp[32] = 0; |
add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]); |
} |
fseek (inputfs, fpos, SEEK_SET); |
} |
} |
|
for (i = 0; i < n; i++) |
if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) |
{ |
fclose (inputfs); |
perror ("readsyms_coff3"); |
exit (1); |
} |
syms -= n; |
count += n; |
} |
|
fclose (inputfs); |
PRINTF ("Finished loading symbols.\n"); |
return; |
} |
|
/*---------------------------------------------------------------------------*/ |
/*!Read an ELF file |
|
@param[in] filename File to load */ |
/*---------------------------------------------------------------------------*/ |
void |
MemoryLoad::readfile_elf (char *filename) |
{ |
|
FILE *inputfs; |
struct elf32_hdr elfhdr; |
struct elf32_phdr *elf_phdata = NULL; |
struct elf32_shdr *elf_spnt, *elf_shdata; |
struct elf32_sym *sym_tbl = (struct elf32_sym *) 0; |
uint32_t syms = 0; |
char *str_tbl = (char *) 0; |
char *s_str = (char *) 0; |
int breakpoint = 0; |
uint32_t inputbuf; |
uint32_t padd; |
uint32_t insn; |
int i, j, sectsize, len; |
|
if (!(inputfs = fopen (filename, "r"))) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if ((elf_shdata = |
(struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) * |
ELF_SHORT_H (elfhdr.e_shnum))) == NULL) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread |
(elf_shdata, |
ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1, |
inputfs) != 1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (ELF_LONG_H (elfhdr.e_phoff)) |
{ |
if ((elf_phdata = |
(struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) * |
ELF_SHORT_H (elfhdr.e_phentsize))) == |
NULL) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread |
(elf_phdata, |
ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize), |
1, inputfs) != 1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
} |
|
for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum); |
i++, elf_spnt++) |
{ |
|
if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB) |
{ |
if (NULL != str_tbl) |
{ |
free (str_tbl); |
} |
|
if ((str_tbl = |
(char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != |
0) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != |
1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
} |
else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB) |
{ |
|
if (NULL != sym_tbl) |
{ |
free (sym_tbl); |
} |
|
if ((sym_tbl = |
(struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size))) |
== NULL) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != |
0) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != |
1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
syms = |
ELF_LONG_H (elf_spnt->sh_size) / |
ELF_LONG_H (elf_spnt->sh_entsize); |
} |
} |
|
if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF) |
{ |
elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)]; |
|
if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
|
if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1) |
{ |
perror ("readfile_elf"); |
exit (1); |
} |
} |
|
|
for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum); |
i++, elf_spnt++) |
{ |
|
if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS) |
&& (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC)) |
{ |
|
padd = ELF_LONG_H (elf_spnt->sh_addr); |
for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++) |
{ |
if (ELF_LONG_H (elf_phdata[j].p_offset) && |
ELF_LONG_H (elf_phdata[j].p_offset) <= |
ELF_LONG_H (elf_spnt->sh_offset) |
&& (ELF_LONG_H (elf_phdata[j].p_offset) + |
ELF_LONG_H (elf_phdata[j].p_memsz)) > |
ELF_LONG_H (elf_spnt->sh_offset)) |
padd = |
ELF_LONG_H (elf_phdata[j].p_paddr) + |
ELF_LONG_H (elf_spnt->sh_offset) - |
ELF_LONG_H (elf_phdata[j].p_offset); |
} |
|
|
|
if (ELF_LONG_H (elf_spnt->sh_name) && s_str) |
PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]); |
else |
PRINTF ("Section: noname,"); |
PRINTF (" vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr)); |
PRINTF (" paddr: 0x%" PRIx32, padd); |
PRINTF (" offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset)); |
PRINTF (" size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size)); |
|
freemem = padd; |
sectsize = ELF_LONG_H (elf_spnt->sh_size); |
|
if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != |
0) |
{ |
perror ("readfile_elf"); |
free (elf_phdata); |
exit (1); |
} |
|
while (sectsize > 0 |
&& (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs))) |
{ |
insn = ELF_LONG_H (inputbuf); |
//PRINTF("* addprogram(%.8x, %.8x, %d)\n", freemem, insn, breakpoint); |
addprogram (freemem, insn, &breakpoint); |
sectsize -= 4; |
} |
} |
} |
|
if (str_tbl) |
{ |
i = 0; |
while (syms--) |
{ |
if (sym_tbl[i].st_name && sym_tbl[i].st_info |
&& ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000) |
{ |
add_label (ELF_LONG_H (sym_tbl[i].st_value), |
&str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]); |
} |
i++; |
} |
} |
|
if (NULL != str_tbl) |
{ |
free (str_tbl); |
} |
|
if (NULL != sym_tbl) |
{ |
free (sym_tbl); |
} |
|
free (s_str); |
free (elf_phdata); |
free (elf_shdata); |
|
} |
|
/* Identify file type and call appropriate readfile_X routine. It only |
handles orX-coff-big executables at the moment. */ |
|
void |
MemoryLoad::identifyfile (char *filename) |
{ |
FILE *inputfs; |
COFF_FILHDR coffhdr; |
struct elf32_hdr elfhdr; |
|
if (!(inputfs = fopen (filename, "r"))) |
{ |
perror (filename); |
fflush (stdout); |
fflush (stderr); |
exit (1); |
} |
|
if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1) |
{ |
if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a) |
{ |
uint32_t opthdr_size; |
PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic)); |
PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags)); |
PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr)); |
if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) |
{ |
PRINTF ("This COFF is not an executable.\n"); |
exit (1); |
} |
opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr); |
if (opthdr_size != sizeof (COFF_AOUTHDR)) |
{ |
PRINTF ("COFF optional header is missing or not recognized.\n"); |
PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size); |
exit (1); |
} |
fclose (inputfs); |
readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns)); |
readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr), |
COFF_LONG_H (coffhdr.f_nsyms)); |
return; |
} |
else |
{ |
PRINTF ("Not COFF file format\n"); |
fseek (inputfs, 0, SEEK_SET); |
} |
} |
if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1) |
{ |
if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45 |
&& elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) |
{ |
PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type)); |
PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine)); |
PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version)); |
PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum)); |
if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC) |
{ |
PRINTF ("This ELF is not an executable.\n"); |
exit (1); |
} |
fclose (inputfs); |
readfile_elf (filename); |
return; |
} |
else |
{ |
PRINTF ("Not ELF file format.\n"); |
fseek (inputfs, 0, SEEK_SET); |
} |
} |
|
perror ("identifyfile2"); |
fclose (inputfs); |
|
return; |
} |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Load file to memory |
|
Loads file to memory starting at address startaddr and returns freemem. |
|
@param[in] filename File to load |
@param[in] startaddr Start address at which to load |
@param[in] virtphy_transl Virtual to physical transation table if |
required. Only used for microkernel simulation, |
and not used in Ork1sim at present (set to NULL) |
|
@return zero on success, negative on failure. */ |
/*---------------------------------------------------------------------------*/ |
uint32_t |
MemoryLoad::loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl) |
{ |
//int breakpoint = 0; |
|
init_labels (); // jb |
|
transl_error = 0; |
transl_table = virtphy_transl; |
freemem = startaddr; |
PRINTF ("* MemoryLoad::loadcode: filename %s startaddr=%" PRIxADDR " virtphy_transl=%" |
PRIxADDR "\n", filename, startaddr, virtphy_transl); |
identifyfile (filename); |
|
#if IMM_STATS |
{ |
int i = 0, a = 0, b = 0, c = 0; |
PRINTF ("index:arith/branch/jump\n"); |
for (i = 0; i < 33; i++) |
PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i, |
100. * (a += bcnt[i][0]) / bsum[0], 100. * (b += |
bcnt[i][1]) / |
bsum[1], 100. * (c += |
bcnt[i][2]) / bsum[2], bcnt[i][0], |
bcnt[i][1], bcnt[i][2]); |
PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]); |
} |
#endif |
|
/* |
if (transl_error) |
return -1; |
else |
return translate (freemem, &breakpoint); |
*/ |
return (uint32_t) freemem; |
|
} |
|
/* From arch sim labels.c */ |
void |
MemoryLoad::init_labels () |
{ |
int i; |
for (i = 0; i < LABELS_HASH_SIZE; i++) |
label_hash[i] = NULL; |
} |
|
void |
MemoryLoad::add_label (oraddr_t addr, char *name) |
{ |
struct label_entry **tmp; |
tmp = &(label_hash[addr % LABELS_HASH_SIZE]); |
for (; *tmp; tmp = &((*tmp)->next)); |
*tmp = (label_entry *) malloc (sizeof (**tmp)); |
(*tmp)->name = (char *) malloc (strlen (name) + 1); |
(*tmp)->addr = addr; |
strcpy ((*tmp)->name, name); |
(*tmp)->next = NULL; |
} |
|
struct label_entry * |
MemoryLoad::get_label (oraddr_t addr) |
{ |
struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE]; |
while (tmp) |
{ |
if (tmp->addr == addr) |
return tmp; |
tmp = tmp->next; |
} |
return NULL; |
} |
|
struct label_entry * |
MemoryLoad::find_label (char *name) |
{ |
int i; |
for (i = 0; i < LABELS_HASH_SIZE; i++) |
{ |
struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE]; |
while (tmp) |
{ |
if (strcmp (tmp->name, name) == 0) |
return tmp; |
tmp = tmp->next; |
} |
} |
return NULL; |
} |
|
/* Searches mem array for a particular label and returns label's address. |
If label does not exist, returns 0. */ |
oraddr_t |
MemoryLoad::eval_label (char *name) |
{ |
struct label_entry *le; |
char *plus; |
char *minus; |
int positive_offset = 0; |
int negative_offset = 0; |
|
if ((plus = strchr (name, '+'))) |
{ |
*plus = '\0'; |
positive_offset = atoi (++plus); |
} |
|
if ((minus = strchr (name, '-'))) |
{ |
*minus = '\0'; |
negative_offset = atoi (++minus); |
} |
le = find_label (name); |
if (!le) |
return 0; |
|
return le->addr + positive_offset - negative_offset; |
} |
/orpsocv2/bench/sysc/src/OrpsocMain.cpp
45,11 → 45,9
|
#include "Vorpsoc_top.h" |
#include "OrpsocAccess.h" |
#include "MemoryLoad.h" |
|
//#if VM_TRACE |
//#include <systemc.h> |
#include <SpTraceVcdC.h> |
//#endif |
|
//#include "TraceSC.h" |
#include "ResetSC.h" |
107,13 → 105,18
int time_val; |
int cmdline_name_found=0; |
|
// Executable app load variables |
int do_program_file_load = 0; // Default: we don't require a file, we use the VMEM |
char* program_file; // Old char* style for program name |
|
// Verilator accessor |
OrpsocAccess *accessor; |
|
// Modules |
Vorpsoc_top *orpsoc; // Verilated ORPSoC |
//TraceSC *trace; // Drive VCD |
|
MemoryLoad *memoryload; // Memory loader |
|
ResetSC *reset; // Generate a RESET signal |
Or1200MonitorSC *monitor; // Handle l.nop x instructions |
UartSC *uart; // Handle UART signals |
120,24 → 123,23
|
// Instantiate the Verilator model, VCD trace handler and accessor |
orpsoc = new Vorpsoc_top ("orpsoc"); |
//trace = new TraceSC ("trace", orpsoc, argc, argv); |
|
accessor = new OrpsocAccess (orpsoc); |
|
memoryload = new MemoryLoad (accessor); |
|
// Instantiate the SystemC modules |
reset = new ResetSC ("reset", BENCH_RESET_TIME); |
monitor = new Or1200MonitorSC ("monitor", accessor, argc, argv); |
monitor = new Or1200MonitorSC ("monitor", accessor, memoryload, argc, argv); |
uart = new UartSC("uart"); // TODO: Probalby some sort of param |
|
|
// Parse command line options |
// Default is for VCD generation OFF, only turned on if specified on command line |
dump_start_delay = 0; |
dump_stop_set = 0; |
dumping_now = 0; |
|
|
// Search through the command line parameters for options |
|
// Search through the command line parameters for options |
if (argc > 1) |
{ |
for(int i=1; i<argc; i++) |
160,10 → 162,14
time_val = atoi(argv[i+1]); |
sc_time opt_end_time(time_val,TIMESCALE_UNIT); |
finish_time = opt_end_time; |
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Sim. will end at " << finish_time.to_string() << endl; |
finish_time_set = 1; |
} |
//#if VM_TRACE |
else if ( (strcmp(argv[i], "-f")==0) || |
(strcmp(argv[i], "--program")==0) ) |
{ |
do_program_file_load = 1; // Enable program loading - will be done after sim init |
program_file = argv[i+1]; // Old char* style for program name |
} |
else if ( (strcmp(argv[i], "-s")==0) || |
(strcmp(argv[i], "--vcdstart")==0) ) |
{ |
170,7 → 176,6
time_val = atoi(argv[i+1]); |
sc_time dump_start_time(time_val,TIMESCALE_UNIT); |
dump_start = dump_start_time; |
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump start time set at " << dump_start.to_string() << endl; |
dump_start_delay = 1; |
dumping_now = 0; |
} |
180,25 → 185,26
time_val = atoi(argv[i+1]); |
sc_time dump_stop_time(time_val,TIMESCALE_UNIT); |
dump_stop = dump_stop_time; |
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump stop time set at " << dump_stop.to_string() << endl; |
dump_stop_set = 1; |
} |
/* Depth setting of VCD doesn't appear to work, I think it's set during verilator script compile time */ |
/* Depth setting of VCD doesn't appear to work, |
I think it's set during verilator script |
compile time */ |
/* else if ( (strcmp(argv[i], "-p")==0) || |
(strcmp(argv[i], "--vcddepth")==0) ) |
{ |
dump_depth = atoi(argv[i+1]); |
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump depth set to " << dump_depth << endl; |
}*/ |
(strcmp(argv[i], "--vcddepth")==0) ) |
{ |
dump_depth = atoi(argv[i+1]); |
}*/ |
else if ( (strcmp(argv[i], "-h")==0) || |
(strcmp(argv[i], "--help")==0) ) |
{ |
printf("\n ORPSoC Cycle Accurate model usage:\n"); |
printf(" %s [-vh] [-d <file>] [-e <time>] [-s <time>] [-t <time>]",argv[0]); |
printf(" %s [-vh] [-f <file] [-d <file>] [-e <time>] [-s <time>] [-t <time>]",argv[0]); |
monitor->printSwitches(); |
printf("\n\n"); |
printf(" -h, --help\t\tPrint this help message\n"); |
printf(" -e, --endtime\t\tStop the sim at this time (ns)\n"); |
printf(" -f, --program\t\tLoad program from an OR32 ELF\n"); |
printf(" -v, --vcdon\t\tEnable VCD generation\n"); |
printf(" -d, --vcdfile\t\tEnable and specify target VCD file name\n"); |
|
307,8 → 313,21
// Init the UART function |
uart->initUart(25000000, 115200); |
|
SIM_RUNNING = 1; |
if (do_program_file_load) // Did the user specify a file to load? |
{ |
cout << "* Loading program from " << program_file << endl; |
if (memoryload->loadcode(program_file,0,0) < 0) |
{ |
cout << "* Error: executable file " << program_file << " not loaded" << endl; |
} |
} |
else // Load SRAM from VMEM file |
{ |
accessor->do_ram_readmemh(); |
} |
|
SIM_RUNNING = 1; |
|
// First check how we should run the sim. |
if (VCD_enabled || finish_time_set) |
{ // We'll run sim with step |
/orpsocv2/bench/verilog/smii_phy.v
147,10 → 147,10
|
// Allow us to check if RX DV has been low for a while |
reg [3:0] rx_dv_long_low_sr; |
wire dv_long_low; |
wire rx_dv_long_low; |
always @(posedge ethphy_mii_rx_clk) |
rx_dv_long_low_sr[3:0] <= {rx_dv_long_low_sr[2:0], ethphy_mii_rx_dv}; |
assign rx_dv_long_low = ~(|rx_dv_long_low_sr); |
assign rx_dv_long_low = ~(|rx_dv_long_low_sr[3:0]); |
reg rx_dv; |
wire [8:0] rx_fifo_out; |
wire rx_fifo_empty,rx_fifo_almost_empty; |
/orpsocv2/rtl/verilog/eth_defines.v
317,8 → 317,11
`define ETH_REGISTERED_OUTPUTS |
|
// Settings for TX FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 5 |
`define ETH_TX_FIFO_DEPTH 16 |
//`define ETH_TX_FIFO_CNT_WIDTH 5 |
//`define ETH_TX_FIFO_DEPTH 16 |
// Settings for TX FIFO buffer for a while ethernet packet (1500 bytes) |
`define ETH_TX_FIFO_CNT_WIDTH 9 |
`define ETH_TX_FIFO_DEPTH 375 |
`define ETH_TX_FIFO_DATA_WIDTH 32 |
|
// Settings for RX FIFO |
/orpsocv2/rtl/verilog/components/or1200r2/or1200_except.v
225,9 → 225,9
// |
// Internal regs and wires |
// |
reg [`OR1200_EXCEPT_WIDTH-1:0] except_type; |
reg [`OR1200_EXCEPT_WIDTH-1:0] except_type /* verilator public */; |
reg [31:0] id_pc /* verilator public */; |
reg [31:0] ex_pc; |
reg [31:0] ex_pc /* verilator public */; |
reg [31:0] wb_pc /* verilator public */; |
reg [31:0] epcr; |
reg [31:0] eear; |
303,10 → 303,6
get_wb_pc = wb_pc; |
endfunction // get_wb_pc |
|
`endif |
|
|
`ifdef verilator |
// Function to access id_pc (for Verilator). Have to hide this from |
// simulator, since functions with no inputs are not allowed in IEEE |
// 1364-2001. |
315,6 → 311,21
get_id_pc = id_pc; |
endfunction // get_id_pc |
|
// Function to access ex_pc (for Verilator). Have to hide this from |
// simulator, since functions with no inputs are not allowed in IEEE |
// 1364-2001. |
function [31:0] get_ex_pc; |
// verilator public |
get_ex_pc = ex_pc; |
endfunction // get_ex_pc |
// Function to access except_type[3:0] (for Verilator). Have to hide this from |
// simulator, since functions with no inputs are not allowed in IEEE |
// 1364-2001. |
function [3:0] get_except_type; |
// verilator public |
get_except_type = except_type; |
endfunction // get_except_type |
|
`endif |
|
// |
/orpsocv2/rtl/verilog/components/or1200r2/or1200_ctrl.v
145,11 → 145,11
input clk; |
input rst; |
input id_freeze; |
input ex_freeze; |
input ex_freeze /* verilator public */; |
input wb_freeze /* verilator public */; |
input flushpipe; |
input [31:0] if_insn; |
output [31:0] ex_insn; |
output [31:0] ex_insn/* verilator public */; |
output [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op; |
output [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; |
input branch_taken; |
202,7 → 202,7
reg [`OR1200_SHROTOP_WIDTH-1:0] shrot_op; |
reg [31:0] id_insn /* verilator public */; |
reg [31:0] ex_insn; |
reg [31:0] wb_insn; |
reg [31:0] wb_insn /* verilator public */; |
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw; |
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] wb_rfaddrw; |
reg [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op; |
277,9 → 277,7
// verilator public |
get_wb_insn = wb_insn; |
endfunction // get_wb_insn |
`endif |
|
`ifdef verilator |
// Function to access id_insn (for Verilator). Have to hide this from |
// simulator, since functions with no inputs are not allowed in IEEE |
// 1364-2001. |
287,6 → 285,15
// verilator public |
get_id_insn = id_insn; |
endfunction // get_id_insn |
|
// Function to access ex_insn (for Verilator). Have to hide this from |
// simulator, since functions with no inputs are not allowed in IEEE |
// 1364-2001. |
function [31:0] get_ex_insn; |
// verilator public |
get_ex_insn = ex_insn; |
endfunction // get_ex_insn |
|
`endif |
|
|
/orpsocv2/rtl/verilog/components/ram_wb/ram_wb_sc_sw.v
10,7 → 10,7
output reg [dat_width-1:0] dat_o; |
input clk; |
|
reg [dat_width-1:0] ram [0:mem_size - 1] /* synthesis ram_style = no_rw_check */; |
reg [dat_width-1:0] ram [0:mem_size - 1] /* verilator public */ /* synthesis ram_style = no_rw_check */; |
|
// Preload the memory |
// Note! This vmem file must be WORD addressed, not BYTE addressed |
19,12 → 19,40
// @00000008 00000000 00000000 00000000 00000000 |
// @0000000c 00000000 00000000 00000000 00000000 |
// etc.. |
parameter memory_file = "sram.vmem"; |
|
parameter memory_file = "sram.vmem"; |
|
`ifdef verilator |
|
task do_readmemh; |
// verilator public |
$readmemh(memory_file, ram); |
endtask // do_readmemh |
|
`else |
|
initial |
begin |
$readmemh(memory_file, ram); |
end |
|
`endif |
|
// Function to access RAM (for use by Verilator). |
function [31:0] get_mem; |
// verilator public |
input [adr_width-1:0] addr; |
get_mem = ram[addr]; |
endfunction // get_mem |
|
// Function to write RAM (for use by Verilator). |
function set_mem; |
// verilator public |
input [adr_width-1:0] addr; |
input [dat_width-1:0] data; |
ram[addr] = data; |
endfunction // set_mem |
|
always @ (posedge clk) |
begin |
dat_o <= ram[adr_i]; |
/orpsocv2/sim/bin/Makefile
275,11 → 275,13
EVENT_SIM_FLAGS += "-D USE_SDRAM=$(USE_SDRAM)" |
endif |
|
|
|
# Enable ethernet if defined on the command line |
ifdef USE_ETHERNET |
EVENT_SIM_FLAGS += "-D USE_ETHERNET=$(USE_ETHERNET) -D USE_ETHERNET_IO=$(USE_ETHERNET)" |
# Extra tests we do if ethernet is enabled |
TESTS += eth-basic |
TESTS += eth-basic eth-int |
endif |
|
SIM_FLASH_MEM_FILE="flash.in" |
293,12 → 295,15
# Event-driven simulator build rules (Icarus, NCSim) |
################################################################################ |
|
.PHONY: prepare_rtl |
prepare_rtl: |
@cd $(RTL_VERILOG_DIR)/components/wb_sdram_ctrl && perl fizzim.pl -encoding onehot -terse < wb_sdram_ctrl_fsm.fzm > wb_sdram_ctrl_fsm.v |
$(RTL_VERILOG_DIR)/components/wb_sdram_ctrl/wb_sdram_ctrl_fsm.v: |
@cd $(RTL_VERILOG_DIR)/components/wb_sdram_ctrl && perl fizzim.pl -encoding onehot -terse < wb_sdram_ctrl_fsm.fzm > wb_sdram_ctrl_fsm.v |
$(RTL_VERILOG_DIR)/intercon.v: |
@cd $(RTL_VERILOG_DIR) && sed '/defparam/!s/\([a-zA-Z0-9_]\)\.//g' intercon.vm > intercon.v |
|
.PHONY: prepare_rtl |
prepare_rtl: $(RTL_VERILOG_DIR)/components/wb_sdram_ctrl/wb_sdram_ctrl_fsm.v $(RTL_VERILOG_DIR)/intercon.v |
|
|
ifdef UART_PRINTF |
TEST_SW_MAKE_OPTS="UART_PRINTF=1" |
endif |
540,7 → 545,7
|
# List of System C models - use this list to link the sources into the Verilator |
# build directory |
SYSC_MODELS=OrpsocAccess |
SYSC_MODELS=OrpsocAccess MemoryLoad |
|
ifdef VLT_DEBUG |
VLT_DEBUG_COMPILE_FLAGS = -g |
555,7 → 560,8
VLT_CPPFLAGS=-g -pg |
VLT_DEBUG_OPTIONS +=-profile-cfuncs |
else |
VLT_CPPFLAGS=-fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -O3 |
#VLT_CPPFLAGS=-fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -O3 |
VLT_CPPFLAGS=-Wall |
endif |
|
ifdef VLT_DO_PROFILING |
584,8 → 590,8
@echo; echo "\tGenerating simulation executable"; echo |
cd $(SIM_VLT_DIR) && g++ $(VLT_DEBUG_COMPILE_FLAGS) $(VLT_CPPFLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -o Vorpsoc_top -L. -L$(BENCH_SYSC_SRC_DIR) -L$(SYSTEMC)/$(SYSC_LIB_ARCH_DIR) OrpsocMain.o -lVorpsoc_top -lmodules -lsystemc |
|
$(SIM_VLT_DIR)/OrpsocMain.o: |
# Now compile the top level systemC "testbench" module |
# Now compile the top level systemC "testbench" module from the systemC source path |
$(SIM_VLT_DIR)/OrpsocMain.o: $(BENCH_SYSC_SRC_DIR)/OrpsocMain.cpp |
@echo; echo "\tCompiling top level SystemC testbench"; echo |
cd $(SIM_VLT_DIR) && g++ $(VLT_DEBUG_COMPILE_FLAGS) $(VLT_CPPFLAGS) $(TRACE_FLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -c $(BENCH_SYSC_SRC_DIR)/OrpsocMain.cpp |
|
615,7 → 621,7
for SYSCMODEL in $(SYSC_MODELS_BUILD); do \ |
echo;echo "\t$$SYSCMODEL"; echo; \ |
export CXXFLAGS=$(VLT_DEBUG_COMPILE_FLAGS); \ |
export USER_CPPFLAGS="$(VLT_CPPFLAGS)"; \ |
export USER_CPPFLAGS="$(VLT_CPPFLAGS) -I$(BENCH_SYSC_INCLUDE_DIR)"; \ |
export USER_LDDFLAGS="$(VLT_CPPFLAGS)"; \ |
$(MAKE) -f Vorpsoc_top.mk $$SYSCMODEL.o; \ |
done |
640,9 → 646,11
$(MAKE) -C $(BENCH_SYSC_SRC_DIR) -f $(BENCH_SYSC_SRC_DIR)/Modules.make $(VLT_SYSC_DEBUG_DEFINE) |
|
|
ALL_VLOG=$(shell find $(RTL_VERILOG_DIR) -name "*.v") |
|
# Verilator command script |
# Generate the compile script to give Verilator |
$(SIM_VLT_DIR)/$(VLT_COMMAND_FILE).generated: |
# Generate the compile script to give Verilator - make it sensitive to the RTL |
$(SIM_VLT_DIR)/$(VLT_COMMAND_FILE).generated: $(ALL_VLOG) |
@echo; echo "\tGenerating verilator compile script"; echo |
@sed < $(SIM_BIN_DIR)/$(VLT_COMMAND_FILE) > $(SIM_VLT_DIR)/$(VLT_COMMAND_FILE).generated \ |
-e s!\$$BENCH_DIR!$(BENCH_VERILOG_DIR)! \ |
764,7 → 772,7
|
clean-sim: |
#backup any profiling output files |
@if [ -f $(SIM_VLT_DIR)/OrpsocMain.gcda ]; then echo "\tBacking up verilator profiling output"; \ |
@if [ -f $(SIM_VLT_DIR)/OrpsocMain.gcda ]; then echo;echo "\tBacking up verilator profiling output to /tmp"; echo; \ |
cp $(SIM_VLT_DIR)/*.gc* /tmp; \ |
cp $(BENCH_SYSC_SRC_DIR)/*.gc* /tmp; fi |
rm -rf $(SIM_RESULTS_DIR) $(SIM_RUN_DIR)/*.* $(SIM_VLT_DIR) |
/orpsocv2/sw/support/time.c
10,7 → 10,7
#define USEC_PER_TICK (USEC_PER_SEC/TICKS_PER_SEC) |
|
unsigned long tick_period = SYS_CLKS_PER_TICK; |
unsigned long usec, msec, sec; // simple usec counter |
unsigned long usec, msec, sec; |
|
/* Start the timer, enabling interrupt, self-restart and set the period */ |
void |
/orpsocv2/sw/support/except.S
25,7 → 25,8
/* r31: EA address of handler */ ;\ |
LOAD_SYMBOL_2_GPR(r12,handler) ;\ |
l.mtspr r0,r12,SPR_EPCR_BASE ;\ |
l.rfe |
l.rfe ;\ |
l.nop |
|
|
#define HANDLER_ENTRY(handler) \ |
162,7 → 163,7
l.lwz r31,0(r1) |
l.lwz r30,4(r1) |
l.addi r1, r1, 8 |
EXCEPTION_HANDLE(_timer_handler) |
EXCEPTION_HANDLE(_timer_handler) |
#endif |
|
.org 0x400 |
245,10 → 246,13
l.jalr r8 |
l.nop |
l.j _ret_from_intr |
l.nop |
|
/* ---[ End of Timer exception ]----------------------------------------- */ |
|
ENTRY(_ret_from_intr) |
RESTORE_ALL |
/* |
// i386 version: |
// GET_CURRENT(%ebx) |
|
258,9 → 262,6
l.sfeqi r3,0 |
l.bnf _restore_all |
l.nop |
/* |
* return to usermode |
*/ |
|
ENTRY(_restore_all) |
// we need to save KSP here too |
268,4 → 269,4
l.addi r4,r1,INT_FRAME_SIZE |
l.sw (TI_KSP)(r10),r4 |
RESTORE_ALL |
|
*/ |