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

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [XUPV5-LX110T_SoC/] [MIPS32-Pipelined-Hw/] [src/] [UART/] [uart_bootloader_v2.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ayersg
`timescale 1ns / 1ps
2
/*
3
 * File         : uart_bootloader_v2.v
4
 * Project      : University of Utah, XUM Project MIPS32 core
5
 * Creator(s)   : Grant Ayers (ayers@cs.utah.edu)
6
 *
7
 * Modification History:
8
 *   Rev   Date         Initials  Description of Change
9
 *   1.0   24-May-2010  GEA       Initial design of standalone bootloader
10
 *   2.0    7-Jul-2012  GEA       Added data memory bus to allow for general-purpose use.
11
 *
12
 * Standards/Formatting:
13
 *   Verilog 2001, 4 soft tab, wide column.
14
 *
15
 * Description:
16
 *   An RS-232 compatible UART coupled with the XUM bootloader.
17
 *
18
 *   The UART is general-purpose and capable of sending and receiving at a
19
 *   pre-determined BAUD rate (determined by the clocking module)
20
 *   with 8 data bits, 1 stop bit, and no parity. In other words it
21
 *   is 8N1 with only RxD and TxD signals. It uses two 256-byte FIFO
22
 *   buffers, one for receiving and the other for transmitting.
23
 *
24
 *   The XUM bootloader protocol is as follows:
25
 *
26
 *      1. Programmer sends 'XUM' ASCII bytes.
27
 *      2. Programmer sends a number indicating how many 32-bit data words
28
 *         it has to send, minus 1. (For example, if it has one 32-bit data word,
29
 *         this number would be 0.) The size of this number is 18 bits.
30
 *         This means the minimum transmission size is 1 word (32 bits), and
31
 *         the maximum transmission size is 262144 words, or exactly 1 MB.
32
 *         This 18-bit number is sent MSB first, in three bytes, with the six
33
 *         most-significant bits set to 0.
34
 *      3. The FPGA sends back the third size byte from the programmer, allowing
35
 *         the programmer to determine if the FPGA is listening and conforming
36
 *         to the XUM boot protocol.
37
 *      4. The programmer sends another 18-bit number indicating the starting
38
 *         offset in memory where the data should be placed. Normally this will
39
 *         be 0. This number is also sent in three bytes, and the six most-significant
40
 *         bits of the first byte are ignored.
41
 *      5. The programmer sends the data. A copy of each byte that it sends will be
42
 *         sent back to the programmer from the FPGA, allowing the programmer
43
 *         to determine if all of the data was transmitted successfully.
44
 *
45
 *   On reset, the bootloader is enabled by default. When the bootloader is enabled,
46
 *   the data memory bus will not see any incoming data. To configure the UART for
47
 *   general-purpose use, software must issue a write command to the UART
48
 *   over the data memory bus with bit 8 set. This disables the boot protocol until
49
 *   the UART is reset again and allows normal use. Note however that there is
50
 *   a 5-second guard time after reset during which the boot loader is
51
 *   enabled regardless of any software commands to disable it. After the 5 second
52
 *   time has lapsed after reset, the software state determines the operating mode
53
 *   of the UART.
54
 */
55
module uart_bootloader(
56
    input  clock,
57
    input  reset,
58
    input  Read,                // MMIO
59
    input  Write,               // MMIO
60
    input  [8:0] DataIn,        // MMIO
61
    output reg [16:0] DataOut,  // MMIO
62
    output Ack,                 // MMIO
63
    output DataReady,           // Can be used as an interrupt
64
    output BootResetCPU,        // XUM Boot Protocol: Reset CPU
65
    output BootWriteMem,        // XUM Boot Protocol: Write to CPU memory
66
    output reg [17:0] BootAddr, // XUM Boot Protocol
67
    output reg [31:0] BootData, // XUM Boot Protocol
68
    input RxD,                  // UART Rx Signal
69
    output TxD                  // UART Tx Signal
70
    );
71
 
72
    localparam [4:0]    IDLE=0, WRITE=1, READ=2, BUSW=3, XHEAD1=4, XHEAD2=5, XHEAD3=6, XSIZE1=7, XSIZE2=8, XSIZE3=9,
73
                        XOFST1=10, XOFST2=11, XOFST3=12, XDATA1=13, XDATA2=14, XDATA3=15, XDATA4=16, XADDRI=17;
74
 
75
    // UART module signals
76
    wire uart_write;
77
    reg  uart_read;
78
    wire uart_data_ready;
79
    wire [7:0] uart_data_in;
80
    wire [7:0] uart_data_out;
81
    wire [8:0] uart_rx_count;
82
 
83
    reg [8:0] DataIn_r;             // Latch for incoming data to improve timing
84
    wire DisableBoot = DataIn_r[8]; // Software boot disable command is bit 8
85
    reg [28:0] BootTimedEnable;     // Hardware override enabler for boot loader after reset
86
    reg  BootSwEnabled;             // Software enabled/disabled state of bootloader
87
    wire BootProtoEnabled;          // Master bootloader enabled signal
88
    reg [17:0] rx_count;            // Number of 32-bit words received (boot loader)
89
    reg [17:0] rx_size;             // Number of 32-bit words to expect (boot loader)
90
    reg  [4:0] state;
91
 
92
    always @(posedge clock) begin
93
        if (reset) begin
94
            state <= IDLE;
95
        end
96
        else begin
97
            case (state)
98
                IDLE:    begin
99
                            if      (Write)                              state <= WRITE;
100
                            else if (Read)                               state <= READ;
101
                            else if (BootProtoEnabled & uart_data_ready) state <= XHEAD1;
102
                            else                                         state <= IDLE;
103
                         end
104
                WRITE:   state <= BUSW;
105
                READ:    state <= BUSW;
106
                BUSW:    state <= ~(Read | Write) ? IDLE : BUSW;
107
                XHEAD1:  state <= (uart_data_out == 8'h58) ? XHEAD2 : IDLE;                                 // 'X'
108
                XHEAD2:  state <= (uart_data_ready) ? ((uart_data_out == 8'h55) ? XHEAD3 : IDLE) : XHEAD2;  // 'U'
109
                XHEAD3:  state <= (uart_data_ready) ? ((uart_data_out == 8'h4D) ? XSIZE1 : IDLE) : XHEAD3;  // 'M'
110
                XSIZE1:  state <= (uart_data_ready) ? ((uart_data_out[7:2] == 6'b000000) ? XSIZE2 : IDLE) : XSIZE1;
111
                XSIZE2:  state <= (uart_data_ready) ? XSIZE3 : XSIZE2;
112
                XSIZE3:  state <= (uart_data_ready) ? XOFST1 : XSIZE3;
113
                XOFST1:  state <= (uart_data_ready) ? XOFST2 : XOFST1;
114
                XOFST2:  state <= (uart_data_ready) ? XOFST3 : XOFST2;
115
                XOFST3:  state <= (uart_data_ready) ? XDATA1 : XOFST3;
116
                XDATA1:  state <= (uart_data_ready) ? XDATA2 : XDATA1;
117
                XDATA2:  state <= (uart_data_ready) ? XDATA3 : XDATA2;
118
                XDATA3:  state <= (uart_data_ready) ? XDATA4 : XDATA3;
119
                XDATA4:  state <= (uart_data_ready) ? XADDRI : XDATA4;
120
                XADDRI:  state <= (rx_count == rx_size) ? IDLE : XDATA1;
121
                default: state <= IDLE;
122
            endcase
123
        end
124
    end
125
 
126
    always @(*) begin
127
        case (state)
128
            IDLE:    uart_read <= 0;
129
            WRITE:   uart_read <= 0;
130
            READ:    uart_read <= 1;
131
            BUSW:    uart_read <= 0;
132
            XHEAD1:  uart_read <= uart_data_ready;
133
            XHEAD2:  uart_read <= uart_data_ready;
134
            XHEAD3:  uart_read <= uart_data_ready;
135
            XSIZE1:  uart_read <= uart_data_ready;
136
            XSIZE2:  uart_read <= uart_data_ready;
137
            XSIZE3:  uart_read <= uart_data_ready;
138
            XOFST1:  uart_read <= uart_data_ready;
139
            XOFST2:  uart_read <= uart_data_ready;
140
            XOFST3:  uart_read <= uart_data_ready;
141
            XDATA1:  uart_read <= uart_data_ready;
142
            XDATA2:  uart_read <= uart_data_ready;
143
            XDATA3:  uart_read <= uart_data_ready;
144
            XDATA4:  uart_read <= uart_data_ready;
145
            XADDRI:  uart_read <= 0;
146
            default: uart_read <= 0;
147
        endcase
148
    end
149
 
150
    always @(posedge clock) begin
151
        DataIn_r <= ((state == IDLE) & Write) ? DataIn : DataIn_r;
152
    end
153
 
154
    always @(posedge clock) begin
155
        DataOut <= (reset) ? 17'h00000 : ((state == READ) ? {uart_rx_count[8:0], uart_data_out[7:0]} : DataOut);
156
    end
157
 
158
    always @(posedge clock) begin
159
        BootTimedEnable <= (reset) ? 29'h00000000 : (BootTimedEnable != 29'h1dcd6500) ? BootTimedEnable + 1 : BootTimedEnable; // 5 sec @ 100 MHz
160
        BootSwEnabled <= (reset) ? 1 : ((state == WRITE) ? ~DisableBoot : BootSwEnabled);
161
    end
162
 
163
    assign BootResetCPU = (state != IDLE) && (state != WRITE) && (state != READ) && (state != BUSW) &&
164
                          (state != XHEAD1) && (state != XHEAD2) && (state != XHEAD3) && (state != XSIZE1);
165
    assign BootWriteMem = (state == XADDRI);
166
    assign uart_write   = ((state == WRITE) & ~DisableBoot) |
167
                          (uart_data_ready & ((state == XSIZE3) | (state == XDATA1) | (state == XDATA2) | (state == XDATA3) | (state == XDATA4)));
168
    assign uart_data_in = (state == WRITE) ? DataIn_r[7:0] : uart_data_out;
169
    assign Ack          = (state == BUSW);
170
    assign DataReady    = uart_data_ready;
171
    assign BootProtoEnabled = BootSwEnabled | (BootTimedEnable != 29'h1dcd6500);
172
 
173
 
174
    // XUM Boot Protocol Logic
175
    always @(posedge clock) begin
176
        BootData[31:24] <= (reset) ? 8'h00 : (((state == XDATA1) & uart_data_ready) ? uart_data_out : BootData[31:24]);
177
        BootData[23:16] <= (reset) ? 8'h00 : (((state == XDATA2) & uart_data_ready) ? uart_data_out : BootData[23:16]);
178
        BootData[15:8]  <= (reset) ? 8'h00 : (((state == XDATA3) & uart_data_ready) ? uart_data_out : BootData[15:8]);
179
        BootData[7:0]   <= (reset) ? 8'h00 : (((state == XDATA4) & uart_data_ready) ? uart_data_out : BootData[7:0]);
180
    end
181
 
182
    always @(posedge clock) begin
183
        if (reset) begin
184
            BootAddr <= 18'h00000;
185
        end
186
        else if (state == XADDRI) begin
187
            BootAddr <= BootAddr + 1;
188
        end
189
        else begin
190
            BootAddr[17:16] <= ((state == XOFST1) & uart_data_ready) ? uart_data_out[1:0] : BootAddr[17:16];
191
            BootAddr[15:8]  <= ((state == XOFST2) & uart_data_ready) ? uart_data_out[7:0] : BootAddr[15:8];
192
            BootAddr[7:0]   <= ((state == XOFST3) & uart_data_ready) ? uart_data_out[7:0] : BootAddr[7:0];
193
        end
194
    end
195
 
196
    always @(posedge clock) begin
197
        rx_count <= (state == IDLE) ? 18'h00000 : ((state == XADDRI) ? rx_count + 1 : rx_count);
198
    end
199
 
200
    always @(posedge clock) begin
201
        rx_size[17:16] <= (reset) ? 2'b00 : (((state == XSIZE1) & uart_data_ready) ? uart_data_out[1:0] : rx_size[17:16]);
202
        rx_size[15:8]  <= (reset) ? 8'h00 : (((state == XSIZE2) & uart_data_ready) ? uart_data_out[7:0] : rx_size[15:8]);
203
        rx_size[7:0]   <= (reset) ? 8'h00 : (((state == XSIZE3) & uart_data_ready) ? uart_data_out[7:0] : rx_size[7:0]);
204
    end
205
 
206
    // UART Driver
207
    uart_min UART (
208
        .clock       (clock),
209
        .reset       (reset),
210
        .write       (uart_write),
211
        .data_in     (uart_data_in),
212
        .read        (uart_read),
213
        .data_out    (uart_data_out),
214
        .data_ready  (uart_data_ready),
215
        .rx_count    (uart_rx_count),
216
        .RxD         (RxD),
217
        .TxD         (TxD)
218
    );
219
 
220
endmodule
221 3 ayersg
 

powered by: WebSVN 2.1.0

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