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

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [rtl/] [pipeline/] [pipeline_if.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * This file is subject to the terms and conditions of the BSD License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
`include "defines.v"
9
 
10
module pipeline_if(
11
    input               clk,
12
    input               rst_n,
13
 
14
    //
15
    input               config_kernel_mode,
16
    input       [5:0]   entryhi_asid,
17
 
18
    //
19
    input               micro_flush_do,
20
 
21
    //
22
    input               exception_start,
23
    input       [31:0]  exception_start_pc,
24
 
25
    //
26
    input               mem_stall,
27
 
28
    //
29
    output              if_exc_address_error,
30
    output              if_exc_tlb_inv,
31
    output              if_exc_tlb_miss,
32
    output              if_ready,
33
    output      [31:0]  if_instr,
34
    output reg  [31:0]  if_pc,
35
 
36
    //
37
    input               branch_start,
38
    input       [31:0]  branch_address,
39
 
40
    //
41
    output      [8:0]   fetch_cache_read_address,
42
    input       [53:0]  fetch_cache_q,
43
 
44
    output      [8:0]   fetch_cache_write_address,
45
    output              fetch_cache_write_enable,
46
    output      [53:0]  fetch_cache_data,
47
 
48
    //
49
    output              tlb_ram_fetch_start,
50
    output      [19:0]  tlb_ram_fetch_vpn,
51
    input               tlb_ram_fetch_hit,
52
    input       [49:0]  tlb_ram_fetch_result,
53
    input               tlb_ram_fetch_missed,
54
 
55
    //
56
    output      [31:0]  ram_instr_address,
57
    output              ram_instr_req,
58
    input               ram_instr_ack,
59
 
60
    //
61
    input       [31:0]  ram_result_address,
62
    input               ram_result_valid,
63
    input               ram_result_is_read_instr,
64
    input       [2:0]   ram_result_burstcount,
65
    input       [31:0]  ram_result
66
); /* verilator public_module */
67
 
68
//------------------------------------------------------------------------------
69
//------------------------------------------------------------------------------
70
//------------------------------------------------------------------------------
71
 
72
reg [31:0] branch_pc;
73
always @(posedge clk or negedge rst_n) begin
74
    if(rst_n == 1'b0)                       branch_pc <= 32'h0;
75
    else if(branch_start)                   branch_pc <= branch_address;
76
end
77
 
78
reg branch_waiting;
79
always @(posedge clk or negedge rst_n) begin
80
    if(rst_n == 1'b0)                       branch_waiting <= `FALSE;
81
    else if(if_ready || exception_start)    branch_waiting <= `FALSE;
82
    else if(branch_start && ~(if_ready))    branch_waiting <= `TRUE;
83
end
84
 
85
reg [31:0] exc_start_pc;
86
always @(posedge clk or negedge rst_n) begin
87
    if(rst_n == 1'b0)                       exc_start_pc <= 32'hBFC00000;
88
    else if(exception_start)                exc_start_pc <= exception_start_pc;
89
end
90
 
91
reg exc_waiting;
92
always @(posedge clk or negedge rst_n) begin
93
    if(rst_n == 1'b0)                       exc_waiting <= `TRUE;
94
    else if(exception_start)                exc_waiting <= `TRUE;
95
    else if(fetch_state == FETCH_IDLE)      exc_waiting <= `FALSE;
96
end
97
 
98
wire [31:0] if_pc_next = (exc_waiting)? exc_start_pc : (branch_start)? branch_address : (branch_waiting)? branch_pc : if_pc + 32'd4;
99
 
100
wire if_pc_update = if_ready || (exc_waiting && fetch_state == FETCH_IDLE);
101
 
102
always @(posedge clk or negedge rst_n) begin
103
    if(rst_n == 1'b0)       if_pc <= 32'h0;
104
    else if(if_pc_update)   if_pc <= if_pc_next;
105
end
106
 
107
reg if_pc_updated;
108
always @(posedge clk or negedge rst_n) begin
109
    if(rst_n == 1'b0)       if_pc_updated <= `FALSE;
110
    else                    if_pc_updated <= if_pc_update;
111
end
112
 
113
//------------------------------------------------------------------------------
114
 
115
reg [19:0] if_pc_vpn_last;
116
always @(posedge clk or negedge rst_n) begin
117
    if(rst_n == 1'b0)   if_pc_vpn_last <= 20'd0;
118
    else                if_pc_vpn_last <= if_pc[31:12];
119
end
120
 
121
reg if_pc_vpn_changed;
122
always @(posedge clk or negedge rst_n) begin
123
    if(rst_n == 1'b0)                       if_pc_vpn_changed <= `FALSE;
124
    else if(fetch_state == FETCH_IDLE)      if_pc_vpn_changed <= `FALSE;
125
    else if(if_pc[31:12] != if_pc_vpn_last) if_pc_vpn_changed <= `TRUE;
126
end
127
 
128
wire if_pc_vpn_change = if_pc[31:12] != if_pc_vpn_last || if_pc_vpn_changed;
129
 
130
//------------------------------------------------------------------------------
131
//------------------------------------------------------------------------------
132
//------------------------------------------------------------------------------
133
 
134
wire tlb_use_at_idle = fetch_state == FETCH_IDLE && (if_pc[31] == 1'b0 || if_pc[31:30] == 2'b11);
135
 
136
wire [19:0] pfn_at_idle =
137
    (~(tlb_use_at_idle))?   { 3'b0, if_pc[28:12] } :
138
    (micro_check_matched)?  micro_check_result[39:20] :
139
                            tlb_ram_fetch_result[39:20];
140
 
141
reg [19:0] pfn_reg;
142
always @(posedge clk or negedge rst_n) begin
143
    if(rst_n == 1'b0)                   pfn_reg <= 20'd0;
144
    else if(fetch_state == FETCH_IDLE)  pfn_reg <= pfn_at_idle;
145
    else if(fetch_tlb_tlb_ok_cache_bad) pfn_reg <= tlb_ram_fetch_result[39:20];
146
end
147
 
148
wire n_at_idle =
149
    (~(tlb_use_at_idle))?   if_pc[31:29] == 3'b101 :
150
    (micro_check_matched)?  micro_check_result[46] :
151
                            tlb_ram_fetch_result[46];
152
 
153
reg n_reg;
154
always @(posedge clk or negedge rst_n) begin
155
    if(rst_n == 1'b0)                   n_reg <= `FALSE;
156
    else if(fetch_state == FETCH_IDLE)  n_reg <= n_at_idle;
157
    else if(fetch_tlb_tlb_ok_cache_bad) n_reg <= tlb_ram_fetch_result[46];
158
end
159
 
160
reg [53:0] fetch_cache_q_reg;
161
always @(posedge clk or negedge rst_n) begin
162
    if(rst_n == 1'b0)                   fetch_cache_q_reg <= 54'd0;
163
    else if(fetch_state == FETCH_IDLE)  fetch_cache_q_reg <= fetch_cache_q;
164
end
165
 
166
//------------------------------------------------------------------------------
167
 
168
localparam [1:0] FETCH_IDLE    = 2'd0;
169
localparam [1:0] FETCH_TLB     = 2'd1;
170
localparam [1:0] FETCH_RESULT  = 2'd2;
171
localparam [1:0] FETCH_STOPPED = 2'd3;
172
 
173
reg [1:0] fetch_state;
174
always @(posedge clk or negedge rst_n) begin
175
    if(rst_n == 1'b0)                                                   fetch_state <= FETCH_STOPPED;
176
 
177
    else if(fetch_state == FETCH_STOPPED && exc_waiting)                fetch_state <= FETCH_IDLE;
178
 
179
    else if(fetch_idle_exc_address_error)                               fetch_state <= FETCH_STOPPED;
180
    else if(fetch_idle_tlb_bad_exc_inv)                                 fetch_state <= FETCH_STOPPED;
181
    else if(fetch_idle_tlb_ok_cache_bad)                                fetch_state <= FETCH_RESULT;
182
    else if(fetch_idle_tlb_wait)                                        fetch_state <= FETCH_TLB;
183
 
184
    else if(fetch_tlb_tlb_ok_cache_ok)                                  fetch_state <= FETCH_IDLE;
185
    else if(fetch_tlb_tlb_bad_exc_inv || fetch_tlb_tlb_bad_exc_miss)    fetch_state <= FETCH_STOPPED;
186
    else if(fetch_tlb_tlb_ok_cache_bad)                                 fetch_state <= FETCH_RESULT;
187
 
188
    else if(fetch_result_finished)                                      fetch_state <= FETCH_IDLE;
189
end
190
 
191
assign if_ready = ~(mem_stall) && ~(exc_waiting) && (
192
    fetch_idle_tlb_ok_cache_ok ||
193
    fetch_tlb_tlb_ok_cache_ok ||
194
    (ram_result_valid && ram_result_is_read_instr && ram_result_address[31:2] == { pfn_reg, if_pc[11:2] } && if_pc[1:0] == 2'b00 && ~(if_pc_vpn_change))
195
);
196
 
197
assign if_instr =
198
    (fetch_idle_tlb_ok_cache_ok)?   fetch_cache_q[31:0] :
199
    (fetch_state == FETCH_TLB)?     fetch_cache_q_reg[31:0] :
200
                                    ram_result;
201
 
202
assign ram_instr_req     = fetch_idle_tlb_ok_cache_bad || fetch_tlb_tlb_ok_cache_bad || (fetch_state == FETCH_RESULT && ~(was_ram_ack) && ~(ram_instr_ack));
203
assign ram_instr_address = (fetch_state == FETCH_IDLE)? { pfn_at_idle, if_pc[11:0] } : { pfn_reg, if_pc[11:0] };
204
 
205
assign if_exc_address_error = ~(exc_waiting) && (fetch_idle_exc_address_error || exception_reg == 2'd1);
206
assign if_exc_tlb_inv       = ~(exc_waiting) && (fetch_idle_tlb_bad_exc_inv || fetch_tlb_tlb_bad_exc_inv || (fetch_tlb_tlb_bad_exc_miss && if_pc[31] == 1'b1) || exception_reg == 2'd2);
207
assign if_exc_tlb_miss      = ~(exc_waiting) && ((fetch_tlb_tlb_bad_exc_miss && if_pc[31] == 1'b0) || exception_reg == 2'd3);
208
 
209
reg [1:0] exception_reg;
210
always @(posedge clk or negedge rst_n) begin
211
    if(rst_n == 1'b0)                       exception_reg <= 2'd0;
212
    else if(exception_start || exc_waiting) exception_reg <= 2'd0;
213
    else if(if_exc_address_error)           exception_reg <= 2'd1;
214
    else if(if_exc_tlb_inv)                 exception_reg <= 2'd2;
215
    else if(if_exc_tlb_miss)                exception_reg <= 2'd3;
216
end
217
 
218
//------------------------------------------------------------------------------
219
 
220
assign tlb_ram_fetch_start = if_pc_updated || (fetch_state == FETCH_IDLE && (~(tlb_ram_fetch_active) || tlb_ram_fetch_hit || tlb_ram_fetch_missed)) || (fetch_state == FETCH_TLB && ~(tlb_ram_fetch_active));
221
assign tlb_ram_fetch_vpn   = if_pc[31:12];
222
 
223
reg tlb_ram_fetch_active;
224
always @(posedge clk or negedge rst_n) begin
225
    if(rst_n == 1'b0)                                   tlb_ram_fetch_active <= `FALSE;
226
    else if(tlb_ram_fetch_start)                        tlb_ram_fetch_active <= `TRUE;
227
    else if(tlb_ram_fetch_hit || tlb_ram_fetch_missed)  tlb_ram_fetch_active <= `FALSE;
228
end
229
 
230
//------------------------------------------------------------------------------ state IDLE
231
 
232
wire fetch_idle_no_addr_exc = if_pc[1:0] == 2'b00 && (config_kernel_mode || if_pc[31] == 1'b0);
233
wire fetch_idle_exc_address_error = fetch_state == FETCH_IDLE && ~(fetch_idle_no_addr_exc) && ~(exc_waiting);
234
 
235
wire fetch_idle_tlb_ok_cache_ok = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_cache_q[53] && ~(n_at_idle) && fetch_idle_no_addr_exc && (
236
    (~(tlb_use_at_idle) && fetch_cache_q[52:32] == { pfn_at_idle, if_pc[11] }) ||                                                           //tlb not in use
237
    (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && fetch_cache_q[52:32] == {micro_check_result[39:20], if_pc[11]})    //tlb in micro
238
);
239
 
240
wire fetch_idle_tlb_bad_exc_inv = fetch_state == FETCH_IDLE && ~(exc_waiting) && tlb_use_at_idle && fetch_idle_no_addr_exc && (
241
    (micro_check_matched && ~(micro_check_result[48])) //tlb in micro
242
);
243
 
244
wire fetch_idle_tlb_ok_cache_bad = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_idle_no_addr_exc && (
245
    (~(tlb_use_at_idle) && (~(fetch_cache_q[53]) || n_at_idle || fetch_cache_q[52:32] != { pfn_at_idle, if_pc[11] })) ||                                                        //tlb not in use
246
    (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && (~(fetch_cache_q[53]) || n_at_idle || fetch_cache_q[52:32] != {micro_check_result[39:20], if_pc[11]})) //tlb in micro
247
);
248
 
249
wire fetch_idle_tlb_wait = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_idle_no_addr_exc && tlb_use_at_idle && ~(micro_check_matched);
250
 
251
//------------------------------------------------------------------------------ state TLB
252
 
253
wire fetch_tlb_tlb_ok_cache_ok  = fetch_state == FETCH_TLB && tlb_ram_fetch_hit && tlb_ram_fetch_result[48] && fetch_cache_q_reg[53] && fetch_cache_q_reg[52:32] == { tlb_ram_fetch_result[39:20], if_pc[11] };
254
 
255
wire fetch_tlb_tlb_bad_exc_inv  = fetch_state == FETCH_TLB && tlb_ram_fetch_hit    && ~(tlb_ram_fetch_result[48]);
256
wire fetch_tlb_tlb_bad_exc_miss = fetch_state == FETCH_TLB && ~(tlb_ram_fetch_hit) && tlb_ram_fetch_missed;
257
 
258
wire fetch_tlb_tlb_ok_cache_bad = fetch_state == FETCH_TLB && tlb_ram_fetch_hit && tlb_ram_fetch_result[48] && (~(fetch_cache_q_reg[53]) || fetch_cache_q_reg[52:32] != { tlb_ram_fetch_result[39:20], if_pc[11] });
259
 
260
//------------------------------------------------------------------------------ state RESULT
261
 
262
reg was_ram_ack;
263
always @(posedge clk or negedge rst_n) begin
264
    if(rst_n == 1'b0)                       was_ram_ack <= `FALSE;
265
    else if(fetch_state != FETCH_RESULT)    was_ram_ack <= `FALSE;
266
    else if(ram_instr_ack)                  was_ram_ack <= `TRUE;
267
end
268
 
269
reg is_ram_stalled;
270
always @(posedge clk or negedge rst_n) begin
271
    if(rst_n == 1'b0)                                                                                   is_ram_stalled <= `FALSE;
272
    else if(mem_stall && ram_result_valid && ram_result_is_read_instr && ram_result_burstcount == 3'd1) is_ram_stalled <= `TRUE;
273
    else if(~(mem_stall))                                                                               is_ram_stalled <= `FALSE;
274
end
275
 
276
wire fetch_result_finished = ~(mem_stall) && fetch_state == FETCH_RESULT && ((ram_result_valid && ram_result_is_read_instr && ram_result_burstcount == 3'd1) || is_ram_stalled);
277
 
278
//------------------------------------------------------------------------------ cache
279
//------------------------------------------------------------------------------
280
//------------------------------------------------------------------------------
281
 
282
assign fetch_cache_read_address  = (if_pc_update)? if_pc_next[10:2] : if_pc[10:2];
283
 
284
assign fetch_cache_write_address = ram_result_address[10:2];
285
 
286
assign fetch_cache_write_enable = (~(n_reg) && ram_result_valid && ram_result_is_read_instr);
287
 
288
/*
289
[53]    valid
290
[52:32] tag
291
[31:0]  data
292
*/
293
assign fetch_cache_data = { 1'b1, ram_result_address[31:11], ram_result }; //load
294
 
295
//------------------------------------------------------------------------------ micro
296
//------------------------------------------------------------------------------
297
//------------------------------------------------------------------------------
298
 
299
/*
300
[19:0]  vpn
301
[39:20] pfn
302
[45:40] asid
303
[46]    n noncachable
304
[47]    d dirty = write-enable
305
[48]    v valid
306
[49]    g global
307
*/
308
 
309
//input               micro_check_matched,
310
//input       [49:0]  micro_check_result,
311
 
312
wire        micro_check_do   = tlb_use_at_idle;
313
wire [19:0] micro_check_vpn  = if_pc[31:12];
314
wire [5:0]  micro_check_asid = entryhi_asid;
315
 
316
wire micro_write_do = tlb_ram_fetch_hit && fetch_state == FETCH_TLB;
317
 
318
wire [49:0] micro_write_value = tlb_ram_fetch_result;
319
 
320
wire        micro_check_matched;
321
wire [49:0] micro_check_result;
322
 
323
memory_instr_tlb_micro memory_instr_tlb_micro_inst(
324
    .clk                (clk),
325
    .rst_n              (rst_n),
326
 
327
    //
328
    .micro_flush_do     (micro_flush_do),       //input
329
 
330
    //
331
    .micro_write_do     (micro_write_do),       //input
332
    .micro_write_value  (micro_write_value),    //input [49:0]
333
 
334
    //
335
    .micro_check_do     (micro_check_do),       //input
336
    .micro_check_vpn    (micro_check_vpn),      //input [19:0]
337
    .micro_check_asid   (micro_check_asid),     //input [5:0]
338
    .micro_check_matched(micro_check_matched),  //output
339
    .micro_check_result (micro_check_result)    //output [49:0]
340
);
341
 
342
//------------------------------------------------------------------------------
343
// synthesis translate_off
344
wire _unused_ok = &{ 1'b0, ram_result_address[1:0], micro_check_result[49], micro_check_result[47], micro_check_result[45:40], micro_check_result[19:0], 1'b0 };
345
// synthesis translate_on
346
//------------------------------------------------------------------------------
347
 
348
endmodule

powered by: WebSVN 2.1.0

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