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

Subversion Repositories rtfsimpleuart

[/] [rtfsimpleuart/] [trunk/] [rtl/] [verilog/] [rtfSimpleUart.v] - Blame information for rev 6

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

Line No. Rev Author Line
1 6 robfinch
/* ============================================================================
2
        2007,2011  Robert Finch
3
        robfinch@<remove>sympatico.ca
4
 
5
        rtfSimpleUart.v
6
                Basic uart with baud rate generator based on a harmonic
7
        frequency synthesizer.
8
 
9
    This source code is available for evaluation and validation purposes
10
    only. This copyright statement and disclaimer must remain present in
11
    the file.
12
 
13
 
14
        NO WARRANTY.
15
    THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
16
    EXPRESS OR IMPLIED. The user must assume the entire risk of using the
17
    Work.
18
 
19
    IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20
    INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
21
    THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
22
 
23
    IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
24
    IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
25
    REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
26
    LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
27
    AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
28
    LOSSES RELATING TO SUCH UNAUTHORIZED USE.
29
 
30
 
31
        To use:
32
 
33
        Set the pClkFreq parameter to the frequency of the system
34
        clock (clk_i). This can be done when the core is instanced.
35
 
36
    1) set the baud rate value in the clock multiplier
37
    registers (CM1,2,3). A default multiplier value may
38
    be specified using the pClkMul parameter, so it
39
    doesn't have to be programmed at run time. (Note the
40
    pBaud parameter may also be set, but it doesn't work
41
    in all cases due to arithmetic limitations).
42
    2) enable communication by activating the rts, and
43
    dtr signals in the modem control register. These
44
    signals are defaulted to be active on reset, so they
45
    may not need to be set. The pRts and pDtr parameters
46
    may be used to change the default setting.
47
    3) use interrupts or poll the status register to
48
    determine when to transmit or receive a byte of data
49
    4) read / write the transmit / recieve data buffer
50
    for communication.
51
 
52
    Notes:
53
        This core only supports a single transmission /
54
    reception format: 1 start, 8 data, and 1 stop bit (no
55
    parity).
56
        The baud rate generator uses a 24 bit harmonic
57
    frequency synthesizer. Compute the multiplier value
58
    as if a 32 bit value was needed, then take the upper
59
    24 bits of the value. (The number of significant bits
60
    in the value determine the minimum frequency
61
    resolution or the precision of the value).
62
 
63
                                baud rate * 16
64
        value = -----------------------
65
                        (clock frequency / 2^32)
66
 
67
                eg                      38400 * 16
68
                value = -----------------------
69
                                (28.63636MHz / 2^32)
70
 
71
                                = 92149557.65
72
                                = 057E1736 (hex)
73
 
74
 
75
                taking the upper 24 bits
76
                                top 24 = 057E17
77
                                                = 359959
78
 
79
                so the value needed to be programmed into the register
80
        for 38.4k baud is 57E17 (hex)
81
                eg      CM0 = 0 (not used)
82
                        CM1 = 17 hex
83
                        CM2 = 7E hex
84
                        CM3 = 05 hex
85
 
86
 
87
        Register Description
88
 
89
        reg
90
 
91
                TRB - transmit / receive buffer
92
                transmit / receive buffer
93
                write   - write to transmit buffer
94
                read    - read from receive buffer
95
 
96
        1       read only (RO)
97
                LS      - line status register
98
                bit 0 = receiver not empty, this bit is set if there is
99
                                any data available in the receiver fifo
100
                bit 1 = overrun, this bit is set if receiver overrun occurs
101
                bit 3 = framing error, this bit is set if there was a
102
                                framing error with the current byte in the receiver
103
                                buffer.
104
                bit 5 = transmitter not full, this bit is set if the transmitter
105
                                can accept more data
106
                bit 6 = transmitter empty, this bit is set if the transmitter is
107
                                completely empty
108
 
109
        2       MS      - modem status register (RO)
110
                writing to the modem status register clears the change
111
                indicators, which should clear a modem status interrupt
112
                bit 3 = change on dcd signal
113
                bit 4 = cts signal level
114
                bit 5 = dsr signal level
115
                bit 6 = ri signal level
116
                bit 7 = dcd signal level
117
 
118
        3       IS      - interrupt status register (RO)
119
                bit 0-4 = mailbox number
120
                bit 0,1 = 00
121
                bit 2-4 = encoded interrupt value
122
                bit 5-6 = not used, reserved
123
                bit 7 = 1 = interrupt pending, 0 = no interrupt
124
 
125
        4       IE      - interrupt enable register (RW)
126
                bit 0 = receive interrupt (data present)
127
                bit 1 = transmit interrupt (data empty)
128
                bit 3 = modem status (dcd) register change
129
                bit 5-7 = unused, reserved
130
 
131
        5       FF      - frame format register         (RW)
132
                this register doesn't do anything in the simpleUart
133
                but is reserved for compatiblity with the more
134
                advanced uart
135
 
136
        6       MC      - modem control register (RW)
137
                bit 0 = dtr signal level output
138
                bit 1 = rts signal level output
139
 
140
        7       - control register
141
                bit 0 = hardware flow control,
142
                        when this bit is set, the transmitter output is
143
                        controlled by the cts signal line automatically
144
 
145
 
146
                * Clock multiplier steps the 16xbaud clock frequency
147
                in increments of 1/2^32 of the clk_i input using a
148
                harmonic frequency synthesizer
149
                eg. to get a 9600 baud 16x clock (153.6 kHz) with a
150
                27.175 MHz clock input,
151
                value  = upper24(9600 * 16  / (27.175MHz / 2^32))
152
                Higher frequency baud rates will exhibit more jitter
153
                on the 16x clock, but this will mostly be masked by the
154
                16x clock factor.
155
 
156
        8       CM0     - Clock Multiplier byte 0 (RW)
157
                this is the least significant byte
158
                of the clock multiplier value
159
                this register is not used unless the clock
160
                multiplier is set to contain 32 bit values
161
 
162
        9       CM1 - Clock Multiplier byte 1   (RW)
163
                this is the third most significant byte
164
                of the clock multiplier value
165
                this register is not used unless the clock
166
                multiplier is set to contain 24 or 32 bit values
167
 
168
        10      CM2 - Clock Multiplier byte 2   (RW)
169
                this is the second most significant byte of the clock
170
                multiplier value
171
 
172
        11      CM3     - Clock Multiplier byte 3       (RW)
173
                this is the most significant byte of the multiplier value
174
 
175
        12      FC      - Fifo control register         (RW)
176
                this register doesnt' do anything in the simpleUart
177
                but is reserved for compatibility with the more
178
                advanced uart
179
 
180
        13-14   reserved registers
181
 
182
        15      SPR     - scratch pad register (RW)
183
 
184
 
185
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
186
        |WISHBONE Datasheet
187
        |WISHBONE SoC Architecture Specification, Revision B.3
188
        |
189
        |Description:                                           Specifications:
190
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191
        |General Description:                           simple UART core
192
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
193
        |Supported Cycles:                                      SLAVE,READ/WRITE
194
        |                                                                       SLAVE,BLOCK READ/WRITE
195
        |                                                                       SLAVE,RMW
196
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
197
        |Data port, size:                                       8 bit
198
        |Data port, granularity:                        8 bit
199
        |Data port, maximum operand size:       8 bit
200
        |Data transfer ordering:                        Undefined
201
        |Data transfer sequencing:                      Undefined
202
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203
        |Clock frequency constraints:           none
204
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205
        |Supported signal list and                      Signal Name             WISHBONE equiv.
206
        |cross reference to equivalent          ack_o                   ACK_O
207
        |WISHBONE signals                                       adr_i[3:0]              ADR_I()
208
        |                                                                       clk_i                   CLK_I
209
        |                                   rst_i           RST_I()
210
        |                                                                       dat_i(7:0)              DAT_I()
211
        |                                                                       dat_o(7:0)              DAT_O()
212
        |                                                                       cyc_i                   CYC_I
213
        |                                                                       stb_i                   STB_I
214
        |                                                                       we_i                    WE_I
215
        |
216
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
217
        |Special requirements:
218
        +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
219
 
220
 
221
        Ref. Spartan3 -4
222
        117 LUTs / 87 slices / 133 MHz
223
============================================================================ */
224
 
225
`define UART_TRB    4'd0    // transmit/receive buffer
226
`define UART_LS     4'd1    // line status register
227
`define UART_MS     4'd2    // modem status register
228
`define UART_IS         4'd3    // interrupt status register
229
`define UART_IER    4'd4    // interrupt enable
230
`define UART_FF     4'd5    // frame format register
231
`define UART_MC     4'd6    // modem control register
232
`define UART_CTRL       4'd7    // control register
233
`define UART_CLKM0      4'd8    // clock multiplier byte 0
234
`define UART_CLKM1      4'd9    // clock multiplier byte 1
235
`define UART_CLKM2      4'd10   // clock multiplier byte 2
236
`define UART_CLKM3      4'd11   // clock multiplier byte 3
237
`define UART_FC     4'd12   // fifo control register
238
 
239
module rtfSimpleUart(
240
        // WISHBONE Slave interface
241
        input rst_i,            // reset
242
        input clk_i,            // eg 100.7MHz
243
        input cyc_i,            // cycle valid
244
        input stb_i,            // strobe
245
        input we_i,                     // 1 = write
246
        input [31:0] adr_i,              // register address
247
        input [7:0] dat_i,               // data input bus
248
        output reg [7:0] dat_o,  // data output bus
249
        output ack_o,           // transfer acknowledge
250
        output vol_o,           // volatile register selected
251
        output irq_o,           // interrupt request
252
        //----------------
253
        input cts_ni,           // clear to send - active low - (flow control)
254
        output reg rts_no,      // request to send - active low - (flow control)
255
        input dsr_ni,           // data set ready - active low
256
        input dcd_ni,           // data carrier detect - active low
257
        output reg dtr_no,      // data terminal ready - active low
258
        input rxd_i,                    // serial data in
259
        output txd_o,                   // serial data out
260
        output data_present_o
261
);
262
parameter pClkFreq = 20000000;  // clock frequency in MHz
263
parameter pBaud = 19200;
264
parameter pClkMul = (4096 * pBaud) / (pClkFreq / 65536);
265
parameter pRts = 1;             // default to active
266
parameter pDtr = 1;
267
 
268
wire cs = cyc_i && stb_i && (adr_i[31:4]==28'hFFDC_0A0);
269
assign ack_o = cs;
270
assign vol_o = cs && adr_i[3:2]==2'b00;
271
 
272
//-------------------------------------------
273
// variables
274
reg [23:0] c;    // current count
275
reg [23:0] ck_mul;       // baud rate clock multiplier
276
wire tx_empty;
277
wire baud16;    // edge detector (active one cycle only!)
278
reg rx_present_ie;
279
reg tx_empty_ie;
280
reg dcd_ie;
281
reg hwfc;                       // hardware flow control enable
282
wire clear = cyc_i && stb_i && we_i && adr_i==4'd13;
283
wire frame_err;         // receiver char framing error
284
wire over_run;          // receiver over run
285
reg [1:0] ctsx;          // cts_ni sampling
286
reg [1:0] dcdx;
287
reg [1:0] dsrx;
288
wire dcd_chg = dcdx[1]^dcdx[0];
289
 
290
 
291
wire rxIRQ = data_present_o & rx_present_ie;
292
wire txIRQ = tx_empty & tx_empty_ie;
293
wire msIRQ = dcd_chg & dcd_ie;
294
 
295
assign irq_o =
296
          rxIRQ
297
        | txIRQ
298
        | msIRQ
299
        ;
300
 
301
wire [2:0] irqenc =
302
        rxIRQ ? 1 :
303
        txIRQ ? 3 :
304
        msIRQ ? 4 :
305
        0;
306
 
307
wire [7:0] rx_do;
308
wire txrx = cs && adr_i[3:0]==4'd0;
309
 
310
rtfSimpleUartRx uart_rx0(
311
        .rst_i(rst_i),
312
        .clk_i(clk_i),
313
        .cyc_i(cyc_i),
314
        .stb_i(stb_i),
315
        .cs_i(txrx),
316
        .we_i(we_i),
317
        .dat_o(rx_do),
318
        .baud16x_ce(baud16),
319
        .clear(clear),
320
        .rxd(rxd_i),
321
        .data_present(data_present_o),
322
        .frame_err(frame_err),
323
        .overrun(over_run)
324
);
325
 
326
rtfSimpleUartTx uart_tx0(
327
        .rst_i(rst_i),
328
        .clk_i(clk_i),
329
        .cyc_i(cyc_i),
330
        .stb_i(stb_i),
331
        .cs_i(txrx),
332
        .we_i(we_i),
333
        .dat_i(dat_i),
334
        .baud16x_ce(baud16),
335
        .cts(ctsx[1]|~hwfc),
336
        .txd(txd_o),
337
        .empty(tx_empty)
338
);
339
 
340
// mux the reg outputs
341
always @*
342
        if (cs) begin
343
                case(adr_i[3:0]) // synopsys full_case parallel_case
344
                `UART_MS:       dat_o <= {dcdx[1],1'b0,dsrx[1],ctsx[1],dcd_chg,3'b0};
345
                `UART_IS:       dat_o <= {irq_o, 2'b0, irqenc, 2'b0};
346
                `UART_LS:       dat_o <= {1'b0, tx_empty, tx_empty, 1'b0, frame_err, 1'b0, over_run, data_present_o};
347
                default:        dat_o <= rx_do;
348
                endcase
349
        end
350
        else
351
                dat_o <= 8'b0;
352
 
353
// Note: baud clock should pulse high for only a single
354
// cycle!
355
always @(posedge clk_i)
356
        if (rst_i)
357
                c <= 0;
358
        else
359
                c <= c + ck_mul;
360
 
361
// for detecting an edge on the msb
362
edge_det ed0(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(c[23]), .pe(baud16), .ne(), .ee() );
363
 
364
// register updates
365
always @(posedge clk_i) begin
366
        if (rst_i) begin
367
                rts_no <= ~pRts;
368
                rx_present_ie <= 1'b0;
369
                tx_empty_ie <= 1'b0;
370
                dcd_ie <= 1'b0;
371
                hwfc <= 1'b1;
372
                dtr_no <= ~pDtr;
373
                ck_mul <= pClkMul;
374
        end
375
        else if (cs & we_i) begin
376
                case (adr_i)
377
                `UART_IER:
378
                                begin
379
                                rx_present_ie <= dat_i[0];
380
                                tx_empty_ie <= dat_i[1];
381
                                dcd_ie <= dat_i[3];
382
                                end
383
                `UART_MC:
384
                                begin
385
                                dtr_no <= ~dat_i[0];
386
                                rts_no <= ~dat_i[1];
387
                                end
388
                `UART_CTRL:             hwfc <= dat_i[0];
389
                `UART_CLKM1:    ck_mul[7:0] <= dat_i;
390
                `UART_CLKM2:    ck_mul[15:8] <= dat_i;
391
                `UART_CLKM3:    ck_mul[23:16] <= dat_i;
392
                default:
393
                        ;
394
                endcase
395
        end
396
end
397
 
398
 
399
// synchronize external signals
400
always @(posedge clk_i)
401
        ctsx <= {ctsx[0],~cts_ni};
402
 
403
always @(posedge clk_i)
404
        dcdx <= {dcdx[0],~dcd_ni};
405
 
406
always @(posedge clk_i)
407
        dsrx <= {dsrx[0],~dsr_ni};
408
 
409
endmodule
410
 

powered by: WebSVN 2.1.0

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