5afa17f3c72d62583030195d6730606972ba95a5
[gram.git] / gram / simulation / simsoctb.v
1 // This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 `timescale 1 ns / 1 ns
4
5 module simsoctb;
6 // GSR & PUR init requires for Lattice models
7 GSR GSR_INST (
8 .GSR(1'b1)
9 );
10 PUR PUR_INST (
11 .PUR (1'b1)
12 );
13
14 reg clkin;
15 wire sync;
16 wire sync2x;
17 wire dramsync;
18 wire init;
19
20 // Generate 100 Mhz clock
21 always
22 begin
23 clkin = 1;
24 #5;
25 clkin = 0;
26 #5;
27 end
28
29 // DDR3 init
30 wire dram_ck;
31 wire dram_cke;
32 wire dram_we_n;
33 wire dram_cs_n;
34 wire dram_ras_n;
35 wire dram_cas_n;
36 wire [15:0] dram_dq;
37 inout wire [1:0] dram_dqs;
38 inout wire [1:0] dram_dqs_n;
39 wire [13:0] dram_a;
40 wire [2:0] dram_ba;
41 wire [1:0] dram_dm;
42 wire dram_odt;
43 wire [1:0] dram_tdqs_n;
44 wire dram_rst;
45
46 // anything here with "_n" has to be inverted. nmigen platforms
47 // sort that out by inverting (with PinsN)
48 ddr3 #(
49 .check_strict_timing(0)
50 ) ram_chip (
51 .rst_n(~dram_rst),
52 .ck(dram_ck),
53 .ck_n(~dram_ck),
54 .cke(dram_cke),
55 .cs_n(~dram_cs_n),
56 .ras_n(dram_ras_n),
57 .cas_n(dram_cas_n),
58 .we_n(dram_we_n),
59 .dm_tdqs(dram_dm),
60 .ba(dram_ba),
61 .addr(dram_a),
62 .dq(dram_dq),
63 .dqs(dram_dqs),
64 .dqs_n(dram_dqs_n),
65 .tdqs_n(dram_tdqs_n),
66 .odt(dram_odt)
67 );
68
69 assign dram_dqs_n = (dram_dqs != 2'hz) ? ~dram_dqs : 2'hz;
70
71 // Wishbone
72 reg [31:0] wishbone_adr = 0;
73 reg [31:0] wishbone_dat_w = 0;
74 wire [31:0] wishbone_dat_r;
75 reg [3:0] wishbone_sel = 0;
76 reg wishbone_cyc = 0;
77 reg wishbone_stb = 0;
78 reg wishbone_we = 0;
79 wire wishbone_ack;
80
81 //defparam ram_chip.
82
83 top simsoctop (
84 .ddr3_0__rst__io(dram_rst),
85 .ddr3_0__dq__io(dram_dq),
86 .ddr3_0__dqs__p(dram_dqs),
87 .ddr3_0__clk__p(dram_ck),
88 .ddr3_0__clk_en__io(dram_cke),
89 .ddr3_0__we__io(dram_we_n),
90 .ddr3_0__cs__io(dram_cs_n),
91 .ddr3_0__ras__io(dram_ras_n),
92 .ddr3_0__cas__io(dram_cas_n),
93 .ddr3_0__a__io(dram_a),
94 .ddr3_0__ba__io(dram_ba),
95 .ddr3_0__dm__io(dram_dm),
96 .ddr3_0__odt__io(dram_odt),
97 .wishbone_0__adr__io(wishbone_adr),
98 .wishbone_0__dat_r__io(wishbone_dat_r),
99 .wishbone_0__dat_w__io(wishbone_dat_w),
100 .wishbone_0__cyc__io(wishbone_cyc),
101 .wishbone_0__stb__io(wishbone_stb),
102 .wishbone_0__sel__io(wishbone_sel),
103 .wishbone_0__ack__io(wishbone_ack),
104 .wishbone_0__we__io(wishbone_we),
105 .clk100_0__io(clkin),
106 .rst_0__io(1'b0)
107 );
108
109 initial
110 begin
111 $dumpfile("simsoc.fst");
112 $dumpvars(0, clkin);
113 $dumpvars(0, dram_rst);
114 $dumpvars(0, dram_dq);
115 $dumpvars(0, dram_dqs);
116 $dumpvars(0, dram_ck);
117 $dumpvars(0, dram_cke);
118 $dumpvars(0, dram_cs_n);
119 $dumpvars(0, dram_we_n);
120 $dumpvars(0, dram_ras_n);
121 $dumpvars(0, dram_cas_n);
122 $dumpvars(0, dram_a);
123 $dumpvars(0, dram_ba);
124 $dumpvars(0, dram_dm);
125 $dumpvars(0, dram_odt);
126 $dumpvars(0, wishbone_adr);
127 $dumpvars(0, wishbone_dat_w);
128 $dumpvars(0, wishbone_dat_r);
129 $dumpvars(0, wishbone_ack);
130 $dumpvars(0, wishbone_stb);
131 $dumpvars(0, wishbone_cyc);
132 $dumpvars(0, wishbone_sel);
133 $dumpvars(0, wishbone_we);
134 $dumpvars(0, simsoctop);
135 $dumpvars(0, ram_chip);
136 end
137
138 // UART
139 reg [31:0] tmp;
140 initial
141 begin
142 #350; // Wait for RESET and POR
143
144 $display("Release RESET_N");
145 wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
146 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
147 wishbone_write(32'h00009000 >> 2, 8'h0C); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N
148
149 $display("Enable CKE");
150 wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
151 if (dram_cke != 1)
152 begin
153 $display("CKE activation failure");
154 $finish;
155 end
156
157 // Set MR2
158 $display("Set MR2");
159 wishbone_write(32'h0000900c >> 2, 32'h200); // p0 address
160 wishbone_write(32'h00009010 >> 2, 32'h2); // p0 baddress
161 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
162 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
163
164 // Set MR3
165 $display("Set MR3");
166 wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
167 wishbone_write(32'h00009010 >> 2, 32'h3); // p0 baddress
168 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
169 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
170
171 // Set MR1
172 $display("Set MR1");
173 wishbone_write(32'h0000900c >> 2, 32'h6); // p0 address
174 wishbone_write(32'h00009010 >> 2, 32'h1); // p0 baddress
175 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
176 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
177
178 // Set MR0
179 $display("Set MR0");
180 wishbone_write(32'h0000900c >> 2, 32'h320); // p0 address
181 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
182 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
183 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
184 wishbone_write(32'h0000900c >> 2, 32'h220); // p0 address
185 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
186 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
187 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
188 #6000; // tDLLK
189
190 // ZQ calibration
191 $display("Start ZQ calibration");
192 wishbone_write(32'h0000900c >> 2, 32'h400); // p0 address (A10=1)
193 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
194 wishbone_write(32'h00009004 >> 2, 8'h03); // WE|CS
195 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
196 #6000; // tZQinit
197
198 // Hardware control
199 wishbone_write(32'h00009000 >> 2, 8'h01); // DFII_CONTROL_SEL
200 #2000;
201
202 // reset burst detect
203 //wishbone_write(32'h00008000 >> 2, 0); // burst detect reset
204
205 // read on burst detect
206 //wishbone_read(32'h00008000 >> 2, tmp); // burst detect
207
208 // Read test on provisioned data, row 0, col 0-7
209 wishbone_read(32'h10000000 >> 2, tmp);
210 assert_equal_32(tmp, 32'hFACECA8C);
211 wishbone_read(32'h10000004 >> 2, tmp);
212 assert_equal_32(tmp, 32'h0A0A0A0A);
213 wishbone_read(32'h10000008 >> 2, tmp);
214 assert_equal_32(tmp, 32'hFAAFFEEF);
215 wishbone_read(32'h1000000C >> 2, tmp);
216 assert_equal_32(tmp, 32'h12345678);
217
218 // Read test on provisioned data, row 0, col 8-15
219 wishbone_read(32'h10000010 >> 2, tmp);
220 assert_equal_32(tmp, 32'h33333333);
221 wishbone_read(32'h10000014 >> 2, tmp);
222 assert_equal_32(tmp, 32'h22222222);
223 wishbone_read(32'h10000018 >> 2, tmp);
224 assert_equal_32(tmp, 32'h11111111);
225 wishbone_read(32'h1000001C >> 2, tmp);
226 assert_equal_32(tmp, 32'h00000000);
227
228 // Read test on provisioned data, row 0, col 16-23
229 wishbone_read(32'h10000020 >> 2, tmp);
230 assert_equal_32(tmp, 32'hA0A0A0A0);
231 wishbone_read(32'h10000024 >> 2, tmp);
232 assert_equal_32(tmp, 32'h55556666);
233 wishbone_read(32'h10000028 >> 2, tmp);
234 assert_equal_32(tmp, 32'h01020304);
235 wishbone_read(32'h1000002C >> 2, tmp);
236 assert_equal_32(tmp, 32'hF00DF00D);
237
238 // Read test on provisioned data, row 0, col 24-31
239 wishbone_read(32'h10000030 >> 2, tmp);
240 assert_equal_32(tmp, 32'hAAAAAAAA);
241 wishbone_read(32'h10000034 >> 2, tmp);
242 assert_equal_32(tmp, 32'h000C0C0A);
243 wishbone_read(32'h10000038 >> 2, tmp);
244 assert_equal_32(tmp, 32'h000CACA0);
245 wishbone_read(32'h1000003C >> 2, tmp);
246 assert_equal_32(tmp, 32'hC0CAC0CA);
247
248 // Write
249 wishbone_write(32'h1000000C >> 2, 32'h00BA0BAB);
250 wishbone_write(32'h10000008 >> 2, 32'h13374242);
251 wishbone_write(32'h10000004 >> 2, 32'hC0DEC0DE);
252 wishbone_write(32'h10000000 >> 2, 32'h01020304);
253
254 wishbone_read(32'h10000000 >> 2, tmp);
255 assert_equal_32(tmp, 32'h01020304);
256 wishbone_read(32'h10000004 >> 2, tmp);
257 assert_equal_32(tmp, 32'hC0DEC0DE);
258 wishbone_read(32'h10000008 >> 2, tmp);
259 assert_equal_32(tmp, 32'h13374242);
260 wishbone_read(32'h1000000C >> 2, tmp);
261 assert_equal_32(tmp, 32'h00BA0BAB);
262
263 $finish;
264 end
265
266 task wishbone_write;
267 input [31:0] address;
268 input [31:0] value;
269
270 begin
271 wishbone_adr = address;
272 wishbone_dat_w = value;
273 wishbone_cyc = 1;
274 wishbone_stb = 1;
275 wishbone_sel = 4'hF;
276 wishbone_we = 1;
277
278 while (wishbone_ack == 0)
279 begin
280 #10;
281 end
282
283 wishbone_cyc = 0;
284 wishbone_stb = 0;
285
286 #10;
287 end
288 endtask
289
290 task wishbone_read;
291 input [31:0] address;
292 output [31:0] value;
293
294 begin
295 wishbone_adr = address;
296 wishbone_we = 0;
297 wishbone_cyc = 1;
298 wishbone_stb = 1;
299 wishbone_sel = 4'hF;
300
301 while (wishbone_ack == 0)
302 begin
303 #10;
304 end
305
306 value = wishbone_dat_r;
307 wishbone_cyc = 0;
308 wishbone_stb = 0;
309
310 #10;
311 end
312 endtask
313
314 task assert_equal_32;
315 input [31:0] inA;
316 input [31:0] inB;
317
318 begin
319 if (inA != inB)
320 begin
321 $display("%m at %t: Assertion failed (32-bit) equality: %08x != %08x", $time, inA, inB);
322 $finish;
323 end
324 end
325 endtask
326
327 integer i;
328 integer tstart;
329 integer tend;
330
331 task speedtest_read;
332 begin
333 tstart = $time;
334 for (i = 0; i < 10; i = i+1) begin
335 wishbone_read(32'h10000000 >> 2, tmp);
336 wishbone_read(32'h10000004 >> 2, tmp);
337 wishbone_read(32'h10000008 >> 2, tmp);
338 wishbone_read(32'h1000000C >> 2, tmp);
339 wishbone_read(32'h10000010 >> 2, tmp);
340 wishbone_read(32'h10000014 >> 2, tmp);
341 wishbone_read(32'h10000018 >> 2, tmp);
342 wishbone_read(32'h1000001C >> 2, tmp);
343 wishbone_read(32'h10000020 >> 2, tmp);
344 wishbone_read(32'h10000024 >> 2, tmp);
345 wishbone_read(32'h10000028 >> 2, tmp);
346 wishbone_read(32'h1000002C >> 2, tmp);
347 wishbone_read(32'h10000030 >> 2, tmp);
348 wishbone_read(32'h10000034 >> 2, tmp);
349 wishbone_read(32'h10000038 >> 2, tmp);
350 wishbone_read(32'h1000003C >> 2, tmp);
351 end
352 tend = $time;
353
354 //$display("Read speedtest: %d B/s", (10*16*4)*1000000000/(1024*1024)/(tend-tstart));
355 $display("Read speedtest: %d MB/s", 610352/(tend-tstart));
356 end
357 endtask
358
359 task speedtest_write;
360 begin
361 tstart = $time;
362 for (i = 0; i < 10; i = i+1) begin
363 wishbone_write(32'h1000000C >> 2, 32'h00BA0BAB);
364 wishbone_write(32'h10000008 >> 2, 32'h13374242);
365 wishbone_write(32'h10000004 >> 2, 32'hC0DEC0DE);
366 wishbone_write(32'h10000000 >> 2, 32'h01020304);
367 wishbone_write(32'h1000001C >> 2, 32'h00BA0BAB);
368 wishbone_write(32'h10000018 >> 2, 32'h13374242);
369 wishbone_write(32'h10000014 >> 2, 32'hC0DEC0DE);
370 wishbone_write(32'h10000010 >> 2, 32'h01020304);
371 wishbone_write(32'h1000002C >> 2, 32'h00BA0BAB);
372 wishbone_write(32'h10000028 >> 2, 32'h13374242);
373 wishbone_write(32'h10000024 >> 2, 32'hC0DEC0DE);
374 wishbone_write(32'h10000020 >> 2, 32'h01020304);
375 wishbone_write(32'h1000003C >> 2, 32'h00BA0BAB);
376 wishbone_write(32'h10000038 >> 2, 32'h13374242);
377 wishbone_write(32'h10000034 >> 2, 32'hC0DEC0DE);
378 wishbone_write(32'h10000030 >> 2, 32'h01020304);
379 end
380 tend = $time;
381
382 //$display("Write speedtest: %d B/s", (10*16*4)*1000000000/(1024*1024)/(tend-tstart));
383 $display("Write speedtest: %d MB/s", 610352/(tend-tstart));
384 end
385 endtask
386 endmodule