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

Subversion Repositories 8051

[/] [8051/] [trunk/] [rtl/] [verilog/] [oc8051_uart.v] - Blame information for rev 46

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 46 simont
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  8051 cores serial interface                                 ////
4
////                                                              ////
5
////  This file is part of the 8051 cores project                 ////
6
////  http://www.opencores.org/cores/8051/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////   uart for 8051 core                                         ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   Nothing                                                    ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Simon Teran, simont@opencores.org                     ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//
44
// CVS Revision History
45
//
46
// $Log: not supported by cvs2svn $
47
//
48
 
49
// synopsys translate_off
50
`include "oc8051_timescale.v"
51
// synopsys translate_on
52
 
53
`include "oc8051_defines.v"
54
 
55
module oc8051_uart (rst, clk, bit_in, rd_addr, data_in, bit_out, wr, wr_bit, wr_addr, data_out,
56
                   rxd, txd, intr, t1_ow);
57
 
58
input rst, clk, bit_in, wr, rxd, wr_bit, t1_ow;
59
input [7:0] rd_addr, data_in, wr_addr;
60
 
61
output txd, intr, bit_out;
62
output [7:0] data_out;
63
 
64
reg txd, bit_out;
65
reg [7:0] data_out;
66
 
67
reg tr_start, trans, trans_buf, t1_ow_buf;
68
reg [5:0] smod_cnt_r, smod_cnt_t;
69
reg receive, receive_buf, rxd_buf, r_int;
70
//
71
reg [7:0] sbuf_rxd, sbuf_txd, scon, pcon;
72
reg [10:0] sbuf_rxd_tmp;
73
//
74
//tr_count      trancive counter
75
//re_count      receive counter
76
reg [3:0] tr_count, re_count, re_count_buff;
77
 
78
 
79
assign intr = scon[1] | scon [0];
80
 
81
//
82
//serial port control register
83
//
84
always @(posedge clk or posedge rst)
85
begin
86
  if (rst)
87
    scon <= #1 `OC8051_RST_SCON;
88
  else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_SCON))
89
    scon <= #1 data_in;
90
  else if ((wr) & (wr_bit) & (wr_addr[7:3]==`OC8051_SFR_B_SCON))
91
    scon[wr_addr[2:0]] <= #1 bit_in;
92
  else if ((trans_buf) & !(trans))
93
    scon[1] <= #1 1'b1;
94
  else if ((receive_buf) & !(receive) & !(sbuf_rxd_tmp[0])) begin
95
    case (scon[7:6])
96
      2'b00: scon[0] <= #1 1'b1;
97
      default: begin
98
        if ((sbuf_rxd_tmp[9]) | !(scon[5])) scon[0] <= #1 1'b1;
99
        scon[2] <= #1 sbuf_rxd_tmp[9];
100
      end
101
    endcase
102
  end
103
 
104
end
105
 
106
//
107
//serial port buffer (transmit)
108
//
109
always @(posedge clk or posedge rst)
110
begin
111
  if (rst) begin
112
    sbuf_txd <= #1 `OC8051_RST_SBUF;
113
    tr_start <= #1 1'b0;
114
  end else if ((wr_addr==`OC8051_SFR_SBUF) & (wr) & !(wr_bit)) begin
115
    sbuf_txd <= #1 data_in;
116
    tr_start <= #1 1'b1;
117
  end else tr_start <= #1 1'b0;
118
end
119
 
120
//
121
// transmit
122
//
123
always @(posedge clk or posedge rst)
124
begin
125
  if (rst) begin
126
    txd <= #1 1'b1;
127
    tr_count <= #1 4'd0;
128
    trans <= #1 1'b0;
129
    smod_cnt_t <= #1 6'h0;
130
//
131
// start transmiting
132
//
133
  end else if (tr_start) begin
134
    case (scon[7:6])
135
      2'b00: begin  // mode 0
136
        txd <= #1 sbuf_txd[0];
137
        tr_count <= #1 4'd1;
138
      end
139
      2'b10: begin
140
        txd <= #1 1'b0;
141
        tr_count <= #1 4'd0;
142
      end
143
      default: begin  // mode 1 and mode 3
144
        tr_count <= #1 4'b1111;
145
      end
146
    endcase
147
    trans <= #1 1'b1;
148
    smod_cnt_t <= #1 6'h0;
149
//
150
// transmiting/
151
//
152
  end else if (trans)
153
  begin
154
    case (scon[7:6])
155
      2'b00: begin //mode 0
156
        if (smod_cnt_t == 6'd12) begin
157
          if (tr_count==4'd8)
158
          begin
159
                  trans <= #1 1'b0;
160
                  txd <= #1 1'b1;
161
                end else begin
162
            txd <= #1 sbuf_txd[tr_count];
163
                  tr_count <= #1 tr_count + 4'b1;
164
                end
165
          smod_cnt_t <= #1 6'h0;
166
              end else smod_cnt_t <= #1 smod_cnt_t + 6'h01;
167
      end
168
      2'b01: begin // mode 1
169
        if ((t1_ow) & !(t1_ow_buf))
170
        begin
171
                if (((pcon[7]) &  (smod_cnt_t == 6'd15))| (!(pcon[7]) & (smod_cnt_t==6'd31)))
172
                begin
173
            case (tr_count)
174
              4'd8: txd <= #1 1'b1;  // stop bit
175
                    4'd9: trans <= #1 1'b0;
176
                    4'b1111: txd <= #1 1'b0; //start bit
177
                    default: txd <= #1 sbuf_txd[tr_count];
178
                  endcase
179
            tr_count <= #1 tr_count + 4'b1;
180
                  smod_cnt_t <= #1 6'h0;
181
                end else smod_cnt_t <= #1 smod_cnt_t + 6'h01;
182
              end
183
      end
184
      2'b10: begin // mode 2
185
//
186
// if smod (pcon[7]) is 1 count to 4 else count to 6
187
//
188
        if (((pcon[7]) & (smod_cnt_t==6'd31)) | (!(pcon[7]) & (smod_cnt_t==6'd63))) begin
189
            case (tr_count)
190
            4'd8: begin
191
                    txd <= #1 scon[3];
192
                  end
193
            4'd9: begin
194
                    txd <= #1 1'b1; //stop bit
195
                  end
196
            4'd10: begin
197
                    trans <= #1 1'b0;
198
                  end
199
 
200
                  default: begin
201
                    txd <= #1 sbuf_txd[tr_count];
202
                  end
203
                endcase
204
          tr_count <= #1 tr_count+1'b1;
205
                smod_cnt_t <= #1 6'h00;
206
              end else begin
207
          smod_cnt_t <= #1 smod_cnt_t + 6'h01;
208
              end
209
      end
210
      default: begin // mode 3
211
        if ((t1_ow) & !(t1_ow_buf))
212
        begin
213
      if (((pcon[7]) &  (smod_cnt_t == 6'd15))| (!(pcon[7]) & (smod_cnt_t==6'd31)))
214
          begin
215
            case (tr_count)
216
              4'd8: begin
217
                txd <= #1 scon[3];
218
              end
219
              4'd9: begin
220
                txd <= #1 1'b1; //stop bit
221
              end
222
              4'd10: begin
223
          trans <= #1 1'b0;
224
        end
225
              4'b1111: txd <= #1 1'b0; //start bit
226
              default: begin
227
                txd <= #1 sbuf_txd[tr_count];
228
              end
229
            endcase
230
            tr_count <= #1 tr_count+1'b1;
231
            smod_cnt_t <= #1 6'h00;
232
          end else smod_cnt_t <= #1 smod_cnt_t + 6'h01;
233
        end
234
      end
235
    endcase
236
  end else
237
    txd <= #1 1'b1;
238
end
239
 
240
//
241
//power control register
242
//
243
always @(posedge clk or posedge rst)
244
begin
245
  if (rst)
246
  begin
247
    pcon <= #1 `OC8051_RST_PCON;
248
  end else if ((wr_addr==`OC8051_SFR_PCON) & (wr) & !(wr_bit))
249
    pcon <= #1 data_in;
250
end
251
 
252
//
253
//serial port buffer (receive)
254
//
255
always @(posedge clk or posedge rst)
256
begin
257
  if (rst) begin
258
    re_count <= #1 4'd0;
259
    receive <= #1 1'b0;
260
    sbuf_rxd <= #1 8'h00;
261
    sbuf_rxd_tmp <= #1 11'd0;
262
    smod_cnt_r <= #1 6'h00;
263
    r_int <= #1 1'b0;
264
  end else if (receive) begin
265
    case (scon[7:6])
266
      2'b00: begin // mode 0
267
        if (smod_cnt_r==6'd12) begin
268
          if (re_count==4'd8) begin
269
                  receive <= #1 1'b0;
270
                  r_int <= #1 1'b1;
271
                  sbuf_rxd <= #1 sbuf_rxd_tmp[8:1];
272
              end else begin
273
            sbuf_rxd_tmp[re_count + 4'd1] <= #1 rxd;
274
                  r_int <= #1 1'b0;
275
                end
276
          re_count <= #1 re_count + 4'd1;
277
          smod_cnt_r <= #1 6'h00;
278
        end else smod_cnt_r <= #1 smod_cnt_r + 6'h01;
279
      end
280
      2'b01: begin // mode 1
281
        if ((t1_ow) & !(t1_ow_buf))
282
        begin
283
          if (((pcon[7]) &  (smod_cnt_r == 6'd15))| (!(pcon[7]) & (smod_cnt_r==6'd31)))
284
                begin
285
            r_int <= #1 1'b0;
286
            re_count <= #1 re_count + 4'd1;
287
            smod_cnt_r <= #1 6'h00;
288
            sbuf_rxd_tmp[re_count_buff] <= #1 rxd;
289
            if ((re_count==4'd0) && (rxd))
290
              receive <= #1 1'b0;
291
 
292
                end else smod_cnt_r <= #1 smod_cnt_r + 6'h01;
293
              end else begin
294
              r_int <= #1 1'b1;
295
            if (re_count == 4'd10)
296
          begin
297
              sbuf_rxd <= #1 sbuf_rxd_tmp[8:1];
298
            receive <= #1 1'b0;
299
              r_int <= #1 1'b1;
300
          end else r_int <= #1 1'b0;
301
        end
302
      end
303
      2'b10: begin // mode 2
304
        if (((pcon[7]) & (smod_cnt_r==6'd31)) | (!(pcon[7]) & (smod_cnt_r==6'd63))) begin
305
          r_int <= #1 1'b0;
306
            re_count <= #1 re_count + 4'd1;
307
          smod_cnt_r <= #1 6'h00;
308
          sbuf_rxd_tmp[re_count_buff] <= #1 rxd;
309
          re_count <= #1 re_count + 4'd1;
310
              end else begin
311
          smod_cnt_r <= #1 smod_cnt_r + 6'h1;
312
                if (re_count==4'd11) begin
313
                  sbuf_rxd <= #1 sbuf_rxd_tmp[8:1];
314
                  r_int <= #1 sbuf_rxd_tmp[0] | !scon[5];
315
                  receive <= #1 1'b0;
316
                end else
317
                  r_int <= #1 1'b0;
318
        end
319
      end
320
      default: begin // mode 3
321
        if ((t1_ow) & !(t1_ow_buf))
322
        begin
323
          if (((pcon[7]) &  (smod_cnt_r == 6'd15))| (!(pcon[7]) & (smod_cnt_r==6'd31)))
324
                begin
325
            sbuf_rxd_tmp[re_count] <= #1 rxd;
326
                  r_int <= #1 1'b0;
327
                re_count <= #1 re_count + 4'd1;
328
                  smod_cnt_r <= #1 6'h00;
329
                end else smod_cnt_r <= #1 smod_cnt_r + 6'h01;
330
              end else begin
331
          if (re_count==4'd11) begin
332
            sbuf_rxd <= #1 sbuf_rxd_tmp[8:1];
333
            receive <= #1 1'b0;
334
                  r_int <= #1 sbuf_rxd_tmp[0] | !scon[5];
335
                end else begin
336
            r_int <= #1 1'b0;
337
          end
338
              end
339
      end
340
    endcase
341
  end else begin
342
    case (scon[7:6])
343
      2'b00: begin
344
        if ((scon[4]) && !(scon[0]) && !(r_int)) begin
345
          receive <= #1 1'b1;
346
          smod_cnt_r <= #1 6'h6;
347
        end
348
      end
349
      2'b10: begin
350
        if ((scon[4]) && !(rxd)) begin
351
          receive <= #1 1'b1;
352
          if (pcon[7])
353
            smod_cnt_r <= #1 6'd15;
354
          else smod_cnt_r <= #1 6'd31;
355
        end
356
      end
357
      default: begin
358
        if ((scon[4]) && (!rxd)) begin
359
          if (pcon[7])
360
            smod_cnt_r <= #1 6'd7;
361
          else smod_cnt_r <= #1 6'd15;
362
          receive <= #1 1'b1;
363
        end
364
      end
365
    endcase
366
 
367
    sbuf_rxd_tmp <= #1 11'd0;
368
    re_count <= #1 4'd0;
369
    r_int <= #1 1'b0;
370
  end
371
end
372
 
373
//
374
//
375
//
376
always @(posedge clk or posedge rst)
377
begin
378
  if (rst) data_out <= #1 8'h0;
379
  else if (wr & !wr_bit & (wr_addr==rd_addr) & ((wr_addr==`OC8051_SFR_PCON) |
380
     (wr_addr==`OC8051_SFR_SCON))) begin
381
    data_out <= #1 data_in;
382
  end else begin
383
    case (rd_addr)
384
      `OC8051_SFR_SBUF: data_out <= #1 sbuf_rxd;
385
      `OC8051_SFR_PCON: data_out <= #1 pcon;
386
      default: data_out <= #1 scon;
387
    endcase
388
  end
389
end
390
 
391
 
392
always @(posedge clk or posedge rst)
393
begin
394
  if (rst) begin
395
    trans_buf <= #1 1'b0;
396
    receive_buf <= #1 1'b0;
397
    t1_ow_buf <= #1 1'b0;
398
    rxd_buf <= #1 1'b0;
399
  end else begin
400
    trans_buf <= #1 trans;
401
    receive_buf <= #1 receive;
402
    t1_ow_buf <= #1 t1_ow;
403
    rxd_buf <= #1 rxd;
404
  end
405
end
406
 
407
always  @(posedge clk or posedge rst)
408
begin
409
  if (rst) bit_out <= #1 1'b0;
410
  else if (wr & wr_bit & (rd_addr==wr_addr) & (wr_addr[7:3]==`OC8051_SFR_B_SCON)) begin
411
    bit_out <= #1 bit_in;
412
  end else
413
    bit_out <= #1 scon[rd_addr[2:0]];
414
end
415
 
416
always @(posedge clk or posedge rst)
417
  if (rst)
418
    re_count_buff <= #1 4'h4;
419
  else re_count_buff <= #1 re_count;
420
 
421
endmodule
422
 

powered by: WebSVN 2.1.0

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