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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [rtl/] [verilog/] [WB64ToMIG32.v] - Blame information for rev 52

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 52 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2011-2013  Robert Finch, Stratford
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@opencores.org
7
//       ||
8
//  
9
//
10
// WB2MIG32.v
11
// - 64 bit WISHBONE to 32 bit MIG bus bridge
12
// - supports
13
//              constant address burst cycles
14
//              incrementing address burst cycles
15
//              classic bus cycles
16
//
17
// This source file is free software: you can redistribute it and/or modify 
18
// it under the terms of the GNU Lesser General Public License as published 
19
// by the Free Software Foundation, either version 3 of the License, or     
20
// (at your option) any later version.                                      
21
//                                                                          
22
// This source file is distributed in the hope that it will be useful,      
23
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
24
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
25
// GNU General Public License for more details.                             
26
//                                                                          
27
// You should have received a copy of the GNU General Public License        
28
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
29
//                                                                          
30
// ============================================================================
31
//
32
//`define SUPPORT_INCADR        1
33
`define MAX_MEM         32'h07FF_FFFF
34
//
35
module WB64ToMIG32 (
36
input rst_i,
37
input clk_i,
38
 
39
// WISHBONE PORT
40
input [1:0] bte_i,                                       // burst type extension
41
input [2:0] cti_i,                                       // cycle type indicator
42
input cyc_i,                                            // cycle in progress
43
input stb_i,                                            // data strobe
44
output ack_o,                                           // acknowledge
45
input we_i,                                                     // write cycle
46
input [7:0] sel_i,                                       // byte lane selects
47
input [63:0] adr_i,                                      // address
48
input [63:0] dat_i,                                      // data 
49
output reg [63:0] dat_o,
50
input [4:0] bl_i,                                        // burst length
51
 
52
// MIG port
53
input calib_done,
54
input cmd_full,
55
output reg cmd_en,
56
output reg [2:0] cmd_instr,
57
output reg [5:0] cmd_bl,
58
output reg [29:0] cmd_byte_addr,
59
 
60
output reg rd_en,
61
input [31:0] rd_data,
62
input rd_empty,
63
 
64
output reg wr_en,
65
output reg [3:0] wr_mask,
66
output reg [31:0] wr_data,
67
input wr_empty,
68
input wr_full
69
);
70
parameter IDLE = 4'd1;
71
parameter BWRITE_001a = 4'd2;
72
parameter BWRITE_001b = 4'd3;
73
parameter BWRITE_010a = 4'd4;
74
parameter BWRITE_010b = 4'd5;
75
parameter BWRITE_010c = 4'd6;
76
parameter BWRITE_010d = 4'd7;
77
parameter BWRITE_CMD = 4'd8;
78
parameter BREAD_001a = 4'd9;
79
parameter BREAD_001b = 4'd10;
80
parameter BREAD_010a = 4'd11;
81
parameter BREAD_010b = 4'd12;
82
parameter BREAD_010c = 4'd13;
83
parameter BREAD_010d = 4'd14;
84
parameter NACK = 4'd15;
85
 
86
 
87
// Fill write FIFO then issue write command
88
reg [5:0] ctr;           // burst length counter
89
reg [63:0] dato;
90
reg [3:0] state;
91
reg ack1;
92
 
93
wire cs = cyc_i && stb_i && (adr_i[59:32]==28'h0000001 || adr_i[63:36]==28'hE000000);           // circuit select
94
assign ack_o = ack1 & cs;               // Force ack_o low as soon as cyc_i or stb_i go low
95
 
96
always @(cs or adr_i or dato)
97
if (cs) begin
98
// The following test allows the startup code to determine how much memory is presnet.
99
// Otherwise, the code thinks there's more memory than there actually is, due to aliased
100
// addresses hit during the memory test.
101
        if (adr_i[31:0]>`MAX_MEM)
102
                dat_o <= 64'hDEADDEAD_DEADDEAD;
103
        else
104
                dat_o <= dato;
105
end
106
else
107
        dat_o <= 64'h00000000_00000000; // Allow wire-or'ing data bus
108
 
109
reg [5:0] bl;
110
reg [63:0] prev_adr;
111
 
112
always @(posedge clk_i)
113
if (rst_i) begin
114
        ack1 <= 1'b0;
115
        ctr <= 6'd0;
116
        state <= IDLE;
117
end
118
else begin
119
cmd_en <= 1'b0;         // Forces cmd_en to be just a 1-cycle pulse
120
wr_en <= 1'b0;
121
case(state)
122
IDLE:
123
        if (cs & calib_done) begin
124
                ctr <= 6'd0;
125
                cmd_byte_addr <= {adr_i[29:2],2'b00};
126
                if (cti_i==3'b001)
127
                        cmd_bl <= {bl_i,1'b1};
128
                else begin
129
                        if (sel_i[3:0]==4'h0 || sel_i[7:4]==4'h0)
130
                                cmd_bl <= 6'd0;         // single access required
131
                        else
132
                                cmd_bl <= 6'd1;         // double access required
133
                end
134
                cmd_instr <= we_i ? 3'b000 : 3'b001;    // WRITE or READ
135
                prev_adr <= adr_i;
136
 
137
                // Write cycles
138
                if (we_i) begin
139
                        case(cti_i)
140
                        3'b000,3'b111:
141
                                // Writing for a half-word or less ?
142
                                if (sel_i[3:0]==4'h0 || sel_i[7:4]==4'h0) begin
143
                                        if (!wr_full) begin
144
                                                ack1 <= 1'b1;
145
                                                wr_en <= 1'b1;
146
                                                // data will be reflected for sub-word writes
147
                                                // the same data is on [31:0] as is on [63:32]
148
                                                wr_data <= dat_i[31:0];
149
                                                wr_mask <= ~(sel_i[7:4]|sel_i[3:0]);
150
                                                state <= BWRITE_CMD;
151
                                        end
152
                                end
153
                                // Writing 2 32 bit words
154
                                else begin
155
                                        if (wr_empty)
156
                                                state <= BWRITE_001a;
157
                                end
158
                        // Since we want to write a burst of numerous data, we wait until the
159
                        // write FIFO is empty. We could wait until the FIFO count is greater
160
                        // than the burst length.
161
                        3'b001:
162
                                if (wr_empty)
163
                                        state <= BWRITE_001a;
164
`ifdef SUPPORT_INCADR
165
                        3'b010:
166
                                if (wr_empty)
167
                                        state <= BWRITE_010a;
168
`endif
169
                        default:        ;
170
                        endcase
171
                end
172
                // Read cycles
173
                else begin
174
                        if (!cmd_full) begin
175
                                cmd_en <= 1'b1;
176
                                case(cti_i)
177
                                3'b000: state <= BREAD_001a;
178
                                3'b001: state <= BREAD_001a;
179
`ifdef SUPPORT_INCADR
180
                                3'b010: state <= BREAD_010a;
181
`endif
182
                                3'b111: state <= BREAD_001a;
183
                                default:        ;
184
                                endcase
185
                        end
186
                end
187
        end
188
 
189
//---------------------------------------------------------
190
// Burst write
191
//---------------------------------------------------------
192
 
193
// Constant address burst:
194
BWRITE_001a:
195
        begin
196
                ack1 <= 1'b0;
197
                if (stb_i) begin
198
                        wr_en <= 1'b1;
199
                        wr_data <= dat_i[31:0];
200
                        wr_mask <= ~sel_i[3:0];
201
                        ctr <= ctr + 6'd1;
202
                        state <= BWRITE_001b;
203
                end
204
        end
205
BWRITE_001b:
206
        if (stb_i) begin
207
                ack1 <= 1'b1;
208
                wr_en <= 1'b1;
209
                wr_data <= dat_i[63:32];
210
                wr_mask <= ~sel_i[7:4];
211
                ctr <= ctr + 6'd1;
212
                if (ctr >= bl_i || cti_i==3'b000 || cti_i==3'b111 || !cyc_i)
213
                        state <= BWRITE_CMD;
214
                else
215
                        state <= BWRITE_001a;
216
        end
217
        else
218
                ack1 <= 1'b0;
219
 
220
`ifdef SUPPORT_INCADR
221
// Incrementing address burst:
222
// Write the first word
223
// Write subsequent words, checking for an address change
224
BWRITE_010a:
225
        begin
226
                ack1 <= 1'b0;
227
                if (stb_i) begin
228
                        wr_en <= 1'b1;
229
                        wr_data <= dat_i[31:0];
230
                        wr_mask <= ~sel_i[3:0];
231
                        ctr <= ctr + 6'd1;
232
                        state <= BWRITE_010b;
233
                end
234
        end
235
BWRITE_010b:
236
        if (stb_i) begin
237
                ack1 <= 1'b1;
238
                wr_en <= 1'b1;
239
                wr_data <= dat_i[63:32];
240
                wr_mask <= ~sel_i[7:4];
241
                ctr <= ctr + 6'd1;
242
                if (ctr >= bl_i || cti_i==3'b000 || cti_i==3'b111 || !cyc_i)
243
                        state <= BWRITE_CMD;
244
                else
245
                        state <= BWRITE_010c;
246
        end
247
        else
248
                ack1 <= 1'b0;
249
BWRITE_010c:
250
        begin
251
                ack1 <= 1'b0;
252
                if (stb_i) begin
253
                        if (adr_i!=prev_adr) begin
254
                                prev_adr <= adr_i;
255
                                wr_en <= 1'b1;
256
                                wr_data <= dat_i[31:0];
257
                                wr_mask <= ~sel_i[3:0];
258
                                ctr <= ctr + 6'd1;
259
                                state <= BWRITE_010d;
260
                        end
261
                end
262
        end
263
BWRITE_010d:
264
        if (stb_i) begin
265
                ack1 <= 1'b1;
266
                wr_en <= 1'b1;
267
                wr_data <= dat_i[63:32];
268
                wr_mask <= ~sel_i[7:4];
269
                ctr <= ctr + 6'd1;
270
                if (ctr >= bl_i || cti_i==3'b000 || cti_i==3'b111 || !cyc_i)
271
                        state <= BWRITE_CMD;
272
                else
273
                        state <= BWRITE_010c;
274
        end
275
        else
276
                ack1 <= 1'b0;
277
`endif
278
 
279
BWRITE_CMD:
280
        begin
281
                if (cyc_i==1'b0)
282
                        ack1 <= 1'b0;
283
                if (!cmd_full) begin
284
                        cmd_en <= 1'b1;
285
                        state <= NACK;
286
                end
287
        end
288
 
289
//---------------------------------------------------------
290
// Burst read or single read
291
//---------------------------------------------------------
292
BREAD_001a:
293
        begin
294
                rd_en <= 1'b1;
295
                ack1 <= 1'b0;
296
                if (rd_en & !rd_empty) begin
297
                        dato <= {rd_data,rd_data};
298
                        ctr <= ctr + 6'd1;
299
                        if (sel_i[7:4]!=4'h0 && sel_i[3:0]!=4'h0 && cyc_i)
300
                                state <= BREAD_001b;
301
                        else begin
302
                                ack1 <= 1'b1;
303
                                state <= NACK;
304
                        end
305
                end
306
        end
307
BREAD_001b:
308
        if (rd_en & !rd_empty) begin
309
                dato[63:32] <= rd_data;
310
                ack1 <= 1'b1;
311
                ctr <= ctr + 6'd1;
312
                if (ctr>={bl_i,1'b1} || !cyc_i || cti_i==3'b000 || cti_i==3'b111)
313
                        state <= NACK;
314
                else
315
                        state <= BREAD_001a;
316
        end
317
 
318
`ifdef SUPPORT_INCADR
319
BREAD_010a:
320
        begin
321
                rd_en <= 1'b1;
322
                ack1 <= 1'b0;
323
                if (rd_en & !rd_empty) begin
324
                        prev_adr <= adr_i;
325
                        dato <= {rd_data,rd_data};
326
                        ctr <= ctr + 6'd1;
327
                        state <= BREAD_010b;
328
                end
329
        end
330
BREAD_010b:
331
        if (rd_en & !rd_empty) begin
332
                rd_en <= 1'b0;
333
                dato[63:32] <= rd_data;
334
                ack1 <= 1'b1;
335
                ctr <= ctr + 6'd1;
336
                if (ctr>={bl_i,1'b1} || !cyc_i || cti_i==3'b000 || cti_i==3'b111)
337
                        state <= NACK;
338
                else
339
                        state <= BREAD_010c;
340
        end
341
BREAD_010c:
342
        begin
343
                ack1 <= 1'b0;
344
                if (adr_i != prev_adr) begin
345
                        rd_en <= 1'b1;
346
                        if (rd_en & !rd_empty) begin
347
                                prev_adr <= adr_i;
348
                                dato <= {rd_data,rd_data};
349
                                ctr <= ctr + 6'd1;
350
                                state <= BREAD_010d;
351
                        end
352
                end
353
        end
354
BREAD_010d:
355
        if (rd_en & !rd_empty) begin
356
                rd_en <= 1'b0;
357
                ack1 <= 1'b1;
358
                dato[63:32] <= rd_data;
359
                ctr <= ctr + 6'd1;
360
                if (ctr >= bl_i || cti_i==3'b000 || cti_i==3'b111 || !cyc_i)
361
                        state <= NACK;
362
                else
363
                        state <= BREAD_010c;
364
        end
365
`endif
366
 
367
//---------------------------------------------------------
368
//---------------------------------------------------------
369
// If cyc_o went inactive during BWRITE_CMD (ack1==1'b0) then move
370
// to next state. cyc_i might have gone back to active as the next
371
// bus cycle could have started.
372
//
373
NACK:
374
        if (!cyc_i || ack1==1'b0) begin
375
                ack1 <= 1'b0;
376
                rd_en <= 1'b0;
377
                state <= IDLE;
378
        end
379
endcase
380
end
381
endmodule

powered by: WebSVN 2.1.0

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