OpenCores
URL https://opencores.org/ocsvn/socgen/socgen/trunk

Subversion Repositories socgen

[/] [socgen/] [trunk/] [common/] [opencores.org/] [Testbench/] [bfms/] [uart_model/] [rtl/] [verilog/] [serial_rcvr] - Blame information for rev 131

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 131 jt_eaton
/**********************************************************************/
2
/*                                                                    */
3
/*             -------                                                */
4
/*            /   SOC  \                                              */
5
/*           /    GEN   \                                             */
6
/*          /     LIB    \                                            */
7
/*          ==============                                            */
8
/*          |            |                                            */
9
/*          |____________|                                            */
10
/*                                                                    */
11
/*  Generic model for a serial asynchronous receiver                  */
12
/*                                                                    */
13
/*  Author(s):                                                        */
14
/*      - John Eaton, jt_eaton@opencores.org                          */
15
/*                                                                    */
16
/**********************************************************************/
17
/*                                                                    */
18
/*    Copyright (C) <2010>                     */
19
/*                                                                    */
20
/*  This source file may be used and distributed without              */
21
/*  restriction provided that this copyright statement is not         */
22
/*  removed from the file and that any derivative work contains       */
23
/*  the original copyright notice and the associated disclaimer.      */
24
/*                                                                    */
25
/*  This source file is free software; you can redistribute it        */
26
/*  and/or modify it under the terms of the GNU Lesser General        */
27
/*  Public License as published by the Free Software Foundation;      */
28
/*  either version 2.1 of the License, or (at your option) any        */
29
/*  later version.                                                    */
30
/*                                                                    */
31
/*  This source is distributed in the hope that it will be            */
32
/*  useful, but WITHOUT ANY WARRANTY; without even the implied        */
33
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR           */
34
/*  PURPOSE.  See the GNU Lesser General Public License for more      */
35
/*  details.                                                          */
36
/*                                                                    */
37
/*  You should have received a copy of the GNU Lesser General         */
38
/*  Public License along with this source; if not, download it        */
39
/*  from http://www.opencores.org/lgpl.shtml                          */
40
/*                                                                    */
41
/**********************************************************************/
42
 
43
module
44
uart_model_serial_rcvr
45
#(parameter   WIDTH=8,           // Number of data bits
46
  parameter   SIZE=4             // binary size of shift_cnt, must be able to hold  WIDTH + 4 states
47
 )(
48
input  wire               clk,
49
input  wire               reset,
50
input  wire               edge_enable,                 // one pulse per bit time for 16 x data rate timing
51
input  wire               parity_enable,               // 0 = no parity bit sent, 1= parity bit sent
52
input  wire   [1:0]       parity_type,                 // 00= odd,01=even,10=force a 0,11= force a 1
53
input  wire               stop_value,                  // value out for stop bit
54
input  wire               ser_in,                      // from pad_ring
55
output  reg   [WIDTH-1:0] shift_buffer,
56
output  reg               stop_cnt,
57
output  reg               last_cnt,
58
output  reg               parity_calc,
59
output  reg               parity_samp,
60
output  reg               frame_err
61
 
62
);
63
 
64
reg           [SIZE-1:0]  shift_cnt;
65
 
66
//
67
//   shift_cnt controls the serial bit out
68
//
69
//   0           Start bit
70
//   1-> WIDTH   Data bit lsb first
71
//   WIDTH+1     Parity bit if enabled
72
//   2^SIZE-2    Second stop bit if enabled
73
//   2^SIZE-1    Last stop bit and idle
74
 
75
always@(posedge clk)
76
  if( reset )
77
    begin
78
    shift_cnt       <= {SIZE{1'b1}};
79
    last_cnt        <= 1'b0;
80
    end
81
  else
82
  if(!edge_enable)
83
    begin
84
    shift_cnt       <= shift_cnt;
85
    last_cnt        <= 1'b0;
86
    end
87
  else
88
  if(( shift_cnt ==  {SIZE{1'b1}}))
89
   begin
90
    shift_cnt       <= {SIZE{1'b0}};
91
    last_cnt        <= 1'b0;
92
   end
93
  else
94
  if ( shift_cnt == WIDTH)
95
    case( parity_enable )
96
      (1'b0):
97
        begin
98
        shift_cnt   <= {SIZE{1'b1}};
99
        last_cnt    <= 1'b1;
100
        end
101
 
102
      (1'b1):
103
        begin
104
        shift_cnt   <= shift_cnt + 1'b1;
105
        last_cnt    <= 1'b0;
106
        end
107
   endcase // case (parity_enable)
108
  else
109
  if ( shift_cnt == (WIDTH+1))
110
     begin
111
     shift_cnt      <= {SIZE{1'b1}};
112
     last_cnt       <= 1'b1;
113
     end
114
  else
115
     begin
116
     shift_cnt      <= shift_cnt + 1'b1;
117
     last_cnt       <= 1'b0;
118
     end
119
//
120
//
121
//   load shift_buffer during start_bit
122
//   shift down every bit
123
//
124
//
125
always@(posedge clk)
126
  if(reset)                                                        shift_buffer <= {WIDTH{1'b0}};
127
  else
128
  if(!edge_enable)                                                 shift_buffer <= shift_buffer;
129
  else
130
  if(shift_cnt == {SIZE{1'b1}})                                    shift_buffer <= {WIDTH{1'b0}};
131
  else
132
  if(shift_cnt <= WIDTH-1 )                                        shift_buffer <= {ser_in,shift_buffer[WIDTH-1:1]};
133
  else                                                             shift_buffer <= shift_buffer;
134
//
135
//
136
//   calculate parity on the fly
137
//   seed reg with 0 for odd and 1 for even
138
//   force reg to 0 or 1 if needed
139
//
140
always@(posedge clk)
141
  if(reset)                                                        parity_calc <= 1'b0;
142
  else
143
  if(!edge_enable)                                                 parity_calc <= parity_calc;
144
  else
145
  if(parity_type[1] || (shift_cnt == {SIZE{1'b1}}))                parity_calc <= parity_type[0];
146
  else
147
  if(shift_cnt <= WIDTH-1 )                                        parity_calc <= parity_calc ^ ser_in;
148
  else                                                             parity_calc <= parity_calc;
149
//
150
//   sample parity bit and hold it until next start bit
151
//
152
always@(posedge clk)
153
  if(reset)                                                        parity_samp <= 1'b0;
154
  else
155
  if(!edge_enable)                                                 parity_samp <= parity_samp;
156
  else
157
  if(shift_cnt == {SIZE{1'b1}})                                    parity_samp <= 1'b0;
158
  else
159
  if(shift_cnt == WIDTH  )                                         parity_samp <= ser_in;
160
  else                                                             parity_samp <= parity_samp;
161
//
162
//   check for stop bit error
163
//
164
always@(posedge clk)
165
  if(reset)                                                        frame_err <= 1'b0;
166
  else
167
  if(!edge_enable)                                                 frame_err <= frame_err;
168
  else
169
  if(shift_cnt == {SIZE{1'b1}})                                    frame_err <= 1'b0;
170
  else
171
  if(shift_cnt == WIDTH+1  )                                       frame_err <= ser_in ^ stop_value;
172
  else                                                             frame_err <= frame_err;
173
 
174
always@(*)
175
  if(  shift_cnt ==  {SIZE{1'b1}})                                 stop_cnt    = 1'b1;
176
  else                                                             stop_cnt    = 1'b0;
177
 
178
 
179
endmodule
180
 
181
 
182
 
183
 

powered by: WebSVN 2.1.0

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