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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [rtl/] [wbicapetwo.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 3 dgisselq
///////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbicapetwo.v
4
//
5
// Project:     Wishbone to ICAPE2 interface conversion
6
//
7
// Purpose:     This routine maps the configuration registers of a 7-series
8
//              Xilinx part onto register addresses on a wishbone bus interface
9
//              via the ICAPE2 access port to those parts.  The big thing this
10
//              captures is the timing and handshaking required to read and
11
//              write registers from the configuration interface.
12
//
13
//              As an example of what can be done, writing a 32'h00f to
14
//              local address 5'h4 sends the IPROG command to the FPGA, causing
15
//              it to immediately reconfigure itself.
16
//
17
//              As another example, the warm boot start address is located
18
//              in register 5'h10.  Writing to this address, followed by
19
//              issuing the IPROG command just mentioned will cause the
20
//              FPGA to configure from that warm boot start address.
21
// 
22
//              For more details on the configuration interface, the registers
23
//              in question, their meanings and what they do, please see
24
//              User's Guide 470, the "7 Series FPGAs Configuration" User
25
//              Guide.
26
//
27
// Notes:       This module supports both reads and writes from the ICAPE2
28
//              interface.  These follow the following pattern.
29
//
30
//      For writes:
31
//              (Idle)  0xffffffff      (Dummy)
32
//              (CS/W)  0x20000000      NOOP
33
//              (CS/W)  0xaa995566      SYNC WORD
34
//              (CS/W)  0x20000000      NOOP
35
//              (CS/W)  0x20000000      NOOP
36
//              (CS/W)  ...             Write command
37
//              (CS/W)  ...             Write value, from Wishbone bus
38
//              (CS/W)  0x20000000      NOOP
39
//              (CS/W)  0x20000000      NOOP
40
//              (CS/W)  0x30008001      Write to CMD register (address 4)
41
//              (CS/W)  0x0000000d      DESYNC command
42
//              (CS/W)  0x20000000      NOOP
43
//              (CS/W)  0x20000000      NOOP
44
//              (Idle)
45
//
46
//      and for reads:
47
//              (Idle)  0xffffffff      (Dummy)
48
//              (CS/W)  0x20000000      NOOP
49
//              (CS/W)  0xaa995566      SYNC WORD
50
//              (CS/W)  0x20000000      NOOP
51
//              (CS/W)  0x20000000      NOOP
52
//              (CS/W)  ...             Read command
53
//              (CS/W)  0x20000000      NOOP
54
//              (CS/W)  0x20000000      NOOP
55
//              (Idle)  0x20000000      (Idle the interface again, so we can rd)
56
//              (CS/R)  0x20000000      (Wait)
57
//              (CS/R)  0x20000000      (Wait)
58
//              (CS/R)  0x20000000      (Wait)
59
//              (CS/R)  0x20000000      (Wait)
60
//              (Idle)  0x20000000      (Idle the interface before writing)
61
//              (CS/W)  0x20000000      NOOP
62
//              (CS/W)  0x20000000      NOOP
63
//              (CS/W)  0x30008001      Write to CMD register (address 4)
64
//              (CS/W)  0x0000000d      DESYNC command
65
//              (CS/W)  0x20000000      NOOP
66
//              (CS/W)  0x20000000      NOOP
67
//              (Idle)
68
// Creator:     Dan Gisselquist, Ph.D.
69
//              Gisselquist Technology, LLC
70
//
71
///////////////////////////////////////////////////////////////////////////
72
//
73
// Copyright (C) 2015, Gisselquist Technology, LLC
74
//
75
// This program is free software (firmware): you can redistribute it and/or
76
// modify it under the terms of  the GNU General Public License as published
77
// by the Free Software Foundation, either version 3 of the License, or (at
78
// your option) any later version.
79
//
80
// This program is distributed in the hope that it will be useful, but WITHOUT
81
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
82
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
83
// for more details.
84
//
85
// License:     GPL, v3, as defined and found on www.gnu.org,
86
//              http://www.gnu.org/licenses/gpl.html
87
//
88
//
89
///////////////////////////////////////////////////////////////////////////
90
//
91
`define MBOOT_IDLE      5'h00
92
`define MBOOT_START     5'h01
93
`define MBOOT_READ      5'h06
94
`define MBOOT_WRITE     5'h0f
95
`define MBOOT_DESYNC    5'h11
96
module  wbicapetwo(i_clk,
97
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
98
                        o_wb_ack, o_wb_stall, o_wb_data);
99
        input                   i_clk;
100
        // Wishbone inputs
101
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
102
        input           [4:0]    i_wb_addr;
103
        input           [31:0]   i_wb_data;
104
        // Wishbone outputs
105
        output  reg             o_wb_ack, o_wb_stall;
106
        output  reg     [31:0]   o_wb_data;
107
        // ICAPE2 interface signals
108
        //      These are kept internal to this block ...
109
 
110
        reg             wb_req, r_we;
111
        reg     [31:0]   r_data;
112
        reg     [4:0]    r_addr;
113
 
114
        reg             slow_clk;
115
        reg     [31:0]   cfg_in;
116
        reg             cfg_cs_n, cfg_rdwrn;
117
        wire    [31:0]   cfg_out;
118
        reg     [4:0]    state;
119
        initial state = `MBOOT_IDLE;
120
        initial cfg_cs_n = 1'b1;
121
        always @(posedge i_clk)
122
        begin
123
                o_wb_ack <= 1'b0;
124
                // Turn any request "off", so that it will not be ack'd, if
125
                // the wb_cyc line is ever lowered.
126
                wb_req <= wb_req & i_wb_cyc;
127
                slow_clk <= slow_clk ^ 1'b1;
128
                o_wb_stall <= (state != `MBOOT_IDLE)&&(slow_clk);
129
                if (~slow_clk)
130
                begin
131
                        state <= state + 5'h01;
132
                        case(state)
133
                        `MBOOT_IDLE: begin
134
                                cfg_cs_n <= 1'b1;
135
                                cfg_rdwrn <= 1'b1;
136
                                cfg_in <= 32'hffffffff; // Dummy word
137
 
138
                                state <= `MBOOT_IDLE;
139
 
140
                                o_wb_ack <= 1'b0;
141
 
142
                                r_addr <= i_wb_addr;
143
                                r_data <= i_wb_data;
144
                                r_we   <= i_wb_we;
145
                                if(i_wb_stb)
146
                                begin
147
                                        state <= `MBOOT_START;
148
                                        wb_req <= 1'b1;
149
                                        //
150
                                        o_wb_ack <= 1'b0;
151
                                end end
152
                        `MBOOT_START: cfg_in <= 32'hffffffff; // NOOP
153
                        5'h02: begin
154
                                cfg_cs_n <= 1'b0; // Activate interface
155
                                cfg_rdwrn <= 1'b0;
156
                                cfg_in <= 32'h20000000; // NOOP
157
                                end
158
                        5'h03: cfg_in <= 32'haa995566;  // Sync word
159
                        5'h04: cfg_in <= 32'h20000000; // NOOP
160
                        5'h05: begin
161
                                cfg_in <= 32'h20000000; // NOOP
162
                                state <= (r_we) ? `MBOOT_WRITE : `MBOOT_READ;
163
                                end
164
                        `MBOOT_READ: cfg_in <= { 8'h28, 6'h0, r_addr, 13'h001 };
165
                        5'h07: cfg_in <= 32'h20000000; // NOOP
166
                        5'h08: cfg_in <= 32'h20000000; // NOOP
167
                        5'h09: begin // Idle the interface before the read cycle
168
                                cfg_cs_n <= 1'b1;
169
                                cfg_rdwrn <= 1'b1;
170
                                cfg_in <= 32'h20000000; // NOOP
171
                                end
172
                        5'h0a: begin // Re-activate the interface and wait 3 cycles
173
                                cfg_cs_n <= 1'b0;
174
                                cfg_rdwrn <= 1'b1;
175
                                cfg_in <= 32'h20000000; // NOOP
176
                                end
177
                        5'h0b: // ... still waiting, cycle two
178
                                cfg_in <= 32'h20000000; // NOOP
179
                        5'h0c: // ... still waiting, cycle three
180
                                cfg_in <= 32'h20000000; // NOOP
181
                        5'h0d: // ... still waiting, cycle four
182
                                cfg_in <= 32'h20000000; // NOOP
183
                        5'h0e: begin // and now our answer is there
184
                                cfg_cs_n <= 1'b1;
185
                                cfg_rdwrn <= 1'b1;
186
                                cfg_in <= 32'h20000000; // NOOP
187
                                //
188
                                // Wishbone return
189
                                o_wb_ack <= wb_req;
190
                                o_wb_data <= cfg_out;
191
                                wb_req <= 1'b0;
192
                                //
193
                                state <= `MBOOT_DESYNC;
194
                                end
195
                        `MBOOT_WRITE:   // Issue a write command to the given address
196
                                cfg_in <= { 8'h30, 6'h0, r_addr, 13'h001 };
197
                        5'h10: cfg_in <= r_data;        // Write the value
198
                        `MBOOT_DESYNC: begin
199
                                cfg_cs_n <= 1'b0;
200
                                cfg_rdwrn <= 1'b0;
201
                                cfg_in <= 32'h20000000; // 1st NOOP
202
                                end
203
                        5'h12: cfg_in <= 32'h20000000;  // 2nd NOOP
204
                        5'h13: cfg_in <= 32'h30008001;  // Write to CMD register
205
                        5'h14: cfg_in <= 32'h0000000d;  // DESYNC command
206
                        5'h15: cfg_in <= 32'h20000000;  // NOOP
207
                        5'h16: cfg_in <= 32'h20000000;  // NOOP
208
                        5'h17: begin
209
                                // Acknowledge the bus transaction, it is now complete
210
                                o_wb_ack <= wb_req;
211
                                wb_req <= 1'b0;
212
                                //
213
                                cfg_cs_n <= 1'b1;
214
                                cfg_rdwrn <= 1'b0;
215
                                cfg_in <= 32'hffffffff; // DUMMY
216
                                //
217
                                state <= `MBOOT_IDLE;
218
                                end
219
                        default: begin
220
                                o_wb_ack <= 1'b0;
221
                                cfg_cs_n <= 1'b1;
222
                                cfg_rdwrn <= 1'b0;
223
                                state <= `MBOOT_IDLE;
224
                                cfg_in <= 32'hffffffff; // DUMMY WORD
225
                                end
226
                        endcase
227
                end else begin
228
                        o_wb_ack <= 1'b0;
229
                end
230
        end
231
 
232
        genvar  k;
233
        //
234
        // The data registers to the ICAPE2 interface are bit swapped within
235
        // each byte.  Thus, in order to read from or write to the interface,
236
        // we need to bit swap the bits in each byte.  These next lines
237
        // accomplish that for both the input and output ports.
238
        //
239
        wire    [31:0]   bit_swapped_cfg_in;
240
        generate
241
        for(k=0; k<8; k=k+1)
242
        begin
243
                assign bit_swapped_cfg_in[   k] = cfg_in[   7-k];
244
                assign bit_swapped_cfg_in[ 8+k] = cfg_in[ 8+7-k];
245
                assign bit_swapped_cfg_in[16+k] = cfg_in[16+7-k];
246
                assign bit_swapped_cfg_in[24+k] = cfg_in[24+7-k];
247
        end endgenerate
248
 
249
        wire    [31:0]   bit_swapped_cfg_out;
250
        generate
251
        for(k=0; k<8; k=k+1)
252
        begin
253
                assign cfg_out[   k] = bit_swapped_cfg_out[   7-k];
254
                assign cfg_out[ 8+k] = bit_swapped_cfg_out[ 8+7-k];
255
                assign cfg_out[16+k] = bit_swapped_cfg_out[16+7-k];
256
                assign cfg_out[24+k] = bit_swapped_cfg_out[24+7-k];
257
        end endgenerate
258
 
259
        ICAPE2 #(.ICAP_WIDTH("X32")) reconfig(.CLK(slow_clk),
260
                        .CSIB(cfg_cs_n), .RDWRB(cfg_rdwrn),
261
                        .I(bit_swapped_cfg_in), .O(bit_swapped_cfg_out));
262
endmodule

powered by: WebSVN 2.1.0

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