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

Subversion Repositories myblaze

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

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

powered by: WebSVN 2.1.0

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