1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include <stdio.h>
#include <verilated.h>
#include "Vsimtop.h"
Vsimtop *sim;
int return_value = 0;
#ifdef SPI_MASTER_SS
# define SET_SS(mod, v)
#else
# define SET_SS(mod,v) ((mod)->ss = (v))
#endif
uint32_t main_time = 0;
double sc_time_stamp() {
return main_time;
}
static void progress() {
sim->eval();
main_time++;
sim->clk = !sim->clk;
sim->eval();
main_time++;
sim->clk = !sim->clk;
}
static void progress_n(int f) {
for (int i = 0; i < f; i++)
progress();
}
static void test_reset_pin(void) {
sim->rst_L = 0;
progress();
sim->rdy = 1;
sim->activate = 1;
progress_n(200);
assert(!sim->master_finished);
sim->rst_L = 1;
}
static void test_cross_transfer(unsigned m2s, unsigned s2m) {
#ifndef SPI_MASTER_NO_WRITE
sim->master_to_slave = m2s;
#endif
#ifndef SPI_MASTER_NO_READ
sim->slave_to_master = s2m;
#endif
sim->rst_L = 1;
progress();
SET_SS(sim, 1);
sim->rdy = 1;
sim->activate = 1;
progress();
while (!sim->master_finished)
progress();
progress_n(5);
sim->activate = 0;
SET_SS(sim, 0);
sim->rdy = 0;
progress_n(5);
if (sim->err) {
printf("slave error\n");
return_value = 1;
}
#ifndef SPI_MASTER_NO_WRITE
if (sim->master_to_slave != sim->from_master) {
printf("(m2s) %lx != %lx\n", sim->master_to_slave, sim->from_master);
return_value = 1;
}
#endif
#ifndef SPI_MASTER_NO_READ
if (sim->slave_to_master != sim->from_slave) {
printf("(m2s) %lx != %lx\n", sim->slave_to_master, sim->from_slave);
return_value = 1;
}
#endif
}
static void test_interrupted(unsigned m2s, unsigned s2m) {
sim->rst_L = 1;
progress();
sim->rdy = 1;
sim->activate = 1;
progress_n(6);
sim->rst_L = 0;
progress_n(100);
sim->rst_L = 1;
test_cross_transfer(m2s, s2m);
}
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
Verilated::traceEverOn(true);
sim = new Vsimtop;
SET_SS(sim, 0);
sim->clk = 0;
sim->activate = 0;
sim->rdy = 0;
test_reset_pin();
test_cross_transfer(0b101010101010101010101010, 0b010101010101010101010101);
test_cross_transfer(0b110011001100110011001100, 0b001100110011001100110011);
test_reset_pin();
for (int i = 0; i < 10000; i++) {
unsigned m2s = rand() & ((1 << WID) - 1);
unsigned s2m = rand() & ((1 << WID) - 1);
if (i % (((rand() + 1) % 32) + 1) == 0)
test_interrupted(m2s, s2m);
else
test_cross_transfer(m2s, s2m);
if (i % (((rand() + 1) % 64) + 1) == 0)
test_reset_pin();
}
sim->final();
delete sim;
return return_value;
}
|