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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbicape6.v] - Blame information for rev 38

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

Line No. Rev Author Line
1 21 dgisselq
///////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbicape6.v
4
//
5
// Project:     Wishbone to ICAPE_SPARTAN6 interface conversion
6
//
7
// Purpose:     This is a companion project to the ICAPE2 conversion, instead
8
//              involving a conversion from a 32-bit WISHBONE bus to read
9
//      and write the ICAPE_SPARTAN6 program.  This is the 'non-simple'
10
//      portion of the interface, sporting all of the smarts necessary to run
11
//      the simple interface and make working with ICAPE as simple as 
12
//      reading and writing from a wishbone bus.  For example, register ID's
13
//      are given by bus addresses, even though they take extra cycles to 
14
//      set and clear within the interface.
15
//
16
//
17
// Creator:     Dan Gisselquist, Ph.D.
18
//              Gisselquist Technology, LLC
19
//
20
///////////////////////////////////////////////////////////////////////////
21
//
22
// Copyright (C) 2015, Gisselquist Technology, LLC
23
//
24
// This program is free software (firmware): you can redistribute it and/or
25
// modify it under the terms of  the GNU General Public License as published
26
// by the Free Software Foundation, either version 3 of the License, or (at
27
// your option) any later version.
28
//
29
// This program is distributed in the hope that it will be useful, but WITHOUT
30
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
31
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
32
// for more details.
33
//
34
// License:     GPL, v3, as defined and found on www.gnu.org,
35
//              http://www.gnu.org/licenses/gpl.html
36
//
37
//
38
///////////////////////////////////////////////////////////////////////////
39
//
40
// Following instructions on page 116-117 of the configuration guide ...
41
//
42
// W FFFF
43
// W FFFF
44
// W AA99
45
// W 5566
46
// W 2000       NOOP
47
// W 2901       Write Type-1 packet header to read register 901??
48
// W 2000       NOOP
49
// W 2000       NOOP
50
// W 2000       NOOP
51
// W 2000       NOOP
52
// R vvvv       Read register from previous packet header command
53
// W 30A1       Write word to CMD register
54
// W 000D       DESYNC command
55
// W 2000       NOOP
56
// W 2000       NOOP
57
//
58
// Bits need to be bit-reversed within a byte
59
//
60
//
61
// IPROG example
62
//
63
// W FFFF
64
// W AA99
65
// W 5566
66
// W 3261       Write 1 words to GENERAL_1
67
// W xxxx       write Multiboot start address [15:0]
68
// W 3281       Write 1 words to GENERAL_2
69
// W xxxx       write Opcode and multiboot start address [23:16]
70
// W 32A1       Write 1 words to GENERAL_3
71
// W xxxx       write Fallback start address
72
// W 32C1       Write 1 words to GENERAL_4
73
// W xxxx       write Opcode dne Fallback start address [23:16]
74
// W 30A1       Write 1 word to CMD
75
// W 000E       IPGROG Cmd
76
// W 2000       NOOP
77
//
78
//
79
//
80
// This fails when using wgregs on the XuLA2 board because the ICAPE port and
81
// the JTAG port cannot both be active at the same time.
82
//
83
//
84
`define ICAP_IDLE       5'h0
85
`define ICAP_START      5'h1
86
`define ICAP_CLOSE      5'hf
87
module  wbicape6(i_clk, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
88
                        o_wb_ack, o_wb_stall, o_wb_data, dbg_data);
89
        input   i_clk;
90
        // Wishbone slave inputs
91
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
92
        input   [5:0]            i_wb_addr;
93
        input   [31:0]           i_wb_data;
94
        // Wishbone outputs
95
        output  reg             o_wb_ack;
96
        output  reg             o_wb_stall;
97
        output  wire    [31:0]   o_wb_data;
98
        output  wire    [31:0]   dbg_data;
99
 
100
        // Interface to the lower level ICAPE port
101
        reg             icap_cyc, icap_stb, icap_we;
102
        reg     [15:0]   icap_data_i;
103
        wire            icap_ack, icap_stall;
104
        wire    [15:0]   icap_data_o;
105
 
106
        reg     [4:0]    state;
107
        reg             r_we;
108
        reg     [15:0]   r_data;
109
 
110
        wire    [25:0]   icap_dbg;
111
        assign  dbg_data = { i_wb_stb, state[3:0], r_we, icap_dbg };
112
 
113
        reg     stalled_state;
114
        reg     [7:0]    r_cmd_word;
115
        wire    [15:0]   w_cmd_word;
116
        assign  w_cmd_word = { 3'b001, r_cmd_word, 5'h00 }; // Type-1 packet hdr
117
        initial icap_stb = 1'b0;
118
        initial icap_cyc = 1'b0;
119
        initial state    = `ICAP_IDLE;
120
        always @(posedge i_clk)
121
        begin
122
                o_wb_ack   <= 1'b0;
123
                o_wb_stall <= 1'b0;
124
                if (stalled_state)
125
                        state <= `ICAP_IDLE;
126
                else if ((~icap_stall)&&(state != `ICAP_IDLE))
127
                        state <= state + 1;
128
                case(state)
129
                `ICAP_IDLE: begin
130
                        icap_stb <= 1'b0;
131
                        icap_cyc <= 1'b0;
132
                        state <= `ICAP_IDLE;
133
                        r_data <= i_wb_data[15:0];
134
                        r_we   <= i_wb_we;
135
                        if ((i_wb_cyc)&&(i_wb_stb))
136
                        begin
137
                                state <= `ICAP_START;
138
                                icap_stb    <= i_wb_stb;
139
                                icap_cyc    <= i_wb_cyc;
140
                                icap_we     <= 1'b1;
141
                                icap_data_i <= 16'hffff;
142
                                r_cmd_word <= { (i_wb_we)? 2'b10:2'b01, i_wb_addr };
143
                                o_wb_stall <= 1'b1;
144
                        end end
145
                `ICAP_START: begin
146
                        if (~icap_stall)
147
                                icap_data_i <= 16'hffff;
148
                        end
149
                5'h2: begin
150
                        if (~icap_stall)
151
                                icap_data_i <= 16'haa99;
152
                        end
153
                5'h3: begin
154
                        if (~icap_stall)
155
                                icap_data_i <= 16'h5566;
156
                        end
157
                5'h4: begin
158
                        if (~icap_stall)
159
                                icap_data_i <= 16'h2000;
160
                        end
161
                5'h5: begin
162
                        if (~icap_stall)
163
                        begin
164
                                icap_data_i <= w_cmd_word; // Includes address
165
                        end end
166
                5'h6: begin // Write
167
                        if (~icap_stall)
168
                        begin
169
                                if (r_we)
170
                                        icap_data_i <= r_data;
171
                                else
172
                                        icap_data_i <= 16'h2000;
173
                        end end
174
                5'h7: begin
175
                        // Need to send four NOOPs before we can begin
176
                        // reading.  Send the four NOOPs for a write anyway.
177
                        if (~icap_stall)
178
                                icap_data_i <= 16'h2000;
179
                        end
180
                5'h8: begin
181
                        if (~icap_stall)
182
                                icap_data_i <= 16'h2000;
183
                        end
184
                5'h9: begin
185
                        if (~icap_stall)
186
                        begin
187
                                icap_data_i <= 16'h2000;
188
                                if (r_we)
189
                                        state <= `ICAP_CLOSE;
190
                        end end
191
                5'ha: begin
192
                        if (~icap_stall)
193
                        begin
194
                                // We now request the chip enable line be 
195
                                // dropped, so we can switch from writing to
196
                                // reading
197
                                icap_data_i <= 16'h2000;
198
                                icap_stb    <= 1'b0;
199
                                icap_cyc    <= 1'b0;
200
                        end end
201
                5'hb: begin
202
                        if (~icap_stall)
203
                        begin
204
                                // Switch the write line to read, must be done
205
                                // w/the chip enable off (hence _cyc=0).  O/w
206
                                // the interface will abort.
207
                                icap_data_i <= 16'h2000;
208
                                icap_we <=1'b0;
209
                        end end
210
                5'hc: begin
211
                        if (~icap_stall)
212
                        begin
213
                                // We can finally issue our read command
214
                                //      Re-activate the interface, and read
215
                                icap_data_i <= 16'h2000;
216
                                icap_stb    <= 1'b1;
217
                                icap_cyc    <= 1'b1;
218
                        end end
219
                5'hd: begin
220
                        if (~icap_stall)
221
                        begin
222
                                // De-activate the interface again so we can
223
                                // switch back to write.
224
                                icap_data_i <= 16'h2000;
225
                                icap_stb    <= 1'b0;
226
                                icap_cyc    <= 1'b0;
227
                        end end
228
                5'he: begin
229
                        if (~icap_stall)
230
                        begin
231
                                // Switch back to write while the interface
232
                                // is deactivated.
233
                                icap_we <= 1'b1;
234
                                icap_data_i <= 16'h2000;
235
                        end end
236
                `ICAP_CLOSE: begin
237
                        if (~icap_stall)
238
                        begin
239
                                icap_we <= 1'b1;
240
                                // Type 1: Write 1 word to CMD register
241
                                icap_data_i <= 16'h30a1;
242
                                r_data <= icap_data_o;
243
                                icap_stb    <= 1'b1;
244
                                icap_cyc    <= 1'b1;
245
                        end end
246
                 5'h10: begin // DESYNC Command
247
                        if (~icap_stall)
248
                        begin
249
                                icap_data_i <= 16'h000d;
250
                        end end
251
                 5'h11: begin // DESYNC must be followed by two NOOPs
252
                        if (~icap_stall)
253
                        begin
254
                                icap_data_i <= 16'h2000;
255
                        end end
256
                 5'h12: begin // NOOP
257
                        if (~icap_stall)
258
                        begin
259
                                icap_data_i <= 16'h2000;
260
                                state <= `ICAP_IDLE;
261
                                o_wb_ack <= 1'b1;
262
                                o_wb_stall <= 1'b0;
263
                        end end
264
                default: begin
265
                        // If we were in the middle of a bus cycle, and got
266
                        // here then ...  we just failed that cycle.  Setting
267
                        // the bus error flag would be appropriate, but we
268
                        // have no such flag to our interface.  Hence we just
269
                        // drop things and depend upon a bus watchdog to 
270
                        // catch that we aren't answering.
271
                        o_wb_ack <= 1'b0;
272
                        o_wb_stall <= 1'b0;
273
                        icap_stb <= 1'b0;
274
                        icap_cyc <= 1'b0;
275
                        state <= `ICAP_IDLE;
276
                        end
277
                endcase
278
        end
279
 
280
        wbicapesimple spartancfg(i_clk, icap_cyc,  icap_stb, icap_we,
281
                                icap_data_i,
282
                        icap_ack, icap_stall, icap_data_o,
283
                        icap_dbg);
284
 
285
 
286
        assign  o_wb_data = { 16'h0000, r_data };
287
 
288 27 dgisselq
        reg     [4:0]    last_state;
289 21 dgisselq
        initial last_state = `ICAP_IDLE;
290
        always @(posedge i_clk)
291
                last_state <= state;
292
 
293
        reg     [11:0]   reset_ctr;
294
        always @(posedge i_clk)
295
                if (last_state != state)
296
                        reset_ctr <= 0;
297
                else if (state == `ICAP_IDLE)
298
                        reset_ctr <= 0;
299
                else
300
                        reset_ctr <= reset_ctr + 1;
301
        always @(posedge i_clk)
302
                stalled_state <= (&reset_ctr);
303
 
304
endmodule

powered by: WebSVN 2.1.0

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