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_v1.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 ayersg
               `timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: Grant Ayers (ayers@cs.utah.edu)
5
// 
6
// Create Date:    09:59:05 05/24/2010 
7
// Design Name: 
8
// Module Name:    uart_bootloader 
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description:
13
//       Implements the XUM bootloader protocol over a serial port (115200 8N1).
14
//       The protocol is as follows:
15
//
16
//       1. Programmer sends 'XUM' ascii bytes
17
//       2. Programmer sends a number indicating how many 32-bit data words it
18
//          has to send, minus 1. (For example, if it has one 32-bit data word,
19
//          this number will be 0.) The size of this number is 18 bits.
20
//          This means the minimum transmission size is 1 word (32 bits), and
21
//          the maximum transmission size is 262144 words (exactly 1MB).
22
//          This 18-bit number is sent in three bytes, and the six most
23
//          significant bits of the first byte must be 0.
24
//       3. The FPGA sends back the third size byte from the programmer, allowing
25
//          the programmer to determine if the FPGA is listening and conforming
26
//          to the XUM boot protocol.
27
//       4. The programmer sends another 18-bit number indicating the starting
28
//          offset in memory where the data should be placed. Normally this will
29
//          be 0. This number is also sent in three bytes, and the six most
30
//          significant bits of the first byte are ignored.
31
//       5. The programmer sends the data. A copy of each byte that it sends will
32
//          be sent back to the programmer from the FPGA, allowing the programmer
33
//          to determine if all of the data was transmitted successfully.
34
//
35
// Dependencies: 
36
//
37
// Revision: 
38
// Revision 0.01 - File Created
39
// Additional Comments: 
40
//
41
//////////////////////////////////////////////////////////////////////////////////
42
module uart_bootloader(
43
   input clock,                  // 100Mhz
44
   input reset,                  // System-wide global reset
45
   input RxD,                    // UART data from computer
46
   output TxD,                   // UART data to computer
47
   output resetCPU,              // Reset CPUs' PCs to start execution at 0x0
48
   output reg writeMem = 0,      // Write command to instruction memory
49
   output reg [17:0] addrMem = 0, // address to instruction memory
50
   output reg [31:0] dataMem = 0 // 32-bit data words of instruction memory
51
   );
52
 
53
   localparam [3:0]  HEAD_1=0, HEAD_2=1, HEAD_3=2, SIZE_1=3, SIZE_2=4, SIZE_3=5, OFST_1=6, OFST_2=7,
54
                     OFST_3=8, ADDRSET=9, DATA_1=10, DATA_2=11, DATA_3=12, DATA_4=13, ADDRINC=14;
55
 
56
   /* UART Signals */
57
   reg uart_write = 0;
58
   reg uart_read = 0;
59
 
60
   wire [7:0] uart_rx_data;
61
   wire [7:0] uart_tx_data = uart_rx_data;
62
   wire uart_rx_data_ready;
63
 
64
   reg [17:0] size = 0;       // Number of 32-bit words to expect
65
   reg [17:0] offset = 0;     // Starting address to store words
66
   reg [17:0] rx_count = 0;   // Number of 32-bit words received so far
67
 
68
   reg [3:0] state = HEAD_1;
69
 
70
   // The CPU(s) is continuously reset while memory is being replaced.
71
   assign resetCPU = ((state!=HEAD_1) && (state!=HEAD_2) && (state!=HEAD_3) && (state!=SIZE_1));
72
 
73
   always @(posedge clock) begin
74
      if (reset) begin
75
         state <= HEAD_1;
76
         uart_read <= 0;
77
         uart_write <= 0;
78
         writeMem <= 0;
79
         rx_count <= 0;
80
      end
81
      else begin
82
         uart_read <= uart_rx_data_ready & ((state!=ADDRSET) && (state!=ADDRINC));
83
         uart_write <= uart_rx_data_ready & ((state==SIZE_3) || (state==DATA_1) || (state==DATA_2) || (state==DATA_3) || (state==DATA_4));
84
         writeMem <= uart_rx_data_ready & (state == DATA_4);
85
         rx_count <= (state == HEAD_1) ? 0 : ((state == ADDRINC) ? rx_count + 1 : rx_count);
86
         case (state)
87
            HEAD_1:  begin
88
                        if (uart_rx_data_ready) begin
89
                           state <= (uart_rx_data == 8'h58) ? HEAD_2 : HEAD_1;   // 'X'
90
                        end
91
                        else begin
92
                           state <= HEAD_1;
93
                        end
94
                     end
95
            HEAD_2:  begin
96
                        if (uart_rx_data_ready) begin
97
                           state <= (uart_rx_data == 8'h55) ? HEAD_3 : HEAD_1;   // 'U'
98
                        end
99
                        else begin
100
                           state <= HEAD_2;
101
                        end
102
                     end
103
            HEAD_3:  begin
104
                        if (uart_rx_data_ready) begin
105
                           state <= (uart_rx_data == 8'h4D) ? SIZE_1 : HEAD_1;   // 'M'
106
                        end
107
                        else begin
108
                           state <= HEAD_3;
109
                        end
110
                     end
111
            SIZE_1:  begin
112
                        if (uart_rx_data_ready) begin
113
                           state <= (uart_rx_data[7:2] == 6'b000000) ? SIZE_2 : HEAD_1;   // 6 leading 0s
114
                           size[17:16] <= uart_rx_data[1:0];
115
                        end
116
                        else begin
117
                           state <= SIZE_1;
118
                        end
119
                     end
120
            SIZE_2:  begin
121
                        state <= (uart_rx_data_ready) ? SIZE_3 : SIZE_2;
122
                        size[15:8] <= (uart_rx_data_ready) ? uart_rx_data : size[15:8];
123
                     end
124
            SIZE_3:  begin
125
                        state <= (uart_rx_data_ready) ? OFST_1 : SIZE_3;
126
                        size[7:0] <= (uart_rx_data_ready) ? uart_rx_data : size[7:0];
127
                     end
128
            OFST_1:  begin
129
                        state <= (uart_rx_data_ready) ? OFST_2 : OFST_1;
130
                        offset[17:16] <= (uart_rx_data_ready) ? uart_rx_data[1:0] : offset[17:16];
131
                     end
132
            OFST_2:  begin
133
                        state <= (uart_rx_data_ready) ? OFST_3 : OFST_2;
134
                        offset[15:8] <= (uart_rx_data_ready) ? uart_rx_data : offset[15:8];
135
                     end
136
            OFST_3:  begin
137
                        state <= (uart_rx_data_ready) ? ADDRSET : OFST_3;
138
                        offset[7:0] <= (uart_rx_data_ready) ? uart_rx_data : offset[7:0];
139
                     end
140
            ADDRSET: begin
141
                        state <= DATA_1;
142
                        addrMem <= offset;
143
                     end
144
            DATA_1:  begin
145
                        state <= (uart_rx_data_ready) ? DATA_2 : DATA_1;
146
                        dataMem[31:24] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[31:24];
147
                     end
148
            DATA_2:  begin
149
                        state <= (uart_rx_data_ready) ? DATA_3 : DATA_2;
150
                        dataMem[23:16] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[23:16];
151
                     end
152
            DATA_3:  begin
153
                        state <= (uart_rx_data_ready) ? DATA_4 : DATA_3;
154
                        dataMem[15:8] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[15:8];
155
                     end
156
            DATA_4:  begin
157
                        state <= (uart_rx_data_ready) ? ADDRINC : DATA_4;
158
                        dataMem[7:0] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[7:0];
159
                     end
160
            ADDRINC:   begin
161
                        addrMem <= addrMem + 1;
162
                        state <= (rx_count == size) ? HEAD_1 : DATA_1;
163
                     end
164
            default: state <= HEAD_1;
165
         endcase
166
      end
167
   end
168
 
169
 
170
   uart_min uart (
171
      .clock      (clock),
172
      .reset      (reset),
173
      .write      (uart_write),
174
      .data_in    (uart_tx_data),
175
      .read       (uart_read),
176
      .data_out   (uart_rx_data),
177
      .data_ready (uart_rx_data_ready),
178
      .RxD        (RxD),
179
      .TxD        (TxD)
180
   );
181
 
182
endmodule

powered by: WebSVN 2.1.0

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