Article View: comp.lang.verilog
Article #67Re: Simulating processor architectures
From: Rob Warnock
Date: Fri, 21 Aug 1992 04:22
Date: Fri, 21 Aug 1992 04:22
256 lines
8167 bytes
8167 bytes
kuttanna@eemips.tamu.edu (Belliappa Kuttanna) writes:
+---------------
| the gnu CC compiler can generate code using this instruction set.
| However, I do not know how to generate the Verilog input from the
| a.out or the assembly code file, without having to develop some
| software specifically for this purpose.
+---------------
Actually, the easiest thing would be to "develop some software specifically
for this purpose". That's what I did. I wrote a hack about a year ago I
call "o2rmh", that takes a couple of formats of COFF files (AMD 29000
standard and gas/29k) and writes files suitable for reading into Verilog
with $readmemh(). You use it like this:
% cat foo.s
; test 29030 I-cache -- XXX stub only
.include "std0.h"
mtsrim CFG, 0 ; enable cache
mtsrim CPS, 0x73 ; leave FZ mode
nop ; don't jump back here (erratum #4)
nop
nop ; ditto
nop
nop
const v0, 0x1234
loop:
jmp loop ; tight loop [note "store" in dly slot]
store 0, 0, v0, 0x98 ; i.e. loc 98 gets 1234
nop
nop
nop ; filler for prefetch
nop
nop
nop
.end
% gas29 -o foo.o foo.s
% o2rmh -o foo.rmh foo.o
'foo.o': GNU .o/a.out format
% cat foo.rmh
// [generated by o2rmh]
04000300 04000273 70400101 70400101
70400101 70400101 70400101 03126034
a0000000 1f006098 70400101 70400101
70400101 70400101 70400101 70400101
Then in your Verilog simulation you just $readmemh("foo.rmh", instruction_mem).
Attached below find the source for "o2rmh.c". It's an ugly hack, is missing
many features (relocation, etc.), and may not do what you want, but what do
you expect? I threw it together in an hour or two.
Note: I have *not* included the required AMD-specific include file "coff.h"
(which probably contains licensed AT&T Unix material), so you will have to
fix that part up for yourself. [Hint: Just rip out (or fix) the part that
starts with "if (fh->f_magic == SIPFBOMAGIC)". The demo output above uses
the GNU assembler format, which *is* included.
In any case, you should be able to modify it easily for your format...
-Rob
-----
Rob Warnock, MS-9U/510 rpw3@sgi.com
Silicon Graphics, Inc. (415)390-1673
2011 N. Shoreline Blvd.
Mountain View, CA 94043
============== attachment ===============================================
/*
** Copyright 1991, 1992 Silicon Graphics Inc.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appears in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation, and that the name of SGI not be used in advertising
** or publicity pertaining to distribution of the software without specific,
** written prior permission. SGI makes no representations about the
** suitability of this software for any purpose. It is provided "as is"
** without express or implied warranty.
**
** SGI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SGI
** BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
** OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
** CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**
**
** Author: Rob Warnock <rpw3@sgi.com>
*/
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <malloc.h>
#include <string.h>
#include "coff.h" /* Note: 29000 version of COFF */
struct gnuhdr /* simpler to copy than include */
{
u_long a_info; /* Use macros N_MAGIC, etc for access */
#define GNUOBJMAGIC 0407
u_long a_text; /* length of text, in bytes */
u_long a_data; /* length of data, in bytes */
u_long a_bss; /* length of bss, in bytes */
u_long a_syms; /* length of sym tab data in file, in bytes */
u_long a_entry; /* start address */
u_long a_trsize; /* length of reloc info for text, in bytes */
u_long a_drsize; /* length of reloc info for data, in bytes */
};
extern char *optarg;
extern int optind, opterr;
char *myname;
int fd;
/*
* error message routine (non-varargs version):
* fatal(printf_args...) ==> fprintf(stderr,printf_args...), then exit(errno).
*/
fatal(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
char * fmt;
int x0,x1,x2,x3,x4,x5,x6,x7,x8,x9;
{
char real_fmt[1024];
extern int errno;
sprintf(real_fmt, "%s: %s\n", myname, fmt);
fprintf(stderr, real_fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
exit(errno?errno:EINVAL);
}
/*
* the usual main program template...
*/
main(int argc, char **argv)
{
int c, i, n, errs = 0;
if ((myname = strrchr(argv[0], '/') + 1) == ((char*)NULL) + 1)
myname = argv[0];
while ((c = getopt(argc, argv, "o:")) != EOF) switch (c) {
case 'o':
if (freopen(optarg, "w", stdout) == NULL)
fatal("cannot open output file '%s'", optarg);
break;
case '?':
default: ++errs;
}
if (argc - optind < 1 || errs) {
fprintf(stderr, "usage: o2rmh [-o outputfile] obj_file(s)...\n");
exit(1);
}
while (argc - optind > 0)
read_and_load(argv[optind++]);
exit(0);
}
/*
* This version of read_and_load() is about as subtle as a 20 kton nuke
*/
read_and_load(char *fname)
{
#define MONGO (262144 + 20000) /* max SRAM + room for some syms */
int fd2 = open(fname, 0);
static void *fbuf;
int len;
struct filehdr *fh; /* AMD COFF header */
struct aouthdr *ah;
struct scnhdr *sh;
struct gnuhdr *gh; /* GNU a.out header */
u_char *txtp;
int tlen;
if (fd2 < 0) {
fatal("Can't open file '%s': %s (%d)\n",
fname, sys_errlist[errno], errno);
}
if (!fbuf && !(fbuf = malloc(MONGO))) {
fatal("read_and_load: Can't get enough memory\n");
}
if ((len = read(fd2, fbuf, MONGO)) < 0) {
fatal("Error reading file '%s': %s (%d)\n",
fname, sys_errlist[errno], errno);
}
if (len == MONGO) {
fatal("File '%s' too large\n", fname);
}
/*
* alias to various possibilities of .o formats
*/
fh = (struct filehdr *)fbuf;
gh = (struct gnuhdr *)fbuf;
if (fh->f_magic == SIPFBOMAGIC) { /* first try AMD COFF format */
fprintf(stderr, "'%s': COFF .o/a.out format\n", fname);
sh = (struct scnhdr *)((u_long)fbuf + sizeof(*fh));
if (fh->f_opthdr) {
ah = (struct aouthdr *)sh;
sh = (struct scnhdr *)((u_long)sh + fh->f_opthdr);
} else
ah = 0;
if (!(sh->s_flags & STYP_TEXT)) {
fatal("File '%s' 1st section type (%x) not executable text\n",
fname, sh->s_flags);
}
txtp = (u_char *)fbuf + sh->s_scnptr;
tlen = sh->s_size;
} else if (gh->a_info == GNUOBJMAGIC) { /* how about GNU .o? */
fprintf(stderr, "'%s': GNU .o/a.out format\n", fname);
txtp = (u_char *)fbuf + sizeof(*gh);
tlen = gh->a_text;
} else {
fatal("File '%s' bad magic number %x, no known Am29000 .o format\n",
fname, fh->f_magic);
}
if (tlen % sizeof(u_long)) {
fatal("File '%s' text section size (%d) not whole words\n",
fname, tlen);
}
do_dma(txtp, /*opt_LoadAddr,*/ tlen);
/* opt_LoadAddr += tlen; */ /* assert: tlen%4 == 0 */
}
/*
* Output image in $readmemh() format.
* (Historical name, from when the object file
* would actually get downloaded at this point...)
*/
do_dma(u_char *p, int n)
{
int i;
printf("// [generated by o2rmh]\n\n");
for (i = 0, n/= 4; i < n; ++i) {
printf("%8.8x ", ((u_long *)p)[i]);
if (i%4 == 3)
printf("\n");
}
printf("\n");
}
Technical Details
Message-ID:
<or6oej4@sgi.sgi.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!swrinde!mips!mips!decwrl!sgi!rigden.wpd.sgi.com!rpw3Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!swrinde!mips!mips!decwrl!sgi!rigden.wpd.sgi.com!rpw3 From: rpw3@rigden.wpd.sgi.com (Rob Warnock) Newsgroups: comp.lang.verilog Subject: Re: Simulating processor architectures Message-ID: <or6oej4@sgi.sgi.com> Date: 21 Aug 92 04:22:52 GMT Sender: rpw3@rigden.wpd.sgi.com Organization: Silicon Graphics, Inc. Mountain View, CA Lines: 256