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

Subversion Repositories darkriscv

[/] [darkriscv/] [trunk/] [rtl/] [darkuart.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcelos
/*
2
 * Copyright (c) 2018, Marcelo Samsoniuk
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * * Neither the name of the copyright holder nor the names of its
16
 *   contributors may be used to endorse or promote products derived from
17
 *   this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
 
31
`timescale 1ns / 1ps
32
`include "../rtl/config.vh"
33
 
34
// the following defines are automatically defined:
35
/*
36
`ifdef __ICARUS__
37
    `define SIMULATION 1
38
`endif
39
 
40
`ifdef XILINX_ISIM
41
    `define SIMULATION 2
42
`endif
43
 
44
`ifdef MODEL_TECH
45
    `define SIMULATION 3
46
`endif
47
 
48
`ifdef XILINX_SIMULATOR
49
    `define SIMULATION 4
50
`endif
51
*/
52
// uart states
53
 
54
`define UART_STATE_IDLE  6
55
`define UART_STATE_START 7
56
`define UART_STATE_DATA0 8
57
`define UART_STATE_DATA1 9
58
`define UART_STATE_DATA2 10
59
`define UART_STATE_DATA3 11
60
`define UART_STATE_DATA4 12
61
`define UART_STATE_DATA5 13
62
`define UART_STATE_DATA6 14
63
`define UART_STATE_DATA7 15
64
`define UART_STATE_STOP  0
65
`define UART_STATE_ACK   1
66
 
67
// UART registers
68
// 
69 6 marcelos
// 0: status register ro, 1 = xmit busy, 2 = recv bfusy
70 2 marcelos
// 1: buffer register rw, w = xmit fifo, r = recv fifo
71
// 2: baud rate msb   rw (not used)
72
// 3: baud rate lsb   rw (not used)
73
 
74
module darkuart
75
//#(
76
// parameter [15:0] BAUD = 0
77
//) 
78
(
79
    input           CLK,            // clock
80
    input           RES,            // reset
81
 
82
    input           RD,             // bus read
83
    input           WR,             // bus write
84
    input  [ 3:0]   BE,             // byte enable
85
    input  [31:0]   DATAI,          // data input
86
    output [31:0]   DATAO,          // data output
87
    output          IRQ,            // interrupt req
88
 
89
    input           RXD,            // UART recv line
90
    output          TXD,            // UART xmit line
91 4 marcelos
 
92
`ifdef SIMULATION
93
    output reg      FINISH_REQ = 0,
94
`endif
95 2 marcelos
 
96
    output [3:0]    DEBUG           // osc debug
97
);
98
 
99
    reg [15:0]  UART_TIMER = `__BAUD__;  // baud rate from config.vh
100
    reg         UART_IREQ  = 0;     // UART interrupt req
101
    reg         UART_IACK  = 0;     // UART interrupt ack
102
 
103 6 marcelos
`ifdef __UARTQUEUE__
104
    reg [ 7:0]  UART_XFIFO [0:255]; // UART TX FIFO
105
    wire [7:0]  UART_XTMP;          // UART TX FIFO
106
    reg [ 8:0]  UART_XREQ  = 0;     // xmit request (core side)
107
    reg [ 8:0]  UART_XACK  = 0;     // xmit ack (uart side)
108
`else
109 2 marcelos
    reg [ 7:0]  UART_XFIFO = 0;     // UART TX FIFO
110
    reg         UART_XREQ  = 0;     // xmit request (core side)
111
    reg         UART_XACK  = 0;     // xmit ack (uart side)
112 6 marcelos
`endif
113
    reg [15:0]  UART_XBAUD = 0;     // baud rate counter
114 2 marcelos
    reg [ 3:0]  UART_XSTATE= 0;     // idle state
115
 
116 6 marcelos
`ifdef __UARTQUEUE__
117
    reg [ 7:0]  UART_RFIFO [0:255]; // UART RX FIFO
118
    reg [ 7:0]  UART_RTMP  = 0;     // UART RX FIFO
119
    reg [ 8:0]  UART_RREQ  = 0;     // request (uart side)
120
    reg [ 8:0]  UART_RACK  = 0;     // ack (core side)
121
`else
122 2 marcelos
    reg [ 7:0]  UART_RFIFO = 0;     // UART RX FIFO
123
    reg         UART_RREQ  = 0;     // request (uart side)
124
    reg         UART_RACK  = 0;     // ack (core side)
125 6 marcelos
`endif
126
    reg [15:0]  UART_RBAUD = 0;     // baud rate counter
127 2 marcelos
    reg [ 3:0]  UART_RSTATE= 0;     // idle state
128
 
129
    reg [2:0]   UART_RXDFF = -1;
130
 
131 6 marcelos
`ifdef __UARTQUEUE__
132
    wire [7:0]  UART_STATE = { 6'd0, UART_RREQ!=UART_RACK, UART_XREQ==(UART_XACK^9'h100) };
133 2 marcelos
 
134 6 marcelos
    integer i;
135
 
136
    initial
137
    for(i=0;i!=256;i=i+1)
138
    begin
139
        UART_RFIFO[i] = 0;
140
        UART_XFIFO[i] = 0;
141
    end
142
`else
143
    wire [7:0]  UART_STATE = { 6'd0, UART_RREQ!=UART_RACK, UART_XREQ!=UART_XACK };
144
`endif
145 2 marcelos
    reg [7:0]   UART_STATEFF = 0;
146
 
147
    // bus interface
148
 
149
    reg [31:0] DATAOFF = 0;
150
 
151
    always@(posedge CLK)
152
    begin
153
        if(WR)
154
        begin
155
            if(BE[1])
156
            begin
157 6 marcelos
 
158 2 marcelos
`ifdef SIMULATION
159
                // print the UART output to console! :)
160
                if(DATAI[15:8]!=13) // remove the '\r'
161
                begin
162
                    $write("%c",DATAI[15:8]);
163
                end
164
 
165
                if(DATAI[15:8]=="#") // break point
166
                begin
167
                    $display("[checkpoint #]");
168
                    $stop();
169
                end
170
 
171
                if(DATAI[15:8]==">") // prompt '>'
172
                begin
173 4 marcelos
                    $display(" no UART input, end simulation request...");
174
                    FINISH_REQ <= 1;
175 2 marcelos
                end
176
`else
177 6 marcelos
    `ifdef __UARTQUEUE__
178
                if(UART_XREQ!=(UART_XACK^9'h100))
179
                begin
180
                    UART_XFIFO[UART_XREQ[7:0]] <= DATAI[15:8];
181
                    UART_XREQ <= UART_XREQ+1;
182
                end
183
    `else
184
                UART_XFIFO <= DATAI[15:8];
185 2 marcelos
                UART_XREQ <= !UART_XACK;    // activate UART!
186 6 marcelos
    `endif
187 2 marcelos
`endif
188
            end
189
            //if(BE[2]) UART_TIMER[ 7:0] <= DATAI[23:16];
190
            //if(BE[3]) UART_TIMER[15:8] <= DATAI[31:24];           
191
        end
192
 
193
        if(RES)
194
        begin
195
            UART_RACK <= UART_RREQ;
196
            UART_STATEFF <= UART_STATE;
197
        end
198
        else
199
        if(RD)
200
        begin
201 6 marcelos
`ifdef __UARTQUEUE__
202
            if(BE[1]) UART_RACK     <= UART_RACK!=UART_RREQ?UART_RACK+1:UART_RACK; // fifo ready
203
`else
204 2 marcelos
            if(BE[1]) UART_RACK     <= UART_RREQ; // fifo ready
205 6 marcelos
`endif
206 2 marcelos
            if(BE[0]) UART_STATEFF <= UART_STATE; // state update, clear irq
207
        end
208
    end
209
 
210
    assign IRQ   = |(UART_STATE^UART_STATEFF);
211 6 marcelos
`ifdef __UARTQUEUE__
212
    assign DATAO = { UART_TIMER, UART_RFIFO[UART_RACK[7:0]], UART_STATE };
213
`else
214 2 marcelos
    assign DATAO = { UART_TIMER, UART_RFIFO, UART_STATE };
215 6 marcelos
`endif
216 2 marcelos
 
217
    // xmit path: 6(IDLE), 7(START), 8, 9, 10, 11, 12, 13, 14, 15, 0(STOP), 1(ACK)
218
 
219
    always@(posedge CLK)
220
    begin
221
        UART_XBAUD <= UART_XSTATE==`UART_STATE_IDLE ? UART_TIMER :      // xbaud=timer
222
                      UART_XBAUD ? UART_XBAUD-1 : UART_TIMER;           // while() { while(xbaud--); xbaud=timer }
223
 
224
        UART_XSTATE <= RES||UART_XSTATE==`UART_STATE_ACK  ? `UART_STATE_IDLE :
225 6 marcelos
                            UART_XSTATE==`UART_STATE_IDLE ? UART_XSTATE+(UART_XREQ!=UART_XACK) :
226 2 marcelos
                                                            UART_XSTATE+(UART_XBAUD==0);
227 6 marcelos
`ifdef __UARTQUEUE__
228
        UART_XACK   <= RES ? UART_XREQ : UART_XSTATE==`UART_STATE_ACK && UART_XACK!=UART_XREQ  ? UART_XACK+1 : UART_XACK;
229
`else
230 2 marcelos
        UART_XACK   <= RES||UART_XSTATE==`UART_STATE_ACK  ? UART_XREQ : UART_XACK;
231 6 marcelos
`endif
232 2 marcelos
    end
233
 
234 6 marcelos
`ifdef __UARTQUEUE__
235
    assign UART_XTMP = UART_XFIFO[UART_XACK[7:0]];
236
 
237
    assign TXD = UART_XSTATE[3] ? UART_XTMP[UART_XSTATE[2:0]] : UART_XSTATE==`UART_STATE_START ? 0 : 1;
238
`else
239 2 marcelos
    assign TXD = UART_XSTATE[3] ? UART_XFIFO[UART_XSTATE[2:0]] : UART_XSTATE==`UART_STATE_START ? 0 : 1;
240 6 marcelos
`endif
241 2 marcelos
 
242
    // recv path: 6(IDLE), 7(START), 8, 9, 10, 11, 12, 13, 14, 15, 0(STOP), 1(ACK)
243
 
244
    always@(posedge CLK)
245
    begin
246
        UART_RXDFF <= (UART_RXDFF<<1)|RXD;
247
 
248
        UART_RBAUD <= UART_RSTATE==`UART_STATE_IDLE ? { 1'b0, UART_TIMER[15:1] } :    // rbaud=timer/2
249
                      UART_RBAUD ? UART_RBAUD-1 : UART_TIMER;               // while() { while(rbaud--); rbaud=timer }
250
 
251
 
252
        UART_RSTATE <= RES||UART_RSTATE==`UART_STATE_ACK  ? `UART_STATE_IDLE :
253
                            UART_RSTATE==`UART_STATE_IDLE ? UART_RSTATE+(UART_RXDFF[2:1]==2'b10) : // start bit detection
254
                                                            UART_RSTATE+(UART_RBAUD==0);
255
 
256 6 marcelos
`ifdef __UARTQUEUE__
257
        if(UART_RSTATE==`UART_STATE_ACK&&(UART_RREQ!=(UART_RACK^9'h100)))
258
        begin
259
            UART_RREQ <= UART_RREQ+1;
260
            UART_RFIFO[UART_RREQ[7:0]] <= UART_RTMP;
261
        end
262
`else
263 2 marcelos
        UART_RREQ <= UART_RSTATE==`UART_STATE_ACK ? !UART_RACK : UART_RREQ;
264 6 marcelos
`endif
265 2 marcelos
        if(UART_RSTATE[3])
266
        begin
267 6 marcelos
`ifdef __UARTQUEUE__
268
            UART_RTMP[UART_RSTATE[2:0]] <= UART_RXDFF[2];
269
`else
270 2 marcelos
            UART_RFIFO[UART_RSTATE[2:0]] <= UART_RXDFF[2];
271 6 marcelos
`endif
272 2 marcelos
        end
273
    end
274
 
275
    //debug
276
 
277
    assign DEBUG = { RXD, TXD, UART_XSTATE!=`UART_STATE_IDLE, UART_RSTATE!=`UART_STATE_IDLE };
278
 
279
endmodule

powered by: WebSVN 2.1.0

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