| Line 37... |
Line 37... |
//
|
//
|
#include <stdio.h>
|
#include <stdio.h>
|
|
|
#include <verilated.h>
|
#include <verilated.h>
|
#include <verilated_vcd_c.h>
|
#include <verilated_vcd_c.h>
|
#include "testb.h"
|
|
#include "Vwbscope_tb.h"
|
#include "Vwbscope_tb.h"
|
|
#include "testb.h"
|
|
#define INTERRUPTWIRE o_interrupt
|
|
#include "wb_tb.h"
|
|
|
#define MMUFLAG_RONW 8 // Read only (not writeable)
|
const int LGMEMSIZE = 15;
|
#define MMUFLAG_ACCS 4 // Accessed
|
|
#define MMUFLAG_CCHE 2 // Cachable
|
class WBSCOPE_TB : public WB_TB<Vwbscope_tb> {
|
#define MMUFLAG_THSP 1 // Page has this context
|
bool m_bomb, m_debug;
|
|
|
const int BOMBCOUNT = 32,
|
|
LGMEMSIZE = 15;
|
|
|
|
class WBSCOPE_TB : public TESTB<Vwbscope_tb> {
|
|
bool m_bomb, m_miss, m_err, m_debug;
|
|
int m_last_tlb_index;
|
|
public:
|
public:
|
|
|
WBSCOPE_TB(void) {
|
WBSCOPE_TB(void) {
|
m_debug = true;
|
m_debug = true;
|
m_last_tlb_index = 0;
|
|
}
|
}
|
|
|
void tick(void) {
|
void tick(void) {
|
|
|
TESTB<Vwbscope_tb>::tick();
|
WB_TB<Vwbscope_tb>::tick();
|
|
|
bool writeout = true;
|
bool writeout = true;
|
if ((m_debug)&&(writeout)) {}
|
if ((m_debug)&&(writeout)) {}
|
}
|
}
|
|
|
| Line 74... |
Line 68... |
m_core->i_wb_stb = 0;
|
m_core->i_wb_stb = 0;
|
tick();
|
tick();
|
m_core->i_rst = 0;
|
m_core->i_rst = 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 wb_read(unsigned a) {
|
|
unsigned result;
|
|
|
|
printf("WB-READM(%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>>2)&1;
|
|
|
|
// Dont need to check for stalls, since the wbscope never stalls
|
|
tick();
|
|
|
|
m_core->i_wb_stb = 0;
|
|
|
|
while(!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;
|
|
|
|
// Let the bus idle for one cycle
|
|
tick();
|
|
|
|
return result;
|
|
}
|
|
|
|
void wb_read(unsigned a, int len, unsigned *buf) {
|
|
int cnt, rdidx;
|
|
|
|
printf("WB-READM(%08x, %d)\n", a, len);
|
|
|
|
m_core->i_wb_cyc = 1;
|
|
m_core->i_wb_stb = 1;
|
|
m_core->i_wb_we = 0;
|
|
m_core->i_wb_addr = (a>>2)&1;
|
|
|
|
rdidx =0; cnt = 0;
|
|
|
|
do {
|
|
tick();
|
|
// Normally, we'd increment the address here. For the
|
|
// scope, multiple reads only make sense if they are
|
|
// from the same address, hence we don't increment the
|
|
// address here
|
|
// m_core->i_wb_addr += inc;
|
|
cnt += 1;
|
|
if (m_core->o_wb_ack)
|
|
buf[rdidx++] = m_core->o_wb_data;
|
|
} while(cnt < len);
|
|
|
|
m_core->i_wb_stb = 0;
|
|
|
|
while(rdidx < len) {
|
|
tick();
|
|
if (m_core->o_wb_ack)
|
|
buf[rdidx++] = m_core->o_wb_data;
|
|
}
|
|
|
|
// Release the bus?
|
|
m_core->i_wb_cyc = 0;
|
|
|
|
tick();
|
|
assert(!m_core->o_wb_ack);
|
|
}
|
|
|
|
void wb_write(unsigned a, unsigned v) {
|
|
int errcount = 0;
|
|
|
|
printf("WB-WRITEM(%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>>2)&1;
|
|
m_core->i_wb_data= v;
|
|
|
|
tick();
|
|
m_core->i_wb_stb = 0;
|
|
|
|
while(!m_core->o_wb_ack) {
|
|
tick();
|
|
}
|
|
|
|
tick();
|
|
|
|
// Release the bus?
|
|
m_core->i_wb_cyc = 0;
|
|
m_core->i_wb_stb = 0;
|
|
|
|
assert(!m_core->o_wb_ack);
|
|
}
|
|
|
|
unsigned trigger(void) {
|
unsigned trigger(void) {
|
m_core->i_trigger = 1;
|
m_core->i_trigger = 1;
|
wb_tick();
|
idle();
|
m_core->i_trigger = 0;
|
m_core->i_trigger = 0;
|
printf("TRIGGERED AT %08x\n", m_core->o_data);
|
|
return m_core->o_data;
|
return m_core->o_data;
|
}
|
}
|
|
|
bool debug(void) const { return m_debug; }
|
bool debug(void) const { return m_debug; }
|
bool debug(bool nxtv) { return m_debug = nxtv; }
|
bool debug(bool nxtv) { return m_debug = nxtv; }
|
| Line 194... |
Line 85... |
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
WBSCOPE_TB *tb = new WBSCOPE_TB;
|
WBSCOPE_TB *tb = new WBSCOPE_TB;
|
unsigned v;
|
unsigned v;
|
unsigned *buf;
|
unsigned *buf;
|
int trigpt;
|
int trigpt;
|
|
unsigned trigger_time, expected_first_value;
|
|
|
tb->opentrace("wbscope_tb.vcd");
|
tb->opentrace("wbscope_tb.vcd");
|
printf("Giving the core 2 cycles to start up\n");
|
printf("Giving the core 2 cycles to start up\n");
|
// Before testing, let's give the unit time enough to warm up
|
// Before testing, let's give the unit time enough to warm up
|
tb->reset();
|
tb->reset();
|
for(int i=0; i<2; i++)
|
tb->idle(2);
|
tb->wb_tick();
|
|
|
|
#define WBSCOPE_STATUS 0
|
#define WBSCOPE_STATUS 0
|
#define WBSCOPE_DATA 4
|
#define WBSCOPE_DATA 4
|
#define WBSCOPE_NORESET 0x80000000
|
#define WBSCOPE_NORESET 0x80000000
|
#define WBSCOPE_TRIGGER (WBSCOPE_NO_RESET|0x08000000)
|
#define WBSCOPE_TRIGGER (WBSCOPE_NO_RESET|0x08000000)
|
| Line 215... |
Line 106... |
#define WBSCOPE_DISABLED 0x04000000
|
#define WBSCOPE_DISABLED 0x04000000
|
#define WBSCOPE_LGLEN(A) ((A>>20)&0x01f)
|
#define WBSCOPE_LGLEN(A) ((A>>20)&0x01f)
|
#define WBSCOPE_LENGTH(A) (1<<(LGLEN(A)))
|
#define WBSCOPE_LENGTH(A) (1<<(LGLEN(A)))
|
|
|
// First test ... read the status register
|
// First test ... read the status register
|
v = tb->wb_read(WBSCOPE_STATUS);
|
v = tb->readio(WBSCOPE_STATUS);
|
int ln = WBSCOPE_LGLEN(v);
|
int ln = WBSCOPE_LGLEN(v);
|
printf("V = %08x\n", v);
|
printf("V = %08x\n", v);
|
printf("LN = %d, or %d entries\n", ln, (1<<ln));
|
printf("LN = %d, or %d entries\n", ln, (1<<ln));
|
printf("DLY = %d\n", (v&0xfffff));
|
printf("DLY = %d\n", (v&0xfffff));
|
if (((1<<ln) < tb->m_tickcount)&&(v&0x10000000)) {
|
if (((1<<ln) < tb->m_tickcount)&&(v&0x10000000)) {
|
printf("SCOPE is already triggered! ??\n");
|
printf("SCOPE is already triggered! ??\n");
|
goto test_failure;
|
goto test_failure;
|
}
|
}
|
buf = new unsigned[(1<<ln)];
|
buf = new unsigned[(1<<ln)];
|
|
|
for(int i=0; i<(1<<ln); i++)
|
tb->idle(1<<ln);
|
tb->wb_tick();
|
|
|
|
v = tb->wb_read(WBSCOPE_STATUS);
|
v = tb->readio(WBSCOPE_STATUS);
|
if ((v&WBSCOPE_PRIMED)==0) {
|
if ((v&WBSCOPE_PRIMED)==0) {
|
printf("v = %08x\n", v);
|
printf("v = %08x\n", v);
|
printf("SCOPE hasn\'t primed! ??\n");
|
printf("SCOPE hasn\'t primed! ??\n");
|
goto test_failure;
|
goto test_failure;
|
}
|
}
|
|
|
tb->trigger();
|
trigger_time = tb->trigger() & 0x7fffffff;
|
v = tb->wb_read(WBSCOPE_STATUS);
|
printf("TRIGGERED AT %08x\n", trigger_time);
|
|
|
|
v = tb->readio(WBSCOPE_STATUS);
|
if ((v&WBSCOPE_TRIGGERED)==0) {
|
if ((v&WBSCOPE_TRIGGERED)==0) {
|
printf("v = %08x\n", v);
|
printf("v = %08x\n", v);
|
printf("SCOPE hasn\'t triggered! ??\n");
|
printf("SCOPE hasn\'t triggered! ??\n");
|
goto test_failure;
|
goto test_failure;
|
}
|
}
|
|
|
while((v & WBSCOPE_STOPPED)==0)
|
while((v & WBSCOPE_STOPPED)==0)
|
v = tb->wb_read(WBSCOPE_STATUS);
|
v = tb->readio(WBSCOPE_STATUS);
|
printf("SCOPE has stopped, reading data\n");
|
printf("SCOPE has stopped, reading data\n");
|
|
|
tb->wb_read(WBSCOPE_DATA, (1<<ln), buf);
|
tb->readz(WBSCOPE_DATA, (1<<ln), buf);
|
for(int i=0; i<(1<<ln); i++) {
|
for(int i=0; i<(1<<ln); i++) {
|
printf("%4d: %08x\n", i, buf[i]);
|
printf("%4d: %08x%s\n", i, buf[i],
|
if ((i>0)&&(((buf[i]&0x7fffffff)-(buf[i-1]&0x7fffffff))!=1))
|
(i== (1<<ln)-1-(v&0x0fffff)) ? " <<--- TRIGGER!":"");
|
|
if ((i>0)&&(((buf[i]&0x7fffffff)-(buf[i-1]&0x7fffffff))!=1)) {
|
|
printf("ERR: Scope data doesn't increment!\n");
|
|
printf("\tIn other words--its not matching the test signal\n");
|
goto test_failure;
|
goto test_failure;
|
}
|
}
|
|
}
|
|
|
trigpt = (1<<ln)-v&(0x0fffff);
|
trigpt = (1<<ln)-v&(0x0fffff)-1;
|
if ((trigpt >= 0)&&(trigpt < (1<<ln))) {
|
if ((trigpt >= 0)&&(trigpt < (1<<ln))) {
|
printf("Trigger value = %08x\n", buf[trigpt]);
|
printf("Trigger value = %08x\n", buf[trigpt]);
|
if (((0x80000000 & buf[trigpt])==0)&&(trigpt>0)) {
|
if (((0x80000000 & buf[trigpt])==0)&&(trigpt>0)) {
|
printf("Pre-Trigger value = %08x\n", buf[trigpt-1]);
|
printf("Pre-Trigger value = %08x\n", buf[trigpt-1]);
|
if ((buf[trigpt-1]&0x80000000)==0) {
|
if ((buf[trigpt-1]&0x80000000)==0) {
|
| Line 267... |
Line 163... |
goto test_failure;
|
goto test_failure;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
expected_first_value = trigger_time + (v&0x0fffff) - (1<<ln);
|
|
if (buf[0] != expected_first_value) {
|
|
printf("Initial value = %08x\n", buf[0]);
|
|
printf("Expected: %08x\n", expected_first_value);
|
|
printf("ERR: WRONG STARTING-VALUE\n");
|
|
goto test_failure;
|
|
}
|
|
|
printf("SUCCESS!!\n");
|
printf("SUCCESS!!\n");
|
delete tb;
|
delete tb;
|
exit(0);
|
exit(0);
|
test_failure:
|
test_failure:
|
printf("FAIL-HERE\n");
|
printf("FAIL-HERE\n");
|