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

Subversion Repositories socgen

[/] [socgen/] [trunk/] [common/] [opencores.org/] [cde/] [ip/] [serial/] [rtl/] [verilog/] [serial_rcvr.v] - Blame information for rev 131

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 131 jt_eaton
module
2
cde_serial_rcvr
3
#(parameter   WIDTH=8,           // Number of data bits
4
  parameter   SIZE=4,             // binary size of shift_cnt, must be able to hold  WIDTH + 4 states
5
  parameter   BREAK=0,             // 1 enables break_detect
6
  parameter   STOP_VALUE=1             // stop bit level
7
  //        
8
 )(
9
input  wire               clk,
10
input  wire               reset,
11
input  wire               edge_enable,                 // one pulse per bit time for 16 x data rate timing
12
input  wire               parity_enable,               // 0 = no parity bit sent, 1= parity bit sent
13
input  wire               parity_type,                 // 0= odd,1=even
14
input  wire               parity_force,                // 1=force to parity_type
15
input  wire               ser_in,                      // from pad_ring
16
output  reg   [WIDTH-1:0] shift_buffer,
17
output  reg               stop_cnt,
18
output  reg               last_cnt,
19
output  reg               parity_calc,
20
output  reg               parity_samp,
21
output  reg               frame_err,
22
output  reg               break_detect
23
 
24
);
25
 
26
reg           [SIZE-1:0]  shift_cnt;
27
 
28
 
29
 
30
 
31
 
32
//
33
//   shift_cnt controls the serial bit out
34
//  
35
//   0           Start bit  
36
//   1-> WIDTH   Data bit lsb first
37
//   WIDTH+1     Parity bit if enabled
38
//   2^SIZE-1    Last stop bit and idle
39
 
40
always@(posedge clk)
41
  if( break_detect)
42
    begin
43
    shift_cnt       <= {SIZE{1'b1}};
44
    last_cnt        <= 1'b0;
45
    end
46
  else
47
  if(!edge_enable)
48
    begin
49
    shift_cnt       <= shift_cnt;
50
    last_cnt        <= 1'b0;
51
    end
52
  else
53
  if(( shift_cnt ==  {SIZE{1'b1}}))
54
   begin
55
    shift_cnt       <= {SIZE{1'b0}};
56
    last_cnt        <= 1'b0;
57
   end
58
  else
59
  if ( shift_cnt == WIDTH)
60
    case( parity_enable )
61
      (1'b0):
62
        begin
63
        shift_cnt   <= {SIZE{1'b1}};
64
        last_cnt    <= 1'b1;
65
        end
66
 
67
      (1'b1):
68
        begin
69
        shift_cnt   <= shift_cnt + 1'b1;
70
        last_cnt    <= 1'b0;
71
        end
72
   endcase // case (parity_enable)
73
  else
74
  if ( shift_cnt == (WIDTH+1))
75
     begin
76
     shift_cnt      <= {SIZE{1'b1}};
77
     last_cnt       <= 1'b1;
78
     end
79
  else
80
     begin
81
     shift_cnt      <= shift_cnt + 1'b1;
82
     last_cnt       <= 1'b0;
83
     end
84
//
85
//
86
//   load shift_buffer during start_bit
87
//   shift down every bit
88
//   
89
//   
90
always@(posedge clk)
91
  if(reset)                                                        shift_buffer <= {WIDTH{1'b0}};
92
  else
93
  if(!edge_enable)                                                 shift_buffer <= shift_buffer;
94
  else
95
  if(shift_cnt == {SIZE{1'b1}})                                    shift_buffer <= {WIDTH{1'b0}};
96
  else
97
  if(shift_cnt <= WIDTH-1 )                                        shift_buffer <= {ser_in,shift_buffer[WIDTH-1:1]};
98
  else                                                             shift_buffer <= shift_buffer;
99
//
100
//
101
//   calculate parity on the fly
102
//   seed reg with 0 for odd and 1 for even
103
//   force reg to 0 or 1 if needed  
104
//   
105
always@(posedge clk)
106
  if(reset)                                                        parity_calc <= 1'b0;
107
  else
108
  if(!edge_enable)                                                 parity_calc <= parity_calc;
109
  else
110
  if(parity_force || (shift_cnt == {SIZE{1'b1}}))                  parity_calc <= parity_type;
111
  else
112
  if(shift_cnt <= WIDTH-1 )                                        parity_calc <= parity_calc ^ ser_in;
113
  else                                                             parity_calc <= parity_calc;
114
//   
115
//   sample parity bit and hold it until next start bit
116
//   
117
always@(posedge clk)
118
  if(reset)                                                        parity_samp <= 1'b0;
119
  else
120
  if(!edge_enable)                                                 parity_samp <= parity_samp;
121
  else
122
  if(shift_cnt == {SIZE{1'b1}})                                    parity_samp <= 1'b0;
123
  else
124
  if(shift_cnt == WIDTH  )                                         parity_samp <= ser_in;
125
  else                                                             parity_samp <= parity_samp;
126
//   
127
//   check for stop bit error
128
//   
129
always@(posedge clk)
130
  if(reset)                                                        frame_err <= 1'b0;
131
  else
132
  if(!edge_enable)                                                 frame_err <= frame_err;
133
  else
134
  if(shift_cnt == {SIZE{1'b1}})                                    frame_err <= 1'b0;
135
  else
136
    begin
137
    case( parity_enable )
138
      (1'b0):
139
        begin
140
        if(shift_cnt == WIDTH    )                                       frame_err <= ser_in ^ STOP_VALUE;
141
        else                                                             frame_err <= frame_err;
142
        end
143
 
144
      (1'b1):
145
        begin
146
        if(shift_cnt == WIDTH+1  )                                       frame_err <= ser_in ^ STOP_VALUE;
147
        else                                                             frame_err <= frame_err;
148
        end
149
    endcase // case (parity_enable)
150
    end
151
 
152
 
153
 
154
 
155
 
156
 
157
 
158
 
159
 
160
 
161
//   
162
//   create break_detect
163
//   
164
always@(posedge clk)
165
  if(reset)                                                        break_detect  <= 1'b1;
166
  else
167
  if(BREAK)
168
    begin
169
    if(!break_detect)                                              break_detect  <= last_cnt && (ser_in ^ STOP_VALUE);
170
    else                                                           break_detect  <= (ser_in ^ STOP_VALUE);
171
    end
172
  else
173
    begin
174
                                                                   break_detect  <= 1'b0;
175
    end
176
 
177
 
178
 
179
 
180
 
181
always@(*)
182
  if(  shift_cnt ==  {SIZE{1'b1}})                                 stop_cnt   = 1'b1;
183
  else                                                             stop_cnt   = 1'b0;
184
 
185
 
186
endmodule
187
 
188
 
189
 

powered by: WebSVN 2.1.0

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