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

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [decoder.py] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rockee
# -*- coding: utf-8 -*-
2
"""
3
    decoder.py
4
    ==========
5
 
6
    Instruction Decoder
7
 
8
    :copyright: Copyright (c) 2010 Jian Luo.
9
    :author-email: jian <dot> luo <dot> cn <at> gmail <dot> com.
10
    :license: BSD, see LICENSE for details.
11
    :revision: $Id: decoder.py 3 2010-11-21 07:17:00Z rockee $
12
"""
13
 
14
from random import randrange
15
from myhdl import *
16
from defines import *
17
from functions import *
18
from gprf import *
19
from debug import *
20
 
21
def Decoder(
22
        # Inputs
23
        clock,
24
        reset,
25
        enable,
26
        dmem_data_in,
27
        imem_data_in,
28
        if_program_counter,
29
        ex_flush_id,
30
        mm_alu_result,
31
        mm_mem_read,
32
        mm_reg_d,
33
        mm_reg_write,
34
        mm_transfer_size,
35
 
36
        # Outputs
37
        gprf_dat_a,
38
        gprf_dat_b,
39
        gprf_dat_d,
40
        of_alu_op,
41
        of_alu_src_a,
42
        of_alu_src_b,
43
        of_branch_cond,
44
        of_carry,
45
        of_carry_keep,
46
        of_delay,
47
        of_hazard,
48
        of_immediate,
49
        of_mem_read,
50
        of_mem_write,
51
        of_operation,
52
        of_program_counter,
53
        of_reg_a,
54
        of_reg_b,
55
        of_reg_d,
56
        of_reg_write,
57
        of_transfer_size,
58
 
59
        # Write back stage outputs
60
        of_fwd_mem_result,
61
        of_fwd_reg_d,
62
        of_fwd_reg_write,
63
 
64
        # XXX: if __debug__:
65
        #of_instruction=False,
66
    ):
67
    """
68
    Python System Model of the OF Stage
69
    """
70
    of_comb_r_has_imm_high = Signal(False)
71
    of_comb_r_hazard = Signal(False)
72
    of_comb_r_immediate_high = Signal(intbv(0)[16:])
73
    of_comb_r_instruction = Signal(intbv(0)[CFG_DMEM_WIDTH:])
74
    of_comb_r_mem_read = Signal(False)
75
    of_comb_r_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
76
    of_comb_r_reg_d = Signal(intbv(0)[5:])
77
    of_r_has_imm_high = Signal(False)
78
    of_r_hazard = Signal(False)
79
    of_r_immediate_high = Signal(intbv(0)[16:])
80
    of_r_instruction = Signal(intbv(0)[CFG_DMEM_WIDTH:])
81
    of_r_mem_read = Signal(False)
82
    of_r_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
83
    of_r_reg_d = Signal(intbv(0)[5:])
84
 
85
    of_comb_alu_op = Signal(alu_operation.ALU_ADD)
86
    of_comb_alu_src_a = Signal(src_type_a.REGA)
87
    of_comb_alu_src_b = Signal(src_type_b.REGB)
88
    of_comb_branch_cond = Signal(branch_condition.NOP)
89
    of_comb_carry = Signal(carry_type.C_ZERO)
90
    of_comb_carry_keep = Signal(False)
91
    of_comb_delay = Signal(False)
92
    of_comb_immediate = Signal(intbv(0)[CFG_DMEM_WIDTH:])
93
    of_comb_instruction = Signal(intbv(0)[CFG_DMEM_WIDTH:])
94
    of_comb_mem_write = Signal(False)
95
    of_comb_operation = Signal(False)
96
    of_comb_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
97
    of_comb_reg_a = Signal(intbv(0)[5:])
98
    of_comb_reg_b = Signal(intbv(0)[5:])
99
    of_comb_reg_write = Signal(False)
100
    of_comb_transfer_size = Signal(transfer_size_type.WORD)
101
 
102
    wb_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
103
 
104
    gprf = GPRF(
105
                clock=clock,
106
                enable=enable,
107
                gprf_adr_a_i=of_comb_reg_a,
108
                gprf_adr_b_i=of_comb_reg_b,
109
                gprf_adr_d_i=of_comb_r_reg_d,
110
                gprf_dat_w_i=wb_dat_d,
111
                gprf_adr_w_i=mm_reg_d,
112
                gprf_wre_i=mm_reg_write,
113
                gprf_dat_a_o=gprf_dat_a,
114
                gprf_dat_b_o=gprf_dat_b,
115
                gprf_dat_d_o=gprf_dat_d,
116
           )
117
 
118
    @always(clock.posedge)
119
    def decode():
120
        #cfg_reg_fwd_wrb = CFG_REG_FWD_WRB   # Hacked to pass VHDL syntax check
121
 
122
        if reset:
123
            of_alu_op.next = alu_operation.ALU_ADD
124
            of_alu_src_a.next = src_type_a.REGA
125
            of_alu_src_b.next = src_type_b.REGB
126
            of_branch_cond.next = branch_condition.NOP
127
            of_carry.next = carry_type.C_ZERO
128
            of_carry_keep.next = False
129
            of_delay.next = False
130
            of_immediate.next = 0
131
            of_mem_write.next = False
132
            of_operation.next = False
133
            of_program_counter.next = 0
134
            of_reg_a.next = 0
135
            of_reg_b.next = 0
136
            of_reg_write.next = False
137
            of_transfer_size.next = transfer_size_type.WORD
138
 
139
            of_r_mem_read.next = False
140
            of_r_reg_d.next = 0
141
            of_r_hazard.next = False
142
            of_r_has_imm_high.next = False
143
            of_r_immediate_high.next = 0
144
            of_r_instruction.next = 0
145
            of_r_program_counter.next = 0
146
 
147
            of_fwd_mem_result.next = 0
148
            of_fwd_reg_d.next = 0
149
            of_fwd_reg_write.next = False
150
 
151
        elif enable:
152
            of_alu_op.next = of_comb_alu_op
153
            of_alu_src_a.next = of_comb_alu_src_a
154
            of_alu_src_b.next = of_comb_alu_src_b
155
            of_branch_cond.next = of_comb_branch_cond
156
            of_carry.next = of_comb_carry
157
            of_carry_keep.next = of_comb_carry_keep
158
            of_delay.next = of_comb_delay
159
            of_immediate.next = of_comb_immediate
160
            of_mem_write.next = of_comb_mem_write
161
            of_operation.next = of_comb_operation
162
            of_program_counter.next = of_comb_program_counter
163
            of_reg_a.next = of_comb_reg_a
164
            of_reg_b.next = of_comb_reg_b
165
            of_reg_write.next = of_comb_reg_write
166
            of_transfer_size.next = of_comb_transfer_size
167
 
168
            of_r_mem_read.next = of_comb_r_mem_read
169
            of_r_reg_d.next = of_comb_r_reg_d
170
            of_r_hazard.next = of_comb_r_hazard
171
            of_r_has_imm_high.next = of_comb_r_has_imm_high
172
            of_r_immediate_high.next = of_comb_r_immediate_high
173
            of_r_instruction.next = of_comb_r_instruction
174
            of_r_program_counter.next = of_comb_r_program_counter
175
 
176
            #if cfg_reg_fwd_wrb == True:
177
            of_fwd_mem_result.next = wb_dat_d
178
            of_fwd_reg_d.next = mm_reg_d
179
            of_fwd_reg_write.next = mm_reg_write
180
 
181
        #if __debug__:
182
            #if 0: # DEBUG_VERBOSE:
183
                #print 'OF reged:', of_reg_write, of_reg_d,' ra:', of_reg_a
184
                #print 'OF reged pc:', of_r_program_counter
185
                #print 'OF rd:', mm_reg_write, mm_reg_d, wb_dat_d,
186
                #print ' ra:', imem_data_in[21:16]
187
                #print 'OF pc:', of_comb_program_counter
188
 
189
    @always_comb
190
    def regout():
191
        of_hazard.next = of_r_hazard
192
        of_mem_read.next = of_r_mem_read
193
        of_reg_d.next = of_r_reg_d
194
        #if __debug__:
195
        #of_instruction.next = of_r_instruction
196
 
197
    @always_comb
198
    def comb():
199
        # XXX intbvs should be explicitly declared
200
        # Register
201
        r_instruction = intbv(0)[32:]
202
        r_instruction[:] = imem_data_in
203
        r_program_counter = intbv(0)[CFG_IMEM_SIZE:]
204
        r_program_counter[:] = if_program_counter
205
        r_immediate_high = intbv(0)[16:]
206
        r_has_imm_high = False
207
        r_reg_d = intbv(0)[5:]
208
        # Local
209
        r_hazard = False
210
        immediate = intbv(0)[32:]
211
        #r_immediate_high = intbv(0)[16:]
212
        immediate_low = intbv(0)[16:]
213
        instruction = intbv(0)[32:]
214
        mem_result = intbv(0)[32:]
215
        opcode = intbv(0)[6:]
216
        opgroup = intbv(0)[5:]
217
        program_counter = intbv(0)[CFG_IMEM_SIZE:]
218
        reg_a = intbv(0)[5:]
219
        reg_b = intbv(0)[5:]
220
 
221
        if mm_mem_read:
222
            mem_result[:] = align_mem_load(dmem_data_in, mm_transfer_size,
223
                                           mm_alu_result[2:])
224
            #print 'of: load %x' % mem_result
225
        else:
226
            mem_result[:] = mm_alu_result
227
 
228
        wb_dat_d.next = mem_result
229
 
230
        if not ex_flush_id and of_r_mem_read and (
231
                imem_data_in[21:16] == of_r_reg_d or
232
                imem_data_in[16:11] == of_r_reg_d):
233
            # A hazard occurred on register a or b
234
            instruction[:] = 0
235
            program_counter[:] = 0
236
            r_hazard = True
237
        elif not ex_flush_id and of_r_mem_read and (
238
                imem_data_in[26:21] == of_r_reg_d):
239
            # A hazard occurred on register d
240
            # This actually only applies to store after load, but it's also
241
            # nonsense to discard the result just after read it from memory.
242
            # So, trigger a hazard alarm whenever Rd is the same,
243
            # in order to simplify the logic.
244
            instruction[:] = 0
245
            program_counter[:] = 0
246
            r_hazard = True
247
        elif of_r_hazard:
248
            instruction[:] = of_r_instruction
249
            program_counter[:] = of_r_program_counter
250
            r_hazard = False
251
        else:
252
            instruction[:] = imem_data_in
253
            program_counter[:] = if_program_counter
254
            r_hazard = False
255
 
256
        # Dissemble instruction
257
        opgroup[:] = concat(instruction[32:30], instruction[29:26])
258
        opcode[:] = instruction[32:26]
259
        has_imm = opcode[3]
260
        immediate_low[:] = instruction[16:]
261
        reg_a[:] = instruction[21:16]
262
        reg_b[:] = instruction[16:11]
263
        r_reg_d[:] = instruction[26:21]
264
 
265
        # Process immediate
266
        # IMM15 will only be used as msr bitmap
267
        # so there is no need to treat it separately
268
        if of_r_has_imm_high: # last inst is imm
269
            immediate[:] = concat(of_r_immediate_high, immediate_low)
270
        else:
271
            immediate[:] = sign_extend16(immediate_low, immediate_low[15])
272
 
273
 
274
        # Default Mux States
275
        alu_op = alu_operation.ALU_ADD
276
        alu_src_a = src_type_a.REGA
277
        alu_src_b = src_type_b.REGB
278
        branch_cond = branch_condition.NOP
279
        carry = carry_type.C_ZERO
280
        carry_keep = False
281
        delay = False
282
        r_mem_read = False
283
        mem_write = False
284
        operation = False
285
        reg_write = False
286
        transfer_size = transfer_size_type.WORD
287
 
288
        if bool(ex_flush_id or r_hazard):
289
            pass
290
        elif opgroup[5:3] == OPG_ADD:
291
            # ADD / SUBTRACT / COMPARE
292
            alu_op = alu_operation.ALU_ADD
293
 
294
            if opcode[0]:
295
                alu_src_a = src_type_a.NOT_REGA
296
 
297
            if opcode == OPG_CMP and instruction[1]:
298
                operation = True # cmpu
299
 
300
            if has_imm:
301
                alu_src_b = src_type_b.IMM
302
            else:
303
                alu_src_b = src_type_b.REGB
304
 
305
            #carry_code = intbv(0)[2:]
306
            #carry_code[:] = opcode[2:]
307
            #if carry_code == 0:
308
            if opcode[2:] == 0:
309
                carry = carry_type.C_ZERO
310
            #elif carry_code == 1:
311
            elif opcode[2:] == 1:
312
                carry = carry_type.C_ONE
313
            else:
314
                carry = carry_type.ALU
315
 
316
            carry_keep = opcode[2]
317
 
318
            reg_write = not (r_reg_d == 0)
319
 
320
        elif opgroup[5:2] == OPG_LOG:
321
            # OR/AND/XOR
322
            #logic_code = intbv(0)[2:]
323
            #logic_code[:] = opcode[2:]
324
            #if logic_code == 0:
325
            if opcode[2:] == 0:
326
                alu_op = alu_operation.ALU_OR
327
            #elif logic_code == 2:
328
            elif opcode[2:] == 2:
329
                alu_op = alu_operation.ALU_XOR
330
            else:
331
                alu_op = alu_operation.ALU_AND
332
 
333
            #if has_imm and logic_code == 3:
334
            if has_imm and opcode[2:] == 3:
335
                alu_src_b = src_type_b.NOT_IMM
336
            elif has_imm:
337
                alu_src_b = src_type_b.IMM
338
            #elif not has_imm and logic_code == 3:
339
            elif not has_imm and opcode[2:] == 3:
340
                alu_src_b = src_type_b.NOT_REGB
341
            else:
342
                alu_src_b = src_type_b.REGB
343
 
344
            reg_write = not (r_reg_d == 0)
345
 
346
        elif opcode == OPG_IMM:
347
            # Immediate
348
            r_immediate_high[:] = instruction[16:]
349
            r_has_imm_high = True
350
 
351
        elif opcode == OPG_EXT:
352
            # Sign extend / Shift right
353
            #func_code = intbv(0)[2:]
354
            #func_code[:] = instruction[7:5]
355
            #if func_code == 3:
356
            if instruction[7:5] == 3:
357
                if instruction[0]:
358
                    alu_op = alu_operation.ALU_SEXT16
359
                else:
360
                    alu_op = alu_operation.ALU_SEXT8
361
            else:
362
                alu_op = alu_operation.ALU_SHIFT
363
                carry_keep = False
364
                #if func_code == 2:
365
                if instruction[7:5] == 2:
366
                    carry = carry_type.C_ZERO
367
                #elif func_code == 1:
368
                elif instruction[7:5] == 1:
369
                    carry = carry_type.ALU
370
                else:
371
                    carry = carry_type.ARITH
372
 
373
            reg_write = not (r_reg_d == 0)
374
 
375
        elif opgroup == OPG_BRU:
376
            branch_cond = branch_condition.BRU
377
 
378
            if has_imm:
379
                alu_src_b = src_type_b.IMM
380
            else:
381
                alu_src_b = src_type_b.REGB
382
 
383
            if reg_a[2]:
384
                reg_write = not (r_reg_d == 0)
385
 
386
            if reg_a[3]:
387
                alu_src_a = src_type_a.REGA_ZERO
388
            else:
389
                alu_src_a = src_type_a.PC
390
 
391
            delay = reg_a[4]
392
 
393
        elif opgroup == OPG_BCC:
394
            alu_op  = alu_operation.ALU_ADD
395
            alu_src_a = src_type_a.PC
396
 
397
            if has_imm:
398
                alu_src_b = src_type_b.IMM
399
            else:
400
                alu_src_b = src_type_b.REGB
401
 
402
            #br_code = intbv(0)[3:]
403
            #br_code[:] = r_reg_d[3:]
404
            #if br_code == 0:
405
            if r_reg_d[3:] == 0:
406
                branch_cond = branch_condition.BEQ
407
            #elif br_code == 1:
408
            elif r_reg_d[3:] == 1:
409
                branch_cond = branch_condition.BNE
410
            #elif br_code == 2:
411
            elif r_reg_d[3:] == 2:
412
                branch_cond = branch_condition.BLT
413
            #elif br_code == 3:
414
            elif r_reg_d[3:] == 3:
415
                branch_cond = branch_condition.BLE
416
            #elif br_code == 4:
417
            elif r_reg_d[3:] == 4:
418
                branch_cond = branch_condition.BGT
419
            else:
420
                branch_cond = branch_condition.BGE
421
 
422
            delay = r_reg_d[4]
423
 
424
        elif opcode == OPG_RET:
425
            branch_cond = branch_condition.BRU
426
            alu_src_b = src_type_b.IMM
427
            delay = True
428
 
429
        elif opgroup[5:3] == OPG_MEM:
430
            alu_op = alu_operation.ALU_ADD
431
            alu_src_a = src_type_a.REGA
432
 
433
            if has_imm:
434
                alu_src_b = src_type_b.IMM
435
            else:
436
                alu_src_b = src_type_b.REGB
437
 
438
            carry = carry_type.C_ZERO
439
 
440
            if opcode[2]:
441
                mem_write = True
442
                r_mem_read = False
443
                reg_write = False
444
            else:
445
                mem_write = False
446
                r_mem_read = True
447
                reg_write = not (r_reg_d == 0)
448
 
449
            #transfer_size_code = intbv(0)[2:]
450
            #transfer_size_code[:] = opcode[2:]
451
            #if transfer_size_code == 0:
452
            if opcode[2:] == 0:
453
                transfer_size = transfer_size_type.BYTE
454
            #elif transfer_size_code == 1:
455
            elif opcode[2:] == 1:
456
                transfer_size = transfer_size_type.HALFWORD
457
            else:
458
                transfer_size = transfer_size_type.WORD
459
 
460
            delay = False
461
        else:
462
            pass
463
 
464
        # Outputs
465
        of_comb_r_has_imm_high.next = r_has_imm_high
466
        of_comb_r_immediate_high.next = r_immediate_high
467
        of_comb_r_instruction.next = r_instruction
468
        of_comb_r_program_counter.next = r_program_counter
469
        of_comb_r_hazard.next = r_hazard
470
        of_comb_r_mem_read.next = r_mem_read
471
        of_comb_r_reg_d.next = r_reg_d
472
 
473
        of_comb_alu_op.next = alu_op
474
        of_comb_alu_src_a.next = alu_src_a
475
        of_comb_alu_src_b.next = alu_src_b
476
        of_comb_branch_cond.next = branch_cond
477
        of_comb_carry.next = carry
478
        of_comb_carry_keep.next = carry_keep
479
        of_comb_delay.next = delay
480
        of_comb_immediate.next = immediate
481
        of_comb_mem_write.next = mem_write
482
        of_comb_operation.next = operation
483
        of_comb_program_counter.next = program_counter
484
        of_comb_reg_a.next = reg_a
485
        of_comb_reg_b.next = reg_b
486
        of_comb_reg_write.next = reg_write
487
        of_comb_transfer_size.next = transfer_size
488
 
489
    return instances()
490
 
491
if __name__ == '__main__':
492
    clock = Signal(False)
493
    reset = Signal(False)
494
    enable = Signal(False)
495
 
496
    dmem_data_in = Signal(intbv(0)[32:])
497
    imem_data_in = Signal(intbv(0)[32:])
498
    if_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
499
    ex_flush_id = Signal(False)
500
    mm_alu_result = Signal(intbv(0)[32:])
501
    mm_mem_read = Signal(False)
502
    mm_reg_d = Signal(intbv(0)[5:])
503
    mm_reg_write = Signal(False)
504
    mm_transfer_size = Signal(transfer_size_type.WORD)
505
    gprf_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
506
    gprf_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
507
    gprf_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
508
    of_alu_op = Signal(alu_operation.ALU_ADD)
509
    of_alu_src_a = Signal(src_type_a.REGA)
510
    of_alu_src_b = Signal(src_type_b.REGB)
511
    of_branch_cond = Signal(branch_condition.NOP)
512
    of_carry = Signal(carry_type.C_ZERO)
513
    of_carry_keep = Signal(False)
514
    of_delay = Signal(False)
515
    of_hazard = Signal(False)
516
    of_immediate = Signal(intbv(0)[32:])
517
    of_mem_read = Signal(False)
518
    of_mem_write = Signal(False)
519
    of_operation = Signal(False)
520
    of_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
521
    of_reg_a = Signal(intbv(0)[5:])
522
    of_reg_b = Signal(intbv(0)[5:])
523
    of_reg_d = Signal(intbv(0)[5:])
524
    of_reg_write = Signal(False)
525
    of_transfer_size = Signal(transfer_size_type.WORD)
526
 
527
    kw = dict(
528
        Decoder,
529
        clock=clock,
530
        reset=reset,
531
        enable=enable,
532
        dmem_data_in=dmem_data_in,
533
        imem_data_in=imem_data_in,
534
        if_program_counter=if_program_counter,
535
        ex_flush_id=ex_flush_id,
536
        mm_alu_result=mm_alu_result,
537
        mm_mem_read=mm_mem_read,
538
        mm_reg_d=mm_reg_d,
539
        mm_reg_write=mm_reg_write,
540
        mm_transfer_size=mm_transfer_size,
541
        gprf_dat_a=gprf_dat_a,
542
        gprf_dat_b=gprf_dat_b,
543
        gprf_dat_d=gprf_dat_d,
544
        of_alu_op=of_alu_op,
545
        of_alu_src_a=of_alu_src_a,
546
        of_alu_src_b=of_alu_src_b,
547
        of_branch_cond=of_branch_cond,
548
        of_carry=of_carry,
549
        of_carry_keep=of_carry_keep,
550
        of_delay=of_delay,
551
        of_hazard=of_hazard,
552
        of_immediate=of_immediate,
553
        of_mem_read=of_mem_read,
554
        of_mem_write=of_mem_write,
555
        of_operation=of_operation,
556
        of_program_counter=of_program_counter,
557
        of_reg_a=of_reg_a,
558
        of_reg_b=of_reg_b,
559
        of_reg_d=of_reg_d,
560
        of_reg_write=of_reg_write,
561
        of_transfer_size=of_transfer_size,
562
    )
563
    toVerilog(**kw)
564
    toVHDL(**kw)
565
 
566
 
567
### EOF ###
568
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
569
 

powered by: WebSVN 2.1.0

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