OpenCores
URL https://opencores.org/ocsvn/systemverilog-uart16550/systemverilog-uart16550/trunk

Subversion Repositories systemverilog-uart16550

[/] [systemverilog-uart16550/] [trunk/] [rtl/] [uart_receiver.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 hiroshi
/* *****************************************************************************
2
   * title:         uart_16550_rll module                                      *
3
   * description:   RS232 Protocol 16550D uart (mostly supported)              *
4
   * languages:     systemVerilog                                              *
5
   *                                                                           *
6
   * Copyright (C) 2010 miyagi.hiroshi                                         *
7
   *                                                                           *
8
   * This library is free software; you can redistribute it and/or             *
9
   * modify it under the terms of the GNU Lesser General Public                *
10
   * License as published by the Free Software Foundation; either              *
11
   * version 2.1 of the License, or (at your option) any later version.        *
12
   *                                                                           *
13
   * This library is distributed in the hope that it will be useful,           *
14
   * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
15
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
16
   * Lesser General Public License for more details.                           *
17
   *                                                                           *
18
   * You should have received a copy of the GNU Lesser General Public          *
19
   * License along with this library; if not, write to the Free Software       *
20
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111*1307  USA *
21
   *                                                                           *
22
   *         ***  GNU LESSER GENERAL PUBLIC LICENSE  ***                       *
23
   *           from http://www.gnu.org/licenses/lgpl.txt                       *
24
   *****************************************************************************
25
   *                            redleaflogic,ltd                               *
26
   *                    miyagi.hiroshi@redleaflogic.biz                        *
27
   *          $Id: uart_receiver.sv 108 2010-03-30 02:56:26Z hiroshi $         *
28
   ***************************************************************************** */
29
 
30
`ifdef SYN
31
/* empty */
32
`else
33
timeunit      1ps ;
34
timeprecision 1ps ;
35
`endif
36
 
37
import uart_package:: * ;
38
module uart_receiver(
39
                     input wire     clk_i,
40
                     input wire     nrst_i,
41
                     input wire     rxd_clean,
42
                     input wire     rec_clk_en,
43
                     input wire     rec_sample_pulse,
44
                     input wire     leading_edge,
45
                     input wire     timeout_signal,
46
                     fifo_bus       fifo_push,
47
                     input  u_reg_t u_reg,
48
                     output codec_state_t next_state,
49
                     output  logic  rec_buf_empty,
50
                     output  logic  overrun
51
                     ) ;
52
 
53
   //   codec_state_t     next_state ;
54
   u_codec_t         rec_codec ;
55
 
56
   always @(posedge clk_i, negedge nrst_i) begin
57
      if(nrst_i == 1'b0)
58
        rec_codec.line <= #1 1'b1 ;
59
      else
60
        rec_codec.line <= #1 rxd_clean ;
61
   end
62
 
63
   // --- fifo push --
64
   assign fifo_push.push_dat =  {rec_codec.parity_err,    // bit[10]
65
                                 rec_codec.framing_err,   //     9
66
                                 rec_codec.break_err,     //     8
67
                                 rec_codec.data_r}  ;     //     [7:0]
68
   logic push_dly ;
69
   always @(posedge clk_i, negedge nrst_i) begin
70
      if(nrst_i == 1'b0)
71
        push_dly <= #1 1'b0 ;
72
      else
73
        push_dly <= #1 next_state == STOP && rec_sample_pulse == 1'b1 ;
74
   end
75
   assign fifo_push.push = push_dly == 1'b1 ;
76
 
77
   // -- trasmitter state logic --
78
   uart_codec_state rec_state(.u_reg(u_reg),
79
                              .codec(rec_codec),
80
                              .receiver_mode(1'b1),
81
                              .timeout_signal(timeout_signal),
82
                              .next_state(next_state)) ;
83
 
84
   // -- state register --
85
   always_ff @(posedge clk_i, negedge nrst_i) begin
86
      if(nrst_i == 1'b0)
87
        rec_codec.state <= #1 IDLE ;
88
      else if(rec_clk_en == 1'b1 || leading_edge == 1'b1)
89
        rec_codec.state <= #1 next_state ;
90
      else
91
        rec_codec.state <= #1 rec_codec.state ;
92
   end
93
 
94
   // -- line input --
95
   always_ff @(posedge clk_i, negedge nrst_i) begin
96
      if(nrst_i == 1'b0) begin
97
         rec_codec.data_r <= #1 8'h00 ;
98
         rec_codec.framing_err <= #1 1'b0 ;
99
         rec_codec.parity_err  <= #1 1'b0 ;
100
         rec_codec.break_err   <= #1 1'b0 ;
101
         overrun <= #1 1'b0 ;
102
      end
103
      else begin
104
         if(rec_sample_pulse == 1'b1)
105
           case (next_state)
106
             IDLE  : /* empty */ ;
107
             START : begin
108
                overrun   <= #1 1'b0 ;
109
                rec_codec.framing_err <= #1 1'b0 ;
110
                rec_codec.parity_err  <= #1 1'b0 ;
111
                rec_codec.break_err   <= #1 1'b0 ;
112
             end
113
             SEL_0 : rec_codec.data_r[0] <= #1 rec_codec.line ;
114
             SEL_1 : rec_codec.data_r[1] <= #1 rec_codec.line ;
115
             SEL_2 : rec_codec.data_r[2] <= #1 rec_codec.line ;
116
             SEL_3 : rec_codec.data_r[3] <= #1 rec_codec.line ;
117
             SEL_4 : rec_codec.data_r[4] <= #1 rec_codec.line ;
118
             SEL_5 : rec_codec.data_r[5] <= #1 rec_codec.line ;
119
             SEL_6 : rec_codec.data_r[6] <= #1 rec_codec.line ;
120
             DATA_END : begin
121
                if(u_reg.line_control_reg.char_length == CHAR_7_BIT) begin
122
                   rec_codec.data_r[6] <= #1 rec_codec.line ;
123
                   rec_codec.data_r[7] <= #1 1'b0 ;
124
                end
125
                else begin
126
                   rec_codec.data_r[7] <= #1 rec_codec.line ;
127
                end
128
                overrun <= #1 fifo_push.full ;
129
             end
130
             PARITY : begin
131
                if(u_reg.line_control_reg.even_parity == 1'b1)
132
                  rec_codec.parity_err <= #1 (^rec_codec.data_r) ^ rec_codec.line ;
133
                else
134
                  rec_codec.parity_err <= #1 ~(^rec_codec.data_r) ^ rec_codec.line ;
135
             end
136
             STOP  : begin
137
                rec_codec.framing_err <= #1 rec_codec.line == 1'b0 &&
138
                                         rec_codec.data_r[7:0] != 8'h00 ;
139
                rec_codec.break_err <= #1 rec_codec.data_r[7:0] == 8'h00 &&
140
                                       rec_codec.line == 1'b0 &&
141
                                       rec_codec.parity_err == 1'b0 ;
142
             end
143
             default : /* empty */ ;
144
           endcase // case (state)
145
      end // if (sample_en == 1'b1)
146
   end // always_ff @ (posedge clk, negedge nrst)
147
 
148
   always_ff @(posedge clk_i, negedge nrst_i) begin
149
      if(nrst_i == 1'b0)
150
        rec_buf_empty <= 1'b0 ;
151
      else if(next_state == IDLE || next_state == STOP)
152
        rec_buf_empty <= #1 1'b1 ;
153
      else
154
        rec_buf_empty <= #1 1'b0 ;
155
   end
156
 
157
   always_ff @(posedge clk_i, negedge nrst_i) begin
158
      if(nrst_i == 1'b0)
159
        rec_codec.start <= #1 1'b0 ;
160
      else if(rec_codec.state == START)
161
        rec_codec.start <= #1 1'b0 ;
162
      else if(leading_edge == 1'b1)
163
        rec_codec.start <= #1 1'b1 ;
164
      else
165
        rec_codec.start <= #1 rec_codec.start ;
166
   end
167
 
168
endmodule
169
 
170
/// END OF FILE ///

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.