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