]> git.ozlabs.org Git - minimigmac.git/blob - fpga/scc.v
Initial commit
[minimigmac.git] / fpga / scc.v
1 `timescale 1ns / 100ps
2
3 /*
4  * Zilog 8530 SCC 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.
10  * 
11  * NOTE: We don't implement the 85C30 or ESCC additions such as WR7'
12  * for now, it's all very simplified
13  */
14
15 module scc(input        sysclk,
16            input        reset_hw,
17
18            /* Bus interface. 2-bit address, to be wired
19             * appropriately upstream (to A1..A2).
20             */
21            input        cs,
22            input        we,
23            input [1:0]  rs, /* [1] = data(1)/ctl [0] = a_side(1)/b_side */
24            input [7:0]  wdata,
25            output [7:0] rdata,
26            output       _irq,
27
28            /* A single serial port on Minimig */
29            input        rxd,
30            output       txd,
31            input        cts, /* normally wired to device DTR output
32                               * on Mac cables. That same line is also
33                               * connected to the TRxC input of the SCC
34                               * to do fast clocking but we don't do that
35                               * here
36                               */
37            output       rts, /* on a real mac this activates line
38                               * drivers when low */
39
40            /* DCD for both ports are hijacked by mouse interface */
41            input        dcd_a, /* We don't synchronize those inputs */
42            input        dcd_b,
43
44            /* Write request */
45            output       wreq
46            );
47
48         /* Register access is semi-insane */
49         reg [3:0]       rindex;
50         wire            wreg_a;
51         wire            wreg_b;
52         wire            wdata_a;
53         wire            wdata_b;
54         wire            rdata_a;
55         wire            rdata_b;
56
57         /* Resets via WR9, one clk pulses */
58         wire            reset_a;
59         wire            reset_b;
60         wire            reset;
61
62         /* Data registers */
63         reg [7:0]       data_a;
64         reg [7:0]       data_b;
65
66         /* Read registers */
67         wire [7:0]      rr0_a;
68         wire [7:0]      rr0_b;
69         wire [7:0]      rr1_a;
70         wire [7:0]      rr1_b;
71         wire [7:0]      rr2_b;
72         wire [7:0]      rr3_a;
73         wire [7:0]      rr10_a;
74         wire [7:0]      rr10_b;
75         wire [7:0]      rr15_a;
76         wire [7:0]      rr15_b;
77
78         /* Write registers. Only some are implemented,
79          * some result in actions on write and don't
80          * store anything
81          */
82         reg [7:0]       wr1_a;
83         reg [7:0]       wr1_b;
84         reg [7:0]       wr2;
85         reg [7:0]       wr3_a;
86         reg [7:0]       wr3_b;
87         reg [7:0]       wr4_a;
88         reg [7:0]       wr4_b;
89         reg [7:0]       wr5_a;
90         reg [7:0]       wr5_b;
91         reg [7:0]       wr6_a;
92         reg [7:0]       wr6_b;
93         reg [7:0]       wr7_a;
94         reg [7:0]       wr7_b;
95         reg [7:0]       wr8_a;
96         reg [7:0]       wr8_b;
97         reg [5:0]       wr9;
98         reg [7:0]       wr10_a;
99         reg [7:0]       wr10_b;
100         reg [7:0]       wr11_a;
101         reg [7:0]       wr11_b;
102         reg [7:0]       wr12_a;
103         reg [7:0]       wr12_b;
104         reg [7:0]       wr13_a;
105         reg [7:0]       wr13_b;
106         reg [7:0]       wr14_a;
107         reg [7:0]       wr14_b;
108         reg [7:0]       wr15_a;
109         reg [7:0]       wr15_b;
110
111         /* Status latches */
112         reg             latch_open_a;
113         reg             latch_open_b;
114         reg             dcd_latch_a;
115         reg             dcd_latch_b;
116         wire            dcd_ip_a;
117         wire            dcd_ip_b;
118         wire            do_latch_a;
119         wire            do_latch_b;
120         wire            do_extreset_a;
121         wire            do_extreset_b;  
122
123         /* IRQ stuff */
124         wire            rx_irq_pend_a;
125         wire            rx_irq_pend_b;
126         wire            tx_irq_pend_a;
127         wire            tx_irq_pend_b;
128         wire            ex_irq_pend_a;
129         wire            ex_irq_pend_b;
130         reg             ex_irq_ip_a;
131         reg             ex_irq_ip_b;
132         wire [2:0]      rr2_vec_stat;   
133                 
134         /* Register/Data access helpers */
135         assign wreg_a  = cs & we & (~rs[1]) &  rs[0];
136         assign wreg_b  = cs & we & (~rs[1]) & ~rs[0];
137         assign wdata_a = cs & we & (rs[1] | (rindex == 8)) &  rs[0];
138         assign wdata_b = cs & we & (rs[1] | (rindex == 8)) & ~rs[0];
139         assign rdata_a = cs & (~we) & (rs[1] | (rindex == 8)) &  rs[0];
140         assign rdata_b = cs & (~we) & (rs[1] | (rindex == 8)) & ~rs[0];
141
142         /* Register index is set by a write to WR0 and reset
143          * after any subsequent write. We ignore the side
144          */
145         always@(posedge sysclk or posedge reset) begin
146                 if (reset)
147                   rindex <= 0;
148                 else if (cs && !rs[1]) begin
149                         /* Default, reset index */
150                         rindex <= 0;
151
152                         /* Write to WR0 */
153                         if (we && rindex == 0) begin
154                                 /* Get low index bits */
155                                 rindex[2:0] <= wdata[2:0];
156                                   
157                                 /* Add point high */
158                                 rindex[3] <= (wdata[5:3] == 3'b001);
159                         end
160                 end
161         end
162
163         /* Reset logic (write to WR9 cmd)
164          *
165          * Note about resets: Some bits are documented as unchanged/undefined on
166          * HW reset by the doc. We apply this to channel and soft resets, however
167          * we _do_ reset every bit on an external HW reset in this implementation
168          * to make the FPGA & synthesis tools happy.
169          */
170         assign reset   = ((wreg_a | wreg_b) & (rindex == 9) & (wdata[7:6] == 2'b11)) | reset_hw;
171         assign reset_a = ((wreg_a | wreg_b) & (rindex == 9) & (wdata[7:6] == 2'b10)) | reset;   
172         assign reset_b = ((wreg_a | wreg_b) & (rindex == 9) & (wdata[7:6] == 2'b01)) | reset;
173
174         /* WR1
175          * Reset: bit 5 and 2 unchanged */
176         always@(posedge sysclk or posedge reset_hw) begin
177                 if (reset_hw)
178                   wr1_a <= 0;
179                 else begin
180                         if (reset_a)
181                           wr1_a <= { 2'b00, wr1_a[5], 2'b00, wr1_a[2], 2'b00 };
182                         else if (wreg_a && rindex == 1)
183                           wr1_a <= wdata;
184                 end
185         end
186         always@(posedge sysclk or posedge reset_hw) begin
187                 if (reset_hw)
188                   wr1_b <= 0;
189                 else begin
190                         if (reset_b)
191                           wr1_b <= { 2'b00, wr1_b[5], 2'b00, wr1_b[2], 2'b00 };
192                         else if (wreg_b && rindex == 1)
193                           wr1_b <= wdata;
194                 end
195         end
196
197         /* WR2
198          * Reset: unchanged 
199          */
200         always@(posedge sysclk or posedge reset_hw) begin
201                 if (reset_hw)
202                   wr2 <= 0;
203                 else if ((wreg_a || wreg_b) && rindex == 2)
204                   wr2 <= wdata;                 
205         end
206
207         /* WR3
208          * Reset: bit 0 to 0, otherwise unchanged.
209          */
210         always@(posedge sysclk or posedge reset_hw) begin
211                 if (reset_hw)
212                   wr3_a <= 0;
213                 else begin
214                         if (reset_a)
215                           wr3_a[0] <= 0;
216                         else if (wreg_a && rindex == 3)
217                           wr3_a <= wdata;
218                 end
219         end
220         always@(posedge sysclk or posedge reset_hw) begin
221                 if (reset_hw)
222                   wr3_b <= 0;
223                 else begin
224                         if (reset_b)
225                           wr3_b[0] <= 0;
226                         else if (wreg_b && rindex == 3)
227                           wr3_b <= wdata;
228                 end
229         end
230
231         /* WR4
232          * Reset: Bit 2 to 1, otherwise unchanged
233          */
234         always@(posedge sysclk or posedge reset_hw) begin
235                 if (reset_hw)
236                   wr4_a <= 0;
237                 else begin
238                         if (reset_a)
239                           wr4_a[2] <= 1;
240                         else if (wreg_a && rindex == 4)
241                           wr4_a <= wdata;
242                 end
243         end
244         always@(posedge sysclk or posedge reset_hw) begin
245                 if (reset_hw)
246                   wr4_b <= 0;
247                 else begin
248                         if (reset_b)
249                           wr4_b[2] <= 1;
250                         else if (wreg_b && rindex == 4)
251                           wr4_b <= wdata;
252                 end
253         end
254
255         /* WR5
256          * Reset: Bits 7,4,3,2,1 to 0
257          */
258         always@(posedge sysclk or posedge reset_hw) begin
259                 if (reset_hw)
260                   wr5_a <= 0;
261                 else begin
262                         if (reset_a)
263                           wr5_a <= { 1'b0, wr5_a[6:5], 4'b0000, wr5_a[0] };                     
264                         else if (wreg_a && rindex == 5)
265                           wr5_a <= wdata;
266                 end
267         end
268         always@(posedge sysclk or posedge reset_hw) begin
269                 if (reset_hw)
270                   wr5_b <= 0;
271                 else begin
272                         if (reset_b)
273                           wr5_b <= { 1'b0, wr5_b[6:5], 4'b0000, wr5_b[0] };                     
274                         else if (wreg_b && rindex == 5)
275                           wr5_b <= wdata;
276                 end
277         end
278
279         /* WR6
280          * Reset: Unchanged.
281          */
282         always@(posedge sysclk or posedge reset_hw) begin
283                 if (reset_hw)
284                   wr6_a <= 0;
285                 else if (wreg_a && rindex == 6)
286                   wr6_a <= wdata;
287         end
288         always@(posedge sysclk or posedge reset_hw) begin
289                 if (reset_hw)
290                   wr6_b <= 0;
291                 else if (wreg_b && rindex == 6)
292                   wr6_b <= wdata;
293         end
294
295         /* WR7
296          * Reset: Unchanged.
297          */
298         always@(posedge sysclk or posedge reset_hw) begin
299                 if (reset_hw)
300                   wr7_a <= 0;
301                 else if (wreg_a && rindex == 7)
302                   wr7_a <= wdata;
303         end
304         always@(posedge sysclk or posedge reset_hw) begin
305                 if (reset_hw)
306                   wr7_b <= 0;
307                 else if (wreg_b && rindex == 7)
308                   wr7_b <= wdata;
309         end
310         
311         /* WR9. Special: top bits are reset, handled separately, bottom
312          * bits are only reset by a hw reset
313          */
314         always@(posedge sysclk or posedge reset_hw) begin
315                 if (reset_hw)
316                   wr9 <= 0;
317                 else if ((wreg_a || wreg_b) && rindex == 9)
318                   wr9 <= wdata[5:0];                    
319         end
320
321         /* WR10
322          * Reset: all 0, except chanel reset retains 6 and 5
323          */
324         always@(posedge sysclk or posedge reset) begin
325                 if (reset)
326                   wr10_a <= 0;
327                 else begin
328                         if (reset_a)
329                           wr10_a <= { 1'b0, wr10_a[6:5], 5'b00000 };
330                         else if (wreg_a && rindex == 10)
331                           wr10_a <= wdata;
332                 end             
333         end
334         always@(posedge sysclk or posedge reset) begin
335                 if (reset)
336                   wr10_b <= 0;
337                 else begin
338                         if (reset_b)
339                           wr10_b <= { 1'b0, wr10_b[6:5], 5'b00000 };
340                         else if (wreg_b && rindex == 10)
341                           wr10_b <= wdata;
342                 end             
343         end
344
345         /* WR11
346          * Reset: On full reset only, not channel reset
347          */
348         always@(posedge sysclk or posedge reset) begin
349                 if (reset)
350                   wr11_a <= 8'b00001000;
351                 else if (wreg_a && rindex == 11)
352                   wr11_a <= wdata;
353         end
354         always@(posedge sysclk or posedge reset) begin
355                 if (reset)
356                   wr11_b <= 8'b00001000;
357                 else if (wreg_b && rindex == 11)
358                   wr11_b <= wdata;
359         end
360
361         /* WR12
362          * Reset: Unchanged
363          */
364         always@(posedge sysclk or posedge reset_hw) begin
365                 if (reset_hw)
366                   wr12_a <= 0;
367                 else if (wreg_a && rindex == 12)
368                   wr12_a <= wdata;
369         end
370         always@(posedge sysclk or posedge reset_hw) begin
371                 if (reset_hw)
372                   wr12_b <= 0;          
373                 else if (wreg_b && rindex == 12)
374                   wr12_b <= wdata;
375         end
376
377         /* WR13
378          * Reset: Unchanged
379          */
380         always@(posedge sysclk or posedge reset_hw) begin
381                 if (reset_hw)
382                   wr13_a <= 0;
383                 else if (wreg_a && rindex == 13)
384                   wr13_a <= wdata;
385         end
386         always@(posedge sysclk or posedge reset_hw) begin
387                 if (reset_hw)
388                   wr13_b <= 0;          
389                 else if (wreg_b && rindex == 13)
390                   wr13_b <= wdata;
391         end
392
393         /* WR14
394          * Reset: Full reset maintains  top 2 bits,
395          * Chan reset also maitains bottom 2 bits, bit 4 also
396          * reset to a different value
397          */
398         always@(posedge sysclk or posedge reset_hw) begin
399                 if (reset_hw)
400                   wr14_a <= 0;
401                 else begin
402                         if (reset)
403                           wr14_a <= { wr14_a[7:6], 6'b110000 };
404                         else if (reset_a)
405                           wr14_a <= { wr14_a[7:6], 4'b1000, wr14_a[1:0] };
406                         else if (wreg_a && rindex == 14)
407                           wr14_a <= wdata;
408                 end             
409         end
410         always@(posedge sysclk or posedge reset_hw) begin
411                 if (reset_hw)
412                   wr14_b <= 0;
413                 else begin
414                         if (reset)
415                           wr14_b <= { wr14_b[7:6], 6'b110000 };
416                         else if (reset_b)
417                           wr14_b <= { wr14_b[7:6], 4'b1000, wr14_b[1:0] };
418                         else if (wreg_b && rindex == 14)
419                           wr14_b <= wdata;
420                 end             
421         end
422
423         /* WR15 */
424         always@(posedge sysclk or posedge reset) begin
425                 if (reset)
426                   wr15_a <= 8'b11111000;
427                 else if (wreg_a && rindex == 15)
428                   wr15_a <= wdata;                      
429         end
430         always@(posedge sysclk or posedge reset) begin
431                 if (reset)
432                   wr15_b <= 8'b11111000;
433                 else if (wreg_b && rindex == 15)
434                   wr15_b <= wdata;                      
435         end
436         
437         /* Read data mux */     
438         assign rdata = rs[1] && rs[0]       ? data_a :
439                        rs[1]                ? data_b :
440                        rindex ==  0 && rs[0] ? rr0_a :
441                        rindex ==  0          ? rr0_b :
442                        rindex ==  1 && rs[0] ? rr1_a :
443                        rindex ==  1          ? rr1_b :
444                        rindex ==  2 && rs[0] ? wr2 :
445                        rindex ==  2          ? rr2_b :
446                        rindex ==  3 && rs[0] ? rr3_a :
447                        rindex ==  3          ? 0 :
448                        rindex ==  4 && rs[0] ? rr0_a :
449                        rindex ==  4          ? rr0_b :
450                        rindex ==  5 && rs[0] ? rr1_a :
451                        rindex ==  5          ? rr1_b :
452                        rindex ==  6 && rs[0] ? wr2 :
453                        rindex ==  6          ? rr2_b :
454                        rindex ==  7 && rs[0] ? rr3_a :
455                        rindex ==  7          ? 0 :
456
457                        rindex ==  8 && rs[0] ? data_a :
458                        rindex ==  8          ? data_b :
459                        rindex ==  9 && rs[0] ? wr13_a :
460                        rindex ==  9          ? wr13_b :
461                        rindex == 10 && rs[0] ? rr10_a :
462                        rindex == 10          ? rr10_b :
463                        rindex == 11 && rs[0] ? rr15_a :
464                        rindex == 11          ? rr15_b :
465                        rindex == 12 && rs[0] ? wr12_a :
466                        rindex == 12          ? wr12_b :
467                        rindex == 13 && rs[0] ? wr13_a :
468                        rindex == 13          ? wr13_b :
469                        rindex == 14 && rs[0] ? rr10_a :
470                        rindex == 14          ? rr10_b :
471                        rindex == 15 && rs[0] ? rr15_a :
472                        rindex == 15          ? rr15_b : 8'hff;
473
474         /* RR0 */
475         assign rr0_a = { 1'b0, /* Break */
476                          1'b1, /* Tx Underrun/EOM */
477                          1'b0, /* CTS */
478                          1'b0, /* Sync/Hunt */
479                          wr15_a[3] ? dcd_latch_a : dcd_a, /* DCD */
480                          1'b1, /* Tx Empty */
481                          1'b0, /* Zero Count */
482                          1'b0  /* Rx Available */
483                          };
484         assign rr0_b = { 1'b0, /* Break */
485                          1'b1, /* Tx Underrun/EOM */
486                          1'b0, /* CTS */
487                          1'b0, /* Sync/Hunt */
488                          wr15_b[3] ? dcd_latch_b : dcd_b, /* DCD */
489                          1'b1, /* Tx Empty */
490                          1'b0, /* Zero Count */
491                          1'b0  /* Rx Available */
492                          };
493
494         /* RR1 */
495         assign rr1_a = { 1'b0, /* End of frame */
496                          1'b0, /* CRC/Framing error */
497                          1'b0, /* Rx Overrun error */
498                          1'b0, /* Parity error */
499                          1'b0, /* Residue code 0 */
500                          1'b1, /* Residue code 1 */
501                          1'b1, /* Residue code 2 */
502                          1'b1  /* All sent */
503                          };
504         
505         assign rr1_b = { 1'b0, /* End of frame */
506                          1'b0, /* CRC/Framing error */
507                          1'b0, /* Rx Overrun error */
508                          1'b0, /* Parity error */
509                          1'b0, /* Residue code 0 */
510                          1'b1, /* Residue code 1 */
511                          1'b1, /* Residue code 2 */
512                          1'b1  /* All sent */
513                          };
514         
515         /* RR2 (Chan B only, A is just WR2) */
516         assign rr2_b = { wr2[7],
517                          wr9[4] ? rr2_vec_stat[0] : wr2[6],
518                          wr9[4] ? rr2_vec_stat[1] : wr2[5],
519                          wr9[4] ? rr2_vec_stat[2] : wr2[4],
520                          wr9[4] ? wr2[3] : rr2_vec_stat[2],
521                          wr9[4] ? wr2[2] : rr2_vec_stat[1],
522                          wr9[4] ? wr2[1] : rr2_vec_stat[0],
523                          wr2[0]
524                          };
525         
526
527         /* RR3 (Chan A only) */
528         assign rr3_a = { 2'b0,
529                          rx_irq_pend_a, /* Rx interrupt pending */
530                          tx_irq_pend_a, /* Tx interrupt pending */
531                          ex_irq_pend_a, /* Status/Ext interrupt pending */
532                          rx_irq_pend_b,
533                          tx_irq_pend_b,
534                          ex_irq_pend_b
535                         };
536
537         /* RR10 */
538         assign rr10_a = { 1'b0, /* One clock missing */
539                           1'b0, /* Two clocks missing */
540                           1'b0,
541                           1'b0, /* Loop sending */
542                           1'b0,
543                           1'b0,
544                           1'b0, /* On Loop */
545                           1'b0
546                           };
547         assign rr10_b = { 1'b0, /* One clock missing */
548                           1'b0, /* Two clocks missing */
549                           1'b0,
550                           1'b0, /* Loop sending */
551                           1'b0,
552                           1'b0,
553                           1'b0, /* On Loop */
554                           1'b0
555                           };
556         
557         /* RR15 */
558         assign rr15_a = { wr15_a[7],
559                           wr15_a[6],
560                           wr15_a[5],
561                           wr15_a[4],
562                           wr15_a[3],
563                           1'b0,
564                           wr15_a[1],
565                           1'b0
566                           };
567
568         assign rr15_b = { wr15_b[7],
569                           wr15_b[6],
570                           wr15_b[5],
571                           wr15_b[4],
572                           wr15_b[3],
573                           1'b0,
574                           wr15_b[1],
575                           1'b0
576                           };
577         
578         /* Interrupts. Simplified for now
579          *
580          * Need to add latches. Tx irq is latched when buffer goes from full->empty,
581          * it's not a permanent state. For now keep it clear. Will have to fix that.
582          */
583         assign rx_irq_pend_a = 0;
584         assign tx_irq_pend_a = 0 /*& wr1_a[1]*/; /* Tx always empty for now */
585         assign ex_irq_pend_a = ex_irq_ip_a;
586         assign rx_irq_pend_b = 0;
587         assign tx_irq_pend_b = 0 /*& wr1_b[1]*/; /* Tx always empty for now */
588         assign ex_irq_pend_b = ex_irq_ip_b;
589
590         assign _irq = ~(wr9[3] & (rx_irq_pend_a |
591                                   rx_irq_pend_b |
592                                   tx_irq_pend_a |
593                                   tx_irq_pend_b |
594                                   ex_irq_pend_a |
595                                   ex_irq_pend_b));
596
597         /* XXX Verify that... also missing special receive condition */
598         assign rr2_vec_stat = rx_irq_pend_a ? 3'b110 :
599                               tx_irq_pend_a ? 3'b100 :
600                               ex_irq_pend_a ? 3'b101 :
601                               rx_irq_pend_b ? 3'b010 :
602                               tx_irq_pend_b ? 3'b000 :
603                               ex_irq_pend_b ? 3'b001 : 3'b011;
604         
605         /* External/Status interrupt & latch logic */
606         assign do_extreset_a = wreg_a & (rindex == 0) & (wdata[5:3] == 3'b010);
607         assign do_extreset_b = wreg_b & (rindex == 0) & (wdata[5:3] == 3'b010);
608
609         /* Internal IP bit set if latch different from source and
610          * corresponding interrupt is enabled in WR15
611          */
612         assign dcd_ip_a = (dcd_a != dcd_latch_a) & wr15_a[3];
613         assign dcd_ip_b = (dcd_b != dcd_latch_b) & wr15_b[3];
614
615         /* Latches close when an enabled IP bit is set and latches
616          * are currently open
617          */
618         assign do_latch_a = latch_open_a & (dcd_ip_a /* | cts... */);
619         assign do_latch_b = latch_open_b & (dcd_ip_b /* | cts... */);
620
621         /* "Master" interrupt, set when latch close & WR1[0] is set */
622         always@(posedge sysclk or posedge reset) begin
623                 if (reset)
624                   ex_irq_ip_a <= 0;
625                 else if (do_extreset_a)
626                   ex_irq_ip_a <= 0;
627                 else if (do_latch_a && wr1_a[0])
628                   ex_irq_ip_a <= 1;
629         end
630         always@(posedge sysclk or posedge reset) begin
631                 if (reset)
632                   ex_irq_ip_b <= 0;
633                 else if (do_extreset_b)
634                   ex_irq_ip_b <= 0;
635                 else if (do_latch_b && wr1_b[0])
636                   ex_irq_ip_b <= 1;
637         end
638
639         /* Latch open/close control */
640         always@(posedge sysclk or posedge reset) begin
641                 if (reset)
642                   latch_open_a <= 1;
643                 else begin
644                         if (do_extreset_a)
645                           latch_open_a <= 1;
646                         else if (do_latch_a)
647                           latch_open_a <= 0;
648                 end
649         end
650         always@(posedge sysclk or posedge reset) begin
651                 if (reset)
652                   latch_open_b <= 1;
653                 else begin
654                         if (do_extreset_b)
655                           latch_open_b <= 1;
656                         else if (do_latch_b)
657                           latch_open_b <= 0;
658                 end
659         end
660
661         /* Latches proper */
662         always@(posedge sysclk or posedge reset) begin
663                 if (reset) begin
664                         dcd_latch_a <= 0;
665                         /* cts ... */
666                 end else begin
667                         if (do_latch_a)
668                           dcd_latch_a <= dcd_a;
669                         /* cts ... */
670                 end
671         end
672         always@(posedge sysclk or posedge reset) begin
673                 if (reset) begin
674                         dcd_latch_b <= 0;                       
675                         /* cts ... */
676                 end else begin
677                         if (do_latch_b)
678                           dcd_latch_b <= dcd_b;
679                         /* cts ... */
680                 end
681         end
682         
683         /* NYI */
684         assign txd = 1;
685         assign rts = 1;
686
687         assign wreq = 0;        
688 endmodule