URL
https://opencores.org/ocsvn/wbddr3/wbddr3/trunk
Subversion Repositories wbddr3
[/] [wbddr3/] [trunk/] [bench/] [cpp/] [ddrsdram_tb.cpp] - Rev 16
Go to most recent revision | Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////////////// // // Filename: ddrsdram_tb.cpp // // Project: A wishbone controlled DDR3 SDRAM memory controller. // // Purpose: To determine whether or not the wbddrsdram Verilog module works. // Run this program with no arguments. If the last line output // is "SUCCESS", you will know it works. // // 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 "verilated.h" #include "Vwbddrsdram.h" #include "pddrsim.h" // #include "ddrsdramsim.h" const int BOMBCOUNT = 2048, SDRAMMASK = 0x3ffffff, LGMEMSIZE = 28; class DDRSDRAM_TB { long m_tickcount; Vwbddrsdram *m_core; PDDRSIM *m_sdram; bool m_bomb; public: DDRSDRAM_TB(void) { m_core = new Vwbddrsdram; m_sdram= new PDDRSIM(LGMEMSIZE); } unsigned long operator[](const int index) { return (*m_sdram)[index]; } void set(unsigned addr, unsigned long v) { m_sdram->set(addr, v); } void tick(void) { m_core->i_clk = 1; m_core->i_ddr_data = (*m_sdram)( m_core->o_ddr_reset_n, m_core->o_ddr_cke, m_core->o_ddr_bus_oe, m_core->o_ddr_cmd_a, m_core->o_ddr_cmd_b, m_core->o_ddr_data); bool writeout = (!m_core->v__DOT__reset_override); int cmda, cmdb, cmd; cmda = (m_core->o_ddr_reset_n?0:32) |(m_core->o_ddr_cke?0:16) |((m_core->o_ddr_cmd_a&(1<<26))?8:0) |((m_core->o_ddr_cmd_a&(1<<25))?4:0) |((m_core->o_ddr_cmd_a&(1<<24))?2:0) |((m_core->o_ddr_cmd_a&(1<<23))?1:0); cmdb = (m_core->o_ddr_reset_n?0:32) |(m_core->o_ddr_cke?0:16) |((m_core->o_ddr_cmd_b&(1<<26))?8:0) |((m_core->o_ddr_cmd_b&(1<<25))?4:0) |((m_core->o_ddr_cmd_b&(1<<24))?2:0) |((m_core->o_ddr_cmd_b&(1<<23))?1:0); cmd = m_core->o_ddr_cmd_b; if ((cmdb&0x0f)!=DDR_NOOP) cmd = m_core->o_ddr_cmd_a; if ((cmda&0x0f)==DDR_REFRESH) writeout = true; if ((cmdb&0x0f)==DDR_REFRESH) writeout = true; if (writeout) { printf("%08lx-WB: %s/%s %s%s%s %s@0x%08x[%016lx/%016lx] -- ", 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->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)); printf("%s%s %d%d%d%d,%d%d%d%d %s%s[%x%x]%s%s B[%d,%d]@%04x %016lx %016lx", (m_core->o_ddr_reset_n)?" ":"R", (m_core->o_ddr_cke)?"CK":" ", (cmda&0x08)?1:0, (cmda&0x04)?1:0, (cmda&0x02)?1:0, (cmda&0x01)?1:0, (cmdb&0x08)?1:0, (cmdb&0x04)?1:0, (cmdb&0x02)?1:0, (cmdb&0x01)?1:0, // ((m_core->o_ddr_cmd_a>>5)&1)?"D":"-", ((m_core->o_ddr_cmd_b>>5)&1)?"D":"-", ((m_core->o_ddr_cmd_a>>1)&0x0f), ((m_core->o_ddr_cmd_b>>1)&0x0f), (m_core->o_ddr_cmd_a&1)?"O":" ", (m_core->o_ddr_bus_oe)?"E":" ", // (m_core->o_ddr_cmd_a>>(6+14))&0x07, // Get the bank address (m_core->o_ddr_cmd_b>>(6+14))&0x07, // Get the bank address ((cmd>>6)&0x03fff), // The command address (m_core->i_ddr_data), (m_core->o_ddr_data)); printf(" FIFO[%x,%x](%s,%d,%016lx)", m_core->v__DOT__bus_fifo_head, m_core->v__DOT__bus_fifo_tail, (m_core->v__DOT__bus_fifo_new[m_core->v__DOT__bus_fifo_tail])?"N":"o", m_core->v__DOT__bus_fifo_sub[m_core->v__DOT__bus_fifo_tail], m_core->v__DOT__bus_fifo_data[m_core->v__DOT__bus_fifo_tail]); printf(" BUS[A%03x/R%03x/N%03x/K%03x/T%03x/%02x]", (m_core->v__DOT__bus_active), (m_core->v__DOT__bus_read), (m_core->v__DOT__bus_new), (m_core->v__DOT__bus_ack), (m_core->v__DOT__bus_odt), (m_core->v__DOT__bus_subaddr)); /* // Reset logic printf(" RST(%06x%s[%2d] - %08x->%08x)", m_core->v__DOT__reset_timer, (m_core->v__DOT__reset_ztimer)?"Z":" ", (m_core->v__DOT__reset_address), (m_core->v__DOT__reset_instruction), (m_core->v__DOT__reset_cmd)); */ printf(" R_%s%03x[%d]%04x:%d/%02x/%016lx", (!m_core->v__DOT__r_pending)?"_" :(m_core->v__DOT__r_we)?"W":"R", (m_core->v__DOT__r_row), (m_core->v__DOT__r_bank), (m_core->v__DOT__r_col), (m_core->v__DOT__r_sub), (m_core->v__DOT__r_sel), (m_core->v__DOT__r_data)); printf(" S_%s%03x[%d]%04x:%d/%02x/%016lx%s%s%s", (!m_core->v__DOT__s_pending)?"_" :(m_core->v__DOT__s_we)?"W":"R", (m_core->v__DOT__s_row), (m_core->v__DOT__s_bank), (m_core->v__DOT__s_col), (m_core->v__DOT__s_sub), (m_core->v__DOT__s_sel), (m_core->v__DOT__s_data), (m_core->v__DOT__w_s_match)?"M":" ", (m_core->v__DOT__pipe_stall)?"P":" ", "-" //(m_core->v__DOT__s_stall)?"S":" " ); printf(" %s%s%s", "B", // (m_core->v__DOT__all_banks_closed)?"b":"B", (m_core->v__DOT__need_close_bank)?"C":"N", //:(m_core->v__DOT__maybe_close_next_bank)?"c":"N", (m_core->v__DOT__need_open_bank)?"O":"K"); // :(m_core->v__DOT__maybe_open_next_bank)?"o":"K"); for(int i=0; i<8; i++) { printf("%s%s%s%04x|%04x@%x%s", (m_core->v__DOT__r_bank==i)?"R":"[", ((m_core->v__DOT__bank_open)&(1<<i))?"+":" ", ((m_core->v__DOT__bank_closed)&(1<<i))?"-":" ", m_core->v__DOT__bank_status[i], m_sdram->bank_state(i), m_core->v__DOT__bank_address[i], (m_core->v__DOT__r_nxt_bank==i)?"N":"]"); } /* extern int gbl_state, gbl_counts; printf(" %2d:%08x ", gbl_state, gbl_counts); */ printf(" %s%s%s%s%s%s%s%s%s%s%s", (m_core->v__DOT__reset_override)?"R":" ", (m_core->v__DOT__need_refresh)?"N":" ", (m_core->v__DOT__need_close_bank)?"C":" ", (m_core->v__DOT__need_open_bank)?"O":" ", (m_core->v__DOT__valid_bank)?"V":" ", (m_core->v__DOT__maybe_close_next_bank)?"c":" ", (m_core->v__DOT__maybe_open_next_bank)?"o":" ", (m_core->v__DOT__pre_valid)?"p":" ", (m_core->v__DOT__w_r_valid)?"r":" ", (m_core->v__DOT__w_s_valid)?"s":" ", (m_core->v__DOT__pre_ack)?"k":" "); // Refresh logic printf(" F%s%05x:%x/%s", (m_core->v__DOT__refresh_ztimer)?"Z":" ", m_core->v__DOT__refresh_counter, m_core->v__DOT__refresh_addr, (m_core->v__DOT__need_refresh)?"N":" "); if (m_core->v__DOT__reset_override) printf(" OVERRIDE"); //if(m_core->v__DOT__last_open_bank)printf(" LST-OPEN"); switch(cmda) { case DDR_MRSET: printf("%13s", " MRSET"); break; case DDR_REFRESH: printf("%13s", " REFRESH"); break; case DDR_PRECHARGE: printf("%9s%3s", " PRECHARGE", ((m_core->o_ddr_cmd_a>>6)&0x400)?"-ALL":""); break; case DDR_ACTIVATE: printf("%13s", " ACTIVATE"); break; case DDR_WRITE: printf("%13s", " WRITE"); break; case DDR_READ: printf("%13s", " READ"); break; case DDR_ZQS: printf("%13s", " ZQS"); break; case DDR_NOOP: printf("%13s", " NOOP"); break; default: printf(" UCMD(%02x)", cmda); break; } switch(cmdb) { case DDR_MRSET: printf(" MRSET"); break; case DDR_REFRESH: printf(" REFRESH"); break; case DDR_PRECHARGE: printf(" PRECHARGE%s", ((m_core->o_ddr_cmd_b>>6)&0x400)?"-ALL":""); break; case DDR_ACTIVATE: printf(" ACTIVATE"); break; case DDR_WRITE: printf(" WRITE"); break; case DDR_READ: printf(" READ"); break; case DDR_ZQS: printf(" ZQS"); break; case DDR_NOOP: printf(" NOOP"); break; default: printf(" UCMD(%02x)", cmdb); break; } // Decode the command printf("\n"); } // A consistency check ... /* if (m_core->v__DOT__bus_fifo_head != m_core->v__DOT__bus_fifo_tail) { fflush(stdout); if (cmd == DDR_REFRESH) printf("FAIL: CMD=REFRESH, but head != tail\n"); assert(cmd != DDR_REFRESH); } */ 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 reset(void) { m_core->i_reset = 1; m_core->i_wb_cyc = 0; m_core->i_wb_stb = 0; tick(); m_core->i_reset = 0; } void wb_tick(void) { m_core->i_wb_cyc = 0; m_core->i_wb_stb = 0; tick(); assert(!m_core->o_wb_ack); } unsigned long wb_read(unsigned a) { int errcount = 0; unsigned long 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 & SDRAMMASK; 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(); result = m_core->o_wb_data; if (result != (*this)[a]) { printf("READ-FAIL\n"); assert(result == (*this)[a]); } // 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(); assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail); assert(!m_core->o_wb_ack); return result; } void wb_read(unsigned a, int len, unsigned long *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_stb = 1; m_core->i_wb_we = 0; m_core->i_wb_addr= a & SDRAMMASK; rdidx =0; cnt = 0; inc = 1; 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; printf("WB-READ[%08x] = %016lx\n", a+rdidx, m_core->o_wb_data); if (buf[rdidx] != (*this)[a+rdidx]) { printf("READ-FAIL\n"); assert(buf[rdidx] == (*this)[a+rdidx]); } rdidx++; } } 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; printf("WB-READ[%08x] = %016lx\n", a+rdidx, m_core->o_wb_data); if (buf[rdidx] != (*this)[a+rdidx]) { printf("READ-FAIL\n"); assert(buf[rdidx] == (*this)[a+rdidx]); } rdidx++; } } // 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(); assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail); assert(!m_core->o_wb_ack); } void wb_write(unsigned a, unsigned long v) { int errcount = 0; printf("WB-WRITE(%08x) = %016lx\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 & SDRAMMASK; m_core->i_wb_sel = 0x0ff; 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(); assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail); assert(!m_core->o_wb_ack); } void wb_write(unsigned a, unsigned int ln, unsigned long *buf) { unsigned errcount = 0, nacks = 0; m_core->i_wb_cyc = 1; m_core->i_wb_stb = 1; for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) { m_core->i_wb_we = 1; m_core->i_wb_addr= (a+stbcnt) & SDRAMMASK; m_core->i_wb_sel = 0x0ff; 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_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(); assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail); assert(!m_core->o_wb_ack); } bool bombed(void) const { return m_bomb; } }; void uload(unsigned len, unsigned long *buf) { FILE *fp = fopen("/dev/urandom", "r"); if ((NULL == fp)||(len != fread(buf, sizeof(unsigned long), len, fp))) { for(int i=0; i<(int)len; i++) buf[i] = (((unsigned long)rand())<<32) |(((unsigned long)rand())&(-1l<<32)); } if (NULL == fp) fclose(fp); } int main(int argc, char **argv) { Verilated::commandArgs(argc, argv); DDRSDRAM_TB *tb = new DDRSDRAM_TB; unsigned long *rdbuf, *mbuf; unsigned mlen = (1<<(LGMEMSIZE-3)); printf("Giving the core 140k cycles to start up\n"); // Before testing, let's give the unit time enough to warm up tb->reset(); for(int i=0; i<141195; i++) tb->wb_tick(); // Let's short circuit the test, and only test *some* of the memory // space. It'll probably be good enough, and it'll finish while I'm // waiting ... mlen = 1<<16; printf("Getting some memory ...\n"); rdbuf = new unsigned long[mlen]; mbuf = new unsigned long[mlen]; // Match buffer printf("Charging my memory with random values\n"); uload(mlen, rdbuf); #define CASE_TESTS #define SINGULAR_WRITE #define SINGULAR_READ #define BIGPIPELINE_WRITE #define BIGPIPELINE_READ #define PRIMEVEC_WRITE #define PRIMEVEC_READ #define SKIP_WRITE #define SKIP_READ #ifdef CASE_TESTS { unsigned long v; for(int i=0; i<8; i++) { tb->wb_write(i, rdbuf[i]); if ((v=tb->wb_read(i)) != rdbuf[i]) { printf("CASE-1, %16lx -> MEM[%08x] -> %16lx FAILED (R/W not equal)\n", rdbuf[i], i, v); goto test_failure; } else printf("MATCH[%d] = %16lx\n", i, rdbuf[i]); } } // Now repeat, hitting a different bank with each command { unsigned a; unsigned long v; for(int i=0; i<8; i++) { a = 1087 + i*1031; tb->wb_write(a, rdbuf[a]); if ((v=tb->wb_read(a)) != rdbuf[a]) { printf("CASE-2, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v); goto test_failure; } } } // And again, hitting the same bank with each command { unsigned a; unsigned long v; for(int i=0; i<8; i++) { a = 1109 + i*1024; tb->wb_write(a, rdbuf[a]); if ((v=tb->wb_read(a)) != rdbuf[a]) { printf("CASE-3, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v); goto test_failure; } } } // Same thing, but writing all first before reading { unsigned a; unsigned long v; for(int i=0; i<8; i++) { a = 1109 + i*1024; tb->wb_write(a, rdbuf[a]); } for(int i=0; i<8; i++) { a = 1109 + i*1024; if ((v=tb->wb_read(a)) != rdbuf[a]) { printf("CASE-4, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v); goto test_failure; } } } // And a quick pipeline test { unsigned long v, mbuf[8]; unsigned a = 379; tb->wb_write(0, 8, &rdbuf[379]); for(int i=0; i<8; i++) { a = 379+i; if ((v=(*tb)[i]) != rdbuf[a]) { printf("CASE-5, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], i, v); goto test_failure; } } tb->wb_read(0, 8, mbuf); for(int i=0; i<8; i++) { a = 379+i; if (mbuf[i] != rdbuf[a]) { printf("CASE-6, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], i, mbuf[i]); goto test_failure; } } } #endif #ifdef SINGULAR_WRITE // First test: singular reads through the memory, followed by // singular writes printf("Starting the single-read test\n"); for(int i=0; i<(int)mlen; i++) { tb->wb_write(i, rdbuf[i]); tb->wb_tick(); if ((*tb)[i] != rdbuf[i]) { printf("WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n", i, (*tb)[i], rdbuf[i]); goto test_failure; } if (tb->bombed()) goto test_failure; } #else #ifdef SINGULAR_READ // If we aren't doing the write test, we still need to charge // the memory for the read test. Here we do it manually. for(int i=0; i<(int)mlen; i++) tb->set(i, rdbuf[i]); #endif // !SINGULAR_WRITE && SINGULAR_READ #endif // SINGULAR_WRITE #ifdef SINGULAR_READ for(int i=0; i<(int)mlen; i++) { unsigned long v; if (rdbuf[i] != (v=tb->wb_read(i))) { printf("READ[%06x] = %016lx (Expecting %016lx)\n", i, v, rdbuf[i]); goto test_failure; } if (tb->bombed()) goto test_failure; tb->wb_tick(); } #endif #ifdef BIGPIPELINE_WRITE // Second test: Vector writes going through all memory, followed a // massive vector read printf("Starting the big-pipeline write test\n"); uload(mlen, rdbuf); // Get some new values tb->wb_write(0, mlen, rdbuf); if (tb->bombed()) goto test_failure; for(int i=0; i<(int)mlen; i++) { unsigned long v; if (rdbuf[i] != (v=(*tb)[i])) { printf("V-WRITE[%06x] = %016lx (Expecting %016lx)\n", i, v, rdbuf[i]); goto test_failure; } } #else #ifdef BIGPIPELINE_READ uload(mlen, rdbuf); // Get some new values // If we aren't doing the write test, we still need to charge // the memory for the read test. Here we do it manually. for(int i=0; i<(int)mlen; i++) (*tb)[i] = rdbuf[i]; #endif // BIGPIPELINE_WRITE && BIGPIPELINE_READ #endif #ifdef BIGPIPELINE_READ printf("Starting the big-pipeline read test\n"); tb->wb_read( 0, mlen, mbuf); if (tb->bombed()) goto test_failure; for(int i=0; i<(int)mlen; i++) { if (rdbuf[i] != mbuf[i]) { printf("V-READ[%06x] = %016lx (Expecting %016lx)\n", i, mbuf[i], rdbuf[i]); goto test_failure; } } #endif #ifdef PRIMEVEC_WRITE printf("Starting the prime-vector write test\n"); // Third test: Vector writes going through all memory, in prime numbers // of values at a time, followed by reads via a different prime number uload(mlen, rdbuf); // Get some new values { int nw = 3; for(int i=0; i<(int)mlen; i+=nw) { int ln = ((int)mlen-i>nw)?nw:mlen-i; tb->wb_write(i, nw, &rdbuf[i]); for(int j=0; j<ln; j++) { if ((*tb)[i+j] != rdbuf[i+j]) { printf("P-WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n", i, (*tb)[i], rdbuf[i]); goto test_failure; } } if (tb->bombed()) goto test_failure; } } #else #ifdef PRIMEVEC_READ uload(mlen, rdbuf); // Get some new values // If we aren't doing the write test, we still need to charge // the memory for the read test. Here we do it manually. for(int i=0; i<(int)mlen; i++) tb->set(i, rdbuf[i]); #endif #endif #ifdef PRIMEVEC_READ printf("Starting the prime-vector read test\n"); { int nr = 13; for(int i=0; i<(int)mlen; i+=nr) { int ln = ((int)mlen-i>nr)?nr:mlen-i; tb->wb_read(i, nr, &mbuf[i]); for(int j=0; j<ln; j++) { if (mbuf[i+j] != rdbuf[i+j]) { printf("P-READ[%06x] = %016lx (Expecting %016lx) FAILED\n", i, mbuf[i], rdbuf[i]); goto test_failure; } } if (tb->bombed()) goto test_failure; } } #endif #ifdef SKIP_WRITE // Fourth test: Singular writes though all of memory, skipping by some // prime address increment each time, followed by reads via a different // prime numbered increment. uload(mlen, rdbuf); // Get some new values for(int i=0; i<(int)mlen; i++) { int loc = (i*3889)&(mlen-1); tb->wb_write(loc, rdbuf[loc]); if ((*tb)[loc] != rdbuf[loc]) { printf("R-WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n", i, (*tb)[loc], rdbuf[loc]); goto test_failure; } if (tb->bombed()) goto test_failure; } #else #ifdef SKIP_READ uload(mlen, rdbuf); // Get some new values for(int i=0; i<(int)mlen; i++) tb->set(i, rdbuf[i]); #endif // !SKIP_WRITE && SKIP_READ #endif #ifdef SKIP_READ for(int i=0; i<(int)mlen; i++) { int loc = (i*7477)&(mlen-1); mbuf[loc] = tb->wb_read(loc); if (mbuf[loc] != rdbuf[loc]) { printf("R-READ[%06x] = %016lx (Expecting %016lx) FAILED\n", loc, mbuf[loc], rdbuf[loc]); goto test_failure; } if (tb->bombed()) goto test_failure; } #endif 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); }
Go to most recent revision | Compare with Previous | Blame | View Log