1 |
4 |
dgisselq |
//
|
2 |
|
|
//
|
3 |
|
|
// Filename: busmaster_tb.cpp
|
4 |
|
|
//
|
5 |
|
|
// Project: FPGA library development (XuLA2 development board)
|
6 |
|
|
//
|
7 |
|
|
// Purpose: This is piped version of the testbench for the busmaster
|
8 |
|
|
// verilog code. The busmaster code is designed to be a complete
|
9 |
|
|
// code set implementing all of the functionality of the XESS
|
10 |
|
|
// XuLA2 development board. If done well, the programs talking to
|
11 |
|
|
// this one should be able to talk to the board and apply the
|
12 |
|
|
// same tests to the board itself.
|
13 |
|
|
//
|
14 |
|
|
// Creator: Dan Gisselquist
|
15 |
|
|
// Gisselquist Tecnology, LLC
|
16 |
|
|
//
|
17 |
|
|
// Copyright: 2015
|
18 |
|
|
//
|
19 |
|
|
//
|
20 |
|
|
#include <signal.h>
|
21 |
|
|
#include <time.h>
|
22 |
|
|
|
23 |
|
|
#include "verilated.h"
|
24 |
|
|
#include "Vbusmaster.h"
|
25 |
|
|
|
26 |
|
|
#include "testb.h"
|
27 |
|
|
// #include "twoc.h"
|
28 |
|
|
#include "pipecmdr.h"
|
29 |
|
|
#include "qspiflashsim.h"
|
30 |
|
|
#include "sdramsim.h"
|
31 |
|
|
|
32 |
|
|
#include "port.h"
|
33 |
|
|
|
34 |
|
|
// Add a reset line, since Vbusmaster doesn't have one
|
35 |
|
|
class Vbusmasterr : public Vbusmaster {
|
36 |
|
|
public:
|
37 |
|
|
int i_rst;
|
38 |
|
|
virtual ~Vbusmasterr() {}
|
39 |
|
|
};
|
40 |
|
|
|
41 |
|
|
// No particular "parameters" need definition or redefinition here.
|
42 |
|
|
class BUSMASTER_TB : public PIPECMDR<Vbusmasterr> {
|
43 |
|
|
public:
|
44 |
|
|
unsigned long m_tx_busy_count;
|
45 |
|
|
QSPIFLASHSIM m_flash;
|
46 |
|
|
SDRAMSIM m_sdram;
|
47 |
|
|
unsigned m_last_led;
|
48 |
|
|
time_t m_start_time;
|
49 |
|
|
|
50 |
|
|
BUSMASTER_TB(void) : PIPECMDR(FPGAPORT) {
|
51 |
|
|
m_start_time = time(NULL);
|
52 |
|
|
}
|
53 |
|
|
|
54 |
|
|
void reset(void) {
|
55 |
|
|
m_core->i_clk = 1;
|
56 |
|
|
m_core->eval();
|
57 |
|
|
}
|
58 |
|
|
|
59 |
|
|
void tick(void) {
|
60 |
|
|
if ((m_tickcount & ((1<<28)-1))==0) {
|
61 |
|
|
double ticks_per_second = m_tickcount;
|
62 |
|
|
ticks_per_second /= (double)(time(NULL) - m_start_time);
|
63 |
|
|
printf(" ******** %.6f TICKS PER SECOND\n",
|
64 |
|
|
ticks_per_second);
|
65 |
|
|
}
|
66 |
|
|
|
67 |
|
|
// Set up the bus before any clock tick
|
68 |
|
|
m_core->i_clk = 1;
|
69 |
|
|
m_core->i_spi_miso = m_flash(m_core->o_sf_cs_n,
|
70 |
|
|
m_core->o_spi_sck,
|
71 |
|
|
m_core->o_spi_mosi)&0x02;
|
72 |
|
|
m_core->i_ram_data = m_sdram(1,
|
73 |
|
|
m_core->o_ram_cke, m_core->o_ram_cs_n,
|
74 |
|
|
m_core->o_ram_ras_n, m_core->o_ram_cas_n,
|
75 |
|
|
m_core->o_ram_we_n, m_core->o_ram_bs,
|
76 |
|
|
m_core->o_ram_addr, m_core->o_ram_drive_data,
|
77 |
|
|
m_core->o_ram_data);
|
78 |
|
|
PIPECMDR::tick();
|
79 |
|
|
|
80 |
|
|
bool writeout = false;
|
81 |
|
|
/*
|
82 |
|
|
if (m_core->v__DOT__runio__DOT__themouse__DOT__driver__DOT__rx_stb)
|
83 |
|
|
writeout = true;
|
84 |
|
|
else if (m_core->v__DOT__runio__DOT__themouse__DOT__driver__DOT__ps2iface__DOT__state != m_last_ps2_state)
|
85 |
|
|
writeout = true;
|
86 |
|
|
else if (m_core->v__DOT__runio__DOT__themouse__DOT__m_state != m_last_mouse_state)
|
87 |
|
|
writeout = true;
|
88 |
|
|
else if (m_core->i_ps2 != m_last_ps2)
|
89 |
|
|
writeout = true;
|
90 |
|
|
else if (m_core->o_ps2 != m_last_ops2)
|
91 |
|
|
writeout = true;
|
92 |
|
|
else if (m_core->v__DOT__runio__DOT__themouse__DOT__driver__DOT__ps2_perr)
|
93 |
|
|
writeout = true;
|
94 |
|
|
else if (m_core->v__DOT__runio__DOT__themouse__DOT__driver__DOT__ps2_ferr)
|
95 |
|
|
writeout = true;
|
96 |
|
|
*/
|
97 |
|
|
// if ((m_core->v__DOT__genbus__DOT__runwb__DOT__o_wb_cyc)||(m_core->v__DOT__bus_cyc))
|
98 |
|
|
// writeout = true;
|
99 |
|
|
// else if (m_last_cyc)
|
100 |
|
|
// writeout = true;
|
101 |
|
|
if ((m_tickcount > 0x5010)&&(m_core->v__DOT__sdram__DOT__r_state != 0))
|
102 |
|
|
writeout = true;
|
103 |
|
|
else if ((m_core->v__DOT__dwb_cyc)&&((m_core->v__DOT__wb_stb)
|
104 |
|
|
||(m_core->v__DOT__dwb_stall)
|
105 |
|
|
||(m_core->v__DOT__dwb_ack)))
|
106 |
|
|
writeout = true;
|
107 |
|
|
else if (m_core->v__DOT__dwb_cyc)
|
108 |
|
|
writeout = true;
|
109 |
|
|
else if (m_core->v__DOT__sdram__DOT__need_refresh)
|
110 |
|
|
writeout = true;
|
111 |
|
|
else if ((m_core->v__DOT__wbu_cyc)&&((m_core->v__DOT__wbu_addr == 0x106)||(m_core->v__DOT__wbu_addr == 0x0107)))
|
112 |
|
|
writeout = true;
|
113 |
|
|
if (m_tickcount < 0x05010)
|
114 |
|
|
writeout = false;
|
115 |
|
|
if (writeout) {
|
116 |
|
|
printf("%08lx:", m_tickcount);
|
117 |
|
|
|
118 |
|
|
printf("(%d,%d->%d),(%d,%d->%d)|%c[%08x/%08x]@%08x %d%d%c",
|
119 |
|
|
m_core->v__DOT__wbu_cyc,
|
120 |
|
|
m_core->v__DOT__dwb_cyc, // was zip_cyc
|
121 |
|
|
m_core->v__DOT__wb_cyc,
|
122 |
|
|
//
|
123 |
|
|
m_core->v__DOT__wbu_stb,
|
124 |
|
|
// 0, // m_core->v__DOT__dwb_stb, // was zip_stb
|
125 |
|
|
m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_stb_gbl,
|
126 |
|
|
m_core->v__DOT__wb_stb,
|
127 |
|
|
//
|
128 |
|
|
(m_core->v__DOT__wb_we)?'W':'R',
|
129 |
|
|
m_core->v__DOT__wb_data,
|
130 |
|
|
m_core->v__DOT__dwb_idata,
|
131 |
|
|
m_core->v__DOT__wb_addr,
|
132 |
|
|
m_core->v__DOT__dwb_ack,
|
133 |
|
|
m_core->v__DOT__dwb_stall,
|
134 |
|
|
(m_core->v__DOT__wb_err)?'E':'.');
|
135 |
|
|
|
136 |
|
|
printf("%c[%d%d%d%d,%d:%04x%c]@%06x(%d) ->%06x%c",
|
137 |
|
|
(m_core->v__DOT__sdram_sel)?'!':' ',
|
138 |
|
|
m_core->o_ram_cs_n, m_core->o_ram_ras_n,
|
139 |
|
|
m_core->o_ram_cas_n, m_core->o_ram_we_n,
|
140 |
|
|
m_core->o_ram_bs, m_core->o_ram_data,
|
141 |
|
|
(m_core->o_ram_drive_data)?'D':'-',
|
142 |
|
|
m_core->o_ram_addr,
|
143 |
|
|
(m_core->o_ram_addr>>10)&1,
|
144 |
|
|
m_core->i_ram_data,
|
145 |
|
|
(m_core->o_ram_drive_data)?'-':'V');
|
146 |
|
|
|
147 |
|
|
printf(" SD[%d,%d-%3x%d]",
|
148 |
|
|
m_core->v__DOT__sdram__DOT__r_state,
|
149 |
|
|
m_sdram.pwrup(),
|
150 |
|
|
m_core->v__DOT__sdram__DOT__refresh_clk,
|
151 |
|
|
m_core->v__DOT__sdram__DOT__need_refresh);
|
152 |
|
|
|
153 |
|
|
printf(" BNK[%d:%6x,%d:%6x,%d:%6x,%d:%6x],%x%d",
|
154 |
|
|
m_core->v__DOT__sdram__DOT__bank_active[0],
|
155 |
|
|
m_core->v__DOT__sdram__DOT__bank_row[0],
|
156 |
|
|
m_core->v__DOT__sdram__DOT__bank_active[1],
|
157 |
|
|
m_core->v__DOT__sdram__DOT__bank_row[1],
|
158 |
|
|
m_core->v__DOT__sdram__DOT__bank_active[2],
|
159 |
|
|
m_core->v__DOT__sdram__DOT__bank_row[2],
|
160 |
|
|
m_core->v__DOT__sdram__DOT__bank_active[3],
|
161 |
|
|
m_core->v__DOT__sdram__DOT__bank_row[3],
|
162 |
|
|
m_core->v__DOT__sdram__DOT__clocks_til_idle,
|
163 |
|
|
m_core->v__DOT__sdram__DOT__r_barrell_ack);
|
164 |
|
|
|
165 |
|
|
printf(" %s%s%c[%08x@%06x]",
|
166 |
|
|
(m_core->v__DOT__sdram__DOT__bus_cyc)?"C":" ",
|
167 |
|
|
(m_core->v__DOT__sdram__DOT__r_pending)?"PND":" ",
|
168 |
|
|
(m_core->v__DOT__sdram__DOT__r_we)?'W':'R',
|
169 |
|
|
(m_core->v__DOT__sdram__DOT__r_data),
|
170 |
|
|
(m_core->v__DOT__sdram__DOT__r_addr));
|
171 |
|
|
|
172 |
|
|
printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%2x",
|
173 |
|
|
(m_core->v__DOT__zippy__DOT__dbg_ack)?"A":"-",
|
174 |
|
|
(m_core->v__DOT__zippy__DOT__dbg_stall)?"S":"-",
|
175 |
|
|
(m_core->v__DOT__zippy__DOT__sys_dbg_cyc)?"D":"-",
|
176 |
|
|
(m_core->v__DOT__zippy__DOT__cpu_lcl_cyc)?"L":"-",
|
177 |
|
|
(m_core->v__DOT__zippy__DOT__cpu_dbg_stall)?"Z":"-",
|
178 |
|
|
(m_core->v__DOT__zippy__DOT__cmd_halt)?"H":"-",
|
179 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_cyc)?"P":"-",
|
180 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_cyc_gbl)?"G":"-",
|
181 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_cyc_lcl)?"L":"-",
|
182 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdvalid)?"D":"-",
|
183 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__dcd_ce)?"k":"-",
|
184 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid)?"O":"-",
|
185 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_ce)?"k":"-",
|
186 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__new_pc)?"N":"-",
|
187 |
|
|
(m_core->v__DOT__zippy__DOT__thecpu__DOT__clear_pipeline)?"C":"-",
|
188 |
|
|
(m_core->v__DOT__zippy__DOT__cmd_addr));
|
189 |
|
|
|
190 |
|
|
printf("\n");
|
191 |
|
|
}
|
192 |
|
|
|
193 |
|
|
}
|
194 |
|
|
|
195 |
|
|
};
|
196 |
|
|
|
197 |
|
|
BUSMASTER_TB *tb;
|
198 |
|
|
|
199 |
|
|
void busmaster_kill(int v) {
|
200 |
|
|
tb->kill();
|
201 |
|
|
exit(0);
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
int main(int argc, char **argv) {
|
205 |
|
|
Verilated::commandArgs(argc, argv);
|
206 |
|
|
tb = new BUSMASTER_TB;
|
207 |
|
|
|
208 |
|
|
// signal(SIGINT, busmaster_kill);
|
209 |
|
|
|
210 |
|
|
tb->reset();
|
211 |
|
|
|
212 |
|
|
while(1)
|
213 |
|
|
tb->tick();
|
214 |
|
|
|
215 |
|
|
exit(0);
|
216 |
|
|
}
|
217 |
|
|
|