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

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [decoder.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
    decoder.py
4
    ==========
5
 
6
    Instruction Decoder
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: decoder.py 6 2010-11-21 23:18:44Z 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 6 rockee
#from debug import *
20 2 rockee
 
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 6 rockee
        # Ports only for debug
65
        of_instruction=0,
66 2 rockee
    ):
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
    @always_comb
182
    def regout():
183
        of_hazard.next = of_r_hazard
184
        of_mem_read.next = of_r_mem_read
185
        of_reg_d.next = of_r_reg_d
186 6 rockee
        if __debug__:
187
            of_instruction.next = of_r_instruction
188 2 rockee
 
189
    @always_comb
190
    def comb():
191
        # XXX intbvs should be explicitly declared
192
        # Register
193
        r_instruction = intbv(0)[32:]
194
        r_instruction[:] = imem_data_in
195
        r_program_counter = intbv(0)[CFG_IMEM_SIZE:]
196
        r_program_counter[:] = if_program_counter
197
        r_immediate_high = intbv(0)[16:]
198
        r_has_imm_high = False
199
        r_reg_d = intbv(0)[5:]
200 6 rockee
        # Local Variables
201 2 rockee
        r_hazard = False
202
        immediate = intbv(0)[32:]
203
        immediate_low = intbv(0)[16:]
204
        instruction = intbv(0)[32:]
205
        mem_result = intbv(0)[32:]
206
        opcode = intbv(0)[6:]
207
        opgroup = intbv(0)[5:]
208
        program_counter = intbv(0)[CFG_IMEM_SIZE:]
209
        reg_a = intbv(0)[5:]
210
        reg_b = intbv(0)[5:]
211
 
212
        if mm_mem_read:
213
            mem_result[:] = align_mem_load(dmem_data_in, mm_transfer_size,
214
                                           mm_alu_result[2:])
215
        else:
216
            mem_result[:] = mm_alu_result
217
 
218
        wb_dat_d.next = mem_result
219
 
220
        if not ex_flush_id and of_r_mem_read and (
221
                imem_data_in[21:16] == of_r_reg_d or
222
                imem_data_in[16:11] == of_r_reg_d):
223
            # A hazard occurred on register a or b
224
            instruction[:] = 0
225
            program_counter[:] = 0
226
            r_hazard = True
227
        elif not ex_flush_id and of_r_mem_read and (
228
                imem_data_in[26:21] == of_r_reg_d):
229
            # A hazard occurred on register d
230
            # This actually only applies to store after load, but it's also
231
            # nonsense to discard the result just after read it from memory.
232
            # So, trigger a hazard alarm whenever Rd is the same,
233
            # in order to simplify the logic.
234
            instruction[:] = 0
235
            program_counter[:] = 0
236
            r_hazard = True
237
        elif of_r_hazard:
238
            instruction[:] = of_r_instruction
239
            program_counter[:] = of_r_program_counter
240
            r_hazard = False
241
        else:
242
            instruction[:] = imem_data_in
243
            program_counter[:] = if_program_counter
244
            r_hazard = False
245
 
246
        # Dissemble instruction
247
        opgroup[:] = concat(instruction[32:30], instruction[29:26])
248
        opcode[:] = instruction[32:26]
249
        has_imm = opcode[3]
250
        immediate_low[:] = instruction[16:]
251
        reg_a[:] = instruction[21:16]
252
        reg_b[:] = instruction[16:11]
253
        r_reg_d[:] = instruction[26:21]
254
 
255
        # Process immediate
256
        # IMM15 will only be used as msr bitmap
257
        # so there is no need to treat it separately
258
        if of_r_has_imm_high: # last inst is imm
259
            immediate[:] = concat(of_r_immediate_high, immediate_low)
260
        else:
261
            immediate[:] = sign_extend16(immediate_low, immediate_low[15])
262
 
263
 
264
        # Default Mux States
265
        alu_op = alu_operation.ALU_ADD
266
        alu_src_a = src_type_a.REGA
267
        alu_src_b = src_type_b.REGB
268
        branch_cond = branch_condition.NOP
269
        carry = carry_type.C_ZERO
270
        carry_keep = False
271
        delay = False
272
        r_mem_read = False
273
        mem_write = False
274
        operation = False
275
        reg_write = False
276
        transfer_size = transfer_size_type.WORD
277
 
278
        if bool(ex_flush_id or r_hazard):
279
            pass
280
        elif opgroup[5:3] == OPG_ADD:
281
            # ADD / SUBTRACT / COMPARE
282
            alu_op = alu_operation.ALU_ADD
283
 
284
            if opcode[0]:
285
                alu_src_a = src_type_a.NOT_REGA
286
 
287
            if opcode == OPG_CMP and instruction[1]:
288
                operation = True # cmpu
289
 
290
            if has_imm:
291
                alu_src_b = src_type_b.IMM
292
            else:
293
                alu_src_b = src_type_b.REGB
294
 
295
            #carry_code = intbv(0)[2:]
296
            #carry_code[:] = opcode[2:]
297
            #if carry_code == 0:
298
            if opcode[2:] == 0:
299
                carry = carry_type.C_ZERO
300
            #elif carry_code == 1:
301
            elif opcode[2:] == 1:
302
                carry = carry_type.C_ONE
303
            else:
304
                carry = carry_type.ALU
305
 
306
            carry_keep = opcode[2]
307
 
308
            reg_write = not (r_reg_d == 0)
309
 
310
        elif opgroup[5:2] == OPG_LOG:
311
            # OR/AND/XOR
312
            #logic_code = intbv(0)[2:]
313
            #logic_code[:] = opcode[2:]
314
            #if logic_code == 0:
315
            if opcode[2:] == 0:
316
                alu_op = alu_operation.ALU_OR
317
            #elif logic_code == 2:
318
            elif opcode[2:] == 2:
319
                alu_op = alu_operation.ALU_XOR
320
            else:
321
                alu_op = alu_operation.ALU_AND
322
 
323
            #if has_imm and logic_code == 3:
324
            if has_imm and opcode[2:] == 3:
325
                alu_src_b = src_type_b.NOT_IMM
326
            elif has_imm:
327
                alu_src_b = src_type_b.IMM
328
            #elif not has_imm and logic_code == 3:
329
            elif not has_imm and opcode[2:] == 3:
330
                alu_src_b = src_type_b.NOT_REGB
331
            else:
332
                alu_src_b = src_type_b.REGB
333
 
334
            reg_write = not (r_reg_d == 0)
335
 
336
        elif opcode == OPG_IMM:
337
            # Immediate
338
            r_immediate_high[:] = instruction[16:]
339
            r_has_imm_high = True
340
 
341
        elif opcode == OPG_EXT:
342
            # Sign extend / Shift right
343
            #func_code = intbv(0)[2:]
344
            #func_code[:] = instruction[7:5]
345
            #if func_code == 3:
346
            if instruction[7:5] == 3:
347
                if instruction[0]:
348
                    alu_op = alu_operation.ALU_SEXT16
349
                else:
350
                    alu_op = alu_operation.ALU_SEXT8
351
            else:
352
                alu_op = alu_operation.ALU_SHIFT
353
                carry_keep = False
354
                #if func_code == 2:
355
                if instruction[7:5] == 2:
356
                    carry = carry_type.C_ZERO
357
                #elif func_code == 1:
358
                elif instruction[7:5] == 1:
359
                    carry = carry_type.ALU
360
                else:
361
                    carry = carry_type.ARITH
362
 
363
            reg_write = not (r_reg_d == 0)
364
 
365
        elif opgroup == OPG_BRU:
366
            branch_cond = branch_condition.BRU
367
 
368
            if has_imm:
369
                alu_src_b = src_type_b.IMM
370
            else:
371
                alu_src_b = src_type_b.REGB
372
 
373
            if reg_a[2]:
374
                reg_write = not (r_reg_d == 0)
375
 
376
            if reg_a[3]:
377
                alu_src_a = src_type_a.REGA_ZERO
378
            else:
379
                alu_src_a = src_type_a.PC
380
 
381
            delay = reg_a[4]
382
 
383
        elif opgroup == OPG_BCC:
384
            alu_op  = alu_operation.ALU_ADD
385
            alu_src_a = src_type_a.PC
386
 
387
            if has_imm:
388
                alu_src_b = src_type_b.IMM
389
            else:
390
                alu_src_b = src_type_b.REGB
391
 
392
            #br_code = intbv(0)[3:]
393
            #br_code[:] = r_reg_d[3:]
394
            #if br_code == 0:
395
            if r_reg_d[3:] == 0:
396
                branch_cond = branch_condition.BEQ
397
            #elif br_code == 1:
398
            elif r_reg_d[3:] == 1:
399
                branch_cond = branch_condition.BNE
400
            #elif br_code == 2:
401
            elif r_reg_d[3:] == 2:
402
                branch_cond = branch_condition.BLT
403
            #elif br_code == 3:
404
            elif r_reg_d[3:] == 3:
405
                branch_cond = branch_condition.BLE
406
            #elif br_code == 4:
407
            elif r_reg_d[3:] == 4:
408
                branch_cond = branch_condition.BGT
409
            else:
410
                branch_cond = branch_condition.BGE
411
 
412
            delay = r_reg_d[4]
413
 
414
        elif opcode == OPG_RET:
415
            branch_cond = branch_condition.BRU
416
            alu_src_b = src_type_b.IMM
417
            delay = True
418
 
419
        elif opgroup[5:3] == OPG_MEM:
420
            alu_op = alu_operation.ALU_ADD
421
            alu_src_a = src_type_a.REGA
422
 
423
            if has_imm:
424
                alu_src_b = src_type_b.IMM
425
            else:
426
                alu_src_b = src_type_b.REGB
427
 
428
            carry = carry_type.C_ZERO
429
 
430
            if opcode[2]:
431
                mem_write = True
432
                r_mem_read = False
433
                reg_write = False
434
            else:
435
                mem_write = False
436
                r_mem_read = True
437
                reg_write = not (r_reg_d == 0)
438
 
439
            #transfer_size_code = intbv(0)[2:]
440
            #transfer_size_code[:] = opcode[2:]
441
            #if transfer_size_code == 0:
442
            if opcode[2:] == 0:
443
                transfer_size = transfer_size_type.BYTE
444
            #elif transfer_size_code == 1:
445
            elif opcode[2:] == 1:
446
                transfer_size = transfer_size_type.HALFWORD
447
            else:
448
                transfer_size = transfer_size_type.WORD
449
 
450
            delay = False
451
        else:
452
            pass
453
 
454
        # Outputs
455
        of_comb_r_has_imm_high.next = r_has_imm_high
456
        of_comb_r_immediate_high.next = r_immediate_high
457
        of_comb_r_instruction.next = r_instruction
458
        of_comb_r_program_counter.next = r_program_counter
459
        of_comb_r_hazard.next = r_hazard
460
        of_comb_r_mem_read.next = r_mem_read
461
        of_comb_r_reg_d.next = r_reg_d
462
 
463
        of_comb_alu_op.next = alu_op
464
        of_comb_alu_src_a.next = alu_src_a
465
        of_comb_alu_src_b.next = alu_src_b
466
        of_comb_branch_cond.next = branch_cond
467
        of_comb_carry.next = carry
468
        of_comb_carry_keep.next = carry_keep
469
        of_comb_delay.next = delay
470
        of_comb_immediate.next = immediate
471
        of_comb_mem_write.next = mem_write
472
        of_comb_operation.next = operation
473
        of_comb_program_counter.next = program_counter
474
        of_comb_reg_a.next = reg_a
475
        of_comb_reg_b.next = reg_b
476
        of_comb_reg_write.next = reg_write
477
        of_comb_transfer_size.next = transfer_size
478
 
479
    return instances()
480
 
481
if __name__ == '__main__':
482
    clock = Signal(False)
483
    reset = Signal(False)
484
    enable = Signal(False)
485
 
486 6 rockee
    dmem_data_in = Signal(intbv(0)[CFG_DMEM_WIDTH:])
487
    imem_data_in = Signal(intbv(0)[CFG_IMEM_WIDTH:])
488 2 rockee
    if_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
489
    ex_flush_id = Signal(False)
490 6 rockee
    mm_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
491 2 rockee
    mm_mem_read = Signal(False)
492 6 rockee
    mm_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
493 2 rockee
    mm_reg_write = Signal(False)
494
    mm_transfer_size = Signal(transfer_size_type.WORD)
495
    gprf_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
496
    gprf_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
497
    gprf_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
498
    of_alu_op = Signal(alu_operation.ALU_ADD)
499
    of_alu_src_a = Signal(src_type_a.REGA)
500
    of_alu_src_b = Signal(src_type_b.REGB)
501
    of_branch_cond = Signal(branch_condition.NOP)
502
    of_carry = Signal(carry_type.C_ZERO)
503
    of_carry_keep = Signal(False)
504
    of_delay = Signal(False)
505
    of_hazard = Signal(False)
506 6 rockee
    of_immediate = Signal(intbv(0)[CFG_DMEM_WIDTH:])
507 2 rockee
    of_mem_read = Signal(False)
508
    of_mem_write = Signal(False)
509
    of_operation = Signal(False)
510
    of_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
511 6 rockee
    of_reg_a = Signal(intbv(0)[CFG_GPRF_SIZE:])
512
    of_reg_b = Signal(intbv(0)[CFG_GPRF_SIZE:])
513
    of_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
514 2 rockee
    of_reg_write = Signal(False)
515
    of_transfer_size = Signal(transfer_size_type.WORD)
516 6 rockee
    of_fwd_mem_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
517
    of_fwd_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
518
    of_fwd_reg_write = Signal(False)
519
    if __debug__:
520
        of_instruction = Signal(intbv(0)[CFG_IMEM_WIDTH:])
521
    # End Ports only for debug
522 2 rockee
 
523 6 rockee
 
524 2 rockee
    kw = dict(
525
        clock=clock,
526
        reset=reset,
527
        enable=enable,
528
        dmem_data_in=dmem_data_in,
529
        imem_data_in=imem_data_in,
530
        if_program_counter=if_program_counter,
531
        ex_flush_id=ex_flush_id,
532
        mm_alu_result=mm_alu_result,
533
        mm_mem_read=mm_mem_read,
534
        mm_reg_d=mm_reg_d,
535
        mm_reg_write=mm_reg_write,
536
        mm_transfer_size=mm_transfer_size,
537
        gprf_dat_a=gprf_dat_a,
538
        gprf_dat_b=gprf_dat_b,
539
        gprf_dat_d=gprf_dat_d,
540
        of_alu_op=of_alu_op,
541
        of_alu_src_a=of_alu_src_a,
542
        of_alu_src_b=of_alu_src_b,
543
        of_branch_cond=of_branch_cond,
544
        of_carry=of_carry,
545
        of_carry_keep=of_carry_keep,
546
        of_delay=of_delay,
547
        of_hazard=of_hazard,
548
        of_immediate=of_immediate,
549
        of_mem_read=of_mem_read,
550
        of_mem_write=of_mem_write,
551
        of_operation=of_operation,
552
        of_program_counter=of_program_counter,
553
        of_reg_a=of_reg_a,
554
        of_reg_b=of_reg_b,
555
        of_reg_d=of_reg_d,
556
        of_reg_write=of_reg_write,
557
        of_transfer_size=of_transfer_size,
558 6 rockee
        of_fwd_mem_result=of_fwd_mem_result,
559
        of_fwd_reg_d=of_fwd_reg_d,
560
        of_fwd_reg_write=of_fwd_reg_write,
561
 
562 2 rockee
    )
563 6 rockee
    toVerilog(Decoder, **kw)
564
    toVHDL(Decoder, **kw)
565 2 rockee
 
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.