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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [memory/] [dcache_control_ram.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 dcache_control_ram(
32
    input               clk,
33
    input               rst_n,
34
 
35
    input [31:0]        address,
36
 
37
    output [10:0]       q,
38
    input  [10:0]       data,
39
 
40
    //RESP:
41
    input               read_do,
42
    //END
43
 
44
    //RESP:
45
    input               write_do,
46
    //END
47
 
48
    //RESP:
49
    input               invddata_do,
50
    output              invddata_done,
51
    //END
52
 
53
    //RESP:
54
    input               wbinvddata_do,
55
    output              wbinvddata_done,
56
    //END
57
 
58
 
59
    //REQ:
60
    output              wbinvdread_do,
61
    output  [7:0]       wbinvdread_address,
62
 
63
    input   [147:0]     wbinvdread_ram0_q,
64
    input   [147:0]     wbinvdread_ram1_q,
65
    input   [147:0]     wbinvdread_ram2_q,
66
    input   [147:0]     wbinvdread_ram3_q,
67
    //END
68
 
69
    //REQ: write line
70
    output              writeline_do,
71
    input               writeline_done,
72
 
73
    output      [31:0]  writeline_address,
74
    output      [127:0] writeline_line
75
    //END
76
 
77
);
78
 
79
//------------------------------------------------------------------------------
80
 
81
reg [1:0]   state;
82
 
83
reg [7:0]   last_address;
84
 
85
reg         after_invalidate;
86
 
87
reg         init_done;
88
 
89
reg [7:0]   invd_counter;
90
 
91
reg [9:0]   wbinvd_counter;
92
 
93
 
94
//------------------------------------------------------------------------------
95
 
96
wire [10:0]     ram_q_a;
97
 
98
wire            start_wbinvd;
99
 
100
wire            wbinvd_write_control;
101
 
102
wire [9:0]      wbinvd_counter_next;
103
 
104
wire            wbinvd_valid;
105
 
106
wire [147:0]    wbinvd_line;
107
 
108
//------------------------------------------------------------------------------
109
 
110
 
111
assign q = (~(init_done) || state == STATE_INVD || start_wbinvd || state == STATE_WBINVD || after_invalidate)? 11'd0 : ram_q_a;
112
 
113
assign wbinvd_counter_next = wbinvd_counter + 10'd1;
114
 
115
assign wbinvd_valid =
116
    (wbinvd_counter[1:0] == 2'd0)?  ram_q_a[1:0] == 2'b11 :
117
    (wbinvd_counter[1:0] == 2'd1)?  ram_q_a[3:2] == 2'b11 :
118
    (wbinvd_counter[1:0] == 2'd2)?  ram_q_a[5:4] == 2'b11 :
119
                                    ram_q_a[7:6] == 2'b11;
120
 
121
assign wbinvd_line =
122
    (wbinvd_counter[1:0] == 2'd0)?  wbinvdread_ram0_q :
123
    (wbinvd_counter[1:0] == 2'd1)?  wbinvdread_ram1_q :
124
    (wbinvd_counter[1:0] == 2'd2)?  wbinvdread_ram2_q :
125
                                    wbinvdread_ram3_q;
126
 
127
 
128
//------------------------------------------------------------------------------
129
 
130
always @(posedge clk or negedge rst_n) begin
131
    if(rst_n == 1'b0)   last_address <= 8'd0;
132
    else if(read_do)    last_address <= address[11:4];
133
end
134
 
135
 
136
//------------------------------------------------------------------------------
137
 
138
//------------------------------------------------------------------------------
139
 
140
localparam [1:0] STATE_IDLE   = 2'd0;
141
localparam [1:0] STATE_INVD   = 2'd1;
142
localparam [1:0] STATE_WBINVD = 2'd2;
143
 
144
//------------------------------------------------------------------------------
145
 
146
// port a: q - 11 bits; {3 pLRU, 8 msi}; msi: x0 - invalid; 01 - valid clean; 11 - valid dirty
147
 
148
simple_ram #(
149
    .width      (11),
150
    .widthad    (8)
151
)
152
dcache_control_ram_inst(
153
    .clk        (clk),  //input
154
 
155
    .wraddress  ((~(init_done) || state == STATE_INVD)?     invd_counter :
156
                 (state == STATE_WBINVD)?                   wbinvd_counter[9:2] :
157
                                                            address[11:4]),                                                                             //input [7:0]
158
 
159
    .wren       ((~(init_done) || state == STATE_INVD) || wbinvd_write_control || (init_done && state == STATE_IDLE && ~(start_wbinvd) && write_do)),   //input
160
    .data       ((~(init_done) || state == STATE_INVD || state == STATE_WBINVD)? 11'd0 : data),                                                         //input [10:0]
161
 
162
    .rdaddress  ((start_wbinvd || state == STATE_WBINVD)?   wbinvdread_address :
163
                 (read_do)?                                 address[11:4] :
164
                                                            last_address),      //input [7:0]
165
    .q          (ram_q_a)                                                       //output [10:0]
166
);
167
 
168
//------------------------------------------------------------------------------
169
 
170
// synthesis translate_off
171
wire _unused_ok = &{ 1'b0, address[31:12], address[3:0], 1'b0 };
172
// synthesis translate_on
173
 
174
//------------------------------------------------------------------------------
175
 
176
 
177
/*******************************************************************************SCRIPT
178
IF(init_done == `FALSE);
179
 
180
    SAVE(invd_counter, invd_counter + 8'd1);
181
 
182
    IF(invd_counter == 8'd255);
183
        SAVE(after_invalidate, `TRUE);
184
        SAVE(init_done,        `TRUE);
185
    ENDIF();
186
ENDIF();
187
*/
188
 
189
/*******************************************************************************SCRIPT
190
 
191
IF(state == STATE_IDLE);
192
    SAVE(after_invalidate, `FALSE);
193
 
194
    IF(init_done && invddata_do);
195
        SAVE(state, STATE_INVD);
196
 
197
    ELSE_IF(init_done && wbinvddata_do);
198
 
199
        SET(start_wbinvd);
200
 
201
        SET(wbinvdread_do);
202
        SET(wbinvdread_address, wbinvd_counter[9:2]);
203
 
204
        SAVE(state, STATE_WBINVD);
205
    ENDIF();
206
ENDIF();
207
*/
208
 
209
/*******************************************************************************SCRIPT
210
 
211
IF(state == STATE_INVD);
212
    SAVE(invd_counter, invd_counter + 8'd1);
213
 
214
    IF(invd_counter == 8'd255);
215
        SET(invddata_done);
216
 
217
        SAVE(after_invalidate, `TRUE);
218
        SAVE(state, STATE_IDLE);
219
    ENDIF();
220
ENDIF();
221
*/
222
 
223
/*******************************************************************************SCRIPT
224
IF(state == STATE_WBINVD);
225
 
226
    IF(wbinvd_valid);
227
 
228
        SET(writeline_do);
229
        SET(writeline_address, { wbinvd_line[147:128], wbinvd_counter[9:2], 4'd0 });
230
        SET(writeline_line,    wbinvd_line[127:0]);
231
 
232
        IF(writeline_done);
233
            SAVE(wbinvd_counter,      wbinvd_counter_next);
234
 
235
            SET(wbinvd_write_control, wbinvd_counter[1:0] == 2'd3);
236
 
237
            SET(wbinvdread_do);
238
            SET(wbinvdread_address, wbinvd_counter_next[9:2]);
239
 
240
            IF(wbinvd_counter == 10'd1023);
241
                SET(wbinvddata_done);
242
 
243
                SAVE(after_invalidate, `TRUE);
244
                SAVE(state, STATE_IDLE);
245
            ENDIF();
246
        ELSE();
247
            SET(wbinvdread_address, wbinvd_counter[9:2]);
248
        ENDIF();
249
    ELSE();
250
        SAVE(wbinvd_counter, wbinvd_counter_next);
251
 
252
        SET(wbinvd_write_control, wbinvd_counter[1:0] == 2'd3);
253
 
254
        SET(wbinvdread_do);
255
        SET(wbinvdread_address, wbinvd_counter_next[9:2]);
256
 
257
        IF(wbinvd_counter == 10'd1023);
258
            SET(wbinvddata_done);
259
 
260
            SAVE(after_invalidate, `TRUE);
261
            SAVE(state, STATE_IDLE);
262
        ENDIF();
263
    ENDIF();
264
ENDIF();
265
*/
266
 
267
//------------------------------------------------------------------------------
268
 
269
`include "autogen/dcache_control_ram.v"
270
 
271
endmodule

powered by: WebSVN 2.1.0

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