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

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [execute.py] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rockee
# -*- coding: utf-8 -*-
2
"""
3
    execute.py
4
    ==========
5
 
6
    Execute Unit
7
 
8 5 rockee
    :copyright: Copyright (c) 2010 Jian Luo
9
    :author-email: jian.luo.cn(at_)gmail.com
10
    :license: LGPL, see LICENSE for details
11 2 rockee
    :revision: $Id: execute.py 6 2010-11-21 23:18:44Z rockee $
12
"""
13
 
14
from myhdl import *
15
from defines import *
16
from functions import *
17
 
18
def ExecuteUnit(
19
        # Inputs
20
        clock,
21
        reset,
22
        enable,
23
        dmem_data_in,
24
        gprf_dat_a,
25
        gprf_dat_b,
26
        gprf_dat_d,
27
        mm_alu_result,
28
        mm_mem_read,
29
        mm_reg_d,
30
        mm_reg_write,
31
        mm_transfer_size,
32
        of_alu_op,
33
        of_alu_src_a,
34
        of_alu_src_b,
35
        of_branch_cond,
36
        of_carry,
37
        of_carry_keep,
38
        of_delay,
39
        of_immediate,
40
        of_mem_read,
41
        of_mem_write,
42
        of_operation,
43
        of_program_counter,
44
        of_reg_a,
45
        of_reg_b,
46
        of_reg_d,
47
        of_reg_write,
48
        of_transfer_size,
49
 
50
        # Write back stage forwards
51
        of_fwd_mem_result,
52
        of_fwd_reg_d,
53
        of_fwd_reg_write,
54
 
55
        # Outputs
56
        ex_alu_result,
57
        ex_reg_d,
58
        ex_reg_write,
59
 
60
        ex_branch,
61
        ex_dat_d,
62
        ex_flush_id,
63
        ex_mem_read,
64
        ex_mem_write,
65
        ex_program_counter,
66
        ex_transfer_size,
67
 
68 6 rockee
        # Ports only for debug
69
        of_instruction=0,
70
        ex_dat_a=0,
71
        ex_dat_b=0,
72
        ex_instruction=0,
73
        ex_reg_a=0,
74
        ex_reg_b=0,
75 2 rockee
 
76
    ):
77
    """
78
    """
79
    ex_r_carry = Signal(False)
80
    ex_r_flush_ex= Signal(False)
81
 
82 6 rockee
    ex_r_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
83
    ex_r_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
84 2 rockee
    ex_r_reg_write = Signal(False)
85
 
86
    ex_comb_r_carry = Signal(False)
87
    ex_comb_r_flush_ex = Signal(False)
88
 
89 6 rockee
    ex_comb_r_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
90
    ex_comb_r_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
91 2 rockee
    ex_comb_r_reg_write = Signal(False)
92
 
93
    ex_comb_branch = Signal(False)
94 6 rockee
    ex_comb_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
95 2 rockee
    ex_comb_flush_id = Signal(False)
96
    ex_comb_mem_read = Signal(False)
97
    ex_comb_mem_write = Signal(False)
98
    ex_comb_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
99
    ex_comb_transfer_size = Signal(transfer_size_type.WORD)
100
 
101 6 rockee
    if __debug__:
102
        ex_comb_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
103
        ex_comb_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
104
        ex_comb_instruction = Signal(intbv(0)[CFG_DMEM_WIDTH:])
105
        ex_comb_reg_a = Signal(intbv(0)[CFG_GPRF_SIZE:])
106
        ex_comb_reg_b = Signal(intbv(0)[CFG_GPRF_SIZE:])
107 2 rockee
 
108
    @always_comb
109
    def regout():
110
        ex_alu_result.next = ex_r_alu_result
111
        ex_reg_d.next = ex_r_reg_d
112
        ex_reg_write.next = ex_r_reg_write
113
 
114
    cpu_clock = 0
115
    @always(clock.posedge)
116
    def seq():
117 6 rockee
        """
118
        ExecUnit sequential logic
119
        """
120 2 rockee
        if reset:
121
            ex_r_carry.next = False
122
            ex_r_flush_ex.next = False
123
 
124 6 rockee
            ex_r_alu_result.next = intbv(0)[CFG_DMEM_WIDTH:]
125
            ex_r_reg_d.next = intbv(0)[CFG_GPRF_SIZE:]
126 2 rockee
            ex_r_reg_write.next = False
127
 
128
            ex_branch.next = False
129 6 rockee
            ex_dat_d.next = intbv(0)[CFG_DMEM_WIDTH:]
130 2 rockee
            ex_flush_id.next = False
131
            ex_mem_read.next = False
132
            ex_mem_write.next = False
133
            ex_program_counter.next = intbv(0)[CFG_IMEM_SIZE:]
134
            ex_transfer_size.next = transfer_size_type.WORD
135
 
136
        elif enable:
137
            ex_r_carry.next = ex_comb_r_carry
138
            ex_r_flush_ex.next = ex_comb_r_flush_ex
139
 
140
            ex_r_alu_result.next = ex_comb_r_alu_result
141
            ex_r_reg_d.next = ex_comb_r_reg_d
142
            ex_r_reg_write.next = ex_comb_r_reg_write
143
 
144
            ex_branch.next = ex_comb_branch
145
            ex_dat_d.next = ex_comb_dat_d
146
            ex_flush_id.next = ex_comb_flush_id
147
            ex_mem_read.next = ex_comb_mem_read
148
            ex_mem_write.next = ex_comb_mem_write
149
            ex_program_counter.next = ex_comb_program_counter
150
            ex_transfer_size.next = ex_comb_transfer_size
151
 
152 6 rockee
        if __debug__:
153
          if enable:
154
            ex_dat_a.next = ex_comb_dat_a
155
            ex_dat_b.next = ex_comb_dat_b
156
            ex_instruction.next = ex_comb_instruction
157
            ex_reg_a.next = ex_comb_reg_a
158
            ex_reg_b.next = ex_comb_reg_b
159 2 rockee
 
160
    @always_comb
161
    def comb():
162 6 rockee
        """
163
        ExecUnit combinatorial logic
164
        """
165 2 rockee
        # Signals mapping
166
        r_carry = False
167
        r_flush_ex = False
168
 
169
        r_alu_result = intbv(0)[CFG_DMEM_WIDTH:]
170 6 rockee
        r_reg_d = intbv(0)[CFG_GPRF_SIZE:]
171 2 rockee
        r_reg_write = False
172
 
173
        branch = False
174
        dat_d = intbv(0)[CFG_DMEM_WIDTH:]
175
        flush_id = False
176
        mem_read = False
177
        mem_write = False
178
        program_counter = intbv(0)[CFG_IMEM_SIZE:]
179
        transfer_size = transfer_size_type.WORD
180
 
181
        # Local Variables 
182
        alu_src_a = intbv(0)[CFG_DMEM_WIDTH:]
183
        alu_src_b = intbv(0)[CFG_DMEM_WIDTH:]
184
        carry = False
185
 
186
        result = intbv(0)[CFG_DMEM_WIDTH+1:]
187
        result_add = intbv(0)[CFG_DMEM_WIDTH+1:]
188
        zero = False
189
 
190
        dat_a = intbv(0)[CFG_DMEM_WIDTH:]
191
        dat_b = intbv(0)[CFG_DMEM_WIDTH:]
192
        sel_dat_a = intbv(0)[CFG_DMEM_WIDTH:]
193
        sel_dat_b = intbv(0)[CFG_DMEM_WIDTH:]
194
        sel_dat_d = intbv(0)[CFG_DMEM_WIDTH:]
195
        mem_result = intbv(0)[CFG_DMEM_WIDTH:]
196
 
197
        # XXX: write back result must be forwarded,
198
        # if gprf has read old data behaviour
199
        #cfg_reg_fwd_wrb = CFG_REG_FWD_WRB   # Hacked to pass VHDL syntax check
200
        #if cfg_reg_fwd_wrb:
201
        sel_dat_a[:] = select_register_data(
202
                            gprf_dat_a, of_reg_a, of_fwd_mem_result,
203
                            forward_condition(of_fwd_reg_write,
204
                                              of_fwd_reg_d, of_reg_a)
205
                       )
206
        sel_dat_b[:] = select_register_data(
207
                            gprf_dat_b, of_reg_b, of_fwd_mem_result,
208
                            forward_condition(of_fwd_reg_write,
209
                                              of_fwd_reg_d, of_reg_b)
210
                       )
211
        sel_dat_d[:] = select_register_data(
212
                            gprf_dat_d, of_reg_d, of_fwd_mem_result,
213
                            forward_condition(of_fwd_reg_write,
214
                                              of_fwd_reg_d, of_reg_d)
215
                       )
216
        #else:
217
            #sel_dat_a[:] = gprf_dat_a
218
            #sel_dat_b[:] = gprf_dat_b
219
            #sel_dat_d[:] = gprf_dat_d
220
 
221
 
222
        if not ex_r_flush_ex:
223
            mem_write = bool(of_mem_write)
224
            mem_read = bool(of_mem_read)
225
            transfer_size = of_transfer_size.val # Needed?
226
            r_reg_write = bool(of_reg_write)
227
            r_reg_d[:] = of_reg_d
228
 
229
        if mm_mem_read:
230
            mem_result[:] = align_mem_load(dmem_data_in, mm_transfer_size,
231
                                        mm_alu_result[2:])
232
        else:
233
            mem_result[:] = mm_alu_result
234
 
235
        # Reg A
236
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_a) == True:
237
            # Forward from exec
238
            dat_a[:] = ex_r_alu_result
239
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_a) == True:
240
            # Forward from mem
241
            dat_a[:] = mem_result
242
        else:
243
            # Default from gprf
244
            dat_a[:] = sel_dat_a
245
 
246
        # Reg B
247
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_b) == True:
248
            # Forward from exec
249
            dat_b[:] = ex_r_alu_result
250
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_b) == True:
251
            # Forward from mem
252
            dat_b[:] = mem_result
253
        else:
254
            # Default from gprf
255
            dat_b[:] = sel_dat_b
256
 
257
        # XXX Why bother?
258
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_d) == True:
259
            dat_d[:] = align_mem_store(ex_r_alu_result, of_transfer_size)
260
            #print 'fwd_ex r%d=%x' % (of_reg_d, dat_d)
261
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_d) == True:
262
            dat_d[:] = align_mem_store(mem_result, of_transfer_size)
263
 
264
            #print 'fwd_mm r%d=%x' % (of_reg_d, dat_d)
265
        else:
266
            dat_d[:] = align_mem_store(sel_dat_d, of_transfer_size)
267
            #print 'gprf r%d=%x'  % (of_reg_d, dat_d)
268
 
269
        # Operand A
270
        if of_alu_src_a == src_type_a.PC:
271
            alu_src_a[:] = of_program_counter
272
        elif of_alu_src_a == src_type_a.NOT_REGA:
273
            alu_src_a[:] = ~dat_a
274
        elif of_alu_src_a == src_type_a.REGA_ZERO:
275
            alu_src_a[:] = 0
276
        else:
277
            alu_src_a[:] = dat_a
278
 
279
        # Operand B
280
        if of_alu_src_b == src_type_b.IMM:
281
            alu_src_b[:] = of_immediate
282
        elif of_alu_src_b == src_type_b.NOT_IMM:
283
            alu_src_b[:] = ~of_immediate
284
        elif of_alu_src_b == src_type_b.NOT_REGB:
285
            alu_src_b[:] = ~dat_b
286
        else:
287
            alu_src_b[:] = dat_b
288
 
289
        # Determine value of carry in
290
        if of_carry == carry_type.ALU:
291
            carry = bool(ex_r_carry)
292
        elif of_carry == carry_type.C_ONE:
293
            carry = True
294
        elif of_carry == carry_type.ARITH:
295
            carry = alu_src_a[CFG_DMEM_WIDTH-1]
296
        else:
297
            carry = False
298
 
299
        #result_add[:] = alu_src_a.signed() + alu_src_b.signed() + carry
300
        result_add[:] = add(alu_src_a, alu_src_b, carry)
301
 
302
        if of_alu_op == alu_operation.ALU_ADD:
303
            result[:] = result_add
304
        elif of_alu_op == alu_operation.ALU_OR:
305
            or_rslt = intbv(0)[CFG_DMEM_WIDTH:]
306
            or_rslt[:] = alu_src_a | alu_src_b
307
            result[:] = or_rslt
308
        elif of_alu_op == alu_operation.ALU_AND:
309
            and_rslt = intbv(0)[CFG_DMEM_WIDTH:]
310
            and_rslt[:] = alu_src_a & alu_src_b
311
            result[:] = and_rslt
312
        elif of_alu_op == alu_operation.ALU_XOR:
313
            xor_rslt = intbv(0)[CFG_DMEM_WIDTH:]
314
            xor_rslt[:] = alu_src_a ^ alu_src_b
315
            result[:] = xor_rslt
316
        elif of_alu_op == alu_operation.ALU_SHIFT:
317
            result[:] = concat(alu_src_a[0], carry, alu_src_a[CFG_DMEM_WIDTH:1])
318
        elif of_alu_op == alu_operation.ALU_SEXT8:
319
 
320
            result[:] = concat(False, sign_extend8(alu_src_a, alu_src_a[7]))
321
            #result[:] = concat(False, sign_extend(alu_src_a, alu_src_a[7],
322
                                                  #8, CFG_DMEM_WIDTH))
323
        elif of_alu_op == alu_operation.ALU_SEXT16:
324
            result[:] = concat(False, sign_extend16(alu_src_a, alu_src_a[15]))
325
            #result[:] = concat(False, sign_extend(alu_src_a, alu_src_a[15],
326
                                                  #16, CFG_DMEM_WIDTH))
327
        else:
328
            result[:] = 0
329 6 rockee
            if __debug__:
330
                assert False, 'FATAL Error: Unsupported ALU operation'
331 2 rockee
 
332
        # Set carry register
333
        if of_carry_keep:
334
            r_carry = bool(ex_r_carry) # bool() needs for signal type mismatch
335
        else:
336
            r_carry = result[CFG_DMEM_WIDTH]
337
 
338
        if not ex_r_flush_ex:
339
            zero = dat_a == 0
340
 
341
            if of_branch_cond == branch_condition.BRU:
342
                branch = True
343
            elif of_branch_cond == branch_condition.BEQ:
344
                branch = zero
345
            elif of_branch_cond == branch_condition.BNE:
346
                branch = not zero
347
            elif of_branch_cond == branch_condition.BLT:
348
                branch = dat_a[CFG_DMEM_WIDTH-1]
349
            elif of_branch_cond == branch_condition.BLE:
350
                branch = dat_a[CFG_DMEM_WIDTH-1] or zero
351
            elif of_branch_cond == branch_condition.BGT:
352
                branch = not bool(dat_a[CFG_DMEM_WIDTH-1] or zero)
353
            elif of_branch_cond == branch_condition.BGE:
354
                branch = not dat_a[CFG_DMEM_WIDTH-1]
355
            else:
356
                branch = False
357
 
358
        # Handle CMPU
359
        cmp_cond = alu_src_a[CFG_DMEM_WIDTH-1] ^ alu_src_b[CFG_DMEM_WIDTH-1]
360 6 rockee
        if of_operation and bool(cmp_cond):
361 2 rockee
            ## Set MSB
362
            msb = alu_src_a[CFG_DMEM_WIDTH-1]
363
            r_alu_result[:] = concat(msb, result[CFG_DMEM_WIDTH-1:])
364
        else:
365
            r_alu_result[:] = result[CFG_DMEM_WIDTH:]
366
 
367
        program_counter[:] = of_program_counter
368
 
369
        # Determine flush signals
370
        flush_id = branch
371
        r_flush_ex = branch and not of_delay
372
 
373
        # Write to local register
374
        ex_comb_r_carry.next = r_carry
375
        ex_comb_r_flush_ex.next = r_flush_ex
376
 
377
        ex_comb_r_alu_result.next = r_alu_result
378
        ex_comb_r_reg_d.next = r_reg_d
379
        ex_comb_r_reg_write.next = r_reg_write
380
 
381
        ex_comb_branch.next = branch
382
        ex_comb_dat_d.next = dat_d
383
        ex_comb_flush_id.next = flush_id
384
        ex_comb_mem_read.next = mem_read
385
        ex_comb_mem_write.next = mem_write
386
        ex_comb_program_counter.next = program_counter
387
        ex_comb_transfer_size.next = transfer_size
388
 
389 6 rockee
        if __debug__:
390
            ex_comb_dat_a.next = dat_a
391
            ex_comb_dat_b.next = dat_b
392
            ex_comb_instruction.next = of_instruction
393
            ex_comb_reg_a.next = of_reg_a
394
            ex_comb_reg_b.next = of_reg_b
395 2 rockee
 
396
    return instances()
397
 
398
if __name__ == '__main__':
399
    clock = Signal(False)
400
    reset = Signal(False)
401
    enable = Signal(False)
402
 
403 6 rockee
    dmem_data_in = Signal(intbv(0)[CFG_DMEM_WIDTH:])
404 2 rockee
 
405 6 rockee
    mm_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
406 2 rockee
    mm_mem_read =  Signal(False)
407 6 rockee
    mm_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
408 2 rockee
    mm_reg_write = Signal(False)
409
    mm_transfer_size = Signal(transfer_size_type.WORD)
410
 
411 6 rockee
    gprf_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
412
    gprf_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
413
    gprf_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
414 2 rockee
 
415
    ex_flush_id = Signal(False)
416
    of_alu_op = Signal(alu_operation.ALU_ADD)
417
    of_alu_src_a = Signal(src_type_a.REGA)
418
    of_alu_src_b = Signal(src_type_b.REGB)
419
    of_branch_cond = Signal(branch_condition.NOP)
420
    of_carry = Signal(carry_type.C_ZERO)
421
    of_carry_keep = Signal(False)
422
    of_delay = Signal(False)
423
    of_hazard = Signal(False)
424 6 rockee
    of_immediate = Signal(intbv(0)[CFG_DMEM_WIDTH:])
425 2 rockee
    of_mem_read = Signal(False)
426
    of_mem_write = Signal(False)
427
    of_operation = Signal(False)
428
    of_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
429 6 rockee
    of_reg_a = Signal(intbv(0)[CFG_GPRF_SIZE:])
430
    of_reg_b = Signal(intbv(0)[CFG_GPRF_SIZE:])
431
    of_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
432 2 rockee
    of_reg_write = Signal(False)
433
    of_transfer_size = Signal(transfer_size_type.WORD)
434 6 rockee
    # Write back stage forwards
435
    of_fwd_mem_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
436
    of_fwd_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
437
    of_fwd_reg_write = Signal(False)
438 2 rockee
 
439 6 rockee
    ex_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
440
    ex_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
441 2 rockee
    ex_reg_write = Signal(False)
442
 
443
    ex_branch = Signal(False)
444 6 rockee
    ex_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
445 2 rockee
    ex_flush_id = Signal(False)
446
    ex_mem_read = Signal(False)
447
    ex_mem_write = Signal(False)
448
    ex_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
449
    ex_transfer_size = Signal(transfer_size_type.WORD)
450
 
451
    kw = dict(
452
        clock=clock,
453
        reset=reset,
454
        enable=enable,
455
        dmem_data_in=dmem_data_in,
456
        gprf_dat_a=gprf_dat_a,
457
        gprf_dat_b=gprf_dat_b,
458
        gprf_dat_d=gprf_dat_d,
459
        mm_alu_result=mm_alu_result,
460
        mm_mem_read=mm_mem_read,
461
        mm_reg_d=mm_reg_d,
462
        mm_reg_write=mm_reg_write,
463
        mm_transfer_size=mm_transfer_size,
464
        of_alu_op=of_alu_op,
465
        of_alu_src_a=of_alu_src_a,
466
        of_alu_src_b=of_alu_src_b,
467
        of_branch_cond=of_branch_cond,
468
        of_carry=of_carry,
469
        of_carry_keep=of_carry_keep,
470
        of_delay=of_delay,
471
        of_immediate=of_immediate,
472
        of_mem_read=of_mem_read,
473
        of_mem_write=of_mem_write,
474
        of_operation=of_operation,
475
        of_program_counter=of_program_counter,
476
        of_reg_a=of_reg_a,
477
        of_reg_b=of_reg_b,
478
        of_reg_d=of_reg_d,
479
        of_reg_write=of_reg_write,
480
        of_transfer_size=of_transfer_size,
481 6 rockee
        # Write back stage forwards
482
        of_fwd_mem_result=of_fwd_mem_result,
483
        of_fwd_reg_d=of_fwd_reg_d,
484
        of_fwd_reg_write=of_fwd_reg_write,
485 2 rockee
        # Outputs
486
        ex_alu_result=ex_alu_result,
487
        ex_reg_d=ex_reg_d,
488
        ex_reg_write=ex_reg_write,
489
 
490
        ex_branch=ex_branch,
491
        ex_dat_d=ex_dat_d,
492
        ex_flush_id=ex_flush_id,
493
        ex_mem_read=ex_mem_read,
494
        ex_mem_write=ex_mem_write,
495
        ex_program_counter=ex_program_counter,
496
        ex_transfer_size=ex_transfer_size,
497
    )
498 6 rockee
    toVerilog(ExecuteUnit, **kw)
499
    toVHDL(ExecuteUnit, **kw)
500 2 rockee
 
501
### EOF ###
502
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
503
 

powered by: WebSVN 2.1.0

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