URL
https://opencores.org/ocsvn/s6soc/s6soc/trunk
Subversion Repositories s6soc
Compare Revisions
- This comparison shows the changes necessary to convert path
/s6soc/trunk
- from Rev 9 to Rev 10
- ↔ Reverse comparison
Rev 9 → Rev 10
/bench/cpp/qspiflashsim.cpp
46,9 → 46,10
#include <assert.h> |
#include <stdlib.h> |
|
#include "regdefs.h" |
#include "qspiflashsim.h" |
|
#define MEMBYTES (1<<22) |
#define MEMBYTES (FLASHWORDS<<2) |
|
static const unsigned DEVID = 0x0115, |
DEVESD = 0x014, |
103,6 → 104,15
} |
} |
|
void QSPIFLASHSIM::write(const unsigned addr, const unsigned len, const uint32_t *buf) { |
char *ptr; |
printf("FLASH: Copying into memory at S6Add4 %08x, my addr %08x, %d values\n", |
addr, (addr-SPIFLASH)<<2, len<<2); |
ptr = &m_mem[(addr-SPIFLASH)<<2]; |
memcpy(ptr, buf, len<<2); |
printf("%02x %02x %02x %02x\n", ptr[0]&0x0ff, ptr[1]&0x0ff, ptr[2]&0x0ff, ptr[3]&0x0ff); |
} |
|
#define QOREG(A) m_oreg = ((m_oreg & (~0x0ff))|(A&0x0ff)) |
|
int QSPIFLASHSIM::operator()(const int csn, const int sck, const int dat) { |
/bench/cpp/qspiflashsim.h
39,6 → 39,8
#ifndef QSPIFLASHSIM_H |
#define QSPIFLASHSIM_H |
|
#include <stdint.h> |
|
#define QSPIF_WIP_FLAG 0x0001 |
#define QSPIF_WEL_FLAG 0x0002 |
#define QSPIF_DEEP_POWER_DOWN_FLAG 0x0200 |
74,6 → 76,7
QSPIFLASHSIM(void); |
void load(const char *fname) { load(0, fname); } |
void load(const unsigned addr, const char *fname); |
void write(const unsigned addr, const unsigned len, const uint32_t *buf); |
void debug(const bool dbg) { m_debug = dbg; } |
bool debug(void) const { return m_debug; } |
int operator()(const int csn, const int sck, const int dat); |
/bench/cpp/zip_sim.cpp
1,17 → 1,40
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: zip_sim.cpp |
// |
// Filename: busmaster_tb.cpp |
// Project: CMod S6 System on a Chip, ZipCPU demonstration project |
// |
// Project: FPGA library development (S6 development board) |
// Purpose: This provides a simulation capability for the CMod S6 SoC. |
// |
// Purpose: |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
// Creator: Dan Gisselquist |
// Gisselquist Tecnology, LLC |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright: 2015 |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): 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 MERCHANTIBILITY 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. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
19,15 → 42,19
#include <signal.h> |
#include <time.h> |
#include <unistd.h> |
#include <stdint.h> |
|
#include "verilated.h" |
#include "Vbusmaster.h" |
|
#include "regdefs.h" |
#include "testb.h" |
// #include "twoc.h" |
#include "qspiflashsim.h" |
#include "uartsim.h" |
|
typedef uint32_t BUSW; |
|
class GPIOSIM { |
public: |
unsigned operator()(const unsigned o_gpio) { return 0; } |
97,11 → 124,11
|
if (m_core->o_led != m_last_led) { |
printf("LED: %08x\n", m_core->o_led); |
m_last_led = m_core->o_led; |
} |
|
/* |
|
printf("PC: %08x:%08x [%08x:%08x:%08x:%08x:%08x],%08x,%08x,%d,%08x,%08x\n", |
printf("PC: %08x:%08x [%08x:%08x:%08x:%08x:%08x],%08x,%08x,%d,%08x,%08x (%x,%x)\n", |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__ipc, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__upc, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[0], |
113,10 → 140,24
m_core->v__DOT__thecpu__DOT__thecpu__DOT__r_opB, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction_decoder__DOT__w_dcdR_pc, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__r_opA, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__wr_reg_vl); |
*/ |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__wr_reg_vl, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__w_iflags, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__w_iflags, |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__pf_pc |
); |
if (m_core->v__DOT__wb_cyc) { |
printf("WB: %s/%s/%s[@0x%08x] %08x ->%s/%s %08x\n", |
(m_core->v__DOT__wb_cyc)?"CYC":" ", |
(m_core->v__DOT__wb_stb)?"STB":" ", |
(m_core->v__DOT__wb_we )?"WE ":" ", |
(m_core->v__DOT__w_zip_addr), |
(m_core->v__DOT__wb_data), |
(m_core->v__DOT__wb_ack)?"ACK":" ", |
(m_core->v__DOT__wb_stall)?"STL":" ", |
(m_core->v__DOT__wb_idata) |
); |
} |
|
/* |
if (m_core->v__DOT__thecpu__DOT__thecpu__DOT__pf_valid) |
printf("PC: %08x - %08x, uart=%d,%d, pic = %d,%04x,%0d,%04x\n", |
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction_pc, |
127,6 → 168,8
m_core->v__DOT__pic__DOT__r_any, |
m_core->v__DOT__pic__DOT__r_int_state); |
*/ |
|
printf("%08x\n", m_core->v__DOT__zipt_a__DOT__r_value); |
} |
}; |
|
135,23 → 178,284
bool iself(const char *fname) { |
FILE *fp; |
bool ret = true; |
fp = fopen(fname, "rb"); |
|
if (!fp) |
if ((!fname)||(!fname[0])) |
return false; |
if (0x7f != fgetc(fp)) |
ret = false; |
if ('E' != fgetc(fp)) |
ret = false; |
if ('L' != fgetc(fp)) |
ret = false; |
if ('F' != fgetc(fp)) |
ret = false; |
|
fp = fopen(fname, "rb"); |
|
if (!fp) return false; |
if (0x7f != fgetc(fp)) ret = false; |
if ('E' != fgetc(fp)) ret = false; |
if ('L' != fgetc(fp)) ret = false; |
if ('F' != fgetc(fp)) ret = false; |
fclose(fp); |
return ret; |
return ret; |
} |
|
long fgetwords(FILE *fp) { |
// Return the number of words in the current file, and return the |
// file as though it had never been adjusted |
long fpos, flen; |
fpos = ftell(fp); |
if (0 != fseek(fp, 0l, SEEK_END)) { |
fprintf(stderr, "ERR: Could not determine file size\n"); |
perror("O/S Err:"); |
exit(-2); |
} flen = ftell(fp); |
if (0 != fseek(fp, fpos, SEEK_SET)) { |
fprintf(stderr, "ERR: Could not seek on file\n"); |
perror("O/S Err:"); |
exit(-2); |
} flen /= sizeof(BUSW); |
return flen; |
} |
|
class SECTION { |
public: |
unsigned m_start, m_len; |
BUSW m_data[1]; |
}; |
|
SECTION **singlesection(int nwords) { |
fprintf(stderr, "NWORDS = %d\n", nwords); |
size_t sz = (2*(sizeof(SECTION)+sizeof(SECTION *)) |
+(nwords-1)*(sizeof(BUSW))); |
char *d = (char *)malloc(sz); |
SECTION **r = (SECTION **)d; |
memset(r, 0, sz); |
r[0] = (SECTION *)(&d[2*sizeof(SECTION *)]); |
r[0]->m_len = nwords; |
r[1] = (SECTION *)(&r[0]->m_data[r[0]->m_len]); |
r[0]->m_start = 0; |
r[1]->m_start = 0; |
r[1]->m_len = 0; |
|
return r; |
} |
|
SECTION **rawsection(const char *fname) { |
SECTION **secpp, *secp; |
unsigned num_words; |
FILE *fp; |
int nr; |
|
fp = fopen(fname, "r"); |
if (fp == NULL) { |
fprintf(stderr, "Could not open: %s\n", fname); |
exit(-1); |
} |
|
if ((num_words=fgetwords(fp)) > FLASHWORDS) { |
fprintf(stderr, "File overruns flash memory\n"); |
exit(-1); |
} |
secpp = singlesection(num_words); |
secp = secpp[0]; |
secp->m_start = RESET_ADDRESS; |
secp->m_len = num_words; |
nr= fread(secp->m_data, sizeof(BUSW), num_words, fp); |
if (nr != (int)num_words) { |
fprintf(stderr, "Could not read entire file\n"); |
perror("O/S Err:"); |
exit(-2); |
} assert(secpp[1]->m_len == 0); |
|
return secpp; |
} |
|
unsigned byteswap(unsigned n) { |
unsigned r; |
|
r = (n&0x0ff); n>>= 8; |
r = (r<<8) | (n&0x0ff); n>>= 8; |
r = (r<<8) | (n&0x0ff); n>>= 8; |
r = (r<<8) | (n&0x0ff); n>>= 8; |
|
return r; |
} |
|
#include <libelf.h> |
#include <gelf.h> |
|
void elfread(const char *fname, unsigned &entry, SECTION **§ions) { |
Elf *e; |
int fd, i; |
size_t n; |
char *id; |
Elf_Kind ek; |
GElf_Ehdr ehdr; |
GElf_Phdr phdr; |
const bool dbg = false; |
|
if (elf_version(EV_CURRENT) == EV_NONE) { |
fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1)); |
perror("O/S Err:"); |
exit(EXIT_FAILURE); |
} if ((fd = open(fname, O_RDONLY, 0)) < 0) { |
fprintf(stderr, "Could not open %s\n", fname); |
perror("O/S Err:"); |
exit(EXIT_FAILURE); |
} if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) { |
fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} |
|
ek = elf_kind(e); |
if (ek == ELF_K_ELF) { |
; // This is the kind of file we should expect |
} else if (ek == ELF_K_AR) { |
fprintf(stderr, "Cannot run an archive!\n"); |
exit(EXIT_FAILURE); |
} else if (ek == ELF_K_NONE) { |
; |
} else { |
fprintf(stderr, "Unexpected ELF file kind!\n"); |
exit(EXIT_FAILURE); |
} |
|
if (gelf_getehdr(e, &ehdr) == NULL) { |
fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} if ((i=gelf_getclass(e)) == ELFCLASSNONE) { |
fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} if ((id = elf_getident(e, NULL)) == NULL) { |
fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} if (i != ELFCLASS32) { |
fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n"); |
exit(EXIT_FAILURE); |
} |
|
if (dbg) { |
printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type); |
printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine); |
printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version); |
printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry); |
printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff); |
printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff); |
printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags); |
printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize); |
printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize); |
printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize); |
printf("\n"); |
} |
|
|
// Check whether or not this is an ELF file for the ZipCPU ... |
if (ehdr.e_machine != 0x0dadd) { |
fprintf(stderr, "This is not a ZipCPU ELF file\n"); |
exit(EXIT_FAILURE); |
} |
|
// Get our entry address |
entry = ehdr.e_entry; |
|
|
// Now, let's go look at the program header |
if (elf_getphdrnum(e, &n) != 0) { |
fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} |
|
unsigned total_octets = 0, current_offset=0, current_section=0; |
for(i=0; i<(int)n; i++) { |
total_octets += sizeof(SECTION *)+sizeof(SECTION); |
|
if (gelf_getphdr(e, i, &phdr) != &phdr) { |
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} |
|
if (dbg) { |
printf(" %-20s 0x%x\n", "p_type", phdr.p_type); |
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset); |
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr); |
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr); |
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz); |
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz); |
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags); |
|
if (phdr.p_flags & PF_X) printf(" Execute"); |
if (phdr.p_flags & PF_R) printf(" Read"); |
if (phdr.p_flags & PF_W) printf(" Write"); |
printf("]\n"); |
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align); |
} |
|
total_octets += phdr.p_memsz; |
} |
|
char *d = (char *)malloc(total_octets + sizeof(SECTION)+sizeof(SECTION *)); |
memset(d, 0, total_octets); |
|
SECTION **r = sections = (SECTION **)d; |
current_offset = (n+1)*sizeof(SECTION *); |
current_section = 0; |
|
for(i=0; i<(int)n; i++) { |
r[i] = (SECTION *)(&d[current_offset]); |
|
if (gelf_getphdr(e, i, &phdr) != &phdr) { |
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1)); |
exit(EXIT_FAILURE); |
} |
|
if (dbg) { |
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset); |
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr); |
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr); |
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz); |
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz); |
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags); |
|
if (phdr.p_flags & PF_X) printf(" Execute"); |
if (phdr.p_flags & PF_R) printf(" Read"); |
if (phdr.p_flags & PF_W) printf(" Write"); |
printf("]\n"); |
|
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align); |
} |
|
current_section++; |
|
r[i]->m_start = phdr.p_vaddr; |
r[i]->m_len = phdr.p_filesz/ sizeof(BUSW); |
|
current_offset += phdr.p_memsz + sizeof(SECTION); |
|
// Now, let's read in our section ... |
if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) { |
fprintf(stderr, "Could not seek to file position %08lx\n", phdr.p_offset); |
perror("O/S Err:"); |
exit(EXIT_FAILURE); |
} if (phdr.p_filesz > phdr.p_memsz) |
phdr.p_filesz = 0; |
if (read(fd, r[i]->m_data, phdr.p_filesz) != (int)phdr.p_filesz) { |
fprintf(stderr, "Didnt read entire section\n"); |
perror("O/S Err:"); |
exit(EXIT_FAILURE); |
} |
|
// Next, we need to byte swap it from big to little endian |
for(unsigned j=0; j<r[i]->m_len; j++) |
r[i]->m_data[j] = byteswap(r[i]->m_data[j]); |
|
if (dbg) for(unsigned j=0; j<r[i]->m_len; j++) |
fprintf(stderr, "ADR[%04x] = %08x\n", r[i]->m_start+j, |
r[i]->m_data[j]); |
} |
|
r[i] = (SECTION *)(&d[current_offset]); |
r[current_section]->m_start = 0; |
r[current_section]->m_len = 0; |
|
elf_end(e); |
close(fd); |
} |
|
|
void usage(void) { |
fprintf(stderr, "Usage: zip_sim flash_program\n"); |
} |
176,28 → 480,16
fprintf(stderr, "Cannot read code filename, %s\n", codef); |
|
if (iself(codef)) { |
char tmpbuf[TMP_MAX], cmdbuf[256]; |
int unused_fd; |
strcpy(tmpbuf, "/var/tmp/zipsimXXXX"); |
SECTION **secpp, *secp; |
BUSW entry; |
elfread(codef, entry, secpp); |
|
// Make a temporary file |
unused_fd = mkostemp(tmpbuf, O_CREAT|O_TRUNC|O_RDWR); |
// Close it, though, since we don't want to write to it here |
close(unused_fd); |
|
// Now we right to it, as part of calling objcopy |
sprintf(cmdbuf, "zip-objcopy -S -O binary --reverse-bytes=4 %s %s\n", |
codef, tmpbuf); |
if (system(cmdbuf) != 0) { |
unlink(tmpbuf); |
fprintf(stderr, "ZIP_SIM::Could not convert ELF binary to a raw file\n"); |
exit(-2); |
for(int i=0; secpp[i]->m_len; i++) { |
secp = secpp[i]; |
tb->m_flash.write(secp->m_start, secp->m_len, secp->m_data); |
} |
|
tb->m_flash.load(0x0400, tmpbuf); |
unlink(tmpbuf); |
} else { |
tb->m_flash.load(0x0400, codef); |
tb->m_flash.load(RESET_ADDRESS, codef); |
} |
|
tb->reset(); |
208,4 → 500,3
printf("SUCCESS!\n"); |
exit(0); |
} |
|
/bench/cpp/Makefile
36,13 → 36,14
|
CXX := g++ |
FLAGS := -Wall -Og -g |
ZASM := ../../sw/zasm |
SWHOST := ../../sw/host |
RTLD := ../../rtl |
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I/usr/share/verilator/include -I$(ZASM) |
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I/usr/share/verilator/include \ |
-I$(SWHOST) |
SOURCES := zip_sim.cpp twoc.cpp qspiflashsim.cpp uartsim.cpp |
VLIB := /usr/share/verilator/include/verilated.cpp |
RAWLIB := $(VLIB) $(RTLD)/obj_dir/Vbusmaster__ALL.a |
LIBS := $(RAWLIB) |
LIBS := $(RAWLIB) -lelf |
TESTF := $(ZASM)/z.out |
DHRYSTONEF := ../asm/zipdhry.z |
|