4 * NCR5380 SCSI module for minimigmac.
6 * Located on high data bus, but writes are done at odd addresses as
7 * LDS is used as WR signals or something like that on a Mac Plus.
9 * We don't care here and just ignore which side was used. We also don't
10 * implement the interrupt logic (well at least we don't route it to the
11 * CPU like a real Mac) and we do all sort of simplifications such as only
12 * supporting initiator mode
14 * This is implementation is really just a gateway to the backbus, the
15 * microcontroller can observe SCSI line states and exchange data.
21 * We do not support external arbitration & reselection, thus we always
22 * win it. Thus our arbitration logic is as simple as reflecting the
23 * arbitration bit into ICR:AIP and never setting ICR:LA, no timing
26 * Note: We also don't wait for a bus free phase, so we assume SW will
27 * note try to arbitrate while BSY is still asserted by the target, if
28 * that was to happen, I could use a latch to delay arbitration to
29 * finding that BSY is false and checking SEL.
33 * We don't do anything special, just report the state of the line. We
34 * might end up needing to latch it to give a chance for the uC to pick
35 * it up if it's asserted for tfoo short (for ex. the uC is in the middle
36 * of a data transfer).
40 * Not implemented... might need to add, ROM doesn't ues it but MacOS
45 * Nothing implemented, BSR:IRQ never set, ROM doesn't use it, but
46 * MacOS might ... Select Enable Register is not implemented
50 * In dumb mode, it's all manual assertion of the various lines on
51 * both side. However, there's a problem with the Mac ROM when doing
54 * When doing a read, the ROM does not wait for REQ to go down after the
55 * last byte has been read. If the PIC is slow enough to react, that menans
56 * that the subsequent call to SCSIComplete, will incorrectly match that REQ
57 * for the one of the status phase, and get a phase mismatch. This can happen
58 * with my SPI protocol which is somewhat sub optimal for alternating reads
61 * So the PIC has to be fast enough at lowering REQ when ACK gets set ...
62 * or always use automatic mode:
64 * Automatic mode: when in that mode, REQ/ACK is handled in HW and the
65 * separate _scsi_dreq line is used to pace the PIC as follow:
67 * - On reads (target -> initiator)
69 * * Signal din_full set set when PIC writes to IDATA,
70 * causes REQ to be asserted
71 * * ACK (either manual or auto-generated by DMA mode)
72 * clears din_full (and thus de-asserts REQ)
73 * * _scsi_dreq is asserted based on a flip flop that
74 * gets set when data is read by host (DACK) and set
75 * when REQ is asserted (IDATA is written). This only
76 * happens while automatic mode is enabled.
78 * - On writes (initiator -> target)
83 `define RREG_CDR 3'h0 /* Current SCSI data */
84 `define RREG_ICR 3'h1 /* Initiator Command */
85 `define RREG_MR 3'h2 /* Mode register */
86 `define RREG_TCR 3'h3 /* Target Command */
87 `define RREG_CSR 3'h4 /* SCSI bus status */
88 `define RREG_BSR 3'h5 /* Bus and status */
89 `define RREG_IDR 3'h6 /* Input data */
90 `define RREG_RST 3'h7 /* Reset */
93 `define WREG_ODR 3'h0 /* Ouptut data */
94 `define WREG_ICR 3'h1 /* Initiator Command */
95 `define WREG_MR 3'h2 /* Mode register */
96 `define WREG_TCR 3'h3 /* Target Command */
97 `define WREG_SER 3'h4 /* Select Enable */
98 `define WREG_DMAS 3'h5 /* Start DMA Send */
99 `define WREG_DMATR 3'h6 /* Start DMA Target receive */
100 `define WREG_IDMAR 3'h7 /* Start DMA Initiator receive */
102 /* Backbus interface */
103 `define BB_REG_LINES 0 /* Read only, line states set by initiator */
104 `define BB_LINES_BSY 7
105 `define BB_LINES_SEL 6
106 `define BB_LINES_ACK 5
107 `define BB_LINES_ATN 4
108 `define BB_LINES_RST 3
110 `define BB_REG_ASSERT 1 /* RW, assert lines by target */
111 `define BB_ASSERT_BSY 7
112 `define BB_ASSERT_SEL 6
113 `define BB_ASSERT_CD 5
114 `define BB_ASSERT_IO 4
115 `define BB_ASSERT_MSG 3
116 `define BB_ASSERT_REQ 2
117 `define BB_ASSERT_RST 1
118 `define BB_ASSERT_AUTO 0 /* Automatic mode */
120 `define BB_REG_ODATA 2
121 `define BB_REG_IDATA 3
122 `define BB_REG_ACNT_HI 4
123 `define BB_REG_ACNT_LO 5
126 `define MR_DMA_MODE 1
129 /* ICR bit numbers */
131 `define ICR_TEST_MODE 6
132 `define ICR_DIFF_ENBL 5
139 /* TCR bit numbers */
145 module ncr5380(input sysclk,
148 /* Bus interface. 3-bit address, to be wired
149 * appropriately upstream (to A4..A6) plus one
150 * more bit (A9) wired as dack.
161 /* Backbus interface */
163 input [7:0] bb_wdata,
164 output [7:0] bb_rdata,
168 /* External request line */
172 /* Bus interface signals */
182 /* Initiator Command Register */
188 /* Target Command Register */
191 /* Backbus asserts */
194 /* These are the simulated SCSI bus lines, we use positive
195 * polarity to simplify things
207 /* What backbus sees of the above */
218 /* SCSI bus status register */
221 /* Bus and Status register */
230 /* Current data register and logic */
234 /* Data in and out latches and associated
235 * control logic for DMA
242 /* BB automatic mode */
247 reg [7:0] dout_latch;
249 /* --- Main host-side interface --- */
251 /* Register & DMA accesses decodes */
252 assign dma_rd = bus_cs & bus_phase & dack & ~bus_we;
253 assign dma_wr = bus_cs & bus_phase & dack & bus_we;
254 assign reg_rd = bus_cs & bus_phase & ~dack & ~bus_we;
255 assign reg_wr = bus_cs & bus_phase & ~dack & bus_we;
257 /* Hold bus to phase 0 on DMA accesses if necessary, this
258 * makes "blind" transfers 100% reliable since I really don't
259 * know if my SPI interface is fast enough
261 assign bus_hold = dack & (scsi_ack | ~scsi_req) & dma_en;
262 assign bus_ack = bus_cs & ~bus_hold;
266 * Q. to HW dudes... I don't need to test reg_rd everywhere, I can
267 * just let the mux toggle all the time, but would that consume
268 * more power or it's so ridiculous we don't care ?
270 assign rdata = dma_rd ? cur_data :
271 reg_rd && bus_rs == `RREG_CDR ? cur_data :
272 reg_rd && bus_rs == `RREG_ICR ? icr_read :
273 reg_rd && bus_rs == `RREG_MR ? mr :
274 reg_rd && bus_rs == `RREG_TCR ? { 4'h0 | tcr } :
275 reg_rd && bus_rs == `RREG_CSR ? csr :
276 reg_rd && bus_rs == `RREG_BSR ? bsr :
277 reg_rd && bus_rs == `RREG_IDR ? cur_data :
278 reg_rd && bus_rs == `RREG_RST ? 8'hff :
281 /* DMA handhsaking logic. Two phase logic, in phase 0
282 * DRQ follows SCSI _REQ until we see DACK. In phase 1
283 * we just wait for SCSI _REQ to go down and go back to
284 * phase 0. We assert SCSI _ACK in phase 1.
286 always@(posedge sysclk or posedge reset) begin
292 end else if (dphase == 0) begin
293 /* Be careful to do that in bus phase 1,
294 * not phase 0, or we would incorrectly
295 * assert bus_hold and lock up the system
297 if ((dma_rd || dma_wr) && scsi_req) begin
300 end else if (!scsi_req) begin
306 /* Data out latch (in DMA mode, this is one cycle after we've
309 always@(posedge sysclk or posedge reset) begin
312 else if ((reg_wr && bus_rs == `WREG_ODR) || dma_wr)
316 /* Current data register. Simplified logic: We loop back the
317 * output data if we are asserting the bus, else we get the
320 assign cur_data = out_en ? dout : din;
322 /* Logic for "asserting the bus" simplified */
323 assign out_en = icr[`ICR_A_DATA] | mr[`MR_ARB];
326 assign icr_read = { icr[`ICR_A_RST],
335 always@(posedge sysclk or posedge reset) begin
338 end else if (reg_wr && (bus_rs == `WREG_ICR)) begin
344 always@(posedge sysclk or posedge reset) begin
347 else if (reg_wr && (bus_rs == `WREG_MR))
352 always@(posedge sysclk or posedge reset) begin
355 else if (reg_wr && (bus_rs == `WREG_TCR))
359 /* DMA start send & receive registers. We currently ignore
362 always@(posedge sysclk or posedge reset) begin
366 if (!mr[`MR_DMA_MODE]) begin
368 end else if (reg_wr && (bus_rs == `WREG_DMAS)) begin
370 end else if (reg_wr && (bus_rs == `WREG_IDMAR)) begin
376 /* CSR (read only). We don't do parity */
377 assign csr = { scsi_rst, scsi_bsy, scsi_req, scsi_msg,
378 scsi_cd, scsi_io, scsi_sel, 1'b0 };
380 /* BSR (read only). We don't do a few things... */
381 assign bsr_eodma = 0; /* We don't do EOP */
382 assign bsr_dmarq = scsi_req & ~dphase & dma_en;
383 assign bsr_perr = 0; /* We don't do parity */
384 assign bsr_irq = 0; /* XXX ? Does MacOS use this ? */
385 assign bsr_pmatch = tcr[`TCR_A_MSG] == scsi_msg &&
386 tcr[`TCR_A_CD ] == scsi_cd &&
387 tcr[`TCR_A_IO ] == scsi_io;
388 assign bsr_berr = 0; /* XXX ? Does MacOS use this ? */
389 assign bsr = { bsr_eodma, bsr_dmarq, bsr_perr, bsr_irq,
390 bsr_pmatch, bsr_berr, scsi_atn, scsi_ack };
392 /* --- Simulated SCSI Signals --- */
394 /* BSY logic (simplified arbitration, see notes) */
395 assign scsi_bsy = icr[`ICR_A_BSY] |
396 bb_assert[`BB_ASSERT_BSY] |
398 /* Remains of simplified arbitration logic */
399 assign icr_aip = mr[`MR_ARB];
402 /* Other ORed SCSI signals */
403 assign scsi_sel = icr[`ICR_A_SEL] | bb_assert[`BB_ASSERT_SEL];
404 assign scsi_rst = icr[`ICR_A_RST] | bb_assert[`BB_ASSERT_RST];
405 assign scsi_ack = icr[`ICR_A_ACK] | dphase;
406 assign scsi_atn = icr[`ICR_A_ATN];
408 /* Other trivial lines set by target */
409 assign scsi_cd = bb_assert[`BB_ASSERT_CD];
410 assign scsi_io = bb_assert[`BB_ASSERT_IO];
411 assign scsi_msg = bb_assert[`BB_ASSERT_MSG];
412 assign scsi_req = bb_assert[`BB_ASSERT_REQ] | autoreq;
414 /* --- Backbus interface --- */
416 assign bb_reg_rd = bb_strobe & ~bb_wr;
417 assign bb_reg_wr = bb_strobe & bb_wr;
418 assign bb_reg_lines = bb_addr[3:0] == `BB_REG_LINES;
419 assign bb_reg_assert = bb_addr[3:0] == `BB_REG_ASSERT;
420 assign bb_reg_odata = bb_addr[3:0] == `BB_REG_ODATA;
421 assign bb_reg_idata = bb_addr[3:0] == `BB_REG_IDATA;
422 assign bb_reg_acnt_hi = bb_addr[3:0] == `BB_REG_ACNT_HI;
423 assign bb_reg_acnt_lo = bb_addr[3:0] == `BB_REG_ACNT_LO;
425 /* Backbus lines, ie, pseudo SCSI bus state seen by the
426 * microcontroller. Note that they are positive logic unlike
427 * the real SCSI lines. We only care about the lines that are
428 * not asserted exclusively by the target
430 assign bb_lines = { scsi_bsy, scsi_sel, scsi_ack, scsi_atn,
433 /* Backbus register reads */
434 assign bb_rdata = bb_reg_lines ? bb_lines :
435 bb_reg_assert ? bb_assert :
436 bb_reg_odata ? (bb_assert[`BB_ASSERT_AUTO] ? dout_latch : dout) :
440 /* External handshake logic. We assert it for now when SEL is
441 * asserted in ICR. Or in auto mode, when both req and ack are
444 assign scsi_hshake = icr[`ICR_A_SEL] | icr[`ICR_A_RST] |
445 (bb_assert[`BB_ASSERT_AUTO] & ~(scsi_ack | scsi_req));
448 always@(posedge sysclk or posedge reset) begin
451 else if (bb_reg_wr && bb_reg_idata)
455 /* BB assert register write */
456 always@(posedge sysclk or posedge reset) begin
459 else if (bb_reg_wr && bb_reg_assert)
460 bb_assert <= bb_wdata;
463 /* --- Backbus "automatic" mode logic crackpot --- */
465 /* autocnt register write & decrement */
466 always@(posedge sysclk or posedge reset) begin
469 else if (bb_reg_wr && bb_reg_acnt_hi)
470 autocnt[15:8] <= bb_wdata;
471 else if (bb_reg_wr && bb_reg_acnt_lo)
472 autocnt[7:0] <= bb_wdata;
474 autocnt <= autocnt - 1;
477 /* Hack to workaround SPI interface giving us two strobes
478 * on the first byte of reads. We use this latch to drop
481 always@(posedge sysclk or posedge reset) begin
485 if (bb_reg_wr && bb_reg_acnt_lo)
492 /* An automatic register access happens when auto mode is
493 * enabled, autocnt is non-0 and we access the idata or
496 assign autoreg = bb_assert[`BB_ASSERT_AUTO] & bb_strobe &
497 (bb_reg_idata | (bb_reg_odata & ~autodrop)) &
500 /* Automatic mode, toggle REQ automagically during
501 * data phases if there are still bytes to go
503 always@(posedge sysclk or posedge reset) begin
507 if (!bb_assert[`BB_ASSERT_AUTO])
516 /* In auto mode writes, we are slightly off as REQ is
517 * asserted by a read done by the PIC so we need to
518 * latch the data when ack is asserted so it's still
519 * valid by the time the PIC reads it. To simplify
520 * things we always latch on ACK
522 always@(posedge sysclk or posedge reset) begin