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

Subversion Repositories openarty

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openarty
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/bench/cpp/enetctrlsim.h
0,0 → 1,59
////////////////////////////////////////////////////////////////////////////////
//
// Filename: enetsim.h
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 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
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef ENETCTRLSIM_H
#define ENETCTRLSIM_H
 
#define ENET_MEMWORDS 32
class ENETCTRLSIM {
int m_consecutive_clocks, m_lastout,
m_tickcount, m_ticks_per_clock, m_lastclk;
int TICKS_PER_CLOCK, PHY_ADDR;
int m_mem[ENET_MEMWORDS];
 
public:
bool m_synched;
int m_datareg, m_halfword, m_outreg;
ENETCTRLSIM(void);
~ENETCTRLSIM(void) {}
 
int operator()(int clk, int data);
int operator[](int index) const;
};
 
#endif // ENETCTRLSIM_H
 
/trunk/bench/cpp/eqspiflash_tb.cpp
0,0 → 1,619
#include "verilated.h"
#include "Veqspiflash.h"
#include "eqspiflashsim.h"
 
#define QSPIFLASH 0x0400000
const int BOMBCOUNT = 2048;
 
class EQSPIFLASH_TB {
long m_tickcount;
Veqspiflash *m_core;
EQSPIFLASHSIM *m_flash;
bool m_bomb;
public:
 
EQSPIFLASH_TB(void) {
m_core = new Veqspiflash;
m_flash= new EQSPIFLASHSIM;
}
 
unsigned operator[](const int index) { return (*m_flash)[index]; }
void setflash(unsigned addr, unsigned v) {
m_flash->set(addr, v);
}
void load(const char *fname) {
m_flash->load(0,fname);
}
 
void tick(void) {
m_core->i_clk_200mhz = 1;
 
m_core->i_qspi_dat = (*m_flash)(m_core->o_qspi_cs_n,
m_core->o_qspi_sck, m_core->o_qspi_dat);
 
printf("%08lx-WB: %s %s/%s %s %s[%s%s%s%s%s] %s %s@0x%08x[%08x/%08x] -- SPI %s%s[%x/%x](%d,%d)",
m_tickcount,
(m_core->i_wb_cyc)?"CYC":" ",
(m_core->i_wb_data_stb)?"DSTB":" ",
(m_core->i_wb_ctrl_stb)?"CSTB":" ",
(m_core->o_wb_stall)?"STALL":" ",
(m_core->o_wb_ack)?"ACK":" ",
(m_core->v__DOT__bus_wb_ack)?"BS":" ",
(m_core->v__DOT__rd_data_ack)?"RD":" ",
(m_core->v__DOT__ew_data_ack)?"EW":" ",
(m_core->v__DOT__id_data_ack)?"ID":" ",
(m_core->v__DOT__ct_data_ack)?"CT":" ",
(m_core->o_cmd_accepted)?"BUS":" ",
(m_core->i_wb_we)?"W":"R",
(m_core->i_wb_addr), (m_core->i_wb_data),
(m_core->o_wb_data),
(!m_core->o_qspi_cs_n)?"CS":" ",
(m_core->o_qspi_sck)?"CK":" ",
(m_core->o_qspi_dat), (m_core->i_qspi_dat),
(m_core->o_qspi_dat)&1, ((m_core->i_qspi_dat)&2)?1:0);
 
/// printf("%08lx-EQ: ", m_tickcount);
printf("EQ: ");
if (m_core->v__DOT__owned) {
switch(m_core->v__DOT__owner&3) {
case 0: printf("RD"); break;
case 1: printf("EW"); break;
case 2: printf("ID"); break;
case 3: printf("CT"); break;
}
} else printf(" ");
 
printf(" REQ[%s%s%s%s]",
(m_core->v__DOT__rd_qspi_req)?"RD":" ",
(m_core->v__DOT__ew_qspi_req)?"EW":" ",
(m_core->v__DOT__id_qspi_req)?"ID":" ",
(m_core->v__DOT__ct_qspi_req)?"CT":" ");
 
printf(" %s[%s%2d%s%s0x%08x]",
(m_core->v__DOT__spi_wr)?"CMD":" ",
(m_core->v__DOT__spi_hold)?"HLD":" ",
(m_core->v__DOT__spi_len+1)*8,
(m_core->v__DOT__spi_dir)?"RD":"WR",
(m_core->v__DOT__spi_spd)?"Q":" ",
(m_core->v__DOT__spi_word));
 
printf(" STATE[%2x%s,%2x%s,%2x%s,%2x%s]",
m_core->v__DOT__rdproc__DOT__rd_state,
(m_core->v__DOT__rd_spi_wr)?"W":" ",
m_core->v__DOT__ewproc__DOT__wr_state,
(m_core->v__DOT__ew_spi_wr)?"W":" ",
m_core->v__DOT__idotp__DOT__id_state,
(m_core->v__DOT__id_spi_wr)?"W":" ",
m_core->v__DOT__ctproc__DOT__ctstate,
(m_core->v__DOT__ct_spi_wr)?"W":" ");
 
printf(" LL:[%s%s%d(%08x)->%08x]",
(m_core->v__DOT__spi_busy)?"BSY":" ",
(m_core->v__DOT__lowlvl__DOT__rd_valid)?"VAL":" ",
(m_core->v__DOT__lowlvl__DOT__state),
(m_core->v__DOT__lowlvl__DOT__r_input),
(m_core->v__DOT__spi_out));
 
// printf(" 0x%08x,%02x ", m_core->v__DOT__id_data,
// m_core->v__DOT__bus_addr);
printf(" %s%08x@%08x",
(m_core->v__DOT__bus_wr)?"W":"R",
m_core->v__DOT__bus_data, m_core->v__DOT__bus_addr);
 
if (m_core->v__DOT__idotp__DOT__id_state == 5)
printf(" %s[%2x]%s",
(m_core->v__DOT__idotp__DOT__last_addr)?"LST":" ",
(m_core->v__DOT__idotp__DOT__lcl_id_addr),
(m_core->v__DOT__idotp__DOT__id_loaded)?"LOD":" ");
 
printf(" %s[%08x]",
(m_core->v__DOT__idotp__DOT__nxt_data_ack)
?"NXT":" ", m_core->v__DOT__idotp__DOT__nxt_data);
printf(" %s[%x]",
(m_core->v__DOT__idotp__DOT__set_val)?"SET":" ",
(m_core->v__DOT__idotp__DOT__set_addr));
 
{
unsigned counts = m_flash->counts_till_idle();
if (counts)
printf(" %8d ", counts);
}
printf("%s%s%s%s",
(m_core->v__DOT__rdproc__DOT__accepted)?"RD-ACC":"",
(m_core->v__DOT__ewproc__DOT__accepted)?"EW-ACC":"",
(m_core->v__DOT__idotp__DOT__accepted)?"ID-ACC":"",
(m_core->v__DOT__ctproc__DOT__accepted)?"CT-ACC":"");
 
 
printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(m_core->v__DOT__preproc__DOT__pending)?" PENDING":"",
(m_core->v__DOT__preproc__DOT__lcl_key)?" KEY":"",
(m_core->v__DOT__preproc__DOT__ctreg_stb)?" CTSTB":"",
(m_core->v__DOT__bus_ctreq)?" BUSCTRL":"",
(m_core->v__DOT__bus_other_req)?" BUSOTHER":"",
(m_core->v__DOT__preproc__DOT__wp)?" WP":"",
(m_core->v__DOT__bus_wip)?" WIP":"",
// (m_core->v__DOT__preproc__DOT__lcl_reg)?" LCLREG":"",
// (m_core->v__DOT__w_xip)?" XIP":"",
// (m_core->v__DOT__w_quad)?" QUAD":"",
// (m_core->v__DOT__bus_piperd)?" RDPIPE":"",
(m_core->v__DOT__preproc__DOT__wp)?" WRWP":"",
(m_core->v__DOT__ewproc__DOT__cyc)?" WRCYC":"",
(m_core->v__DOT__bus_pipewr)?" WRPIPE":"",
(m_core->v__DOT__bus_endwr)?" ENDWR":"",
(m_core->v__DOT__ct_ack)?" CTACK":"",
(m_core->v__DOT__rd_bus_ack)?" RDACK":"",
(m_core->v__DOT__id_bus_ack)?" IDACK":"",
(m_core->v__DOT__ew_bus_ack)?" EWACK":"",
(m_core->v__DOT__preproc__DOT__lcl_ack)?" LCLACK":"",
(m_core->v__DOT__rdproc__DOT__r_leave_xip)?" LVXIP":"",
(m_core->v__DOT__preproc__DOT__new_req)?" NREQ":"");
 
printf("%s%s%s",
(m_core->v__DOT__bus_idreq)?" BUSID":"",
(m_core->v__DOT__id_bus_ack)?" BUSAK":"",
(m_core->v__DOT__idotp__DOT__id_read_request)?" IDRD":"");
 
printf("\n");
 
m_core->eval();
m_core->i_clk_200mhz = 0;
m_core->eval();
 
m_tickcount++;
 
/*
if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
printf("SETTING ERR TO TRUE!!!!! ACK w/ no CYC\n");
// m_bomb = true;
}
*/
}
 
void wb_tick(void) {
printf("WB-TICK()\n");
m_core->i_wb_cyc = 0;
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
tick();
}
 
unsigned wb_read(unsigned a) {
int errcount = 0;
unsigned result;
 
printf("WB-READ(%08x)\n", a);
 
m_core->i_wb_cyc = 1;
m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
m_core->i_wb_we = 0;
m_core->i_wb_addr= a & 0x03fffff;
 
if (m_core->o_wb_stall)
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
tick();
else
tick();
 
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
while((errcount++ < BOMBCOUNT)&&(!m_core->o_wb_ack))
tick();
 
 
result = m_core->o_wb_data;
 
// Release the bus?
m_core->i_wb_cyc = 0;
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} else if (!m_core->o_wb_ack) {
printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
m_bomb = true;
}
tick();
 
return result;
}
 
void wb_read(unsigned a, int len, unsigned *buf) {
int errcount = 0;
int THISBOMBCOUNT = BOMBCOUNT * len;
int cnt, rdidx, inc;
 
printf("WB-READ(%08x, %d)\n", a, len);
 
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
wb_tick();
 
if (errcount >= BOMBCOUNT) {
m_bomb = true;
return;
}
 
errcount = 0;
m_core->i_wb_cyc = 1;
m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
m_core->i_wb_we = 0;
m_core->i_wb_addr= a & 0x03fffff;
 
rdidx =0; cnt = 0;
inc = (m_core->i_wb_data_stb);
 
do {
int s;
s = (m_core->o_wb_stall==0)?0:1;
tick();
if (!s)
m_core->i_wb_addr += inc;
cnt += (s==0)?1:0;
if (m_core->o_wb_ack)
buf[rdidx++] = m_core->o_wb_data;
} while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
 
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
tick();
if (m_core->o_wb_ack)
buf[rdidx++] = m_core->o_wb_data;
}
 
// Release the bus?
m_core->i_wb_cyc = 0;
 
if(errcount >= THISBOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
m_bomb = true;
} else if (!m_core->o_wb_ack) {
printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
m_bomb = true;
}
tick();
}
 
void wb_write(unsigned a, unsigned int v) {
int errcount = 0;
 
printf("WB-WRITE(%08x) = %08x\n", a, v);
m_core->i_wb_cyc = 1;
m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
m_core->i_wb_we = 1;
m_core->i_wb_addr= a & 0x03fffff;
m_core->i_wb_data= v;
 
if (m_core->o_wb_stall)
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
tick();
tick();
 
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
while((errcount++ < BOMBCOUNT)&&(!m_core->o_wb_ack))
tick();
 
// Release the bus?
m_core->i_wb_cyc = 0;
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} tick();
}
 
void wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
unsigned errcount = 0, nacks = 0;
 
m_core->i_wb_cyc = 1;
m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
m_core->i_wb_we = 1;
m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
m_core->i_wb_data= buf[stbcnt];
errcount = 0;
 
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
tick(); if (m_core->o_wb_ack) nacks++;
}
// Tick, now that we're not stalled. This is the tick
// that gets accepted.
tick(); if (m_core->o_wb_ack) nacks++;
}
 
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
errcount = 0;
while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
tick();
if (m_core->o_wb_ack) {
nacks++;
errcount = 0;
}
}
 
// Release the bus
m_core->i_wb_cyc = 0;
m_core->i_wb_data_stb = 0;
m_core->i_wb_ctrl_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} tick();
}
 
bool bombed(void) const { return m_bomb; }
 
};
 
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
EQSPIFLASH_TB *tb = new EQSPIFLASH_TB;
const char *fname = "/dev/urandom";
unsigned rdv;
unsigned *rdbuf;
int idx = 4;
 
tb->load(fname);
rdbuf = new unsigned[4096];
tb->setflash(0,0);
 
tb->wb_tick();
rdv = tb->wb_read(QSPIFLASH);
printf("READ[0] = %04x\n", rdv);
if (rdv != 0)
goto test_failure;
 
tb->wb_tick();
if (tb->bombed())
goto test_failure;
 
for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
unsigned tblv;
tblv = (*tb)[i];
rdv = tb->wb_read(QSPIFLASH+i);
 
if(tblv != rdv) {
printf("BOMB: READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+i, rdv, tblv);
goto test_failure;
break;
} else printf("MATCH: %08x == %08x\n", rdv, tblv);
}
 
printf("SINGLE-READ TEST PASSES\n");
 
for(int i=0; i<1000; i++)
rdbuf[i] = -1;
tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
if (tb->bombed())
goto test_failure;
for(int i=0; i<1000; i++) {
if ((*tb)[i+1000] != rdbuf[i]) {
printf("BOMB: V-READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+1000+i, rdv, (*tb)[i+1000]);
goto test_failure;
}
} if (tb->bombed())
goto test_failure;
printf("VECTOR TEST PASSES!\n");
 
// Read the status register
printf("EWCTRL-REG = %02x\n", rdv=tb->wb_read(0));
if(tb->bombed()) goto test_failure;
printf("STATUS-REG = %02x\n", rdv=tb->wb_read(1));
if ((rdv != 0x1c)||(tb->bombed())) goto test_failure;
printf("NVCONF-REG = %02x\n", tb->wb_read(2)); if(tb->bombed()) goto test_failure;
printf("VCONFG-REG = %02x\n", tb->wb_read(3)); if(tb->bombed()) goto test_failure;
printf("EVCONF-REG = %02x\n", tb->wb_read(4)); if(tb->bombed()) goto test_failure;
printf("LOCK -REG = %02x\n", tb->wb_read(5)); if(tb->bombed()) goto test_failure;
printf("FLAG -REG = %02x\n", tb->wb_read(6)); if(tb->bombed()) goto test_failure;
 
if (tb->bombed())
goto test_failure;
 
printf("ID[%2d]-RG = %08x\n", 0, rdv = tb->wb_read(8+0));
if (rdv != 0x20ba1810) {
printf("BOMB: ID[%2d]-RG = %08x != %08x\n", 0, rdv,
0x20ba1810);
goto test_failure;
}
 
for(int i=1; i<5; i++)
printf("ID[%2d]-RG = %02x\n", i, tb->wb_read(8+i));
if (tb->bombed())
goto test_failure;
 
for(int i=0; i<16; i++)
printf("OTP[%2d]-R = %02x\n", i, tb->wb_read(16+i));
if (tb->bombed())
goto test_failure;
printf("OTP[CT]-R = %02x\n", tb->wb_read(15)>>24);
 
if (tb->bombed())
goto test_failure;
 
printf("Attempting to switch in Quad mode\n");
// tb->wb_write(4, (tb->wb_read(4)&0x07f)); // Adjust EVconfig
 
for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
unsigned tblv;
tblv = (*tb)[i];
rdv = tb->wb_read(QSPIFLASH+i);
 
if(tblv != rdv) {
printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
goto test_failure;
break;
} else printf("MATCH: %08x == %08x\n", rdv, tblv);
} tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
if (tb->bombed())
goto test_failure;
for(int i=0; i<1000; i++) {
if ((*tb)[i+1000] != rdbuf[i]) {
printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
goto test_failure;
}
} printf("VECTOR TEST PASSES! (QUAD)\n");
 
printf("Attempting to switch to Quad mode with XIP\n");
tb->wb_write(3, tb->wb_read(3)|0x08);
// tb->wb_write(0, 0x22000000);
 
printf("Attempting to read in Quad mode, using XIP mode\n");
for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
unsigned tblv;
tblv = (*tb)[i];
rdv = tb->wb_read(QSPIFLASH+i);
 
if(tblv != rdv) {
printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
goto test_failure;
break;
} else printf("MATCH: %08x == %08x\n", rdv, tblv);
}
 
// Try a vector read
tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
if (tb->bombed())
goto test_failure;
for(int i=0; i<1000; i++) {
if ((*tb)[i+1000] != rdbuf[i]) {
printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
goto test_failure;
}
} printf("VECTOR TEST PASSES! (QUAD+XIP)\n");
 
rdbuf[0] = tb->wb_read(QSPIFLASH+1023);
rdbuf[1] = tb->wb_read(QSPIFLASH+2048);
 
printf("Turning off write-protect, calling WEL\n");
tb->wb_write(0, 0x620001be);
printf("Attempting to erase subsector 1\n");
tb->wb_write(0, 0xf20005be);
 
while (tb->wb_read(0)&0x01000000)
;
while(tb->wb_read(0)&0x80000000)
;
if (tb->wb_read(QSPIFLASH+1023) != rdbuf[0])
goto test_failure;
if (tb->wb_read(QSPIFLASH+2048) != rdbuf[1])
goto test_failure;
tb->wb_read(QSPIFLASH+1024, 1024, rdbuf);
for(int i=0; i<1024; i++) {
if (rdbuf[i] != 0xffffffff) {
printf("BOMB: SUBSECTOR ERASE, EXPECTED[0x%02x] = 0xffffffff != %08x\n", i, rdv);
goto test_failure;
} break;
}
 
// Try to execute a single write
// Check that this will work ...
for(idx=4; idx<4096; idx++) {
if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
break;
}
// First, turn the write-enable back on
tb->wb_write(0, 0x620001be);
// Now, write the value
tb->wb_write(QSPIFLASH+idx, 0x11111111);
while (tb->wb_read(0)&0x01000000)
;
while(tb->wb_read(0)&(0x80000000))
;
if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
goto test_failure;
 
// Try to write a complete block
{
FILE *fp = fopen(fname, "r"); // Open /dev/urandom
if (4096 != fread(rdbuf, sizeof(unsigned), 4096, fp)) {
perror("Couldnt read /dev/urandom into buffer!");
goto test_failure;
} fclose(fp);
}
 
printf("Attempting to write subsector 1\n");
for(int i=0; i<1024; i+= 64) {
printf("Turning off write-protect, calling WEL\n");
tb->wb_write(0, 0x620001be);
 
printf("Writing from %08x to %08x from rdbuf\n",
QSPIFLASH+1024+i, QSPIFLASH+1024+i+63);
tb->wb_write(QSPIFLASH+1024+i, 64, &rdbuf[i]);
while(tb->wb_read(0)&(0x80000000))
;
}
 
tb->wb_read(QSPIFLASH+1024, 1024, &rdbuf[1024]);
for(int i=0; i<1024; i++) {
if (rdbuf[i] != rdbuf[i+1024]) {
printf("BOMB: SUBSECTOR PROGRAM, EXPECTED[0x%02x] = 0x%08x != %08x\n", i, rdbuf[i], rdbuf[i+1024]);
goto test_failure;
}
}
 
// -Try to write an OTP register
printf("Turning off write-protect, calling WEL\n");
tb->wb_write( 0, 0x620001be);
printf("Writing OTP[2]\n");
tb->wb_write(18, 0x620001be);
while (tb->wb_read(0)&0x01000000)
;
while(tb->wb_read(0)&(0x80000000))
;
if (0x620001be != tb->wb_read(18))
goto test_failure;
 
// -Try to write protect all OTP register
printf("Turning off write-protect, calling WEL\n");
tb->wb_write( 0, 0x620001be);
printf("Writing OTP[END]\n");
tb->wb_write(15, 0);
while (tb->wb_read(0)&0x01000000)
;
while(tb->wb_read(0)&(0x80000000))
;
if (0 != tb->wb_read(15))
goto test_failure;
 
// -Try to write OTP after write protecting all OTP registers
printf("Turning off write-protect, calling WEL\n");
tb->wb_write( 0, 0x620001be);
printf("Writing OTP[7]\n");
tb->wb_write(16+7, 0);
while (tb->wb_read(0)&0x01000000)
;
while(tb->wb_read(0)&(0x80000000))
;
 
// -Verify OTP not written
if (0 == tb->wb_read(16+7))
goto test_failure;
 
 
printf("SUCCESS!!\n");
exit(0);
test_failure:
printf("FAIL-HERE\n");
for(int i=0; i<64; i++)
tb->tick();
printf("TEST FAILED\n");
exit(-1);
}
/trunk/bench/cpp/enetctrl_tb.cpp
0,0 → 1,275
#include "verilated.h"
#include "Venetctrl.h"
#include "enetctrlsim.h"
 
const int BOMBCOUNT = 2048;
 
class ENETCTRL_TB {
long m_tickcount;
Venetctrl *m_core;
ENETCTRLSIM *m_sim;
bool m_bomb;
public:
 
ENETCTRL_TB(void) {
m_core = new Venetctrl;
m_sim = new ENETCTRLSIM;
}
 
int operator[](const int index) { return (*m_sim)[index]; }
 
void tick(void) {
m_core->i_clk = 1;
 
m_core->i_mdio = (*m_sim)(m_core->o_mdclk,
((m_core->o_mdwe)&(m_core->o_mdio))
|((m_core->o_mdwe)?0:1));
 
printf("%08lx-WB: %s %s %s%s %s@0x%02x[%04x/%04x] -- %d[%d->(%d)->%d]",
m_tickcount,
(m_core->i_wb_cyc)?"CYC":" ",
(m_core->i_wb_stb)?"STB":" ",
(m_core->o_wb_stall)?"STALL":" ",
(m_core->o_wb_ack)?"ACK":" ",
(m_core->i_wb_we)?"W":"R",
(m_core->i_wb_addr)&0x01f, (m_core->i_wb_data)&0x0ffff,
(m_core->o_wb_data)&0x0ffff,
(m_core->o_mdclk), (m_core->o_mdio),
(m_core->o_mdwe), (m_core->i_mdio));
 
printf(" [%02x,%d%d%d,%x] ",
m_core->v__DOT__reg_pos,
0, // m_core->v__DOT__rclk,
m_core->v__DOT__zclk,
m_core->v__DOT__zreg_pos,
m_core->v__DOT__ctrl_state);
printf(" 0x%04x/0x%04x ", m_core->v__DOT__write_reg,
m_core->v__DOT__read_reg);
printf(" %s%s ",
(m_core->v__DOT__read_pending)?"R":" ",
(m_core->v__DOT__write_pending)?"W":" ");
 
printf(" %s:%08x,%2d,%08x ",
(m_sim->m_synched)?"S":" ",
m_sim->m_datareg, m_sim->m_halfword,
m_sim->m_outreg);
 
printf("\n");
 
m_core->eval();
m_core->i_clk = 0;
m_core->eval();
 
m_tickcount++;
 
if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
printf("SETTING ERR TO TRUE!!!!! ACK w/ no CYC\n");
// m_bomb = true;
}
}
 
void wb_tick(void) {
// printf("WB-TICK()\n");
m_core->i_wb_cyc = 0;
m_core->i_wb_stb = 0;
tick();
}
 
unsigned wb_read(unsigned a) {
int errcount = 0;
unsigned result;
 
printf("WB-READ(%08x)\n", a);
 
m_core->i_wb_cyc = 1;
m_core->i_wb_stb = 1;
m_core->i_wb_we = 0;
m_core->i_wb_addr= a & 0x01f;
 
if (m_core->o_wb_stall)
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
tick();
else
tick();
 
m_core->i_wb_stb = 0;
 
while((errcount++ < BOMBCOUNT)&&(!m_core->o_wb_ack))
tick();
 
 
result = m_core->o_wb_data;
 
// Release the bus?
m_core->i_wb_cyc = 0;
m_core->i_wb_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} else if (!m_core->o_wb_ack) {
printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
m_bomb = true;
}
tick();
 
return result;
}
 
void wb_read(unsigned a, int len, unsigned *buf) {
int errcount = 0;
int THISBOMBCOUNT = BOMBCOUNT * len;
int cnt, rdidx;
 
printf("WB-READ(%08x, %d)\n", a, len);
 
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
wb_tick();
 
if (errcount >= BOMBCOUNT) {
m_bomb = true;
return;
}
 
errcount = 0;
m_core->i_wb_cyc = 1;
m_core->i_wb_stb = 1;
m_core->i_wb_we = 0;
m_core->i_wb_addr= a & 0x01f;
 
rdidx =0; cnt = 0;
 
do {
int s;
s = (m_core->o_wb_stall==0)?0:1;
tick();
if (!s)
m_core->i_wb_addr = (m_core->i_wb_addr+1)&0x1f;
cnt += (s==0)?1:0;
if (m_core->o_wb_ack)
buf[rdidx++] = m_core->o_wb_data;
} while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
 
m_core->i_wb_stb = 0;
 
while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
tick();
if (m_core->o_wb_ack)
buf[rdidx++] = m_core->o_wb_data;
}
 
// Release the bus?
m_core->i_wb_cyc = 0;
 
if(errcount >= THISBOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
m_bomb = true;
} else if (!m_core->o_wb_ack) {
printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
m_bomb = true;
}
tick();
}
 
void wb_write(unsigned a, unsigned int v) {
int errcount = 0;
 
printf("WB-WRITE(%08x) = %08x\n", a, v);
m_core->i_wb_cyc = 1;
m_core->i_wb_stb = 1;
m_core->i_wb_we = 1;
m_core->i_wb_addr= a & 0x01f;
m_core->i_wb_data= v;
 
if (m_core->o_wb_stall)
while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
tick();
tick();
 
m_core->i_wb_stb = 0;
 
while((errcount++ < BOMBCOUNT)&&(!m_core->o_wb_ack))
tick();
 
// Release the bus?
m_core->i_wb_cyc = 0;
m_core->i_wb_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} tick();
}
 
void wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
unsigned errcount = 0, nacks = 0;
 
m_core->i_wb_cyc = 1;
for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
m_core->i_wb_stb = 1;
m_core->i_wb_we = 1;
m_core->i_wb_addr= (a+stbcnt) & 0x01f;
m_core->i_wb_data= buf[stbcnt];
errcount = 0;
 
do {
tick(); if (m_core->o_wb_ack) nacks++;
} while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall));
}
 
m_core->i_wb_stb = 0;
 
errcount = 0;
while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
tick();
if (m_core->o_wb_ack) {
nacks++;
errcount = 0;
}
}
 
// Release the bus
m_core->i_wb_cyc = 0;
m_core->i_wb_stb = 0;
 
if(errcount >= BOMBCOUNT) {
printf("SETTING ERR TO TRUE!!!!!\n");
m_bomb = true;
} tick();
}
 
bool bombed(void) const { return m_bomb; }
 
};
 
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
ENETCTRL_TB *tb = new ENETCTRL_TB;
// unsigned rdv;
// unsigned *rdbuf;
 
tb->wb_tick();
tb->wb_write(0, 0x7f82);
 
tb->wb_tick();
if (tb->wb_read(0)!=0x7f82)
goto test_failure;
 
//
tb->wb_tick();
tb->wb_write(14, 0x5234);
 
tb->wb_tick();
if (tb->wb_read(14)!=0x5234)
goto test_failure;
 
printf("SUCCESS!!\n");
exit(0);
test_failure:
printf("FAIL-HERE\n");
for(int i=0; i<64; i++)
tb->tick();
printf("TEST FAILED\n");
exit(-1);
}
/trunk/bench/cpp/eqspiflashsim.cpp
0,0 → 1,704
////////////////////////////////////////////////////////////////////////////////
//
// Filename: eqspiflashsim.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: This library simulates the operation of a Quad-SPI commanded
// flash, such as the Micron N25Q128A used on the Arty development
// board by Digilent. As such, it is defined by 16 MBytes of
// memory (4 MWord).
//
// 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, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// 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 <string.h>
#include <assert.h>
#include <stdlib.h>
 
#include "eqspiflashsim.h"
 
#define MEMBYTES (1<<24)
 
static const unsigned
DEVESD = 0x014,
// MICROSECONDS = 200,
// MILLISECONDS = MICROSECONDS * 1000,
// SECONDS = MILLISECONDS * 1000,
MICROSECONDS = 20,
MILLISECONDS = MICROSECONDS * 10,
SECONDS = MILLISECONDS * 10,
tSHSL1 = 4, // S# deselect time after a read command
tSHSL2 = 10, // S# deselect time after a non-read command
tW = 1300 * MICROSECONDS, // write config cycle time
tWNVCR = 200 * MILLISECONDS, // write nonvolatile-config cycle time
tWVECR = 8, // write volatile enhanced config cycle time
tBE = 32 * SECONDS, // Bulk erase time
tDP = 10 * SECONDS, // Deep power down
tRES = 30 * SECONDS,
// Shall we artificially speed up this process?
// These numbers are the "typical" times
tPP = 500 * MICROSECONDS, // Page program time
tSE = 700 * MILLISECONDS, // Sector erase time
tSS = 250 * MILLISECONDS; // Subsector erase time
// These are the maximum times
// tW = 8300 * MICROSECONDS, // write config cycle time
// tWNVCR = 3000 * MILLISECONDS, // write nonvolatile-config cycle time
// tWVECR = 8, // write volatile enhanced config cycle time
// tPP = 5000 * MICROSECONDS,
// tSE = 3000 * MILLISECONDS;
// tSS = 800 * MILLISECONDS;
 
static const char IDSTR[20]= {
0x20, // Micron's ID, assigned by JEDEC
(char)0xba, (char)0x18, // Memory type and capacity
(char)0x10, // Length of data to follow
(char)0xfe, (char)0xfd, // Extended device ID and device config info
(char)0xfc, (char)0xfb, (char)0xfa, (char)0xf9,
(char)0xf8, (char)0xf7, (char)0xf6, (char)0xf5,
(char)0xf4, (char)0xf3, (char)0xf2, (char)0xf1,
(char)0xf0, (char)0xef
};
 
EQSPIFLASHSIM::EQSPIFLASHSIM(void) {
const int NSECTORS = MEMBYTES>>16;
m_mem = new char[MEMBYTES];
m_pmem = new char[256];
m_otp = new char[65];
for(int i=0; i<65; i++)
m_otp[i] = 0x0ff;
m_otp[64] = 1;
m_otp_wp = false;
m_lockregs = new char[NSECTORS];
for(int i=0; i<NSECTORS; i++)
m_lockregs[i] = 0;
 
m_state = EQSPIF_IDLE;
m_last_sck = 1;
m_write_count = 0;
m_ireg = m_oreg = 0;
m_sreg = 0x01c;
m_creg = 0x001; // Initial creg on delivery
m_config = 0x7; // Volatile configuration register
m_nvconfig = 0x0fff; // Nonvolatile configuration register
m_quad_mode = false;
m_mode_byte = 0;
m_flagreg = 0x0a5;
 
m_debug = true;
 
memset(m_mem, 0x0ff, MEMBYTES);
}
 
void EQSPIFLASHSIM::load(const unsigned addr, const char *fname) {
FILE *fp;
size_t len;
 
if (addr >= MEMBYTES)
return; // return void
len = MEMBYTES-addr*4;
 
if (NULL != (fp = fopen(fname, "r"))) {
int nr = 0;
nr = fread(&m_mem[addr*4], sizeof(char), len, fp);
fclose(fp);
if (nr == 0) {
fprintf(stderr, "SPI-FLASH: Could not read %s\n", fname);
perror("O/S Err:");
}
} else {
fprintf(stderr, "SPI-FLASH: Could not open %s\n", fname);
perror("O/S Err:");
}
}
 
#define QOREG(A) m_oreg = ((m_oreg & (~0x0ff))|(A&0x0ff))
 
int EQSPIFLASHSIM::operator()(const int csn, const int sck, const int dat) {
// Keep track of a timer to determine when page program and erase
// cycles complete.
 
if (m_write_count > 0) {
if (0 == (--m_write_count)) {// When done with erase/page pgm,
// Clear the write in progress bit, together with the
// write enable bit.
m_sreg &= 0x0fc;
if (m_debug) printf("Write complete, clearing WIP (inside SIM)\n");
}
}
 
if (csn) {
m_last_sck = 1;
m_ireg = 0; m_oreg = 0;
 
if ((EQSPIF_PP == m_state)||(EQSPIF_QPP == m_state)) {
// Start a page program
if (m_debug) printf("EQSPI: Page Program write cycle begins\n");
if (m_debug) printf("CK = %d & 7 = %d\n", m_count, m_count & 0x07);
if (m_debug) printf("EQSPI: pmem = %08lx\n", (unsigned long)m_pmem);
assert((m_lockregs[(m_addr>>16)&0x0ff]&0x1)==0);
assert((m_count & 7)==0);
m_write_count = tPP;
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
for(int i=0; i<256; i++) {
/*
if (m_debug) printf("%02x: m_mem[%02x] = %02x &= %02x = %02x\n",
i, (m_addr&(~0x0ff))+i,
m_mem[(m_addr&(~0x0ff))+i]&0x0ff, m_pmem[i]&0x0ff,
m_mem[(m_addr&(~0x0ff))+i]& m_pmem[i]&0x0ff);
*/
m_mem[(m_addr&(~0x0ff))+i] &= m_pmem[i];
}
m_quad_mode = false;
} else if (EQSPIF_WRCR == m_state) {
if (m_debug) printf("Actually writing volatile config register\n");
if (m_debug) printf("CK = %d & 7 = %d\n", m_count, m_count & 0x07);
m_state = EQSPIF_IDLE;
} else if (EQSPIF_WRNVCONFIG == m_state) {
if (m_debug) printf("Actually writing nonvolatile config register\n");
m_write_count = tWNVCR;
m_state = EQSPIF_IDLE;
} else if (EQSPIF_WREVCONFIG == m_state) {
if (m_debug) printf("Actually writing Enhanced volatile config register\n");
m_state = EQSPIF_IDLE;
} else if (EQSPIF_WRSR == m_state) {
if (m_debug) printf("Actually writing status register\n");
m_write_count = tW;
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
} else if (EQSPIF_WRLOCK == m_state) {
if (m_debug) printf("Actually writing lock register\n");
m_write_count = tW;
m_state = EQSPIF_IDLE;
} else if (EQSPIF_CLRFLAGS == m_state) {
if (m_debug) printf("Actually clearing the flags register bits\n");
m_state = EQSPIF_IDLE;
m_flagreg &= 0x09f;
} else if (m_state == EQSPIF_SUBSECTOR_ERASE) {
if (m_debug) printf("Actually Erasing subsector, from %08x\n", m_addr);
if (m_debug) printf("CK = %d & 7 = %d\n", m_count, m_count & 0x07);
assert(((m_count & 7)==0)&&(m_count == 32));
assert((m_lockregs[(m_addr>>16)&0x0ff]&0x1)==0);
m_write_count = tSS;
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
m_addr &= (-1<<12);
for(int i=0; i<(1<<12); i++)
m_mem[m_addr + i] = 0x0ff;
if (m_debug) printf("Now waiting %d ticks delay\n", m_write_count);
} else if (m_state == EQSPIF_SECTOR_ERASE) {
if (m_debug) printf("Actually Erasing sector, from %08x\n", m_addr);
m_write_count = tSE;
if (m_debug) printf("CK = %d & 7 = %d\n", m_count, m_count & 0x07);
assert(((m_count & 7)==0)&&(m_count == 32));
assert((m_lockregs[(m_addr>>16)&0x0ff]&0x1)==0);
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
m_addr &= (-1<<16);
for(int i=0; i<(1<<16); i++)
m_mem[m_addr + i] = 0x0ff;
if (m_debug) printf("Now waiting %d ticks delay\n", m_write_count);
} else if (m_state == EQSPIF_BULK_ERASE) {
m_write_count = tBE;
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
// Should I be checking the lock register(s) here?
for(int i=0; i<MEMBYTES; i++)
m_mem[i] = 0x0ff;
} else if (m_state == EQSPIF_PROGRAM_OTP) {
// Program the One-Time Programmable (OTP memory
if (m_debug) printf("EQSPI: OTP Program write cycle begins\n");
if (m_debug) printf("CK = %d & 7 = %d\n", m_count, m_count & 0x07);
// assert((m_lockregs[(m_addr>>16)&0x0ff]&0x1)==0);
assert((m_count & 7)==0);
m_write_count = tPP; // OTP cycle time as well
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
m_sreg |= (EQSPIF_WIP_FLAG);
for(int i=0; i<65; i++)
m_otp[i] &= m_pmem[i];
m_otp_wp = ((m_otp[64]&1)==0);
/*
} else if (m_state == EQSPIF_DEEP_POWER_DOWN) {
m_write_count = tDP;
m_state = EQSPIF_IDLE;
} else if (m_state == EQSPIF_RELEASE) {
m_write_count = tRES;
m_state = EQSPIF_IDLE;
*/
} else if (m_state == EQSPIF_QUAD_READ_CMD) {
m_state = EQSPIF_IDLE;
if (m_mode_byte!=0)
m_quad_mode = false;
else
m_state = EQSPIF_XIP;
} else if (m_state == EQSPIF_QUAD_READ) {
m_state = EQSPIF_IDLE;
if (m_mode_byte!=0)
m_quad_mode = false;
else
m_state = EQSPIF_XIP;
// } else if (m_state == EQSPIF_XIP) {
}
 
m_oreg = 0x0fe;
m_count= 0;
int out = m_nxtout;
m_nxtout = dat;
return out;
} else if ((!m_last_sck)||(sck == m_last_sck)) {
// Only change on the falling clock edge
// printf("SFLASH-SKIP, CLK=%d -> %d\n", m_last_sck, sck);
m_last_sck = sck;
int out = m_nxtout;
if (m_quad_mode)
m_nxtout = (m_oreg>>8)&0x0f;
else
// return ((m_oreg & 0x0100)?2:0) | (dat & 0x0d);
m_nxtout = (m_oreg & 0x0100)?2:0;
return out;
}
 
// We'll only get here if ...
// last_sck = 1, and sck = 0, thus transitioning on the
// negative edge as with everything else in this interface
if (m_quad_mode) {
m_ireg = (m_ireg << 4) | (dat & 0x0f);
m_count+=4;
m_oreg <<= 4;
} else {
m_ireg = (m_ireg << 1) | (dat & 1);
m_count++;
m_oreg <<= 1;
}
 
 
// printf("PROCESS, COUNT = %d, IREG = %02x\n", m_count, m_ireg);
if (m_state == EQSPIF_XIP) {
assert(m_quad_mode);
if (m_count == 24) {
if (m_debug) printf("EQSPI: Entering from Quad-Read Idle to Quad-Read\n");
if (m_debug) printf("EQSPI: QI/O Idle Addr = %02x\n", m_ireg&0x0ffffff);
m_addr = (m_ireg) & 0x0ffffff;
assert((m_addr & 0xfc00000)==0);
m_state = EQSPIF_QUAD_READ;
} m_oreg = 0;
} else if (m_count == 8) {
QOREG(0x0a5);
// printf("SFLASH-CMD = %02x\n", m_ireg & 0x0ff);
// Figure out what command we've been given
if (m_debug) printf("SPI FLASH CMD %02x\n", m_ireg&0x0ff);
switch(m_ireg & 0x0ff) {
case 0x01: // Write status register
if (2 !=(m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: WEL not set, cannot write status reg\n");
m_state = EQSPIF_INVALID;
} else
m_state = EQSPIF_WRSR;
break;
case 0x02: // Normal speed (normal SPI, 1wire MOSI) Page program
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: Cannot program at this time, SREG = %x\n", m_sreg);
m_state = EQSPIF_INVALID;
} else {
m_state = EQSPIF_PP;
if (m_debug) printf("PAGE-PROGRAM COMMAND ACCEPTED\n");
}
break;
case 0x03: // Read data bytes
// Our clock won't support this command, so go
// to an invalid state
if (m_debug) printf("EQSPI INVALID: This sim does not support slow reading\n");
m_state = EQSPIF_INVALID;
break;
case 0x04: // Write disable
m_state = EQSPIF_IDLE;
m_sreg &= (~EQSPIF_WEL_FLAG);
break;
case 0x05: // Read status register
m_state = EQSPIF_RDSR;
if (m_debug) printf("EQSPI: READING STATUS REGISTER: %02x\n", m_sreg);
QOREG(m_sreg);
break;
case 0x06: // Write enable
m_state = EQSPIF_IDLE;
m_sreg |= EQSPIF_WEL_FLAG;
if (m_debug) printf("EQSPI: WRITE-ENABLE COMMAND ACCEPTED\n");
break;
case 0x0b: // Here's the read that we support
if (m_debug) printf("EQSPI: FAST-READ (single-bit)\n");
m_state = EQSPIF_FAST_READ;
break;
case 0x20: // Subsector Erase
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: WEL not set, cannot do a subsector erase\n");
m_state = EQSPIF_INVALID;
assert(0&&"WEL not set");
} else
m_state = EQSPIF_SUBSECTOR_ERASE;
break;
case 0x32: // QUAD Page program, 4 bits at a time
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: Cannot program at this time, SREG = %x\n", m_sreg);
m_state = EQSPIF_INVALID;
assert(0&&"WEL not set");
} else {
m_state = EQSPIF_QPP;
if (m_debug) printf("EQSPI: QUAD-PAGE-PROGRAM COMMAND ACCEPTED\n");
if (m_debug) printf("EQSPI: pmem = %08lx\n", (unsigned long)m_pmem);
}
break;
case 0x42: // Program OTP array
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: WEL not set, cannot program OTP\n");
m_state = EQSPIF_INVALID;
} else if (m_otp_wp) {
if (m_debug) printf("EQSPI: OTP Write protect is set, cannot program OTP ever again\n");
m_state = EQSPIF_INVALID;
} else
m_state = EQSPIF_PROGRAM_OTP;
break;
case 0x4b: // Read OTP array
m_state = EQSPIF_READ_OTP;
QOREG(0);
if (m_debug) printf("EQSPI: Read OTP array command\n");
break;
case 0x50: // Clear flag status register
m_state = EQSPIF_CLRFLAGS;
if (m_debug) printf("EQSPI: Clearing FLAGSTATUS REGISTER: %02x\n", m_flagreg);
QOREG(m_flagreg);
break;
case 0x61: // WRITE Enhanced volatile config register
m_state = EQSPIF_WREVCONFIG;
if (m_debug) printf("EQSPI: WRITING EVCONFIG REGISTER\n");
break;
case 0x65: // Read Enhanced volatile config register
m_state = EQSPIF_RDEVCONFIG;
if (m_debug) printf("EQSPI: READING EVCONFIG REGISTER: %02x\n", m_evconfig);
QOREG(m_evconfig);
break;
case 0x06b:
m_state = EQSPIF_QUAD_READ_CMD;
// m_quad_mode = true; // Not yet, need to wait past dummy registers
break;
case 0x70: // Read flag status register
m_state = EQSPIF_RDFLAGS;
if (m_debug) printf("EQSPI: READING FLAGSTATUS REGISTER: %02x\n", m_flagreg);
QOREG(m_flagreg);
break;
case 0x81: // Write volatile config register
m_state = EQSPIF_WRCR;
if (m_debug) printf("EQSPI: WRITING CONFIG REGISTER: %02x\n", m_config);
break;
case 0x85: // Read volatile config register
m_state = EQSPIF_RDCR;
if (m_debug) printf("EQSPI: READING CONFIG REGISTER: %02x\n", m_config);
QOREG(m_config>>8);
break;
case 0x9e: // Read ID (fall through)
case 0x9f: // Read ID
m_state = EQSPIF_RDID; m_addr = 0;
if (m_debug) printf("EQSPI: READING ID\n");
QOREG(IDSTR[0]);
break;
case 0xb1: // Write nonvolatile config register
m_state = EQSPIF_WRNVCONFIG;
if (m_debug) printf("EQSPI: WRITING NVCONFIG REGISTER: %02x\n", m_nvconfig);
break;
case 0xb5: // Read nonvolatile config register
m_state = EQSPIF_RDNVCONFIG;
if (m_debug) printf("EQSPI: READING NVCONFIG REGISTER: %02x\n", m_nvconfig);
QOREG(m_nvconfig>>8);
break;
case 0xc7: // Bulk Erase
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: WEL not set, cannot erase device\n");
m_state = EQSPIF_INVALID;
} else
m_state = EQSPIF_BULK_ERASE;
break;
case 0xd8: // Sector Erase
if (2 != (m_sreg & 0x203)) {
if (m_debug) printf("EQSPI: WEL not set, cannot erase sector\n");
m_state = EQSPIF_INVALID;
assert(0&&"WEL not set");
} else {
m_state = EQSPIF_SECTOR_ERASE;
if (m_debug) printf("EQSPI: SECTOR_ERASE COMMAND\n");
}
break;
case 0xe5: // Write lock register
m_state = EQSPIF_WRLOCK;
if (m_debug) printf("EQSPI: WRITING LOCK REGISTER\n");
break;
case 0xe8: // Read lock register
m_state = EQSPIF_RDLOCK;
if (m_debug) printf("EQSPI: READ LOCK REGISTER (Waiting on address)\n");
break;
case 0x0eb: // Here's the (other) read that we support
// printf("EQSPI: QUAD-I/O-READ\n");
// m_state = EQSPIF_QUAD_READ_CMD;
// m_quad_mode = true;
assert(0 && "Quad Input/Output fast read not supported");
break;
default:
printf("EQSPI: UNRECOGNIZED SPI FLASH CMD: %02x\n", m_ireg&0x0ff);
m_state = EQSPIF_INVALID;
assert(0 && "Unrecognized command\n");
break;
}
} else if ((0 == (m_count&0x07))&&(m_count != 0)) {
QOREG(0);
switch(m_state) {
case EQSPIF_IDLE:
printf("TOO MANY CLOCKS, SPIF in IDLE\n");
break;
case EQSPIF_WRSR:
if (m_count == 16) {
m_sreg = (m_sreg & 0x07c) | (m_ireg & 0x07c);
if (m_debug) printf("Request to set sreg to 0x%02x\n",
m_ireg&0x0ff);
} else {
printf("TOO MANY CLOCKS FOR WRR!!!\n");
exit(-2);
m_state = EQSPIF_IDLE;
}
break;
case EQSPIF_WRCR: // Write volatile config register, 0x81
if (m_count == 8) {
m_config = m_ireg & 0x0ff;
printf("Setting volatile config register to %08x\n", m_config);
assert((m_config & 0xfb)==0x8b);
} break;
case EQSPIF_WRNVCONFIG: // Write nonvolatile config register
if (m_count == 8) {
m_nvconfig = m_ireg & 0x0ffdf;
printf("Setting nonvolatile config register to %08x\n", m_config);
assert((m_nvconfig & 0xffc5)==0x8fc5);
} break;
case EQSPIF_WREVCONFIG: // Write enhanced volatile config reg
if (m_count == 8) {
m_evconfig = m_ireg & 0x0ff;
printf("Setting enhanced volatile config register to %08x\n", m_evconfig);
assert((m_evconfig & 0x0d7)==0xd7);
} break;
case EQSPIF_WRLOCK:
if (m_count == 32) {
m_addr = (m_ireg>>24)&0x0ff;
if ((m_lockregs[m_addr]&2)==0)
m_lockregs[m_addr] = m_ireg&3;
printf("Setting lock register[%02x] to %d\n", m_addr, m_lockregs[m_addr]);
assert((m_config & 0xfb)==0x8b);
} break;
case EQSPIF_RDLOCK:
if (m_count == 24) {
m_addr = (m_ireg>>16)&0x0ff;
QOREG(m_lockregs[m_addr]);
printf("Reading lock register[%02x]: %d\n", m_addr, m_lockregs[m_addr]);
} else
QOREG(m_lockregs[m_addr]);
break;
case EQSPIF_CLRFLAGS:
assert(0 && "Too many clocks for CLSR command!!\n");
break;
case EQSPIF_READ_OTP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
assert(m_addr < 65);
m_otp[64] = (m_otp_wp)?0:1;
if (m_debug) printf("READOTP, SETTING ADDR = %08x\n", m_addr);
if (m_debug) printf("READOTP, Array is %s, m_otp[64] = %d\n",
(m_otp_wp)?"Locked":"Unlocked",
m_otp[64]);
QOREG(m_otp[m_addr]);
} else if (m_count < 40) {
} // else if (m_count == 40)
else if ((m_count&7)==0) {
if (m_debug) printf("READOTP, ADDR = %08x\n", m_addr);
if (m_addr < 65)
QOREG(m_otp[m_addr]);
else
QOREG(0);
if (m_debug) printf("EQSPI: READING OTP, %02x%s\n",
(m_addr<65)?m_otp[m_addr]&0x0ff:0xfff,
(m_addr > 65)?"-- PAST OTP LENGTH!":"");
m_addr++;
}
break;
case EQSPIF_RDID:
if ((m_count&7)==0) {
m_addr++;
if (m_debug) printf("READID, ADDR = %08x\n", m_addr);
if (m_addr < sizeof(IDSTR))
QOREG(IDSTR[m_addr]);
else
QOREG(0);
if (m_debug) printf("EQSPI: READING ID, %02x%s\n",
IDSTR[m_addr]&0x0ff,
(m_addr >= sizeof(IDSTR))?"-- PAST ID LENGTH!":"");
}
break;
case EQSPIF_RDSR:
// printf("Read SREG = %02x, wait = %08x\n", m_sreg,
// m_write_count);
QOREG(m_sreg);
break;
case EQSPIF_RDCR:
if (m_debug) printf("Read CREG = %02x\n", m_creg);
QOREG(m_creg);
break;
case EQSPIF_FAST_READ:
if (m_count < 32) {
if (m_debug) printf("FAST READ, WAITING FOR FULL COMMAND (count = %d)\n", m_count);
QOREG(0x0c3);
} else if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
if (m_debug) printf("FAST READ, ADDR = %08x\n", m_addr);
QOREG(0x0c3);
assert((m_addr & 0xf000003)==0);
} else if ((m_count >= 40)&&(0 == (m_sreg&0x01))) {
if (m_count == 40)
printf("DUMMY BYTE COMPLETE ...\n");
QOREG(m_mem[m_addr++]);
if (m_debug) printf("SPIF[%08x] = %02x -> %02x\n", m_addr-1, m_mem[m_addr-1]&0x0ff, m_oreg);
} else if (0 != (m_sreg&0x01)) {
m_oreg = 0;
if (m_debug) printf("CANNOT READ WHEN WRITE IN PROGRESS, m_sreg = %02x\n", m_sreg);
} else printf("How did I get here, m_count = %d\n", m_count);
break;
case EQSPIF_QUAD_READ_CMD:
// The command to go into quad read mode took 8 bits
// that changes the timings, else we'd use quad_Read
// below
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
// printf("FAST READ, ADDR = %08x\n", m_addr);
printf("EQSPI: QUAD READ, ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
} else if (m_count == 32+8) {
QOREG(m_mem[m_addr++]);
m_quad_mode = true;
m_mode_byte = (m_ireg & 0x080);
// printf("EQSPI: MODE BYTE = %02x\n", m_mode_byte);
} else if ((m_count > 32+8)&&(0 == (m_sreg&0x01))) {
QOREG(m_mem[m_addr++]);
// printf("EQSPIF[%08x]/QR = %02x\n",
// m_addr-1, m_oreg);
} else m_oreg = 0;
break;
case EQSPIF_QUAD_READ:
if (m_count == 24+8*4) {// Requires 8 QUAD clocks
m_mode_byte = (m_ireg>>24) & 0x10;
// printf("EQSPI/QR: MODE BYTE = %02x\n", m_mode_byte);
QOREG(m_mem[m_addr++]);
} else if ((m_count >= 64)&&(0 == (m_sreg&0x01))) {
QOREG(m_mem[m_addr++]);
// printf("EQSPIF[%08x]/QR = %02x\n", m_addr-1, m_oreg & 0x0ff);
} else m_oreg = 0;
break;
case EQSPIF_PP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
if (m_debug) printf("EQSPI: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
} else if (m_count >= 40) {
m_pmem[m_addr & 0x0ff] = m_ireg & 0x0ff;
// printf("EQSPI: PMEM[%02x] = 0x%02x -> %02x\n", m_addr & 0x0ff, m_ireg & 0x0ff, (m_pmem[(m_addr & 0x0ff)]&0x0ff));
m_addr = (m_addr & (~0x0ff)) | ((m_addr+1)&0x0ff);
} break;
case EQSPIF_QPP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_quad_mode = true;
if (m_debug) printf("EQSPI/QR: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
} else if (m_count >= 40) {
m_pmem[m_addr & 0x0ff] = m_ireg & 0x0ff;
// printf("EQSPI/QR: PMEM[%02x] = 0x%02x -> %02x\n", m_addr & 0x0ff, m_ireg & 0x0ff, (m_pmem[(m_addr & 0x0ff)]&0x0ff));
m_addr = (m_addr & (~0x0ff)) | ((m_addr+1)&0x0ff);
} break;
case EQSPIF_SUBSECTOR_ERASE:
if (m_count == 32) {
m_addr = m_ireg & 0x0fff000;
if (m_debug) printf("SUBSECTOR_ERASE ADDRESS = %08x\n", m_addr);
assert((m_addr & 0xff000000)==0);
} break;
case EQSPIF_SECTOR_ERASE:
if (m_count == 32) {
m_addr = m_ireg & 0x0ff0000;
if (m_debug) printf("SECTOR_ERASE ADDRESS = %08x\n", m_addr);
assert((m_addr & 0xf000000)==0);
} break;
case EQSPIF_PROGRAM_OTP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ff;
for(int i=0; i<65; i++)
m_pmem[i] = 0x0ff;
} else if ((m_count >= 40)&&(m_addr < 65)) {
m_pmem[m_addr++] = m_ireg & 0x0ff;
} break;
/*
case EQSPIF_RELEASE:
if (m_count >= 32) {
QOREG(DEVESD);
} break;
*/
default:
QOREG(0xff);
break;
}
} // else printf("SFLASH->count = %d\n", m_count);
 
m_last_sck = sck;
int out = m_nxtout;
if (m_quad_mode)
m_nxtout = (m_oreg>>8)&0x0f;
else
m_nxtout = (m_oreg & 0x0100)?2:0;
return out;
}
 
/trunk/bench/cpp/enetctrlsim.cpp
0,0 → 1,133
////////////////////////////////////////////////////////////////////////////////
//
// Filename: enetctrlsim.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// 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 "enetctrlsim.h"
 
ENETCTRLSIM::ENETCTRLSIM(void) {
m_consecutive_clocks = 0;
m_synched = false;
m_lastclk = 0;
m_lastout = 0;
m_tickcount = 0;
m_ticks_per_clock = 0;
m_halfword = 0;
m_datareg = -1;
PHY_ADDR = 1;
TICKS_PER_CLOCK = 8;
for(int i=0; i<ENET_MEMWORDS; i++)
m_mem[i] = 0;
m_outreg = -1;
}
 
int ENETCTRLSIM::operator()(int clk, int data) {
int posedge, negedge, output = 1;
 
posedge = ((clk)&&(!m_lastclk));
negedge = ((!clk)&&(m_lastclk));
 
m_tickcount++;
 
if (posedge) {
if ((data)&&(m_consecutive_clocks < 128))
m_consecutive_clocks++;
else if (!data)
m_consecutive_clocks = 0;
if ((m_tickcount != m_ticks_per_clock)
||(m_ticks_per_clock < TICKS_PER_CLOCK)) {
m_consecutive_clocks = 0;
m_synched = false;
} m_ticks_per_clock = m_tickcount;
m_tickcount = 0;
}
if (m_consecutive_clocks > 32) {
if (!m_synched)
printf("ENETCTRL: SYNCH!\n");
m_synched = true;
m_lastout = 1;
m_halfword = 0;
}
 
if ((posedge)&&(m_synched)) {
m_datareg = (m_datareg<<1)|(data&1);
if ((!m_halfword)&&((m_datareg&0x8000)==0)) {
printf("ENETCTRL::HALF-CMD: %08x\n", m_datareg);
m_halfword = 1;
int cmd = (m_datareg>>12)&0x0f;
int phy = (m_datareg>>7)&0x01f;
if ((cmd != 6)&&(cmd != 5))
printf("ENETCTRL: Unknown command, %d, expecting either 5 or 6\n", cmd);
if (phy != PHY_ADDR)
printf("ENETCTRL: Unknown PHY, %d, expecting %d\n", phy, PHY_ADDR);
if ((cmd == 6)&&(phy==PHY_ADDR)) {
int addr = (m_datareg>>2)&0x01f;
m_outreg = ((m_mem[addr]&0x0ffff)<<15)|0x080007fff;
printf("ENETCTRL: Sending %04x = MEM[%01x]\n",
m_mem[addr]&0x0ffff, addr);
}
} else if ((m_halfword)&&(m_halfword < 16)) {
m_halfword++;
} else if (m_halfword) {
printf("ENETCTRL::FULL-CMD: %08x\n", m_datareg);
m_halfword = 0;
int cmd = (m_datareg>>28)&0x0f;
int phy = (m_datareg>>23)&0x01f;
if ((cmd != 6)&&(cmd != 5))
printf("ENETCTRL: Unknown command, %d, expecting either 5 or 6\n", cmd);
if (phy != PHY_ADDR)
printf("ENETCTRL: Unknown PHY, %d, expecting %d\n", phy, PHY_ADDR);
if ((cmd==5)&&(phy==PHY_ADDR)) {
int addr;
addr = (m_datareg>>18)&0x1f;
m_mem[addr] = m_datareg & 0x0ffff;
printf("ENETCTRL: Setting MEM[%01x] = %04x\n",
addr, m_datareg&0x0ffff);
}
m_datareg = -1;
}
} else if (negedge) {
m_outreg = (m_outreg<<1)|1;
} output = (m_outreg&0x80000000)?1:0;
 
 
m_lastclk = clk;
return (data)&(output)&1;
}
 
int ENETCTRLSIM::operator[](int index) const {
return m_mem[index & (ENET_MEMWORDS-1)] & 0x0ffff;
}
/trunk/bench/cpp/Makefile
0,0 → 1,58
################################################################################
##
## Filename: Makefile
##
## Project: OpenArty, an entirely open SoC based upon the Arty platform
##
## Purpose:
##
## Creator: Dan Gisselquist, Ph.D.
## Gisselquist Technology, LLC
##
################################################################################
##
## 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
##
##
################################################################################
##
##
all: eqspiflash_tb
 
CXX := g++
FLAGS := -Wall -Og -g
RTLD := ../../rtl
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I/usr/share/verilator/include
SOURCES := eqspiflashsim.cpp eqspiflash_tb.cpp
VOBJDR := $(RTLD)/obj_dir
VLIB := /usr/share/verilator/include/verilated.cpp
 
eqspiflash_tb: eqspiflash_tb.cpp eqspiflashsim.cpp $(VOBJDR)/Veqspiflash__ALL.a
$(CXX) $(FLAGS) $(INCS) $^ $(VOBJDR)/Veqspiflash__ALL.a $(VLIB) -o $@
 
enetctrl_tb: enetctrl_tb.cpp enetctrlsim.cpp $(VOBJDR)/Venetctrl__ALL.a
$(CXX) $(FLAGS) $(INCS) $^ $(VOBJDR)/Venetctrl__ALL.a $(VLIB) -o $@
 
.PHONY: clean
clean:
rm ./eqspiflash_tb
rm ./enetctrl_tb
 
/trunk/bench/cpp/eqspiflashsim.h
0,0 → 1,117
////////////////////////////////////////////////////////////////////////////////
//
// Filename: eqspiflashsim.h
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: This library simulates the operation of an Extended Quad-SPI
// commanded flash, such as the N25Q128A used on the Arty
// development board by Digilent. As such, it is defined by
// 16 MBytes of memory (4 MWords).
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef EQSPIFLASHSIM_H
#define EQSPIFLASHSIM_H
 
#define EQSPIF_WIP_FLAG 0x0001
#define EQSPIF_WEL_FLAG 0x0002
#define EQSPIF_DEEP_POWER_DOWN_FLAG 0x0200
class EQSPIFLASHSIM {
typedef enum {
EQSPIF_IDLE,
EQSPIF_XIP,
EQSPIF_RDSR,
EQSPIF_RDCR,
EQSPIF_RDNVCONFIG,
EQSPIF_RDEVCONFIG,
EQSPIF_WRSR,
EQSPIF_WRCR,
EQSPIF_WRNVCONFIG,
EQSPIF_WREVCONFIG,
EQSPIF_RDFLAGS,
EQSPIF_CLRFLAGS,
EQSPIF_RDLOCK,
EQSPIF_WRLOCK,
EQSPIF_RDID,
EQSPIF_RELEASE,
EQSPIF_FAST_READ,
EQSPIF_QUAD_READ_CMD,
EQSPIF_QUAD_READ,
EQSPIF_PP,
EQSPIF_QPP,
// Erase states
EQSPIF_SUBSECTOR_ERASE,
EQSPIF_SECTOR_ERASE,
EQSPIF_BULK_ERASE,
// OTP memory
EQSPIF_PROGRAM_OTP,
EQSPIF_READ_OTP,
//
EQSPIF_INVALID
} EQSPIF_STATE;
 
EQSPIF_STATE m_state;
char *m_mem, *m_pmem, *m_otp, *m_lockregs;
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_nvconfig, m_evconfig, m_flagreg, m_nxtout;
bool m_quad_mode, m_debug, m_otp_wp;
 
public:
EQSPIFLASHSIM(void);
void load(const char *fname) { load(0, fname); }
void load(const unsigned addr, const char *fname);
void debug(const bool dbg) { m_debug = dbg; }
bool debug(void) const { return m_debug; }
bool write_enabled(void) const { return m_debug; }
unsigned counts_till_idle(void) const {
return m_write_count; }
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);
};
 
#endif
/trunk/mkdatev.pl
0,0 → 1,89
#!/usr/bin/perl
################################################################################
##
## Filename: mkdatev.pl
##
## Project: OpenArty, an entirely open SoC based upon the Arty platform
##
## Purpose: This file creates a file containing a `define DATESTAMP
## which can be used to tell when the build took place.
##
##
## Creator: Dan Gisselquist, Ph.D.
## Gisselquist Technology, LLC
##
################################################################################
##
## Copyright (C) 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.
##
## License: GPL, v3, as defined and found on www.gnu.org,
## http:##www.gnu.org/licenses/gpl.html
##
##
################################################################################
##
##
 
$now = time;
($sc,$mn,$nhr,$ndy,$nmo,$nyr,$nwday,$nyday,$nisdst) = localtime($now);
$nyr = $nyr+1900; $nmo = $nmo+1;
 
# And just because perl doesn't like my dollars signs ...
$doc = "\$(ROOT)/doc";
 
print <<"EOM";
////////////////////////////////////////////////////////////////////////////////
//
// Filename: builddate.v
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: This file records the date of the last build. Running "make"
// in the main directory will create this file. The `define found
// within it then creates a version stamp that can be used to tell which
// configuration is within an FPGA and so forth.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// 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 $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
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
EOM
 
print "`define DATESTAMP 32\'h";
printf("%04d%02d%02d\n", $nyr, $nmo, $ndy);
 
trunk/mkdatev.pl Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/arty.xdc =================================================================== --- trunk/arty.xdc (nonexistent) +++ trunk/arty.xdc (revision 5) @@ -0,0 +1,292 @@ +## This file is a general .xdc for the ARTY Rev. B +## To use it in a project: +## - uncomment the lines corresponding to used pins +## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project + +# Config setup +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 3.3 [current_design] + +## Clock signal + +set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { i_clk_100mhz }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] +create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { i_clk_100mhz }]; + +##Switches + +set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { i_sw[0] }]; #IO_L12N_T1_MRCC_16 Sch=sw[0] +set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { i_sw[1] }]; #IO_L13P_T2_MRCC_16 Sch=sw[1] +set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { i_sw[2] }]; #IO_L13N_T2_MRCC_16 Sch=sw[2] +set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { i_sw[3] }]; #IO_L14P_T2_SRCC_16 Sch=sw[3] + +##RGB LEDs + +set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led0[0] }]; #IO_L18N_T2_35 Sch=led0_b +set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led0[1] }]; #IO_L19N_T3_VREF_35 Sch=led0_g +set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led0[2] }]; #IO_L19P_T3_35 Sch=led0_r +set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led1[0] }]; #IO_L20P_T3_35 Sch=led1_b +set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led1[1] }]; #IO_L21P_T3_DQS_35 Sch=led1_g +set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led1[2] }]; #IO_L20N_T3_35 Sch=led1_r +set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led2[0] }]; #IO_L21N_T3_DQS_35 Sch=led2_b +set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led2[1] }]; #IO_L22N_T3_35 Sch=led2_g +set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led2[2] }]; #IO_L22P_T3_35 Sch=led2_r +set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led3[0] }]; #IO_L23P_T3_35 Sch=led3_b +set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led3[1] }]; #IO_L24P_T3_35 Sch=led3_g +set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { o_clr_led3[2] }]; #IO_L23N_T3_35 Sch=led3_r + +##LEDs + +set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { o_led[0] }]; #IO_L24N_T3_35 Sch=led[4] +set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { o_led[1] }]; #IO_25_35 Sch=led[5] +set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { o_led[2] }]; #IO_L24P_T3_A01_D17_14 Sch=led[6] +set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { o_led[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7] + +##Buttons + +set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { i_btn[0] }]; #IO_L6N_T0_VREF_16 Sch=btn[0] +set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { i_btn[1] }]; #IO_L11P_T1_SRCC_16 Sch=btn[1] +set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { i_btn[2] }]; #IO_L11N_T1_SRCC_16 Sch=btn[2] +set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { i_btn[3] }]; #IO_L12P_T1_MRCC_16 Sch=btn[3] + +##Pmod Header JA: PModCLS (bottom) + +#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_0_15 Sch=ja[1] +#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L4P_T0_15 Sch=ja[2] +#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L4N_T0_15 Sch=ja[3] +#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L6P_T0_15 Sch=ja[4] +#-- set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { o_cls_ss_n }]; #IO_L6N_T0_VREF_15 Sch=ja[7] +#-- set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { o_cls_mosi }]; #IO_L10P_T1_AD11P_15 Sch=ja[8] +#-- set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { i_cls_miso }]; #IO_L10N_T1_AD11N_15 Sch=ja[9] +#-- set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { o_cls_sck }]; #IO_25_15 Sch=ja[10] + +##Pmod Header JB: OLEDrgb + +set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { o_oled_cs_n }]; #IO_L11P_T1_SRCC_15 Sch=jb_p[1] +set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { o_oled_mosi }]; #IO_L11N_T1_SRCC_15 Sch=jb_n[1] +#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { i_oled_nc }]; #IO_L12P_T1_MRCC_15 Sch=jb_p[2] +set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { o_oled_sck }]; #IO_L12N_T1_MRCC_15 Sch=jb_n[2] +set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { o_oled_dcn }]; #IO_L23P_T3_FOE_B_15 Sch=jb_p[3] +set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { o_oled_reset_n }]; #IO_L23N_T3_FWE_B_15 Sch=jb_n[3] +set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { o_oled_vccen }]; #IO_L24P_T3_RS1_15 Sch=jb_p[4] +set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { o_oled_pmoden }]; #IO_L24N_T3_RS0_15 Sch=jb_n[4] + +##Pmod Header JC: GPS (top), UART (bottom) + +set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { i_gps_3df }]; #IO_L20P_T3_A08_D24_14 Sch=jc_p[1] +set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { o_gps_tx }]; #IO_L20N_T3_A07_D23_14 Sch=jc_n[1] +set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { i_gps_rx }]; #IO_L21P_T3_DQS_14 Sch=jc_p[2] +set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { i_gps_pps }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jc_n[2] +set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { i_aux_rts }]; #IO_L22P_T3_A05_D21_14 Sch=jc_p[3] +set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { o_aux_tx }]; #IO_L22N_T3_A04_D20_14 Sch=jc_n[3] +set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { i_aux_rx }]; #IO_L23P_T3_A03_D19_14 Sch=jc_p[4] +set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { o_aux_cts }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4] + +##Pmod Header JD: SD-Card + +set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { io_sd[3] }]; #IO_L11N_T1_SRCC_35 Sch=jd[1] +set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { io_sd_cmd }]; #IO_L12N_T1_MRCC_35 Sch=jd[2] +set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { io_sd[0] }]; #IO_L13P_T2_MRCC_35 Sch=jd[3] +set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { o_sd_sck }]; #IO_L13N_T2_MRCC_35 Sch=jd[4] +set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { io_sd[1] }]; #IO_L14P_T2_SRCC_35 Sch=jd[7] +set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { io_sd[2] }]; #IO_L14N_T2_SRCC_35 Sch=jd[8] +set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { i_sd_cs }]; #IO_L15P_T2_DQS_35 Sch=jd[9] +set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { i_sd_wp }]; #IO_L15N_T2_DQS_35 Sch=jd[10] + +##USB-UART Interface +# THESE ARE CORRECT +set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { o_uart_tx }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out +set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { i_uart_rx }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in +# + +##ChipKit Single Ended Analog Inputs +##NOTE: The ck_an_p pins can be used as single ended analog inputs with voltages from 0-3.3V (Chipkit Analog pins A0-A5). +## These signals should only be connected to the XADC core. When using these pins as digital I/O, use pins ck_io[14-19]. + +#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[0] }]; #IO_L1N_T0_AD4N_35 Sch=ck_an_n[0] +#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[0] }]; #IO_L1P_T0_AD4P_35 Sch=ck_an_p[0] +#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=ck_an_n[1] +#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[1] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=ck_an_p[1] +#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[2] }]; #IO_L7N_T1_AD6N_35 Sch=ck_an_n[2] +#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[2] }]; #IO_L7P_T1_AD6P_35 Sch=ck_an_p[2] +#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=ck_an_n[3] +#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[3] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=ck_an_p[3] +#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[4] }]; #IO_L10N_T1_AD15N_35 Sch=ck_an_n[4] +#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[4] }]; #IO_L10P_T1_AD15P_35 Sch=ck_an_p[4] +#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[5] }]; #IO_L1N_T0_AD0N_15 Sch=ck_an_n[5] +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[5] }]; #IO_L1P_T0_AD0P_15 Sch=ck_an_p[5] + +##ChipKit Digital I/O Low + +#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[0] }]; #IO_L16P_T2_CSI_B_14 Sch=ck_io[0] +#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[1] }]; #IO_L18P_T2_A12_D28_14 Sch=ck_io[1] +#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[2] }]; #IO_L8N_T1_D12_14 Sch=ck_io[2] +#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[3] }]; #IO_L19P_T3_A10_D26_14 Sch=ck_io[3] +#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { ck_io[4] }]; #IO_L5P_T0_D06_14 Sch=ck_io[4] +#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[5] }]; #IO_L14P_T2_SRCC_14 Sch=ck_io[5] +#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[6] }]; #IO_L14N_T2_SRCC_14 Sch=ck_io[6] +#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[7] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ck_io[7] +#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[8] }]; #IO_L11P_T1_SRCC_14 Sch=ck_io[8] +#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[9] }]; #IO_L10P_T1_D14_14 Sch=ck_io[9] +#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[10] }]; #IO_L18N_T2_A11_D27_14 Sch=ck_io[10] +#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[11] }]; #IO_L17N_T2_A13_D29_14 Sch=ck_io[11] +#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[12] }]; #IO_L12N_T1_MRCC_14 Sch=ck_io[12] +#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[13] }]; #IO_L12P_T1_MRCC_14 Sch=ck_io[13] + +##ChipKit Digital I/O On Outer Analog Header +##NOTE: These pins should be used when using the analog header signals A0-A5 as digital I/O (Chipkit digital pins 14-19) + +#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[14] }]; #IO_0_35 Sch=ck_a[0] +#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { ck_io[15] }]; #IO_L4P_T0_35 Sch=ck_a[1] +#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[16] }]; #IO_L4N_T0_35 Sch=ck_a[2] +#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[17] }]; #IO_L6P_T0_35 Sch=ck_a[3] +#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[18] }]; #IO_L6N_T0_VREF_35 Sch=ck_a[4] +#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[19] }]; #IO_L11P_T1_SRCC_35 Sch=ck_a[5] + +##ChipKit Digital I/O On Inner Analog Header +##NOTE: These pins will need to be connected to the XADC core when used as differential analog inputs (Chipkit analog pins A6-A11) + +#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[20] }]; #IO_L2P_T0_AD12P_35 Sch=ad_p[12] +#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[21] }]; #IO_L2N_T0_AD12N_35 Sch=ad_n[12] +#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[22] }]; #IO_L5P_T0_AD13P_35 Sch=ad_p[13] +#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[23] }]; #IO_L5N_T0_AD13N_35 Sch=ad_n[13] +#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { ck_io[24] }]; #IO_L8P_T1_AD14P_35 Sch=ad_p[14] +#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { ck_io[25] }]; #IO_L8N_T1_AD14N_35 Sch=ad_n[14] + +##ChipKit Digital I/O High + +#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[26] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=ck_io[26] +#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[27] }]; #IO_L16N_T2_A15_D31_14 Sch=ck_io[27] +#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[28] }]; #IO_L6N_T0_D08_VREF_14 Sch=ck_io[28] +#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { ck_io[29] }]; #IO_25_14 Sch=ck_io[29] +#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[30] }]; #IO_0_14 Sch=ck_io[30] +#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[31] }]; #IO_L5N_T0_D07_14 Sch=ck_io[31] +#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[32] }]; #IO_L13N_T2_MRCC_14 Sch=ck_io[32] +#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[33] }]; #IO_L13P_T2_MRCC_14 Sch=ck_io[33] +#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[34] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=ck_io[34] +#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[35] }]; #IO_L11N_T1_SRCC_14 Sch=ck_io[35] +#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[36] }]; #IO_L8P_T1_D11_14 Sch=ck_io[36] +#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[37] }]; #IO_L17P_T2_A14_D30_14 Sch=ck_io[37] +#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[38] }]; #IO_L7N_T1_D10_14 Sch=ck_io[38] +#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[39] }]; #IO_L7P_T1_D09_14 Sch=ck_io[39] +#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[40] }]; #IO_L9N_T1_DQS_D13_14 Sch=ck_io[40] +#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[41] }]; #IO_L9P_T1_DQS_14 Sch=ck_io[41] + +## ChipKit SPI + +#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { ck_miso }]; #IO_L17N_T2_35 Sch=ck_miso +#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { ck_mosi }]; #IO_L17P_T2_35 Sch=ck_mosi +#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { ck_sck }]; #IO_L18P_T2_35 Sch=ck_sck +#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { ck_ss }]; #IO_L16N_T2_35 Sch=ck_ss + +## ChipKit I2C + +#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { ck_scl }]; #IO_L4P_T0_D04_14 Sch=ck_scl +#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { ck_sda }]; #IO_L4N_T0_D05_14 Sch=ck_sda +#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { scl_pup }]; #IO_L9N_T1_DQS_AD3N_15 Sch=scl_pup +#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { sda_pup }]; #IO_L9P_T1_DQS_AD3P_15 Sch=sda_pup + +##Misc. ChipKit signals + +#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_L10N_T1_D15_14 Sch=ck_ioa +set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { i_reset_btn }]; #IO_L16P_T2_35 Sch=ck_rst + +##SMSC Ethernet PHY + +#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col +#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs +set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { o_eth_mdclk }]; #IO_L14N_T2_SRCC_15 Sch=eth_mdc +set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { io_eth_mdio }]; #IO_L17P_T2_A26_15 Sch=eth_mdio +#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk +#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn +#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv +#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0] +#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1] +#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2] +#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3] +#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr +#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk +#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0] +#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1] +#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2] +#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3] + +##Quad SPI Flash + +set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { o_qspi_cs_n }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs +set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { io_qspi_dat[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { io_qspi_dat[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { io_qspi_dat[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { io_qspi_dat[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] +set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { o_qspi_sck }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] + +##Power Measurements + +#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_n }]; #IO_L7N_T1_AD2N_15 Sch=ad_n[2] +#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_p }]; #IO_L7P_T1_AD2P_15 Sch=ad_p[2] +#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_n }]; #IO_L3N_T0_DQS_AD1N_15 Sch=ad_n[1] +#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_p }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ad_p[1] +#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_n }]; #IO_L5N_T0_AD9N_15 Sch=ad_n[9] +#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_p }]; #IO_L5P_T0_AD9P_15 Sch=ad_p[9] +#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_n }]; #IO_L8N_T1_AD10N_15 Sch=ad_n[10] +#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10] + +## Memory + +# Memory address lines +set_property -dict { PACKAGE_PIN R2 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[0] }]; +set_property -dict { PACKAGE_PIN M6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[1] }]; +set_property -dict { PACKAGE_PIN N4 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[2] }]; +set_property -dict { PACKAGE_PIN T1 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[3] }]; +set_property -dict { PACKAGE_PIN N6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[4] }]; +set_property -dict { PACKAGE_PIN R7 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[5] }]; +set_property -dict { PACKAGE_PIN V6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[6] }]; +set_property -dict { PACKAGE_PIN U7 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[7] }]; +set_property -dict { PACKAGE_PIN R8 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[8] }]; +set_property -dict { PACKAGE_PIN V7 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[9] }]; +set_property -dict { PACKAGE_PIN R6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[10] }]; +set_property -dict { PACKAGE_PIN U6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[11] }]; +set_property -dict { PACKAGE_PIN T6 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[12] }]; +set_property -dict { PACKAGE_PIN T8 IOSTANDARD SSTL135 } [get_ports { o_ddr_addr[13] }]; +set_property -dict { PACKAGE_PIN R1 IOSTANDARD SSTL135 } [get_ports { o_ddr_ba[0] }]; +set_property -dict { PACKAGE_PIN P4 IOSTANDARD SSTL135 } [get_ports { o_ddr_ba[1] }]; +set_property -dict { PACKAGE_PIN P2 IOSTANDARD SSTL135 } [get_ports { o_ddr_ba[2] }]; +# +set_property -dict { PACKAGE_PIN M4 IOSTANDARD SSTL135 } [get_ports { o_ddr_cas_n }]; +# Clock lines +set_property -dict { PACKAGE_PIN V9 IOSTANDARD DIFF_SSTL135 } [get_ports { o_ddr_ck_n }]; +set_property -dict { PACKAGE_PIN U9 IOSTANDARD DIFF_SSTL135 } [get_ports { o_ddr_ck_p }]; +# +set_property -dict { PACKAGE_PIN N5 IOSTANDARD SSTL135 } [get_ports { o_ddr_cke }]; +set_property -dict { PACKAGE_PIN U8 IOSTANDARD SSTL135 } [get_ports { o_ddr_cs_n }]; +set_property -dict { PACKAGE_PIN L1 IOSTANDARD SSTL135 } [get_ports { o_ddr_dm[0] }]; +set_property -dict { PACKAGE_PIN U1 IOSTANDARD SSTL135 } [get_ports { o_ddr_dm[1] }]; +# Data (DQ) lines +set_property -dict { PACKAGE_PIN K5 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[0] }]; +set_property -dict { PACKAGE_PIN L3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[1] }]; +set_property -dict { PACKAGE_PIN K3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[2] }]; +set_property -dict { PACKAGE_PIN L6 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[3] }]; +set_property -dict { PACKAGE_PIN M3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[4] }]; +set_property -dict { PACKAGE_PIN M1 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[5] }]; +set_property -dict { PACKAGE_PIN L4 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[6] }]; +set_property -dict { PACKAGE_PIN M2 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[7] }]; +set_property -dict { PACKAGE_PIN V4 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[8] }]; +set_property -dict { PACKAGE_PIN T5 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[9] }]; +set_property -dict { PACKAGE_PIN U4 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[10] }]; +set_property -dict { PACKAGE_PIN V5 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[11] }]; +set_property -dict { PACKAGE_PIN V1 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[12] }]; +set_property -dict { PACKAGE_PIN T3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[13] }]; +set_property -dict { PACKAGE_PIN U3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[14] }]; +set_property -dict { PACKAGE_PIN R3 IOSTANDARD SSTL135 } [get_ports { io_ddr_data[15] }]; +# DQS +set_property -dict { PACKAGE_PIN N1 IOSTANDARD DIFF_SSTL135 } [get_ports { io_ddr_dqs_n[0] }]; +set_property -dict { PACKAGE_PIN V2 IOSTANDARD DIFF_SSTL135 } [get_ports { io_ddr_dqs_n[1] }]; +set_property -dict { PACKAGE_PIN N2 IOSTANDARD DIFF_SSTL135 } [get_ports { io_ddr_dqs_p[0] }]; +set_property -dict { PACKAGE_PIN U2 IOSTANDARD DIFF_SSTL135 } [get_ports { io_ddr_dqs_p[1] }]; +set_property -dict { PACKAGE_PIN R5 IOSTANDARD SSTL135 } [get_ports { o_ddr_odt }]; +set_property -dict { PACKAGE_PIN P3 IOSTANDARD SSTL135 } [get_ports { o_ddr_ras_n }]; +set_property -dict { PACKAGE_PIN K6 IOSTANDARD SSTL135 } [get_ports { o_ddr_reset_n }]; +set_property -dict { PACKAGE_PIN P5 IOSTANDARD SSTL135 } [get_ports { o_ddr_we_n }]; +#Internal VREF +set_property INTERNAL_VREF 0.675 [ get_iobanks 34 ]; Index: trunk/Makefile =================================================================== --- trunk/Makefile (nonexistent) +++ trunk/Makefile (revision 5) @@ -0,0 +1,80 @@ +################################################################################ +## +## Filename: Makefile +## +## Project: OpenArty, an entirely open SoC based upon the Arty platform +## +## Purpose: A master project makefile. It tries to build all targets +## within the project, mostly by directing subdirectory makes. +## +## +## Creator: Dan Gisselquist, Ph.D. +## Gisselquist Technology, LLC +## +################################################################################ +## +## Copyright (C) 2015, 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. +## +## License: GPL, v3, as defined and found on www.gnu.org, +## http:##www.gnu.org/licenses/gpl.html +## +## +################################################################################ +## +## +.PHONY: all +all: archive datestamp +# all: verilated sw bench bit +# +# Could also depend upon load, if desired, but not necessary +BENCH := `find bench -name Makefile` `find bench -name "*.cpp"` `find bench -name "*.h"` +RTL := `find rtl -name "*.v"` `find rtl -name Makefile` +NOTES := `find . -name "*.txt"` `find . -name "*.html"` +SW := `find sw -name "*.cpp"` `find sw -name "*.h"` \ + `find sw -name "*.sh"` `find sw -name "*.py"` \ + `find sw -name "*.pl"` `find sw -name Makefile` +DEVSW := `find sw-board -name "*.cpp"` `find sw-board -name "*.h"` \ + `find sw-board -name Makefile` +PROJ := +BIN := `find xilinx -name "*.bit"` +CONSTRAINTS := arty.xdc +YYMMDD:=`date +%Y%m%d` + +.PHONY: datestamp +datestamp: + @bash -c 'if [ ! -e $(YYMMDD)-build.v ]; then rm 20??????-build.v; perl mkdatev.pl > $(YYMMDD)-build.v; rm -f rtl/builddate.v; fi' + @bash -c 'if [ ! -e rtl/builddate.v ]; then cd rtl; cp ../$(YYMMDD)-build.v builddate.v; fi' + +.PHONY: archive +archive: + tar --transform s,^,$(YYMMDD)-xula/, -chjf $(YYMMDD)-xula.tjz $(BENCH) $(SW) $(RTL) $(NOTES) $(PROJ) $(BIN) $(CONSTRAINTS) + +.PHONY: verilated +verilated: + cd rtl ; $(MAKE) --no-print-directory + +.PHONY: rtl +rtl: verilated + +# .PHONY: bench +# bench: +# cd bench ; $(MAKE) --no-print-directory + +# .PHONY: sw +# sw: +# cd sw ; $(MAKE) --no-print-directory + +# .PHONY: bit +# bit: +# cd xilinx ; $(MAKE) --no-print-directory xula.bit +

powered by: WebSVN 2.1.0

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