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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [avalon_io.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
`include "defines.v"
28
 
29
//PARSED_COMMENTS: this file contains parsed script comments
30
 
31
module avalon_io(
32
    input               clk,
33
    input               rst_n,
34
 
35
    //io_read
36
    input               io_read_do,
37
    input       [15:0]  io_read_address,
38
    input       [2:0]   io_read_length,
39
    output reg  [31:0]  io_read_data,
40
    output reg          io_read_done,
41
 
42
    //io_write
43
    input               io_write_do,
44
    input       [15:0]  io_write_address,
45
    input       [2:0]   io_write_length,
46
    input       [31:0]  io_write_data,
47
    output reg          io_write_done,
48
 
49
    input               dcache_busy,
50
 
51
    //Avalon
52
    output reg  [15:0]  avalon_io_address,
53
    output reg  [3:0]   avalon_io_byteenable,
54
 
55
    output              avalon_io_read,
56
    input               avalon_io_readdatavalid,
57
    input       [31:0]  avalon_io_readdata,
58
 
59
    output              avalon_io_write,
60
    output reg  [31:0]  avalon_io_writedata,
61
 
62
    input               avalon_io_waitrequest
63
);
64
 
65
 
66
//------------------------------------------------------------------------------
67
 
68
reg [2:0] state;
69
 
70
reg       was_readdatavalid;
71
 
72
reg       avalon_io_read_reg;
73
reg       avalon_io_write_reg;
74
 
75
assign avalon_io_read  = (address_out_of_bounds)? 1'b0 : avalon_io_read_reg;
76
assign avalon_io_write = (address_out_of_bounds)? 1'b0 : avalon_io_write_reg;
77
 
78
//------------------------------------------------------------------------------
79
 
80
wire address_out_of_bounds =
81
    (avalon_io_address >= 16'h0010 && avalon_io_address < 16'h0020) ||
82
    (avalon_io_address == 16'h0020 && avalon_io_byteenable[1:0] == 2'b00) ||
83
    (avalon_io_address >= 16'h0024 && avalon_io_address < 16'h0040) ||
84
    (avalon_io_address >= 16'h0044 && avalon_io_address < 16'h0060) ||
85
    (avalon_io_address >= 16'h0068 && avalon_io_address < 16'h0070) ||
86
    (avalon_io_address == 16'h0070 && avalon_io_byteenable[1:0] == 2'b00) ||
87
    (avalon_io_address >= 16'h0074 && avalon_io_address < 16'h0080) ||
88
    (avalon_io_address == 16'h00A0 && avalon_io_byteenable[1:0] == 2'b00) ||
89
    (avalon_io_address >= 16'h00A4 && avalon_io_address < 16'h00C0) ||
90
    (avalon_io_address >= 16'h00E0 && avalon_io_address < 16'h01F0) ||
91
    (avalon_io_address >= 16'h01F8 && avalon_io_address < 16'h0220) ||
92
    (avalon_io_address >= 16'h0230 && avalon_io_address < 16'h0388) ||
93
    (avalon_io_address == 16'h0388 && avalon_io_byteenable[1:0] == 2'b00) ||
94
    (avalon_io_address >= 16'h038C && avalon_io_address < 16'h03B0) ||
95
    (avalon_io_address >= 16'h03E0 && avalon_io_address < 16'h03F0) ||
96
    (avalon_io_address >= 16'h03F8 && avalon_io_address < 16'h8888) ||
97
    (avalon_io_address >= 16'h8890);
98
 
99
wire [31:0] avalon_io_readdata_final =
100
    (address_out_of_bounds)?            32'hFFFFFFFF :
101
    (avalon_io_address == 16'h0020)?    { 16'hFFFF, avalon_io_readdata[15:0] } :
102
    (avalon_io_address == 16'h0070)?    { 16'hFFFF, avalon_io_readdata[15:0] } :
103
    (avalon_io_address == 16'h00A0)?    { 16'hFFFF, avalon_io_readdata[15:0] } :
104
    (avalon_io_address == 16'h0388)?    { 16'hFFFF, avalon_io_readdata[15:0] } :
105
                                        avalon_io_readdata;
106
 
107
//------------------------------------------------------------------------------
108
 
109
wire [3:0]  write_1_byteenable;
110
wire [3:0]  write_2_byteenable;
111
wire [31:0] write_1_data;
112
wire [31:0] write_2_data;
113
wire        write_two_stage;
114
wire [15:0] write_address_next;
115
 
116
wire [3:0]  read_1_byteenable;
117
wire [3:0]  read_2_byteenable;
118
wire        read_two_stage;
119
wire [15:0] read_address_next;
120
wire [31:0] read_data_1;
121
wire [31:0] read_data_2;
122
 
123
//------------------------------------------------------------------------------
124
 
125
localparam [2:0] STATE_IDLE      = 3'd0;
126
localparam [2:0] STATE_WRITE_1   = 3'd1;
127
localparam [2:0] STATE_WRITE_2   = 3'd2;
128
localparam [2:0] STATE_READ_1    = 3'd3;
129
localparam [2:0] STATE_READ_2    = 3'd4;
130
 
131
//------------------------------------------------------------------------------
132
 
133
assign write_address_next = io_write_address + 16'd4;
134
assign read_address_next  = io_read_address  + 16'd4;
135
 
136
//------------------------------------------------------------------------------
137
 
138
assign write_1_byteenable =
139
    (io_write_length == 3'd1 && io_write_address[1:0] == 2'd0)?     4'b0001 :
140
    (io_write_length == 3'd1 && io_write_address[1:0] == 2'd1)?     4'b0010 :
141
    (io_write_length == 3'd1 && io_write_address[1:0] == 2'd2)?     4'b0100 :
142
    (io_write_length == 3'd1 && io_write_address[1:0] == 2'd3)?     4'b1000 :
143
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd0)?     4'b0011 :
144
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd1)?     4'b0110 :
145
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd2)?     4'b1100 :
146
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd3)?     4'b1000 : //write_2 needed
147
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd0)?     4'b1111 :
148
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd1)?     4'b1110 : //write_2 needed
149
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd2)?     4'b1100 : //write_2 needed
150
                                                                    4'b1000;  //write_2 needed
151
 
152
assign write_2_byteenable =
153
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd3)?     4'b0001 :
154
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd1)?     4'b0001 :
155
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd2)?     4'b0011 :
156
                                                                    4'b0111;
157
assign write_1_data =
158
    (io_write_address[1:0] == 2'd0)?    io_write_data :
159
    (io_write_address[1:0] == 2'd1)?    { io_write_data[23:0], 8'd0 } :
160
    (io_write_address[1:0] == 2'd2)?    { io_write_data[15:0], 16'd0 } :
161
                                        { io_write_data[7:0],  24'd0 };
162
 
163
assign write_2_data =
164
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd3)?     { 24'd0, io_write_data[15:8] } :
165
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd1)?     { 24'd0, io_write_data[31:24] } :
166
    (io_write_length == 3'd4 && io_write_address[1:0] == 2'd2)?     { 16'd0, io_write_data[31:16] } :
167
                                                                    { 8'd0,  io_write_data[31:8] };
168
assign write_two_stage =
169
    (io_write_length == 3'd2 && io_write_address[1:0] == 2'd3) ||
170
    (io_write_length == 3'd4 && io_write_address[1:0] >= 2'd1);
171
 
172
//------------------------------------------------------------------------------
173
 
174
assign read_1_byteenable =
175
    (io_read_length == 3'd1 && io_read_address[1:0] == 2'd0)?     4'b0001 :
176
    (io_read_length == 3'd1 && io_read_address[1:0] == 2'd1)?     4'b0010 :
177
    (io_read_length == 3'd1 && io_read_address[1:0] == 2'd2)?     4'b0100 :
178
    (io_read_length == 3'd1 && io_read_address[1:0] == 2'd3)?     4'b1000 :
179
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd0)?     4'b0011 :
180
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd1)?     4'b0110 :
181
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd2)?     4'b1100 :
182
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd3)?     4'b1000 : //read_2 needed
183
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd0)?     4'b1111 :
184
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd1)?     4'b1110 : //read_2 needed
185
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd2)?     4'b1100 : //read_2 needed
186
                                                                  4'b1000;  //read_2 needed
187
 
188
assign read_2_byteenable =
189
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd3)?     4'b0001 :
190
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd1)?     4'b0001 :
191
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd2)?     4'b0011 :
192
                                                                  4'b0111;
193
assign read_two_stage =
194
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd3) ||
195
    (io_read_length == 3'd4 && io_read_address[1:0] >= 2'd1);
196
 
197
assign read_data_1 =
198
    (io_read_address[1:0] == 2'd0)?    avalon_io_readdata_final :
199
    (io_read_address[1:0] == 2'd1)?    { 8'd0,  avalon_io_readdata_final[31:8] } :
200
    (io_read_address[1:0] == 2'd2)?    { 16'd0, avalon_io_readdata_final[31:16] } :
201
                                       { 24'd0, avalon_io_readdata_final[31:24] };
202
 
203
assign read_data_2 =
204
    (io_read_length == 3'd2 && io_read_address[1:0] == 2'd3)?   { avalon_io_readdata_final[23:0], io_read_data[7:0] } :
205
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd1)?   { avalon_io_readdata_final[7:0],  io_read_data[23:0] } :
206
    (io_read_length == 3'd4 && io_read_address[1:0] == 2'd2)?   { avalon_io_readdata_final[15:0], io_read_data[15:0] } :
207
                                                                { avalon_io_readdata_final[23:0], io_read_data[7:0] };
208
 
209
 
210
//------------------------------------------------------------------------------
211
 
212
// synthesis translate_off
213
wire _unused_ok = &{ 1'b0, write_address_next[1:0], read_address_next[1:0], 1'b0 };
214
// synthesis translate_on
215
 
216
//------------------------------------------------------------------------------
217
 
218
/*******************************************************************************SCRIPT
219
 
220
IF(state == STATE_IDLE);
221
 
222
    SAVE(io_write_done, `FALSE);
223
    SAVE(io_read_done,  `FALSE);
224
 
225
    IF(io_write_do && io_write_done == `FALSE && dcache_busy == `FALSE);
226
 
227
        SAVE(avalon_io_address,    { io_write_address[15:2], 2'b0 });
228
        SAVE(avalon_io_byteenable, write_1_byteenable);
229
        SAVE(avalon_io_write_reg,  `TRUE);
230
        SAVE(avalon_io_writedata,  write_1_data);
231
 
232
        SAVE(state, STATE_WRITE_1);
233
    ELSE_IF(io_read_do && io_read_done == `FALSE && dcache_busy == `FALSE);
234
 
235
        SAVE(avalon_io_address,     { io_read_address[15:2], 2'b0 });
236
        SAVE(avalon_io_byteenable,  read_1_byteenable);
237
        SAVE(avalon_io_read_reg,    `TRUE);
238
 
239
        SAVE(was_readdatavalid, `FALSE);
240
        SAVE(state, STATE_READ_1);
241
    ENDIF();
242
ENDIF();
243
 
244
*/
245
 
246
/*******************************************************************************SCRIPT
247
 
248
IF(state == STATE_WRITE_1);
249
 
250
    IF(avalon_io_waitrequest == `FALSE || address_out_of_bounds);
251
 
252
        IF(write_two_stage);
253
 
254
            SAVE(avalon_io_address,     { write_address_next[15:2], 2'b0 });
255
            SAVE(avalon_io_byteenable,  write_2_byteenable);
256
            SAVE(avalon_io_write_reg,   `TRUE);
257
            SAVE(avalon_io_writedata,   write_2_data);
258
 
259
            SAVE(state, STATE_WRITE_2);
260
        ELSE();
261
            SAVE(avalon_io_write_reg, `FALSE);
262
 
263
            SAVE(io_write_done, `TRUE);
264
            SAVE(state, STATE_IDLE);
265
        ENDIF();
266
    ENDIF();
267
ENDIF();
268
*/
269
 
270
/*******************************************************************************SCRIPT
271
 
272
IF(state == STATE_WRITE_2);
273
 
274
    IF(avalon_io_waitrequest == `FALSE || address_out_of_bounds);
275
        SAVE(avalon_io_write_reg, `FALSE);
276
 
277
        SAVE(io_write_done, `TRUE);
278
        SAVE(state, STATE_IDLE);
279
    ENDIF();
280
ENDIF();
281
*/
282
 
283
/*******************************************************************************SCRIPT
284
 
285
IF(state == STATE_READ_1);
286
 
287
    IF(avalon_io_readdatavalid || address_out_of_bounds);
288
        SAVE(io_read_data, read_data_1);
289
 
290
        IF(read_two_stage);
291
 
292
            SAVE(avalon_io_address,     { read_address_next[15:2], 2'b0 });
293
            SAVE(avalon_io_byteenable,  read_2_byteenable);
294
 
295
            SAVE(avalon_io_read_reg, `TRUE);
296
            SAVE(state, STATE_READ_2);
297
        ELSE();
298
            SAVE(io_read_done, `TRUE);
299
 
300
            SAVE(avalon_io_read_reg, `FALSE);
301
            SAVE(state, STATE_IDLE);
302
        ENDIF();
303
    ENDIF();
304
 
305
    IF(avalon_io_waitrequest == `FALSE);
306
        SAVE(avalon_io_read_reg, `FALSE);
307
    ENDIF();
308
 
309
ENDIF();
310
*/
311
 
312
/*******************************************************************************SCRIPT
313
 
314
IF(state == STATE_READ_2);
315
 
316
    IF(avalon_io_readdatavalid || address_out_of_bounds);
317
        SAVE(io_read_done, `TRUE);
318
        SAVE(io_read_data, read_data_2);
319
 
320
        SAVE(avalon_io_read_reg, `FALSE);
321
        SAVE(state, STATE_IDLE);
322
    ENDIF();
323
 
324
    IF(avalon_io_waitrequest == `FALSE);
325
        SAVE(avalon_io_read_reg, `FALSE);
326
    ENDIF();
327
 
328
ENDIF();
329
*/
330
 
331
//------------------------------------------------------------------------------
332
 
333
`include "autogen/avalon_io.v"
334
 
335
//------------------------------------------------------------------------------
336
 
337
endmodule

powered by: WebSVN 2.1.0

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