Root/cap_keyboard/logic/UART/uart.v

1`timescale 1ns / 1ps
2/******************************************************************************/
3/* SIDSA */
4/******************************************************************************/
5/* HSDT100 ARM PERIPHERALS */
6/* */
7/* MODULE: UART */
8/* */
9/* FILE: UART_PC.v VERSION:3.0 DATE: 19-I-98 */
10/******************************************************************************/
11
12 
13module UART (reset, CLK, data_in, data_out, add, nRW, CS,
14        RxD, TxD, nIRQ, CD, RI, DSR, CTS, DTR, RTS);
15
16input reset; // Reset (H)
17input CLK; // System clock
18input [7:0] data_in; // Input Data Bus
19input [2:0] add; // Address Bus
20input nRW; // Read_ / Write from ARM
21input CS; // UART Chip Select
22
23input RxD; // Receiver Data Line
24input CD; // Carrier Detect
25input RI; // Ring Indicator
26input DSR; // Data Send Ready
27input CTS; // Clear To Send
28
29output RTS; // Request To Send
30output DTR; // Data Terminal Ready
31output TxD; // Transmiter Data Line
32output nIRQ; // Interrupt Request Output to ARM
33output [7:0] data_out; // Output Data Bus
34
35
36// Variables
37//.............................................................
38
39wire [7:0] dato_rx; // Dato recibido
40wire [7:0] dato_tx; // Dato para transmitir
41wire err_paridad; // Error de paridad (H)
42wire err_frame; // Error de trama (H)
43wire err_overrun; // Error de rebosamiento (H)
44wire error; // Error (OR de los anteriores)
45wire rx_lleno; // Dato disponible
46wire tx_empty; // Transmisor vacio
47wire txt_empty; // Transmisor completamente vacio
48wire borrar_rdy; // Borrar dato_rdy tras leer DATO_RX
49wire borrar_err; // Borrar err_over tras leer STATUS_RX
50wire carga; // Senal carga
51wire carga_div; // Senal carga cte_div
52
53wire clkl; // Frecuencia de reloj dividida
54wire clkls; // Reloj de muestreo sincronizado (el nivel
55                // alto dura un periodo de reloj)
56wire RxDs; // Senal RxD sincronizada y limpia
57wire sample; // Impulso de muestreo de la senal RxDs
58wire samples; // Impulso de muestreo de RxDs conformado
59wire load_shift;
60
61wire carga_IER; // senal carga IER
62wire carga_MCR; // senal carga MCR
63wire carga_LCR; // senal carga LCR
64wire carga_MSR; // senal carga MSR (para codificacion delta)
65wire carga_ISR; // senal carga ISR
66
67wire [1:0] WordLength; // CONFIGURACIONES UART
68wire Stop;
69wire ParityEnable;
70wire Parity;
71wire ParityForced;
72wire Break;
73wire BaudSelect;
74wire modem_int;
75wire [7:0] modem;
76wire [3:0] ISR;
77wire [7:0] LSR;
78wire [7:0] LCR;
79wire [3:0] IER;
80//.............................................................
81
82
83// The default comunication speed is 115200 (clk = 50MHz); divide the clock if you want another speed
84// The Minimun Clk frequency is 50Mz
85// 50000000/115200 = 434 => 16 X 27 = 432
86
87pc_if_arm_pc if_arm1 (reset, CLK, data_in, data_out, add, nRW, CS,
88                borrar_rdy, borrar_err,
89        carga, carga_div_low, carga_div_high,
90        carga_IER, carga_MCR,
91        carga_LCR, carga_MSR, carga_ISR,
92                BaudSelect, dato_rx, modem, ISR, LSR, LCR);
93
94pc_div27 div27(reset, CLK, 1'b1, clk_pres);
95
96pc_div_ms div_ms1 (reset, CLK, clk_pres,data_in, carga_div_low, carga_div_high, clkl);
97
98pc_pulso pulso1(reset, CLK, clkl, clkls);
99
100pc_div16 div161(reset, CLK, clkls, clktx);
101
102pc_ifrxd ifrxd1(reset, CLK, clkls, RxD, RxDs);
103
104pc_muestreo muestreo1(reset, CLK, rx_lleno, clkls, RxDs, sample);
105
106pc_pulso pulso2(reset, CLK, sample, samples);
107
108pc_buffrx_pc buffrx1(reset, CLK, RxDs, samples, rx_lleno, dato_rx, err_paridad,
109        err_frame, ParityEnable, Parity, ParityForced);
110
111pc_ctrl_rx ctrl_rx1(reset, CLK, samples, rx_lleno);
112
113pc_dato_rdy dato_rdy1(reset, CLK, rx_lleno, borrar_rdy, borrar_err, dato_rdy,
114        err_overrun);
115
116pc_pulso pulso3(reset, CLK, clktx, clktxs);
117
118pc_bufftx bufftx1 (reset, CLK, carga, load_shift, clktxs, data_in, TxD,
119        ParityEnable, Parity, ParityForced);
120
121pc_ctrl_tx_pc ctrl_tx1 (reset, CLK, carga, clktxs, load_shift, tx_empty,
122        txt_empty);
123
124//pc_modem m1(reset, CLK, carga_MCR, carga_MSR, data_in, modem,
125// CD, RI, DSR, CTS, DTR, RTS, modem_int);
126
127pc_ier ier1(reset, CLK, carga_IER, data_in, dato_rdy, tx_empty, modem_int, nIRQ, IER);
128
129pc_lcr lcr1(reset, CLK, LCR, carga_LCR, data_in,
130             WordLength, Stop, ParityEnable, Parity,
131         ParityForced, Break, BaudSelect);
132
133pc_isr isr1(reset, CLK, carga_ISR,
134         err_paridad, err_frame, err_overrun,
135         dato_rdy, tx_empty, txt_empty, modem_int,
136             ISR, LSR, IER);
137
138endmodule
139
140
141
142
143
144
145
146//............................................................
147// BUFFER RECEIVER
148//
149//............................................................
150 
151 
152module pc_buffrx_pc (reset, CLK, RxDs, samples, fin_rx, datorx,
153        err_paridad, err_frame,
154        ParityEnable, Parity, ParityForced);
155
156input reset; // Reset (H)
157input CLK; // Reloj del sistema
158input RxDs; // Linea RxD limpia
159input samples; // Impulso de muestreo de RxDs conformado
160input fin_rx; // Indicador (L) de recepcion en curso
161output [7:0] datorx; // Dato recibido
162output err_paridad; // Error de paridad (H)
163output err_frame; // Error en el bit de parada (H)
164input ParityEnable; // Habilitacion de paridad
165input Parity; // Paridad
166input ParityForced; // Valor de paridad forzada.
167
168
169// Variables
170//.............................................................
171
172reg [9:0] bufrx; // Registro serie-paralelo del Receptor
173                // bufrx[7:0]=dato, bufrx[8]=paridad
174                // bufrx[9]=parada
175reg [7:0] datorx; // Dato recibido
176reg err_paridad; // Error de paridad (H)
177reg err_frame; // Error en el bit de parada (H)
178wire iparity;
179
180//.............................................................
181
182// Si el numero de 1s es par, iparity =1
183
184assign iparity = bufrx[8] ^ bufrx[7] ^ bufrx[6]
185        ^ bufrx[5] ^ bufrx[4] ^ bufrx[3]
186        ^ bufrx[2] ^ bufrx[1] ^ bufrx[0];
187
188
189always @(posedge CLK or posedge reset)
190begin
191    if (reset)
192        begin
193        bufrx <= 0;
194        datorx <= 0;
195        err_paridad <= 0;
196        err_frame <= 0;
197        end
198    else casex ({fin_rx, samples})
199        2'bx1: begin
200            bufrx <= bufrx >> 1;
201            bufrx[9] <= RxDs;
202        end
203
204        2'b1x: begin
205            datorx <= bufrx[7:0];
206
207            casex ({ParityForced, Parity, ParityEnable})
208            3'bxx0: err_paridad <= 0; // No parity
209
210            3'b001: err_paridad <= ~iparity; // ODD parity
211            3'b011: err_paridad <= iparity; // EVEN parity
212            3'b101: err_paridad <= 1; // forced parity
213            3'b111: err_paridad <= 0; // forced parity
214
215            endcase
216
217            err_frame <= !bufrx[9];
218        end
219    endcase
220end
221
222endmodule
223
224
225
226
227
228//............................................................
229// BUFFER TRANSMITER
230//............................................................
231 
232 
233module pc_bufftx (reset, CLK, carga, load_shift, enable, datotx, TxD,
234        ParityEnable, Parity, ParityForced);
235
236input reset; // Reset (H). Lo pone a UNOS.
237input CLK; // Reloj del sistema
238input carga; // Carga (H) nuevo dato
239input load_shift; // Carga(H)/Desplaza(L) dato en reg P-S
240input enable; // Habilitacion (H) del reg P-S
241input [7:0] datotx; // Dato para transmitir
242output TxD; // Salida
243input ParityEnable; // Habilitacion de paridad
244input Parity; // Paridad
245input ParityForced; // Valor de paridad forzada.
246
247
248// Variables
249//.............................................................
250
251reg [7:0] dato_tx; // Registro del dato para transmitir
252reg [10:0] buftx; // Registro paralelo-serie del Transmisor
253                // buftx[8:1]=dato, buftx[9]=paridad
254                // buftx[0]=arranque, parada
255wire TxD; // Salida
256wire iparity; // Evaluacion de la paridad
257//.............................................................
258
259// iparity is 1 when number of ones is odd.
260
261assign iparity = dato_tx[7] ^ dato_tx[6]
262         ^ dato_tx[5] ^ dato_tx[4]
263         ^ dato_tx[3] ^ dato_tx[2]
264         ^ dato_tx[1] ^ dato_tx[0];
265
266
267always @(posedge CLK or posedge reset)
268begin
269    if (reset)
270        begin
271        dato_tx <= 0;
272        buftx[10:0] <= 11'h7FF;
273        end
274    else casex ({load_shift, enable, carga})
275        3'bxx1: begin
276                dato_tx <= datotx;
277            end
278
279        3'b01x: begin
280                buftx[9:0] <= buftx[10:1];
281                buftx[10] <= 1;
282            end
283
284        3'b11x: begin
285                buftx[8:1] <= dato_tx;
286                buftx[0] <= 0;
287
288                casex ({ParityForced, Parity, ParityEnable})
289                3'bxx0: buftx[9] <= 1; // No parity
290
291                3'b001: buftx[9] <= ~iparity; // ODD parity
292                3'b011: buftx[9] <= iparity; // EVEN parity
293                3'b101: buftx[9] <= 1; // forced parity
294                3'b111: buftx[9] <= 0; // forced parity
295
296                endcase
297                
298            end
299
300    endcase
301end
302
303assign TxD = buftx[0];
304
305endmodule
306
307
308
309
310
311
312//............................................................
313// RECEIVER CONTROL
314//............................................................
315 
316module pc_ctrl_rx (reset, CLK, samples, rx_lleno);
317
318input reset; // Reset (H)
319input CLK; // Reloj del sistema
320input samples; // Impulso de muestreo de RxDs conformado
321output rx_lleno; // Indica (H) final de la recepcion de un caracter
322
323// Variables
324//.............................................................
325
326reg rx_lleno; // Indica (H) final de la recepcion de un caracter
327reg [3:0] cont_rx;// Contador de bits recibidos
328
329//.............................................................
330
331always @(posedge CLK or posedge reset)
332begin
333    if (reset)
334        begin
335        rx_lleno <= 0;
336        cont_rx <= 0;
337        end
338    else if (samples)
339            begin
340            cont_rx <= cont_rx + 1;
341            if (cont_rx==10)
342                begin
343                rx_lleno <= 1;
344                cont_rx <= 0;
345                                end
346            else
347                rx_lleno <= 0;
348            end
349        else
350            rx_lleno <= 0;
351end
352
353endmodule
354
355
356//............................................................
357// TRANSMMITER CONTROL
358//............................................................
359 
360module pc_ctrl_tx_pc (reset, CLK, carga, enable, load_shift,
361         tx_empty, txt_empty);
362
363input reset; // Reset (H)
364input CLK; // Reloj del sistema
365input carga; // Carga (H) de un nuevo dato
366input enable; // Habilitacion (H)
367output load_shift; // Carga(H)/Desplaza(L) en reg P-S
368output tx_empty; // Indica (H) TX vacio (PP)
369output txt_empty; // Indica (H) TX totalmente vacio (PP y PS)
370
371// Variables
372//.............................................................
373
374wire load_shift; // Carga(H)/Desplaza(L) en reg P-S
375reg tx_empty; // Indica (H) buffer de tx vacio (PP)
376wire txt_empty; // Indica (H) TX vacio (PP y PS)
377reg tx_on; // Indica (H) transmision activa
378reg [3:0] cont_tx; // Contador de bits transmitidos
379
380//.............................................................
381
382always @(posedge CLK or posedge reset)
383begin
384    if (reset)
385        begin
386        tx_empty <= 1;
387        tx_on <= 0;
388        cont_tx <= 0;
389        end
390    else begin
391                casex ({carga, load_shift})
392                2'b00: tx_empty <= tx_empty;
393                2'b01: tx_empty <= 1;
394                2'b1x: tx_empty <= 0;
395                endcase
396
397 
398                if (enable)
399                        if(tx_on) begin
400                                cont_tx <= cont_tx + 1;
401                                if (cont_tx==10) begin
402                                        cont_tx <= 0;
403                    tx_on <= 0;
404                end
405                                else
406                    tx_on <= 1;
407                        end
408                        else if(load_shift)
409                                tx_on <= 1;
410 
411 
412        end
413 
414end
415 
416assign load_shift = (cont_tx == 0) & enable & !tx_empty & !tx_on;
417assign txt_empty = tx_empty & !tx_on;
418
419endmodule
420
421//............................................................
422// ERROR AND READY CONTROL
423//
424//............................................................
425 
426module pc_dato_rdy (reset, CLK, rx_lleno, borrar_rdy, borrar_err,
427        dato_rdy, err_overrun);
428
429input reset; // Reset (H)
430input CLK; // Reloj del sistema
431input rx_lleno; // Indica dato completo en el receptor
432input borrar_rdy; // Indica lectura de DATO_RX
433input borrar_err; // Indica lectura de STATUS_RX
434output dato_rdy; // Indica (H) final de la recepcion de un caracter
435output err_overrun; // Error de rebosamiento
436
437// Variables
438//.............................................................
439
440reg dato_rdy;// Indica (H) final de la recepcion de un caracter
441reg err_overrun; // Error de rebosamiento
442
443//.............................................................
444
445always @(posedge CLK or posedge reset)
446begin
447    if (reset)
448        begin
449        dato_rdy <= 0;
450        err_overrun <= 0;
451        end
452    else begin
453        if (rx_lleno)
454            dato_rdy <= 1;
455        else if (borrar_rdy)
456            dato_rdy <= 0;
457
458        if (rx_lleno & dato_rdy)
459            err_overrun <= 1;
460        else if(borrar_err)
461            err_overrun <= 0;
462    end
463            
464end
465endmodule
466
467
468//............................................................
469// DIVIDER BY 27
470//............................................................
471 
472module pc_div27 (reset, CLK, clk_in, clk_out);
473
474input reset; // Reset (H)
475input CLK; // Reloj del sistema
476input clk_in; // Frecuencia de entrada
477output clk_out; // Frecuencia de salida
478
479// Variables
480//.............................................................
481
482reg [5:0] div27; // Registro para dividir la frecuencia de
483            // muestreo y obtener la de transmision
484
485
486always @(posedge CLK or posedge reset)
487begin
488    if (reset)
489        div27 <= 0;
490    else if (clk_in)
491        if (div27==26)
492            div27 <= 0;
493        else
494            div27 <= div27 + 1;
495end
496
497assign clk_out = (div27==26)?1:0;
498
499endmodule
500
501
502//............................................................
503// DIVIDER BY 16
504//............................................................
505 
506module pc_div16 (reset, CLK, clk_in, clk_out);
507
508input reset; // Reset (H)
509input CLK; // Reloj del sistema
510input clk_in; // Frecuencia de entrada
511output clk_out; // Frecuencia de salida
512
513// Variables
514//.............................................................
515
516reg [3:0] div16; // Registro para dividir la frecuencia de
517            // muestreo y obtener la de transmision
518
519
520always @(posedge CLK or posedge reset)
521begin
522    if (reset)
523        div16 <= 0;
524    else if (clk_in)
525        if (div16==15)
526            div16 <= 0;
527        else
528            div16 <= div16 + 1;
529end
530
531assign clk_out = (div16==15)?1:0;
532
533endmodule
534
535
536
537
538//............................................................
539// PROGRAMMABLE DIVIDER
540//............................................................
541 
542module pc_div_ms (reset, CLK, clkin, cte_div, carga_div_low, carga_div_high, clk_out);
543
544input reset; // Reset (H)
545input CLK; // Reloj del sistema
546input clkin; // Reloj escalado
547input [7:0] cte_div;// Frecuencia de entrada
548input carga_div_low; // Senal carga de la cte_div
549input carga_div_high; // Senal carga de la cte_div
550
551output clk_out;// Frecuencia de salida
552
553// Variables
554//.............................................................
555
556reg [15:0] div; // Contador del divisor
557reg [15:0] k_div; // Factor de division
558reg clk_out;// Frecuencia de salida
559
560
561always @(posedge CLK or posedge reset)
562begin
563    if (reset)
564      begin
565        div <= 0;
566        k_div <= 1;
567      end
568    else begin
569        if (carga_div_low)
570            k_div[7:0] <= cte_div;
571      if (carga_div_high)
572            k_div[15:8] <= cte_div;
573      if (carga_div_low | carga_div_high) div<=0;
574        if (div==k_div) begin
575             div <= 0;
576             clk_out <= 1;
577        end
578        else begin
579            if (clkin)
580              begin
581                div <= div + 1;
582                clk_out <= 0;
583              end
584        end
585    end
586end
587
588endmodule
589
590
591module pc_ier (reset, CLK, carga_IER, data_in, dato_rdy, tx_empty, modem_int, nIRQ, IER);
592
593input reset;
594input CLK;
595input carga_IER;
596input [7:0] data_in;
597
598input dato_rdy;
599input tx_empty;
600input modem_int;
601output nIRQ; // Data Terminal Ready
602
603output [3:0] IER;
604reg [3:0] IER;
605        
606assign nIRQ= ~|(IER & {modem_int, dato_rdy, tx_empty, dato_rdy});
607
608always @(posedge CLK)
609begin
610  if (reset)
611    begin
612     IER<=4'b0;
613    end
614  else
615
616    if (carga_IER)
617        begin
618        IER<=data_in[3:0];
619        end
620    
621end
622
623
624
625endmodule
626
627
628
629//............................................................
630// ARM INTERFACE
631//............................................................
632
633
634// ADD nRW FUNCTION
635// 000 0 Rx Register.
636// 000 1 TX Register. If enabled, LSB Divisor Latch.
637//
638// 001 0 NA
639// 001 1 Interrupt Enable Register. If enabled, MSB Divisor Latch.
640//
641// 010 0 Interrupt Status Register.
642// 010 1 FIFO Control Register (Not Implemented).
643//
644// 011 0 NA
645// 011 1 Line Control Register
646//
647// 100 0 NA
648// 100 1 Modem Control Register
649//
650//
651// 101 0 Line Status Register
652// 101 1 NA
653//
654// 110 0 Modem Status Register
655// 110 1 NA
656//
657// 111 01 Scratch Pad Register
658//
659
660module pc_if_arm_pc (reset, CLK, data_in, data_out, add, nRW, CS,
661        borrar_rdy, borrar_err, carga, carga_div_low, carga_div_high,
662      carga_IER, carga_MCR, carga_LCR, carga_MSR, carga_ISR,
663      BaudSelect, dato_rx, modem, ISR, LSR, LCR);
664
665input reset; // Reset (H)
666input CLK; // Reloj del sistema
667input [7:0] data_in; // Bus de datos de entrada
668output [7:0] data_out; // Bus de datos de salida
669input [2:0] add; // Bus de direcciones
670input nRW; // senal de lectura del ARM
671input CS; // senal de seleccion de la UART
672input [7:0] dato_rx; // Dato recibido
673output borrar_rdy; // Borrar dato_rdy tras leer DATO_RX
674output borrar_err; // Borrar err_over tras leer STATUS_RX
675output carga; // Senal carga
676output carga_div_low; // Senal carga de la cte_div (byte bajo)
677output carga_div_high; // Senal carga de la cte_div (byte alto)
678output carga_IER; // senal carga IER
679output carga_MCR; // senal carga MCR
680output carga_LCR; // senal carga LCR
681output carga_MSR; // senal carga MSR (para codificacion delta)
682output carga_ISR; // senal carga de ISR
683input BaudSelect; // seleccion de modo de acceso
684input [7:0] modem; // modem bus
685input [3:0] ISR; // Interrupt Status Register
686input [7:0] LSR; // Line Status Register
687input [7:0] LCR; // Line Control Register
688
689
690// Variables
691//.............................................................
692
693reg [7:0] data_out; // Bus de datos de salida
694reg carga; // Senal carga
695reg carga_div_low; // Senal carga de la cte_div (byte bajo)
696reg carga_div_high; // Senal carga de la cte_div (byte alto)
697reg carga_IER; // senal carga IER
698reg carga_MCR; // senal carga MCR
699reg carga_LCR; // senal carga LCR
700reg carga_MSR; // senal lectura del MSR (para puesta a 0)
701reg carga_ISR; // senal recarga del ISR
702reg borrar_rdy; // Borrar dato_rdy tras leer DATO_RX
703reg borrar_err; // Borrar err_over tras leer STATUS_RX
704reg [7:0] dato_tx; // Dato para transmitir
705
706
707
708//.............................................................
709
710
711
712always @(nRW or CS or add or dato_rx or LSR or ISR or LCR or modem or BaudSelect)
713    if (CS)
714      begin
715        casex ({nRW, add})
716            6'b0000: begin //Lectura de DATO_RX
717                data_out <= dato_rx;
718                borrar_rdy <= 1;
719                borrar_err <= 0;
720                carga <= 0;
721                carga_div_low <= 0;
722            carga_div_high <= 0;
723            carga_IER <= 0;
724                carga_MCR <= 0;
725                carga_LCR <= 0;
726                carga_MSR <= 0;
727                carga_ISR <= 0;
728                end
729
730            6'b1000: begin //Escritura Baud_Rate
731            if (BaudSelect)
732            begin
733              carga_div_low <= 1;
734              carga <= 0;
735            end
736            else //Escritura de DATO_TX
737            begin
738              carga_div_low <= 0;
739              carga <= 1;
740            end
741            carga_div_high <= 0;
742            carga_IER <= 0;
743                carga_MCR <= 0;
744                carga_LCR <= 0;
745                carga_MSR <= 0;
746                carga_ISR <= 0;
747                 data_out <= dato_rx;
748                borrar_rdy <= 0;
749                borrar_err <= 0;
750                end
751
752            6'b1001: begin //Escritura Baud_Rate
753                if (BaudSelect)
754                    begin
755                        carga_div_high <= 1;
756                        carga_IER <= 0;
757                    end
758                else //Escritura de IER
759                    begin
760                        carga_div_high <= 0;
761                        carga_IER <= 1;
762                    end
763               carga <= 0;
764               carga_div_low <= 0;
765                carga_MCR <= 0;
766                carga_LCR <= 0;
767                carga_MSR <= 0;
768                carga_ISR <= 0;
769                 data_out <= dato_rx;
770                borrar_rdy <= 0;
771                borrar_err <= 0;
772                end
773
774
775            6'b0010: begin //Lectura ISR
776             carga <= 0;
777             carga_div_low <= 0;
778             carga_div_high <= 0;
779                  data_out <= ISR;
780             carga_IER <= 0;
781                 carga_MCR <= 0;
782                 carga_LCR <= 0;
783                 carga_MSR <= 0;
784                 carga_ISR <= 1;
785                 borrar_rdy <= 0;
786                 borrar_err <= 0;
787                 end
788
789
790            6'b1010: begin //Escritura FCR (no implementado)
791             carga <= 0;
792             carga_div_low <= 0;
793             carga_div_high <= 0;
794             carga_IER <= 0;
795                 carga_MCR <= 0;
796                 carga_LCR <= 0;
797                 carga_MSR <= 0;
798                 carga_ISR <= 0;
799                  data_out <= dato_rx;
800                 borrar_rdy <= 0;
801                 borrar_err <= 0;
802                 end
803
804
805            6'b0011: begin //Lectura LCR
806             carga <= 0;
807             carga_div_low <= 0;
808             carga_div_high <= 0;
809             carga_IER <= 0;
810                 carga_MCR <= 0;
811                 carga_LCR <= 0;
812                 carga_MSR <= 0;
813                 carga_ISR <= 0;
814                  data_out <= LCR;
815                 borrar_rdy <= 0;
816                 borrar_err <= 0;
817                 end
818
819
820            6'b1011: begin //Escritura LCR
821             carga <= 0;
822             carga_div_low <= 0;
823             carga_div_high <= 0;
824             carga_IER <= 0;
825                 carga_MCR <= 0;
826                 carga_LCR <= 1;
827                 carga_MSR <= 0;
828                 carga_ISR <= 0;
829                  data_out <= dato_rx;
830                 borrar_rdy <= 0;
831                 borrar_err <= 0;
832                 end
833
834
835            6'b1100: begin //Escritura de MCR
836             carga <= 0;
837             carga_div_low <= 0;
838             carga_div_high <= 0;
839             carga_IER <= 0;
840                 carga_MCR <= 1;
841                 carga_LCR <= 0;
842                 carga_MSR <= 0;
843                 carga_ISR <= 0;
844                  data_out <= dato_rx;
845                 borrar_rdy <= 0;
846                 borrar_err <= 0;
847                 end
848
849            6'b0101: begin //Lectura del LSR
850             carga<=0;
851             carga_div_low<=0;
852             carga_div_high<=0;
853             carga_IER<=0;
854                 carga_MCR<=0;
855                 carga_LCR<=0;
856                 carga_MSR<=0;
857                 carga_ISR<=0;
858             data_out <= LSR;
859                 borrar_rdy <= 0;
860                 borrar_err <= 0;
861                 end
862
863
864            6'b0110: begin //Lectura del MSR
865             carga<=0;
866             carga_div_low<=0;
867             carga_div_high<=0;
868             carga_IER<=0;
869                 carga_MCR<=0;
870                 carga_LCR<=0;
871                 carga_MSR<=1;
872                 carga_ISR<=0;
873             data_out <= modem;
874                 borrar_rdy <= 0;
875                 borrar_err <= 0;
876                 end
877/*
878            6'b0111: begin
879                                 carga<=0;
880                                 carga_div_low<=0;
881                                 carga_div_high<=0;
882                                 carga_IER<=0;
883                 carga_MCR<=0;
884                 carga_LCR<=0;
885                 carga_ISR<=0;
886                  data_out <= dato_rx;
887                 borrar_rdy <= 0;
888                 borrar_err <= 0;
889                 end
890
891            6'b1111: begin
892                                 carga<=0;
893                                 carga_div_low<=0;
894                                 carga_div_high<=0;
895                                 carga_IER<=0;
896                 carga_MCR<=0;
897                 carga_LCR<=0;
898                 carga_ISR<=0;
899                  data_out <= dato_rx;
900                 borrar_rdy <= 0;
901                 borrar_err <= 0;
902                 end
903*/
904
905           default:
906             begin
907             carga<=0;
908             carga_div_low<=0;
909             carga_div_high<=0;
910             carga_IER<=0;
911                 carga_MCR<=0;
912                 carga_LCR<=0;
913                 carga_MSR<=0;
914                 carga_ISR<=0;
915                  data_out <= dato_rx;
916                 borrar_rdy <= 0;
917                 borrar_err <= 0;
918             end
919
920        endcase
921              end
922           else
923        begin
924             carga<=0;
925             carga_div_low<=0;
926             carga_div_high<=0;
927             carga_IER<=0;
928                 carga_MCR<=0;
929                 carga_LCR<=0;
930                 carga_MSR<=0;
931                 carga_ISR<=0;
932                  data_out <= dato_rx;
933                 borrar_rdy <= 0;
934                 borrar_err <= 0;
935        end
936endmodule
937
938
939
940//............................................................
941// RxD INTERFACE
942//............................................................
943 
944module pc_ifrxd (reset, CLK, clkms, RxD, RxDs);
945
946input reset; // Reset (H)
947input CLK; // Reloj del sistema
948input clkms; // Reloj de muestreo sincronizado (el nivel
949                        // alto dura un periodo de reloj)
950input RxD; // Linea de recepcion de datos
951output RxDs; // RxD sincronizada y limpia
952
953// Variables
954//.............................................................
955
956reg [2:0] ifrxd; // Registro interfaz de la linea RxD
957
958
959//.............................................................
960
961always @(posedge CLK or posedge reset)
962begin
963    if (reset)
964        ifrxd <= 3'b111;
965    else if (clkms)
966        begin
967        if ((ifrxd[0]==ifrxd[2]) & (ifrxd[0]!=ifrxd[1]))
968            ifrxd[2] <= ifrxd[0];
969        else
970            ifrxd[2] <= ifrxd[1];
971        ifrxd[1] <= ifrxd[0];
972        ifrxd[0] <= RxD;
973        end
974end
975
976assign RxDs = ifrxd[2];
977
978endmodule
979module pc_isr (reset, CLK,
980             carga_ISR,
981         err_paridad, err_frame, err_overrun,
982         dato_rdy, tx_empty, txt_empty, modem_int,
983             ISR, LSR, IER);
984
985input reset;
986input CLK;
987input carga_ISR;
988input err_paridad;
989input err_frame;
990input err_overrun;
991input dato_rdy;
992input tx_empty;
993input txt_empty;
994input modem_int;
995
996output [3:0] ISR; // Interrupt Status Register
997output [7:0] LSR; // Line Status Register
998input [3:0] IER; // Interrupt Enable Register
999
1000reg [3:0] ISR;
1001reg [3:0] ISRt;
1002
1003reg mask_error;
1004reg mask_dato_rdy;
1005reg mask_err_overrun;
1006reg mask_tx_empty;
1007reg mask_modem_int;
1008reg carga_ISRd;
1009reg aux1;
1010
1011wire error, errorm, dato_rdym, err_overrunm, tx_emptym, modem_intm;
1012
1013
1014assign errorm= error & mask_error & IER[1];
1015assign dato_rdym= dato_rdy & mask_dato_rdy & IER[0];
1016assign err_overrunm= err_overrun & mask_err_overrun;
1017assign tx_emptym= tx_empty & mask_tx_empty & IER[1];
1018assign modem_intm= modem_int & mask_modem_int & IER[3];
1019
1020
1021always @(errorm or dato_rdym or tx_emptym or err_overrunm or modem_intm)
1022begin
1023  if (errorm) ISRt=4'b0110;
1024  else if (dato_rdym) ISRt=4'b0100;
1025      //else if (err_overrunm) ISRt=4'b1100;
1026          else if (tx_emptym) ISRt=4'b0010;
1027              else if (modem_intm) ISRt=4'b0000;
1028                  else ISRt=4'b0001;
1029end
1030
1031assign error = err_paridad | err_frame | err_overrun;
1032assign LSR = {error, txt_empty, tx_empty, 1'b0, err_frame, err_paridad, err_overrun, dato_rdy};
1033        
1034always @(posedge CLK)
1035begin
1036  if (reset)
1037    begin
1038              ISR<=4'b0001;
1039        mask_error<=1;
1040        mask_dato_rdy<=1;
1041        mask_err_overrun<=1;
1042        mask_tx_empty<=1;
1043        mask_modem_int<=1;
1044        carga_ISRd<=0;
1045        aux1<=1'b0;
1046    end
1047  else
1048    begin
1049
1050        if (mask_error)
1051           begin
1052             if ((ISR==4'b0110) & carga_ISRd) mask_error<=0;
1053           end
1054        else
1055           if (error) mask_error<=1;
1056
1057        if (mask_dato_rdy)
1058           begin
1059             if ((ISR==4'b0100) & carga_ISRd) mask_dato_rdy<=0;
1060           end
1061        else
1062           if (dato_rdy) mask_dato_rdy<=1;
1063
1064        if (mask_err_overrun)
1065           begin
1066             if ((ISR==4'b1100) & carga_ISRd) mask_err_overrun<=0;
1067           end
1068        else
1069           if (err_overrun) mask_err_overrun<=1;
1070
1071        if (mask_tx_empty)
1072           begin
1073             if ((ISR==4'b0010) & carga_ISRd) mask_tx_empty<=0;
1074           end
1075        else
1076           if (tx_empty) mask_tx_empty<=1;
1077
1078        if (mask_modem_int)
1079           begin
1080             if ((ISR==4'b0000) & carga_ISRd) mask_modem_int<=0;
1081           end
1082        else
1083           if (modem_int) mask_modem_int<=1;
1084
1085        ISR<=ISRt;
1086    aux1<=carga_ISR; //Espera a que se deseleccione el carga_ISR para modificar mascaras.
1087    if (~carga_ISR)
1088        begin
1089            carga_ISRd<=aux1;
1090            aux1<=1'b0;
1091        end
1092
1093    end
1094end
1095
1096
1097endmodule
1098
1099
1100module pc_lcr (reset, CLK, LCR,
1101             carga_LCR,
1102             data_in,
1103             WordLength, Stop, ParityEnable, Parity,
1104         ParityForced, Break, BaudSelect);
1105
1106input reset;
1107input CLK;
1108output [7:0] LCR;
1109input carga_LCR;
1110input [7:0] data_in;
1111
1112output [1:0] WordLength;
1113output Stop;
1114output ParityEnable;
1115output Parity;
1116output ParityForced;
1117output Break;
1118output BaudSelect;
1119
1120reg [7:0] LCR;
1121
1122
1123assign WordLength={LCR[1],LCR[0]};
1124assign Stop=LCR[2];
1125assign ParityEnable=LCR[3];
1126assign Parity=LCR[4];
1127assign ParityForced=LCR[5];
1128assign Break=LCR[6];
1129assign BaudSelect=LCR[7];
1130
1131
1132
1133always @(posedge CLK)
1134begin
1135  if (reset)
1136    begin
1137          LCR<=8'b0; //Ver hoja de datos de ST16C552.
1138            //Esta es la situacion en reset.
1139    end
1140  else
1141
1142    if (carga_LCR)
1143        begin
1144            LCR<=data_in;
1145        end
1146    
1147
1148end
1149
1150
1151
1152
1153endmodule
1154
1155
1156//module pc_modem(reset, CLK,
1157// carga_MCR, carga_MSR,
1158// data_in, modem,
1159// CD, RI, DSR, CTS, DTR, RTS, modem_int);
1160//
1161//input reset;
1162//input CLK;
1163//input carga_MCR;
1164//input carga_MSR;
1165//input [7:0] data_in;
1166//output [7:0] modem;
1167//input CD; // Carrier Detect
1168//input RI; // Ring Indicator
1169//input DSR; // Data Send Ready
1170//input CTS; // Clear To Send
1171//output RTS; // Request To Send
1172//output DTR; // Data Terminal Ready
1173//output modem_int;
1174//
1175//reg RTS;
1176//reg DTR;
1177//
1178//reg dCD, sCD;
1179//reg dRI, sRI;
1180//reg dDSR, sDSR;
1181//reg dCTS, sCTS;
1182//wire [7:0] modem;
1183//reg modem_int;
1184//
1185//
1186//assign modem ={~sCD, ~sRI, ~sDSR, ~sCTS,
1187// dCD ^ sCD, dRI ^ sRI, dDSR ^ sDSR, dCTS ^ sCTS};
1188//
1189//
1190//always @(posedge CLK)
1191//begin
1192// if (reset)
1193// begin
1194// dCD<=1; sCD<=1;
1195// dRI<=1; sRI<=1;
1196// dDSR<=1; sDSR<=1;
1197// dCTS<=1; sCTS<=1;
1198// DTR<=1;
1199// RTS<=1;
1200// modem_int<=0;
1201// end
1202// else
1203// begin
1204// sCD<=~CD;
1205// sRI<=~RI;
1206// sDSR<=~DSR;
1207// sCTS<=~CTS;
1208//
1209// modem_int<=modem_int | (|modem[3:0]);
1210//
1211// if (carga_MCR)
1212// begin
1213// RTS<=~data_in[0];
1214// DTR<=~data_in[1];
1215// end
1216//
1217// else
1218// if (carga_MSR)
1219// begin
1220// dCD<=~CD;
1221// dRI<=~RI;
1222// dDSR<=~DSR;
1223// dCTS<=~CTS;
1224// modem_int<=0; //Limpieza de la interrupcion
1225// end
1226//
1227//
1228// end
1229//
1230//end
1231//
1232//
1233//
1234//
1235//endmodule
1236//
1237
1238//............................................................
1239// RxDs SAMPLER
1240//............................................................
1241 
1242module pc_muestreo (reset, CLK, rst_muestreo, clkms, RxDs, sample);
1243
1244input reset; // Reset (H)
1245input CLK; // Reloj del sistema
1246input rst_muestreo; // Reset (H) del circuito de muestreo
1247input clkms; // Reloj de muestreo sincronizado (el nivel
1248                        // alto dura un periodo de reloj)
1249input RxDs; // Senal RxD sincronizada y limpia
1250output sample; // Impulso de muestreo de la senal RxDs
1251
1252// Variables
1253//.............................................................
1254
1255reg [3:0] cont_m; // Contador del circuito de muestreo
1256reg flag_rx;// Indicador de recepcion en curso
1257reg sample; // Impulso de muestreo de la senal RxDs
1258
1259
1260//.............................................................
1261
1262always @(posedge CLK or posedge reset)
1263begin
1264    if (reset)
1265        begin
1266        cont_m <= 4'b0000;
1267        sample <= 0;
1268        flag_rx <= 0;
1269        end
1270    else if (rst_muestreo)
1271        begin
1272         cont_m <= 4'b0000;
1273         sample <= 0;
1274         flag_rx <= 0;
1275                end
1276    else if (clkms)
1277        if ( (flag_rx==0) & (RxDs==0) ) // Arranque
1278            flag_rx <= 1; // Recepcion en curso
1279        else if (flag_rx)
1280            begin
1281            cont_m <= cont_m + 1;
1282            if (cont_m==4'b0110)
1283                sample <= 1;
1284            else
1285                sample <= 0;
1286            end
1287end
1288
1289endmodule
1290
1291
1292
1293//............................................................
1294// TIMING CONTROL
1295//............................................................
1296 
1297module pc_pulso (reset, CLK, dato_asyn, dato_syn);
1298
1299input reset; // Reset (H)
1300input CLK; // Reloj del sistema
1301input dato_asyn; // Entrada de dato asincrona
1302output dato_syn; // Salida de dato conformada
1303
1304// Variables
1305//.............................................................
1306
1307reg dff; // Registro del sincronizador
1308
1309always @(posedge CLK or posedge reset)
1310begin
1311    if (reset)
1312        dff <= 0;
1313    else
1314        dff <= dato_asyn;
1315end
1316
1317assign dato_syn = !dff & dato_asyn;
1318
1319endmodule

Archive Download this file

Branches:
master



interactive