3 `define ROM_MAX 'h20000
6 `define BB_AUTOINC 8'h40
8 `define BB_REG_CTRL_BASE 6'h00
9 `define BB_REG_CPU_BASE 6'h10
10 `define BB_REG_MEM_BASE 6'h20
11 `define BB_REG_IWM_BASE 6'h28
12 `define BB_REG_SCSI_BASE 6'h30
13 `define BB_REG_SCOPE_BASE 6'h38
15 /* SCSI Backbus interface */
16 `define BB_REG_LINES 0
17 `define BB_LINES_BSY 7
18 `define BB_LINES_SEL 6
19 `define BB_LINES_ACK 5
20 `define BB_LINES_ATN 4
21 `define BB_LINES_RST 3
23 `define BB_REG_ASSERT 1
24 `define BB_ASSERT_BSY 7
25 `define BB_ASSERT_SEL 6
26 `define BB_ASSERT_CD 5
27 `define BB_ASSERT_IO 4
28 `define BB_ASSERT_MSG 3
29 `define BB_ASSERT_REQ 2
30 `define BB_ASSERT_RST 1
31 `define BB_ASSERT_AUTO 0 /* Automatic mode */
33 `define BB_REG_ODATA 2
34 `define BB_REG_IDATA 3
35 `define BB_REG_ACNT_HI 4
36 `define BB_REG_ACNT_LO 5
48 reg [7:0] rom[0:`ROM_MAX];
49 reg [7:0] scsi_asserts;
50 reg [7:0] scsi_cdb[0:11];
51 reg [7:0] scsi_buf[0:2047];
54 /* SPI half clock period */
55 parameter SPI_HCLOCK = 40;
56 /* Setup time of data vs rising clock edge */
57 parameter SPI_HEAD = 4;
60 input [7:0] out_byte; /* Out to FPGA */
61 output reg [7:0] in_byte; /* In from FPGA */
69 #(SPI_HCLOCK-SPI_HEAD);
71 out_sr = { out_sr[6:0], 1'b0 };
72 in_sr = { in_sr[6:0], sdi };
87 do_spi(`BB_WRITE | `BB_AUTOINC | `BB_REG_CPU_BASE | 8, val);
88 do_spi(addr[23:16], val);
89 do_spi(addr[15:8], val);
90 do_spi(addr[7:0], val);
94 /* Run CPU interface */
96 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 6, val);
97 do_spi(8'h42, val); /* RUN + BKEN */
102 while(!stat[3]) begin
105 do_spi(`BB_REG_CPU_BASE | 7, val);
109 // $display("stat: %h", stat);
119 do_spi(`BB_WRITE | `BB_REG_SCSI_BASE | `BB_REG_ASSERT, val);
129 scsi_asserts[line] = 1'b1;
130 scsi_set_lines(scsi_asserts);
137 scsi_asserts[line] = 1'b0;
138 scsi_set_lines(scsi_asserts);
142 task scsi_set_autocnt;
146 do_spi(`BB_WRITE | `BB_AUTOINC |
147 `BB_REG_SCSI_BASE | `BB_REG_ACNT_HI, val);
148 do_spi(cnt[15:8], val);
149 do_spi(cnt[7:0], val);
159 do_spi(`BB_WRITE | `BB_REG_SCSI_BASE | `BB_REG_IDATA, val);
171 do_spi(`BB_REG_SCSI_BASE | `BB_REG_ODATA, dummy);
172 do_spi(8'hff, dummy);
184 do_spi(`BB_REG_SCSI_BASE | `BB_REG_LINES, dummy);
185 do_spi(8'hff, dummy);
203 'h12: begin /* INQUIRY */
205 for (i=0; i < 256; i = i + 1)
215 $display("CMD: INQUIRY 0x%h bytes", len);
217 'h08: begin /* READ6 */
219 len = 512 * scsi_cdb[4];
222 $display("CMD: READ6 0x%h bytes", len);
224 'h0a: begin /* WRITE6 */
226 len = 512 * scsi_cdb[4];
229 $display("CMD: WRITE6 0x%h bytes", len);
231 'h28: begin /* READ10 */
233 len = 512 * (scsi_cdb[7] * 256 + scsi_cdb[8]);
234 $display("CMD: READ10 0x%h bytes", len);
236 'h2a: begin /* WRITE10 */
238 len = 512 * (scsi_cdb[7] * 256 + scsi_cdb[8]);
239 $display("CMD: WRITE10 0x%h bytes", len);
242 stat = 1; /* CHECK CONDITION */
246 endtask // scsi_init_cmd
256 scsi_get_lines(lines);
257 $display("Waiting selection... Lines: %h", lines);
258 while (!lines[`BB_LINES_SEL] || lines[`BB_LINES_BSY])
259 scsi_get_lines(lines);
261 $display("Select ID: %h lines %h", data, lines);
264 $display("Wrong ID !");
266 $display("Setting BSY");
267 scsi_set(`BB_ASSERT_BSY);
268 $display("Waiting !SEL...");
269 while(lines[`BB_LINES_SEL])
270 scsi_get_lines(lines);
271 $display("Setting CMD, starting cmd transfer");
272 scsi_set(`BB_ASSERT_CD);
277 scsi_set(`BB_ASSERT_REQ);
278 while(!lines[`BB_LINES_ACK])
279 scsi_get_lines(lines);
281 $display("CMD %h = %h", i, data);
286 /* get command size */
298 $display("CMD size adjust %h", len);
300 scsi_clear(`BB_ASSERT_REQ);
301 while(lines[`BB_LINES_ACK])
302 scsi_get_lines(lines);
305 scsi_do_cmd(len, stat, direction);
306 scsi_clear(`BB_ASSERT_CD);
308 scsi_set(`BB_ASSERT_IO);
311 scsi_set(`BB_ASSERT_AUTO);
312 /* Break up transfer */
318 $display("Chunk of %h, remaining %h...", llen, len);
319 scsi_set_autocnt(llen);
322 do_spi(`BB_WRITE | `BB_REG_SCSI_BASE | `BB_REG_IDATA, val);
323 while(llen != 0) begin
324 $display("Writing byte %h", i);
325 do_spi(scsi_buf[i], val);
333 do_spi(`BB_REG_SCSI_BASE | `BB_REG_ODATA, val);
338 $display("dummy1: %h", val);
342 $display("dummy2: %h", val);
346 $display("dummy3: %h", val);
347 while(llen != 0) begin
353 $display("DATA %h: %h", i, data);
360 scsi_clear(`BB_ASSERT_AUTO);
362 $display("sending status %h", stat);
363 scsi_set(`BB_ASSERT_CD);
364 scsi_set(`BB_ASSERT_IO);
366 scsi_set(`BB_ASSERT_REQ);
367 while(!lines[`BB_LINES_ACK])
368 scsi_get_lines(lines);
369 scsi_clear(`BB_ASSERT_REQ);
370 while(lines[`BB_LINES_ACK])
371 scsi_get_lines(lines);
372 scsi_set(`BB_ASSERT_MSG);
373 $display("Sending message");
375 scsi_set(`BB_ASSERT_REQ);
376 while(!lines[`BB_LINES_ACK])
377 scsi_get_lines(lines);
378 scsi_clear(`BB_ASSERT_REQ);
379 while(lines[`BB_LINES_ACK])
380 scsi_get_lines(lines);
381 $display("Clearing phase & BSY");
382 scsi_clear(`BB_ASSERT_CD);
383 scsi_clear(`BB_ASSERT_IO);
384 scsi_clear(`BB_ASSERT_MSG);
385 scsi_clear(`BB_ASSERT_BSY);
386 end // else: !if(!data[6])
404 do_spi(`BB_AUTOINC | `BB_REG_CPU_BASE, val);
406 do_spi(8'hff, sval[0]);
407 do_spi(8'hff, sval[1]);
408 do_spi(8'hff, sval[2]);
409 do_spi(8'hff, sval[3]);
410 do_spi(8'hff, sval[4]);
411 do_spi(8'hff, sval[5]);
414 $display("RW:%b U:%b L:%b ADDR: %h DATA: %h",
415 sval[5][0], sval[5][1], sval[5][2],
416 { sval[0], sval[1], sval[2] },
417 { sval[3], sval[4] });
419 endtask // dump_latches
425 /* Step CPU interface */
427 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 6, val);
428 do_spi(8'h82, val); /* RUN + STEP */
432 /* Should wait for completion... not useful
433 * in practice as SPI is too slow
435 end // repeat (count)
441 // reg [7:0] scopedump[0:(2048 * 8)-1];
452 do_spi(`BB_AUTOINC | `BB_REG_CTRL_BASE, val);
455 $display("FPGA ID = 0x%h", val);
457 $display("FPGA Version = 0x%h", val);
459 $display("FPGA Control = 0x%h", val);
465 do_spi(`BB_WRITE | `BB_REG_CTRL_BASE | 2, val);
471 $display("Running to puts...");
481 /* Run CPU interface */
483 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 6, val);
484 do_spi(8'h02, val); /* RUN */
489 $display("Running to iwm_test1...");
499 $display("Running to P_mBootBeep...");
504 $display("Running to IWM init...");
509 $display("Running to P_ChecksumRomAndTestMemory...");
514 $display("Running to P_BootPart2 (fake hit)...");
519 $display("Running to P_BootPart2...");
532 /* Write memory from 0x201000 using mem SPI (ROM) */
533 $display("Loading ROM...");
534 rom_file = $fopenr("rom.bin");
535 rom_size = $fread(rom, rom_file, 0);
538 do_spi(`BB_WRITE | `BB_AUTOINC | `BB_REG_MEM_BSAE, val);
539 do_spi(8'h20, val); /* ROM base */
545 do_spi(`BB_WRITE | `BB_REG_MEM_BASE | 3, val);/
547 repeat(rom_size) begin
556 $display("RAM dump...");
557 $display("%h %h %h %h %h %h %h %h",
558 sval[0], sval[1], sval[2], sval[3],
559 sval[4], sval[5], sval[6], sval[7]);
561 /* Start the scope */
563 do_spi(`BB_WRITE | `BB_REG_SCOPE_BASE, val);
570 do_spi(`BB_WRITE | `BB_REG_CTRL_BASE | 2, val);
577 do_spi(`BB_WRITE | `BB_AUTOINC | `BB_REG_CPU_BASE | 8, val);
584 /* Run CPU interface */
586 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 6, val);
587 do_spi(8'h42, val); /* RUN + BKEN */
594 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 7, val);
599 $display("CPU Stat: %h", val);
606 /* Step CPU interface */
608 do_spi(`BB_WRITE | `BB_REG_CPU_BASE | 6, val);
609 do_spi(8'h82, val); /* RUN + STEP */
613 /* We shall wait for cycle to complete but we know
614 * how slow our SPI is ...
618 do_spi(`BB_AUTOINC | `BB_REG_CPU_BASE, val);
620 do_spi(8'hff, sval[0]);
621 do_spi(8'hff, sval[1]);
622 do_spi(8'hff, sval[2]);
623 do_spi(8'hff, sval[3]);
624 do_spi(8'hff, sval[4]);
625 do_spi(8'hff, sval[5]);
628 $display("RW:%b U:%b L:%b ADDR: %h DATA: %h",
629 sval[5][0], sval[5][1], sval[5][2],
630 { sval[0], sval[1], sval[2] },
631 { sval[3], sval[4] });
637 $display("Reading 0x1020 via SPI initiaed read cycle:");
639 /* Read value at 0x1020 */
641 do_spi(8'hc8, val); /* b001_000 */
647 do_spi(8'h01, val); /* _uds = 0, _lds = 0, r_w = 1 */
648 do_spi(8'h04, val); /* ctrl: cycle */
652 /* Here too, shall wait but heh ! */
656 do_spi(8'h48, val); /* b001_000 */
658 do_spi(8'hff, sval[0]);
659 do_spi(8'hff, sval[1]);
660 do_spi(8'hff, sval[2]);
661 do_spi(8'hff, sval[3]);
662 do_spi(8'hff, sval[4]);
663 do_spi(8'hff, sval[5]);
666 $display("RW:%b U:%b L:%b ADDR: %h DATA: %h",
667 sval[5][0], sval[5][1], sval[5][2],
668 { sval[0], sval[1], sval[2] },
669 { sval[3], sval[4] });
671 /* Read memory from 0x1000 using mem SPI */
673 do_spi(8'he0, val); /* b100_000 */
680 do_spi(8'h23, val); /* b100_000 */
682 do_spi(8'hff, val); /* add. dummy cycle for reads */
683 do_spi(8'hff, sval[0]);
684 do_spi(8'hff, sval[1]);
685 do_spi(8'hff, sval[2]);
686 do_spi(8'hff, sval[3]);
687 do_spi(8'hff, sval[4]);
688 do_spi(8'hff, sval[5]);
689 do_spi(8'hff, sval[6]);
690 do_spi(8'hff, sval[7]);
694 $display("RAM dump...");
695 $display("%h %h %h %h %h %h %h %h",
696 sval[0], sval[1], sval[2], sval[3],
697 sval[4], sval[5], sval[6], sval[7]);
704 /* Run CPU interface */
706 do_spi(8'h8e, val); /* b001_110 */
707 do_spi(8'h02, val); /* RUN */
711 /* Wait a bit and stop the scope */
716 do_spi(`BB_WRITE | `BB_REG_SCOPE_BASE, val);
723 /* Dump scope output */
729 do_spi(8'hff, sval[0]);
730 do_spi(8'hff, sval[1]);
731 do_spi(8'hff, sval[2]);
732 do_spi(8'hff, sval[3]);
733 do_spi(8'hff, sval[4]);
734 do_spi(8'hff, sval[5]);
735 do_spi(8'hff, sval[6]);
736 do_spi(8'hff, sval[7]);
737 $display("%h %h %h %h %h %h %h %h",
738 sval[0], sval[1], sval[2], sval[3],
739 sval[4], sval[5], sval[6], sval[7]);