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
+