-
Notifications
You must be signed in to change notification settings - Fork 0
/
busarbiter.v
349 lines (319 loc) · 12.6 KB
/
busarbiter.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
// author: Laurentiu-Cristian Duca, date: 20240322
// spdx license identifier MIT
`include "define.vh"
module busarbiter(
// here we do not keep the w_ notation for wire
input wire CLK, RST_X, output wire [31:0] w_grant,
input wire w_init_done, input wire w_tx_ready,
output wire [31:0] w_mem_paddr, output wire w_data_we, output wire w_data_le,
input wire [3:0] w_data_busy, output reg [3:0] bus_data_busy0, output reg [3:0] bus_data_busy1,
output wire [31:0] w_data_wdata, input wire [31:0] w_data_data,
input wire [63:0] w_mtime,
output wire [1:0] w_tlb_req, output wire w_tlb_busy,
output wire [31:0] w_mip,
output wire [31:0] w_dram_addr, output wire [31:0] w_dram_wdata, input wire [31:0] w_dram_odata, output wire w_dram_we_t,
input wire w_dram_busy, output wire [2:0] w_dram_ctrl, output wire w_dram_le,
input wire [31:0] bus_core_ir0, input wire [3:0] bus_cpustate0,
input wire [31:0] bus_mem_paddr0, input wire bus_data_we0, input wire bus_data_le0,
input wire [31:0] bus_data_wdata0,
output reg [31:0] bus_data_data0,
input wire [1:0] bus_tlb_req0, input wire bus_tlb_busy0,
input [31:0] bus_mip0,
input [31:0] bus_dram_addr0, input [31:0] bus_dram_wdata0, output reg [31:0] bus_dram_odata0, input bus_dram_we_t0,
output reg bus_dram_busy0, input wire [2:0] bus_dram_ctrl0, input bus_dram_le0,
input wire [31:0] bus_core_ir1, input wire [3:0] bus_cpustate1,
input wire [31:0] bus_mem_paddr1, input wire bus_data_we1, input wire bus_data_le1,
input wire [31:0] bus_data_wdata1,
output reg [31:0] bus_data_data1,
input wire [1:0] bus_tlb_req1, input wire bus_tlb_busy1,
input [31:0] bus_mip1,
input [31:0] bus_dram_addr1, input [31:0] bus_dram_wdata1, output reg [31:0] bus_dram_odata1, input bus_dram_we_t1,
output reg bus_dram_busy1, input wire [2:0] bus_dram_ctrl1, input bus_dram_le1
);
/**********************************************************************************************/
reg [31:0] grant=0; // bus granted core
assign w_grant=grant;
reg [7:0] state=0;
wire w_sys_busy = w_dram_busy || !w_tx_ready || w_data_busy;
reg r_pending_req0=0, r_pending_req1=0;
`ifdef USE_SINGLE_CORE
always@(posedge CLK)
begin
if(!RST_X) begin
grant <= 0;
end else if(w_init_done) begin
if(state == 0) begin
if(w_sys_busy) begin
$display("------------- sys-busy in state0");
$finish;
end
if(bus_dram_le0 | bus_dram_we_t0 | bus_data_le0 | bus_data_we0) begin
// set control signals
r_ba_dram_le0 <= bus_dram_le0;
r_ba_dram_we_t0 <= bus_dram_we_t0;
r_ba_data_le0 <= bus_data_le0;
r_ba_data_we0 <= bus_data_we0;
// dram read or write
bus_dram_busy0 <= bus_dram_le0 | bus_dram_we_t0;
r_bus_dram_addr0 <= bus_dram_addr0;
r_bus_dram_ctrl0 <= bus_dram_ctrl0;
r_bus_dram_wdata0 <= bus_dram_wdata0;
// data read or write
bus_data_busy0 <= bus_data_le0 | bus_data_we0;
r_bus_mem_paddr0 <= bus_mem_paddr0;
r_bus_data_wdata0 <= bus_data_wdata0;
state <= 1;
end
end else if(state == 1) begin // dram read
if(w_sys_busy) begin
r_ba_dram_le0 <=0;
r_ba_dram_we_t0 <= 0;
r_ba_data_le0 <= 0;
r_ba_data_we0 <= 0;
state <= 2;
end
end else if(state == 2) begin
if(!w_sys_busy) begin
r_bus_dram_odata0 <= w_dram_odata;
r_bus_data_data0 <= w_data_data;
bus_dram_busy0 <= 0;
bus_data_busy0 <= 0;
state <= 0;
end
end
end // init_done
end
`else // dual core
always@(posedge CLK)
begin
if(!RST_X) begin
grant <= 0;
end else if(w_init_done) begin
if(state == 0) begin
if(w_sys_busy) begin
$display("------------- sys-busy in state0");
$finish;
end
if(grant == 1 && bus_core_ir1[6:0]==`OPCODE_AMO_____) begin
if(bus_dram_le1 | bus_dram_we_t1 | bus_data_le1 | bus_data_we1) begin
prepare_exec1;
state <= 1;
end
check_request0;
end else if(grant == 0 && bus_core_ir0[6:0]==`OPCODE_AMO_____) begin
if(bus_dram_le0 | bus_dram_we_t0 | bus_data_le0 | bus_data_we0) begin
prepare_exec0;
state <= 1;
end
check_request1;
end else if(r_pending_req1) begin
grant <= 1;
state <= 1;
exec1_aux;
check_request0;
end else if(r_pending_req0) begin
grant <= 0;
state <= 1;
exec0_aux;
check_request1;
end else if(bus_dram_le1 | bus_dram_we_t1 | bus_data_le1 | bus_data_we1) begin
grant <= 1;
prepare_exec1;
state <= 1;
check_request0;
end else if(bus_dram_le0 | bus_dram_we_t0 | bus_data_le0 | bus_data_we0) begin
grant <= 0;
prepare_exec0;
state <= 1;
check_request1;
end
end else if(state == 1) begin
if(w_sys_busy) begin
if(grant == 0) begin
r_ba_dram_le0 <=0;
r_ba_dram_we_t0 <= 0;
r_ba_data_le0 <= 0;
r_ba_data_we0 <= 0;
state <= 2;
end else begin
r_ba_dram_le1 <=0;
r_ba_dram_we_t1 <= 0;
r_ba_data_le1 <= 0;
r_ba_data_we1 <= 0;
state <= 2;
end
end
if(grant == 0)
check_request1;
else
check_request0;
end else if(state == 2) begin
if(!w_sys_busy) begin
if(grant == 0) begin
r_bus_dram_odata0 <= w_dram_odata;
r_bus_data_data0 <= w_data_data;
bus_dram_busy0 <= 0;
bus_data_busy0 <= 0;
state <= 0;
r_pending_req0 <= 0;
end else begin
r_bus_dram_odata1 <= w_dram_odata;
r_bus_data_data1 <= w_data_data;
bus_dram_busy1 <= 0;
bus_data_busy1 <= 0;
state <= 0;
r_pending_req1 <= 0;
end
end
if(grant == 0)
check_request1;
else
check_request0;
end
end // init_done
end
`endif
task check_request0;
begin
if((bus_dram_le0 | bus_dram_we_t0 | bus_data_le0 | bus_data_we0) && !r_pending_req0) begin
r_pending_req0 <= 1;
save_exec0;
end
end
endtask
task save_exec0;
begin
// set control signals
r_ba_dram_le0 <= 0;
r_ba_dram_we_t0 <= 0;
r_ba_data_le0 <= 0;
r_ba_data_we0 <= 0;
r_ba_dram_le0_aux <= bus_dram_le0;
r_ba_dram_we_t0_aux <= bus_dram_we_t0;
r_ba_data_le0_aux <= bus_data_le0;
r_ba_data_we0_aux <= bus_data_we0;
bus_dram_busy0 <= bus_dram_le0 | bus_dram_we_t0;
bus_data_busy0 <= bus_data_le0 | bus_data_we0;
save_bus_signals0;
end
endtask
task save_bus_signals0;
begin
// dram read or write
r_bus_dram_addr0 <= bus_dram_addr0;
r_bus_dram_ctrl0 <= bus_dram_ctrl0;
r_bus_dram_wdata0 <= bus_dram_wdata0;
// data read or write
r_bus_mem_paddr0 <= bus_mem_paddr0;
r_bus_data_wdata0 <= bus_data_wdata0;
end
endtask
task exec0_aux;
begin
// set control signals
r_ba_dram_le0 <= r_ba_dram_le0_aux;
r_ba_dram_we_t0 <= r_ba_dram_we_t0_aux;
r_ba_data_le0 <= r_ba_data_le0_aux;
r_ba_data_we0 <= r_ba_data_we0_aux;
end
endtask
task prepare_exec0;
begin
// set control signals
r_ba_dram_le0 <= bus_dram_le0;
r_ba_dram_we_t0 <= bus_dram_we_t0;
r_ba_data_le0 <= bus_data_le0;
r_ba_data_we0 <= bus_data_we0;
bus_dram_busy0 <= bus_dram_le0 | bus_dram_we_t0;
bus_data_busy0 <= bus_data_le0 | bus_data_we0;
save_bus_signals0;
end
endtask
task check_request1;
begin
if((bus_dram_le1 | bus_dram_we_t1 | bus_data_le1 | bus_data_we1) && !r_pending_req1) begin
r_pending_req1 <= 1;
save_exec1;
end
end
endtask
task save_exec1;
begin
// set control signals
r_ba_dram_le1 <= 0;
r_ba_dram_we_t1 <= 0;
r_ba_data_le1 <= 0;
r_ba_data_we1 <= 0;
r_ba_dram_le1_aux <= bus_dram_le1;
r_ba_dram_we_t1_aux <= bus_dram_we_t1;
r_ba_data_le1_aux <= bus_data_le1;
r_ba_data_we1_aux <= bus_data_we1;
bus_dram_busy1 <= bus_dram_le1 | bus_dram_we_t1;
bus_data_busy1 <= bus_data_le1 | bus_data_we1;
save_bus_signals1;
end
endtask
task save_bus_signals1;
begin
// dram read or write
r_bus_dram_addr1 <= bus_dram_addr1;
r_bus_dram_ctrl1 <= bus_dram_ctrl1;
r_bus_dram_wdata1 <= bus_dram_wdata1;
// data read or write
r_bus_mem_paddr1 <= bus_mem_paddr1;
r_bus_data_wdata1 <= bus_data_wdata1;
end
endtask
task exec1_aux;
begin
// set control signals
r_ba_dram_le1 <= r_ba_dram_le1_aux;
r_ba_dram_we_t1 <= r_ba_dram_we_t1_aux;
r_ba_data_le1 <= r_ba_data_le1_aux;
r_ba_data_we1 <= r_ba_data_we1_aux;
end
endtask
task prepare_exec1;
begin
// set control signals
r_ba_dram_le1 <= bus_dram_le1;
r_ba_dram_we_t1 <= bus_dram_we_t1;
r_ba_data_le1 <= bus_data_le1;
r_ba_data_we1 <= bus_data_we1;
bus_dram_busy1 <= bus_dram_le1 | bus_dram_we_t1;
bus_data_busy1 <= bus_data_le1 | bus_data_we1;
save_bus_signals1;
end
endtask
always @(*) begin
bus_dram_odata0 <= r_bus_dram_odata0;
bus_data_data0 <= r_bus_data_data0;
bus_dram_odata1 <= r_bus_dram_odata1;
bus_data_data1 <= r_bus_data_data1;
end
assign w_dram_addr = grant == 0 ? r_bus_dram_addr0 : r_bus_dram_addr1;
assign w_dram_wdata = grant == 0 ? r_bus_dram_wdata0 : r_bus_dram_wdata1;
assign w_dram_we_t = grant == 0 ? r_ba_dram_we_t0 : r_ba_dram_we_t1;
assign w_dram_le = grant == 0 ? r_ba_dram_le0 : r_ba_dram_le1;
assign w_dram_ctrl = grant == 0 ? r_bus_dram_ctrl0 : r_bus_dram_ctrl1;
assign w_mem_paddr = grant == 0 ? r_bus_mem_paddr0 : r_bus_mem_paddr1;
assign w_data_we = grant == 0 ? r_ba_data_we0 : r_ba_data_we1;
assign w_data_le = grant == 0 ? r_ba_data_le0 : r_ba_data_le1;
assign w_data_wdata = grant == 0 ? r_bus_data_wdata0 : r_bus_data_wdata1;
assign w_tlb_req = grant == 0 ? bus_tlb_req0 : bus_tlb_req1;
assign w_tlb_busy = grant == 0 ? bus_tlb_busy0 : bus_tlb_busy1;
assign w_mip = grant == 0 ? bus_mip0 : bus_mip1;
wire [31:0] w_core_ir = grant == 0 ? bus_core_ir0 : bus_core_ir1;
wire [3:0] w_bus_cpustate = grant == 0 ? bus_cpustate0 : bus_cpustate1;
reg [31:0] r_bus_dram_addr0=0, r_bus_dram_addr1=0;
reg [31:0] r_bus_dram_wdata0=0, r_bus_dram_wdata1=0;
reg r_ba_dram_we_t0=0, r_ba_dram_we_t1=0, r_ba_dram_we_t0_aux=0, r_ba_dram_we_t1_aux=0;
reg r_ba_dram_le0=0, r_ba_dram_le1=0, r_ba_dram_le0_aux=0, r_ba_dram_le1_aux=0;
reg [2:0] r_bus_dram_ctrl0=0, r_bus_dram_ctrl1=0;
reg [31:0] r_bus_dram_odata0=0, r_bus_dram_odata1=0;
reg [31:0] r_bus_mem_paddr0=0, r_bus_mem_paddr1=0;
reg r_ba_data_we0=0, r_ba_data_we1=0, r_ba_data_we0_aux=0, r_ba_data_we1_aux=0;
reg r_ba_data_le0=0, r_ba_data_le1=0, r_ba_data_le0_aux=0, r_ba_data_le1_aux=0;
reg [31:0] r_bus_data_wdata0=0, r_bus_data_wdata1=0;
reg [31:0] r_bus_data_data0=0, r_bus_data_data1=0;
endmodule