]> git.ozlabs.org Git - minimigmac.git/blob - fpga/ncr5380.v
Initial commit
[minimigmac.git] / fpga / ncr5380.v
1 `timescale 1ns / 100ps
2
3 /*
4  * NCR5380 SCSI module for minimigmac.
5  * 
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.
8  * 
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
13  * 
14  * This is implementation is really just a gateway to the backbus, the
15  * microcontroller can observe SCSI line states and exchange data.
16  * 
17  * Notes:
18  * 
19  * - Arbitration -
20  * 
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
24  * to care much about.
25  * 
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.
30  * 
31  * - Bus reset -
32  * 
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).
37  * 
38  * - Busy monitoring -
39  * 
40  * Not implemented... might need to add, ROM doesn't ues it but MacOS
41  * might
42  *
43  * - Interrupts -
44  * 
45  * Nothing implemented, BSR:IRQ never set, ROM doesn't use it, but
46  * MacOS might ...  Select Enable Register is not implemented
47  * 
48  * - Data transfers
49  * 
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
52  * that.
53  * 
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
59  * and writes
60  * 
61  * So the PIC has to be fast enough at lowering REQ when ACK gets set ...
62  * or always use automatic mode:
63  * 
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:
66  * 
67  *  - On reads (target -> initiator)
68  * 
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.
77  * 
78  * - On writes (initiator -> target)
79  *      * 
80  *
81
82 /* Read registers */
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 */
91
92 /* Write registers */
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 */
101
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
109
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 */
119
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
124
125 /* MR bit numbers */
126 `define MR_DMA_MODE     1
127 `define MR_ARB          0
128
129 /* ICR bit numbers */
130 `define ICR_A_RST       7
131 `define ICR_TEST_MODE   6
132 `define ICR_DIFF_ENBL   5
133 `define ICR_A_ACK       4
134 `define ICR_A_BSY       3
135 `define ICR_A_SEL       2
136 `define ICR_A_ATN       1
137 `define ICR_A_DATA      0
138
139 /* TCR bit numbers */
140 `define TCR_A_REQ       3
141 `define TCR_A_MSG       2
142 `define TCR_A_CD        1
143 `define TCR_A_IO        0
144
145 module ncr5380(input    sysclk,
146                input    reset,
147
148                /* Bus interface. 3-bit address, to be wired
149                 * appropriately upstream (to A4..A6) plus one
150                 * more bit (A9) wired as dack.
151                 */
152                input            bus_cs,
153                input            bus_we,
154                output           bus_ack,
155                input            bus_phase,
156                input [2:0]      bus_rs,
157                input            dack,
158                input [7:0]      wdata,
159                output [7:0]     rdata,
160
161                /* Backbus interface */
162                input [5:0]      bb_addr,
163                input [7:0]      bb_wdata,
164                output [7:0]     bb_rdata,
165                input            bb_strobe,
166                input            bb_wr,
167
168                /* External request line */
169                output           scsi_hshake
170            );
171
172         /* Bus interface signals */
173         wire                    reg_rd;
174         wire                    reg_wr;
175         wire                    dma_rd;
176         wire                    dma_wr;
177         wire                    bus_hold;       
178
179         /* Mode Register */
180         reg [7:0]               mr;
181
182         /* Initiator Command Register */        
183         wire                    icr_aip;
184         wire                    icr_la;
185         wire [7:0]              icr_read;
186         reg [7:0]               icr;
187
188         /* Target Command Register */
189         reg [3:0]               tcr;
190
191         /* Backbus asserts */
192         reg [7:0]               bb_assert;
193
194         /* These are the simulated SCSI bus lines, we use positive
195          * polarity to simplify things
196          */
197         wire                    scsi_bsy;
198         wire                    scsi_sel;
199         wire                    scsi_ack;
200         wire                    scsi_atn;
201         wire                    scsi_cd;
202         wire                    scsi_io;
203         wire                    scsi_msg;
204         wire                    scsi_req;
205         wire                    scsi_rst;
206
207         /* What backbus sees of the above */
208         wire [7:0]              bb_lines;
209         wire                    bb_reg_rd;
210         wire                    bb_reg_wr;
211         wire                    bb_reg_lines;
212         wire                    bb_reg_assert;
213         wire                    bb_reg_odata;
214         wire                    bb_reg_idata;
215         wire                    bb_reg_acnt_hi;
216         wire                    bb_reg_acnt_lo;
217
218         /* SCSI bus status register */
219         wire [7:0]              csr;
220
221         /* Bus and Status register */
222         wire                    bsr_eodma;
223         wire                    bsr_dmarq;
224         wire                    bsr_perr;
225         wire                    bsr_irq;
226         wire                    bsr_pmatch;
227         wire                    bsr_berr;                       
228         wire [7:0]              bsr;
229
230         /* Current data register and logic */
231         wire [7:0]              cur_data;
232         wire                    out_en;
233
234         /* Data in and out latches and associated
235          * control logic for DMA
236          */
237         reg [7:0]               din;
238         reg [7:0]               dout;
239         reg                     dphase;
240         reg                     dma_en; 
241
242         /* BB automatic mode */
243         reg                     autoreq;
244         reg [15:0]              autocnt;
245         wire                    autoreg;
246         reg                     autodrop;                       
247         reg [7:0]               dout_latch;
248
249         /* --- Main host-side interface --- */
250
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;
256
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
260          */
261         assign bus_hold = dack & (scsi_ack | ~scsi_req) & dma_en;
262         assign bus_ack = bus_cs & ~bus_hold;
263
264         /* System bus reads
265          *
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 ?
269          */
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            :
279                        8'hff;
280         
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.
285          */
286         always@(posedge sysclk or posedge reset) begin
287                 if (reset) begin
288                         dphase <= 0;                    
289                 end else begin
290                         if (!dma_en) begin
291                                 dphase <= 0;                            
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
296                                  */
297                                 if ((dma_rd || dma_wr) && scsi_req) begin
298                                         dphase <= 1;
299                                 end
300                         end else if (!scsi_req) begin
301                                 dphase <= 0;
302                         end
303                 end
304         end
305
306         /* Data out latch (in DMA mode, this is one cycle after we've
307          * asserted ACK)
308          */
309         always@(posedge sysclk or posedge reset) begin
310                 if (reset)
311                   dout <= 8'haa;
312                 else if ((reg_wr && bus_rs == `WREG_ODR) || dma_wr)
313                   dout <= wdata;
314         end
315         
316         /* Current data register. Simplified logic: We loop back the
317          * output data if we are asserting the bus, else we get the
318          * input latch
319          */
320         assign cur_data = out_en ? dout : din;
321
322         /* Logic for "asserting the bus" simplified */
323         assign out_en = icr[`ICR_A_DATA] | mr[`MR_ARB]; 
324         
325         /* ICR read wires */
326         assign icr_read = { icr[`ICR_A_RST],
327                             icr_aip,
328                             icr_la,
329                             icr[`ICR_A_ACK],
330                             icr[`ICR_A_BSY],
331                             icr[`ICR_A_SEL],
332                             icr[`ICR_A_ATN],
333                             icr[`ICR_A_DATA] };
334         /* ICR write */
335         always@(posedge sysclk or posedge reset) begin
336                 if (reset) begin
337                         icr <= 0;
338                 end else if (reg_wr && (bus_rs == `WREG_ICR)) begin
339                         icr <= wdata;
340                 end
341         end
342
343         /* MR write */
344         always@(posedge sysclk or posedge reset) begin
345                 if (reset)
346                   mr <= 8'b0;           
347                 else if (reg_wr && (bus_rs == `WREG_MR))
348                   mr <= wdata;
349         end
350
351         /* TCR write */
352         always@(posedge sysclk or posedge reset) begin
353                 if (reset)
354                   tcr <= 4'b0;          
355                 else if (reg_wr && (bus_rs == `WREG_TCR))
356                   tcr <= wdata[3:0];
357         end
358
359         /* DMA start send & receive registers. We currently ignore
360          * the direction.
361          */
362         always@(posedge sysclk or posedge reset) begin
363                 if (reset) begin
364                         dma_en <= 0;
365                 end else begin
366                         if (!mr[`MR_DMA_MODE]) begin
367                                 dma_en <= 0;
368                         end else if (reg_wr && (bus_rs == `WREG_DMAS)) begin
369                                 dma_en <= 1;
370                         end else if (reg_wr && (bus_rs == `WREG_IDMAR)) begin
371                                 dma_en <= 1;
372                         end
373                 end
374         end
375
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 };      
379
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 };
391
392         /* --- Simulated SCSI Signals --- */
393
394         /* BSY logic (simplified arbitration, see notes) */
395         assign scsi_bsy = icr[`ICR_A_BSY] |
396                           bb_assert[`BB_ASSERT_BSY] |
397                           mr[`MR_ARB];
398         /* Remains of simplified arbitration logic */
399         assign icr_aip = mr[`MR_ARB];
400         assign icr_la = 0;
401
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];
407
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;
413
414         /* --- Backbus interface --- */
415
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;
424
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
429          */     
430         assign bb_lines = { scsi_bsy, scsi_sel, scsi_ack, scsi_atn,
431                             scsi_rst, 3'b0 };
432
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) :
437                           bb_reg_idata  ? din           :
438                           0;
439
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
442          * low
443          */
444         assign scsi_hshake = icr[`ICR_A_SEL] | icr[`ICR_A_RST] |
445                              (bb_assert[`BB_ASSERT_AUTO] & ~(scsi_ack | scsi_req));     
446
447         /* Data in latch */
448         always@(posedge sysclk or posedge reset) begin
449                 if (reset)
450                   din <= 8'h55;
451                 else if (bb_reg_wr && bb_reg_idata)
452                   din <= bb_wdata;
453         end
454        
455         /* BB assert register write */
456         always@(posedge sysclk or posedge reset) begin
457                 if (reset)
458                   bb_assert <= 0;
459                 else if (bb_reg_wr && bb_reg_assert)
460                   bb_assert <= bb_wdata;
461         end
462
463         /* --- Backbus "automatic" mode logic crackpot --- */
464
465         /* autocnt register write & decrement */
466         always@(posedge sysclk or posedge reset) begin
467                 if (reset)
468                   autocnt <= 0;
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;
473                 else if (autoreg)
474                   autocnt <= autocnt - 1;               
475         end
476
477         /* Hack to workaround SPI interface giving us two strobes
478          * on the first byte of reads. We use this latch to drop
479          * the first one.
480          */
481         always@(posedge sysclk or posedge reset) begin
482                 if (reset)
483                   autodrop <= 0;
484                 else begin
485                         if (bb_reg_wr && bb_reg_acnt_lo)
486                           autodrop <= 1;
487                         else if (bb_strobe)
488                           autodrop <= 0;                        
489                 end
490         end
491         
492         /* An automatic register access happens when auto mode is
493          * enabled, autocnt is non-0 and we access the idata or
494          * odata register
495          */
496         assign autoreg = bb_assert[`BB_ASSERT_AUTO] & bb_strobe &
497                          (bb_reg_idata | (bb_reg_odata & ~autodrop)) &
498                          (autocnt != 0);
499
500         /* Automatic mode, toggle REQ automagically during
501          * data phases if there are still bytes to go
502          */
503         always@(posedge sysclk or posedge reset) begin
504                 if (reset)
505                   autoreq <= 0;
506                 else begin
507                         if (!bb_assert[`BB_ASSERT_AUTO])
508                           autoreq <= 0;                 
509                         else if (autoreg)
510                           autoreq <= 1;
511                         else if (scsi_ack)
512                           autoreq <= 0;
513                 end
514         end
515
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
521          */
522         always@(posedge sysclk or posedge reset) begin
523                 if (reset)
524                   dout_latch <= 0;
525                 else begin
526                         if (scsi_ack)
527                           dout_latch <= dout;
528                 end
529         end     
530 endmodule