OpenCores
URL https://opencores.org/ocsvn/qspiflash/qspiflash/trunk

Subversion Repositories qspiflash

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /qspiflash/trunk
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/bench/cpp/qspiflashsim.cpp
1,25 → 1,24
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename: spiflashsim.cpp
// Filename: qspiflashsim.cpp
//
// Project: Wishbone Controlled Quad SPI Flash Controller
//
// Purpose: This library simulates the operation of a Quad-SPI commanded
// flash, such as the S25FL032P used on the Basys-3 development
// board by Digilent. As such, it is defined by 32 Mbits of
// memory (4 Mbyte).
// board by Digilent.
//
// This simulator is useful for testing in a Verilator/C++
// environment, where this simulator can be used in place of
// the actual hardware.
//
// Creator: Dan Gisselquist
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2017, 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
32,7 → 31,7
// 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
// 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.
//
40,16 → 39,17
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
 
#include "qspiflashsim.h"
 
#define MEMBYTES (1<<22)
 
static const unsigned DEVID = 0x0115,
DEVESD = 0x014,
MICROSECONDS = 100,
66,8 → 66,10
// tPP = 1200 * MICROSECONDS,
// tSE = 1500 * MILLISECONDS;
 
QSPIFLASHSIM::QSPIFLASHSIM(void) {
m_mem = new char[MEMBYTES];
QSPIFLASHSIM::QSPIFLASHSIM(const int lglen, bool debug) {
m_membytes = (1<<lglen);
m_memmask = (m_membytes - 1);
m_mem = new char[m_membytes];
m_pmem = new char[256];
m_state = QSPIF_IDLE;
m_last_sck = 1;
78,19 → 80,21
m_quad_mode = false;
m_mode_byte = 0;
 
memset(m_mem, 0x0ff, MEMBYTES);
memset(m_mem, 0x0ff, m_membytes);
}
 
void QSPIFLASHSIM::load(const unsigned addr, const char *fname) {
FILE *fp;
size_t len;
int nr = 0;
 
if (addr >= MEMBYTES)
if (addr >= m_membytes)
return;
len = MEMBYTES-addr*4;
// If not given, then length is from the given address until the end
// of the flash memory
len = m_membytes-addr*4;
 
if (NULL != (fp = fopen(fname, "r"))) {
int nr = 0;
nr = fread(&m_mem[addr], sizeof(char), len, fp);
fclose(fp);
if (nr == 0) {
101,8 → 105,17
fprintf(stderr, "SPI-FLASH: Could not open %s\n", fname);
perror("O/S Err:");
}
 
for(unsigned i=nr; i<m_membytes; i++)
m_mem[i] = 0x0ff;
}
 
void QSPIFLASHSIM::load(const uint32_t offset, const char *data, const uint32_t len) {
uint32_t moff = (offset & (m_memmask));
 
memcpy(&m_mem[moff], data, len);
}
 
#define QOREG(A) m_oreg = ((m_oreg & (~0x0ff))|(A&0x0ff))
 
int QSPIFLASHSIM::operator()(const int csn, const int sck, const int dat) {
165,7 → 178,7
m_state = QSPIF_IDLE;
m_sreg &= (~QSPIF_WEL_FLAG);
m_sreg |= (QSPIF_WIP_FLAG);
for(int i=0; i<MEMBYTES; i++)
for(unsigned i=0; i<m_membytes; i++)
m_mem[i] = 0x0ff;
} else if (m_state == QSPIF_DEEP_POWER_DOWN) {
m_write_count = tDP;
219,8 → 232,8
if (m_count == 24) {
if (m_debug) printf("QSPI: Entering from Quad-Read Idle to Quad-Read\n");
if (m_debug) printf("QSPI: QI/O Idle Addr = %02x\n", m_ireg&0x0ffffff);
m_addr = (m_ireg) & 0x0ffffff;
assert((m_addr & 0xfc00000)==0);
m_addr = (m_ireg) & m_memmask;
assert((m_addr & (~(m_memmask)))==0);
m_state = QSPIF_QUAD_READ;
} m_oreg = 0;
} else if (m_count == 8) {
362,7 → 375,7
break;
case QSPIF_RDID:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & m_memmask;
if (m_debug) printf("READID, ADDR = %08x\n", m_addr);
QOREG((DEVID>>8));
if (m_debug) printf("QSPI: READING ID, %02x\n", (DEVID>>8)&0x0ff);
386,10 → 399,10
break;
case QSPIF_FAST_READ:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & m_memmask;
if (m_debug) printf("FAST READ, ADDR = %08x\n", m_addr);
QOREG(0x0c3);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(m_memmask)))==0);
} else if ((m_count >= 40)&&(0 == (m_sreg&0x01))) {
//if (m_count == 40)
//printf("DUMMY BYTE COMPLETE ...\n");
402,10 → 415,10
// that changes the timings, else we'd use quad_Read
// below
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & m_memmask;
// printf("FAST READ, ADDR = %08x\n", m_addr);
// printf("QSPI: QUAD READ, ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(m_memmask)))==0);
} else if (m_count == 32+24) {
m_mode_byte = (m_ireg>>16) & 0x0ff;
// printf("QSPI: MODE BYTE = %02x\n", m_mode_byte);
426,9 → 439,9
break;
case QSPIF_PP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & m_memmask;
if (m_debug) printf("QSPI: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(m_memmask)))==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
439,10 → 452,10
} break;
case QSPIF_QPP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & m_memmask;
m_quad_mode = true;
if (m_debug) printf("QSPI/QR: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(m_memmask)))==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
/bench/cpp/qspiflashsim.h
1,6 → 1,6
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Filename: spiflashsim.h
// Filename: qspiflashsim.h
//
// Project: Wishbone Controlled Quad SPI Flash Controller
//
9,12 → 9,12
// board by Digilent. As such, it is defined by 32 Mbits of
// memory (4 Mbyte).
//
// Creator: Dan Gisselquist
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2017, 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
27,7 → 27,7
// 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
// 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.
//
35,7 → 35,9
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef QSPIFLASHSIM_H
#define QSPIFLASHSIM_H
 
67,15 → 69,33
char *m_mem, *m_pmem;
int m_last_sck;
unsigned m_write_count, m_ireg, m_oreg, m_sreg, m_addr,
m_count, m_config, m_mode_byte, m_creg;
m_count, m_config, m_mode_byte, m_creg, m_membytes,
m_memmask;
bool m_quad_mode, m_debug;
 
public:
QSPIFLASHSIM(void);
QSPIFLASHSIM(const int lglen = 24, bool debug = false);
void load(const char *fname) { load(0, fname); }
void load(const unsigned addr, const char *fname);
void load(const uint32_t offset, const char *data, const uint32_t len);
void debug(const bool dbg) { m_debug = dbg; }
bool debug(void) const { return m_debug; }
unsigned operator[](const int index) {
unsigned char *cptr = (unsigned char *)&m_mem[index<<2];
unsigned v;
v = (*cptr++);
v = (v<<8)|(*cptr++);
v = (v<<8)|(*cptr++);
v = (v<<8)|(*cptr);
 
return v; }
void set(const unsigned addr, const unsigned val) {
unsigned char *cptr = (unsigned char *)&m_mem[addr<<2];
*cptr++ = (val>>24);
*cptr++ = (val>>16);
*cptr++ = (val>> 8);
*cptr = (val);
return;}
int operator()(const int csn, const int sck, const int dat);
};
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.