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

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [execute.py] - Rev 6

Compare with Previous | Blame | View Log

# -*- coding: utf-8 -*-
"""
    execute.py
    ==========
 
    Execute Unit
 
    :copyright: Copyright (c) 2010 Jian Luo
    :author-email: jian.luo.cn(at_)gmail.com
    :license: LGPL, see LICENSE for details
    :revision: $Id: execute.py 6 2010-11-21 23:18:44Z rockee $
"""
 
from myhdl import *
from defines import *
from functions import *
 
def ExecuteUnit(
        # Inputs
        clock,
        reset,
        enable,
        dmem_data_in,
        gprf_dat_a,
        gprf_dat_b,
        gprf_dat_d,
        mm_alu_result,
        mm_mem_read,
        mm_reg_d,
        mm_reg_write,
        mm_transfer_size,
        of_alu_op,
        of_alu_src_a,
        of_alu_src_b,
        of_branch_cond,
        of_carry,
        of_carry_keep,
        of_delay,
        of_immediate,
        of_mem_read,
        of_mem_write,
        of_operation,
        of_program_counter,
        of_reg_a,
        of_reg_b,
        of_reg_d,
        of_reg_write,
        of_transfer_size,
 
        # Write back stage forwards
        of_fwd_mem_result,
        of_fwd_reg_d,
        of_fwd_reg_write,
 
        # Outputs
        ex_alu_result,
        ex_reg_d,
        ex_reg_write,
 
        ex_branch,
        ex_dat_d,
        ex_flush_id,
        ex_mem_read,
        ex_mem_write,
        ex_program_counter,
        ex_transfer_size,
 
        # Ports only for debug
        of_instruction=0,
        ex_dat_a=0,
        ex_dat_b=0,
        ex_instruction=0,
        ex_reg_a=0,
        ex_reg_b=0,
 
    ):
    """
    """
    ex_r_carry = Signal(False)
    ex_r_flush_ex= Signal(False)
 
    ex_r_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    ex_r_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    ex_r_reg_write = Signal(False)
 
    ex_comb_r_carry = Signal(False)
    ex_comb_r_flush_ex = Signal(False)
 
    ex_comb_r_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    ex_comb_r_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    ex_comb_r_reg_write = Signal(False)
 
    ex_comb_branch = Signal(False)
    ex_comb_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    ex_comb_flush_id = Signal(False)
    ex_comb_mem_read = Signal(False)
    ex_comb_mem_write = Signal(False)
    ex_comb_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
    ex_comb_transfer_size = Signal(transfer_size_type.WORD)
 
    if __debug__:
        ex_comb_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
        ex_comb_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
        ex_comb_instruction = Signal(intbv(0)[CFG_DMEM_WIDTH:])
        ex_comb_reg_a = Signal(intbv(0)[CFG_GPRF_SIZE:])
        ex_comb_reg_b = Signal(intbv(0)[CFG_GPRF_SIZE:])
 
    @always_comb
    def regout():
        ex_alu_result.next = ex_r_alu_result
        ex_reg_d.next = ex_r_reg_d
        ex_reg_write.next = ex_r_reg_write
 
    cpu_clock = 0
    @always(clock.posedge)
    def seq():
        """
        ExecUnit sequential logic
        """
        if reset:
            ex_r_carry.next = False
            ex_r_flush_ex.next = False
 
            ex_r_alu_result.next = intbv(0)[CFG_DMEM_WIDTH:]
            ex_r_reg_d.next = intbv(0)[CFG_GPRF_SIZE:]
            ex_r_reg_write.next = False
 
            ex_branch.next = False
            ex_dat_d.next = intbv(0)[CFG_DMEM_WIDTH:]
            ex_flush_id.next = False
            ex_mem_read.next = False
            ex_mem_write.next = False
            ex_program_counter.next = intbv(0)[CFG_IMEM_SIZE:]
            ex_transfer_size.next = transfer_size_type.WORD
 
        elif enable:
            ex_r_carry.next = ex_comb_r_carry
            ex_r_flush_ex.next = ex_comb_r_flush_ex
 
            ex_r_alu_result.next = ex_comb_r_alu_result
            ex_r_reg_d.next = ex_comb_r_reg_d
            ex_r_reg_write.next = ex_comb_r_reg_write
 
            ex_branch.next = ex_comb_branch
            ex_dat_d.next = ex_comb_dat_d
            ex_flush_id.next = ex_comb_flush_id
            ex_mem_read.next = ex_comb_mem_read
            ex_mem_write.next = ex_comb_mem_write
            ex_program_counter.next = ex_comb_program_counter
            ex_transfer_size.next = ex_comb_transfer_size
 
        if __debug__:
          if enable:
            ex_dat_a.next = ex_comb_dat_a
            ex_dat_b.next = ex_comb_dat_b
            ex_instruction.next = ex_comb_instruction
            ex_reg_a.next = ex_comb_reg_a
            ex_reg_b.next = ex_comb_reg_b
 
    @always_comb
    def comb():
        """
        ExecUnit combinatorial logic
        """
        # Signals mapping
        r_carry = False
        r_flush_ex = False
 
        r_alu_result = intbv(0)[CFG_DMEM_WIDTH:]
        r_reg_d = intbv(0)[CFG_GPRF_SIZE:]
        r_reg_write = False
 
        branch = False
        dat_d = intbv(0)[CFG_DMEM_WIDTH:]
        flush_id = False
        mem_read = False
        mem_write = False
        program_counter = intbv(0)[CFG_IMEM_SIZE:]
        transfer_size = transfer_size_type.WORD
 
        # Local Variables 
        alu_src_a = intbv(0)[CFG_DMEM_WIDTH:]
        alu_src_b = intbv(0)[CFG_DMEM_WIDTH:]
        carry = False
 
        result = intbv(0)[CFG_DMEM_WIDTH+1:]
        result_add = intbv(0)[CFG_DMEM_WIDTH+1:]
        zero = False
 
        dat_a = intbv(0)[CFG_DMEM_WIDTH:]
        dat_b = intbv(0)[CFG_DMEM_WIDTH:]
        sel_dat_a = intbv(0)[CFG_DMEM_WIDTH:]
        sel_dat_b = intbv(0)[CFG_DMEM_WIDTH:]
        sel_dat_d = intbv(0)[CFG_DMEM_WIDTH:]
        mem_result = intbv(0)[CFG_DMEM_WIDTH:]
 
        # XXX: write back result must be forwarded,
        # if gprf has read old data behaviour
        #cfg_reg_fwd_wrb = CFG_REG_FWD_WRB   # Hacked to pass VHDL syntax check
        #if cfg_reg_fwd_wrb:
        sel_dat_a[:] = select_register_data(
                            gprf_dat_a, of_reg_a, of_fwd_mem_result,
                            forward_condition(of_fwd_reg_write,
                                              of_fwd_reg_d, of_reg_a)
                       )
        sel_dat_b[:] = select_register_data(
                            gprf_dat_b, of_reg_b, of_fwd_mem_result,
                            forward_condition(of_fwd_reg_write,
                                              of_fwd_reg_d, of_reg_b)
                       )
        sel_dat_d[:] = select_register_data(
                            gprf_dat_d, of_reg_d, of_fwd_mem_result,
                            forward_condition(of_fwd_reg_write,
                                              of_fwd_reg_d, of_reg_d)
                       )
        #else:
            #sel_dat_a[:] = gprf_dat_a
            #sel_dat_b[:] = gprf_dat_b
            #sel_dat_d[:] = gprf_dat_d
 
 
        if not ex_r_flush_ex:
            mem_write = bool(of_mem_write)
            mem_read = bool(of_mem_read)
            transfer_size = of_transfer_size.val # Needed?
            r_reg_write = bool(of_reg_write)
            r_reg_d[:] = of_reg_d
 
        if mm_mem_read:
            mem_result[:] = align_mem_load(dmem_data_in, mm_transfer_size,
                                        mm_alu_result[2:])
        else:
            mem_result[:] = mm_alu_result
 
        # Reg A
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_a) == True:
            # Forward from exec
            dat_a[:] = ex_r_alu_result
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_a) == True:
            # Forward from mem
            dat_a[:] = mem_result
        else:
            # Default from gprf
            dat_a[:] = sel_dat_a
 
        # Reg B
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_b) == True:
            # Forward from exec
            dat_b[:] = ex_r_alu_result
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_b) == True:
            # Forward from mem
            dat_b[:] = mem_result
        else:
            # Default from gprf
            dat_b[:] = sel_dat_b
 
        # XXX Why bother?
        if forward_condition(ex_r_reg_write, ex_r_reg_d, of_reg_d) == True:
            dat_d[:] = align_mem_store(ex_r_alu_result, of_transfer_size)
            #print 'fwd_ex r%d=%x' % (of_reg_d, dat_d)
        elif forward_condition(mm_reg_write, mm_reg_d, of_reg_d) == True:
            dat_d[:] = align_mem_store(mem_result, of_transfer_size)
 
            #print 'fwd_mm r%d=%x' % (of_reg_d, dat_d)
        else:
            dat_d[:] = align_mem_store(sel_dat_d, of_transfer_size)
            #print 'gprf r%d=%x'  % (of_reg_d, dat_d)
 
        # Operand A
        if of_alu_src_a == src_type_a.PC:
            alu_src_a[:] = of_program_counter
        elif of_alu_src_a == src_type_a.NOT_REGA:
            alu_src_a[:] = ~dat_a
        elif of_alu_src_a == src_type_a.REGA_ZERO:
            alu_src_a[:] = 0
        else:
            alu_src_a[:] = dat_a
 
        # Operand B
        if of_alu_src_b == src_type_b.IMM:
            alu_src_b[:] = of_immediate
        elif of_alu_src_b == src_type_b.NOT_IMM:
            alu_src_b[:] = ~of_immediate
        elif of_alu_src_b == src_type_b.NOT_REGB:
            alu_src_b[:] = ~dat_b
        else:
            alu_src_b[:] = dat_b
 
        # Determine value of carry in
        if of_carry == carry_type.ALU:
            carry = bool(ex_r_carry)
        elif of_carry == carry_type.C_ONE:
            carry = True
        elif of_carry == carry_type.ARITH:
            carry = alu_src_a[CFG_DMEM_WIDTH-1]
        else:
            carry = False
 
        #result_add[:] = alu_src_a.signed() + alu_src_b.signed() + carry
        result_add[:] = add(alu_src_a, alu_src_b, carry)
 
        if of_alu_op == alu_operation.ALU_ADD:
            result[:] = result_add
        elif of_alu_op == alu_operation.ALU_OR:
            or_rslt = intbv(0)[CFG_DMEM_WIDTH:]
            or_rslt[:] = alu_src_a | alu_src_b
            result[:] = or_rslt
        elif of_alu_op == alu_operation.ALU_AND:
            and_rslt = intbv(0)[CFG_DMEM_WIDTH:]
            and_rslt[:] = alu_src_a & alu_src_b
            result[:] = and_rslt
        elif of_alu_op == alu_operation.ALU_XOR:
            xor_rslt = intbv(0)[CFG_DMEM_WIDTH:]
            xor_rslt[:] = alu_src_a ^ alu_src_b
            result[:] = xor_rslt
        elif of_alu_op == alu_operation.ALU_SHIFT:
            result[:] = concat(alu_src_a[0], carry, alu_src_a[CFG_DMEM_WIDTH:1])
        elif of_alu_op == alu_operation.ALU_SEXT8:
 
            result[:] = concat(False, sign_extend8(alu_src_a, alu_src_a[7]))
            #result[:] = concat(False, sign_extend(alu_src_a, alu_src_a[7],
                                                  #8, CFG_DMEM_WIDTH))
        elif of_alu_op == alu_operation.ALU_SEXT16:
            result[:] = concat(False, sign_extend16(alu_src_a, alu_src_a[15]))
            #result[:] = concat(False, sign_extend(alu_src_a, alu_src_a[15],
                                                  #16, CFG_DMEM_WIDTH))
        else:
            result[:] = 0
            if __debug__:
                assert False, 'FATAL Error: Unsupported ALU operation'
 
        # Set carry register
        if of_carry_keep:
            r_carry = bool(ex_r_carry) # bool() needs for signal type mismatch
        else:
            r_carry = result[CFG_DMEM_WIDTH]
 
        if not ex_r_flush_ex:
            zero = dat_a == 0
 
            if of_branch_cond == branch_condition.BRU:
                branch = True
            elif of_branch_cond == branch_condition.BEQ:
                branch = zero
            elif of_branch_cond == branch_condition.BNE:
                branch = not zero
            elif of_branch_cond == branch_condition.BLT:
                branch = dat_a[CFG_DMEM_WIDTH-1]
            elif of_branch_cond == branch_condition.BLE:
                branch = dat_a[CFG_DMEM_WIDTH-1] or zero
            elif of_branch_cond == branch_condition.BGT:
                branch = not bool(dat_a[CFG_DMEM_WIDTH-1] or zero)
            elif of_branch_cond == branch_condition.BGE:
                branch = not dat_a[CFG_DMEM_WIDTH-1]
            else:
                branch = False
 
        # Handle CMPU
        cmp_cond = alu_src_a[CFG_DMEM_WIDTH-1] ^ alu_src_b[CFG_DMEM_WIDTH-1] 
        if of_operation and bool(cmp_cond):
            ## Set MSB
            msb = alu_src_a[CFG_DMEM_WIDTH-1]
            r_alu_result[:] = concat(msb, result[CFG_DMEM_WIDTH-1:])
        else:
            r_alu_result[:] = result[CFG_DMEM_WIDTH:]
 
        program_counter[:] = of_program_counter
 
        # Determine flush signals
        flush_id = branch
        r_flush_ex = branch and not of_delay
 
        # Write to local register
        ex_comb_r_carry.next = r_carry
        ex_comb_r_flush_ex.next = r_flush_ex
 
        ex_comb_r_alu_result.next = r_alu_result
        ex_comb_r_reg_d.next = r_reg_d
        ex_comb_r_reg_write.next = r_reg_write
 
        ex_comb_branch.next = branch
        ex_comb_dat_d.next = dat_d
        ex_comb_flush_id.next = flush_id
        ex_comb_mem_read.next = mem_read
        ex_comb_mem_write.next = mem_write
        ex_comb_program_counter.next = program_counter
        ex_comb_transfer_size.next = transfer_size
 
        if __debug__:
            ex_comb_dat_a.next = dat_a
            ex_comb_dat_b.next = dat_b
            ex_comb_instruction.next = of_instruction
            ex_comb_reg_a.next = of_reg_a
            ex_comb_reg_b.next = of_reg_b
 
    return instances()
 
if __name__ == '__main__':
    clock = Signal(False)
    reset = Signal(False)
    enable = Signal(False)
 
    dmem_data_in = Signal(intbv(0)[CFG_DMEM_WIDTH:])
 
    mm_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    mm_mem_read =  Signal(False)
    mm_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    mm_reg_write = Signal(False)
    mm_transfer_size = Signal(transfer_size_type.WORD)
 
    gprf_dat_a = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    gprf_dat_b = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    gprf_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
 
    ex_flush_id = Signal(False)
    of_alu_op = Signal(alu_operation.ALU_ADD)
    of_alu_src_a = Signal(src_type_a.REGA)
    of_alu_src_b = Signal(src_type_b.REGB)
    of_branch_cond = Signal(branch_condition.NOP)
    of_carry = Signal(carry_type.C_ZERO)
    of_carry_keep = Signal(False)
    of_delay = Signal(False)
    of_hazard = Signal(False)
    of_immediate = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    of_mem_read = Signal(False)
    of_mem_write = Signal(False)
    of_operation = Signal(False)
    of_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
    of_reg_a = Signal(intbv(0)[CFG_GPRF_SIZE:])
    of_reg_b = Signal(intbv(0)[CFG_GPRF_SIZE:])
    of_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    of_reg_write = Signal(False)
    of_transfer_size = Signal(transfer_size_type.WORD)
    # Write back stage forwards
    of_fwd_mem_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    of_fwd_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    of_fwd_reg_write = Signal(False)
 
    ex_alu_result = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    ex_reg_d = Signal(intbv(0)[CFG_GPRF_SIZE:])
    ex_reg_write = Signal(False)
 
    ex_branch = Signal(False)
    ex_dat_d = Signal(intbv(0)[CFG_DMEM_WIDTH:])
    ex_flush_id = Signal(False)
    ex_mem_read = Signal(False)
    ex_mem_write = Signal(False)
    ex_program_counter = Signal(intbv(0)[CFG_IMEM_SIZE:])
    ex_transfer_size = Signal(transfer_size_type.WORD)
 
    kw = dict(
        clock=clock,
        reset=reset,
        enable=enable,
        dmem_data_in=dmem_data_in,
        gprf_dat_a=gprf_dat_a,
        gprf_dat_b=gprf_dat_b,
        gprf_dat_d=gprf_dat_d,
        mm_alu_result=mm_alu_result,
        mm_mem_read=mm_mem_read,
        mm_reg_d=mm_reg_d,
        mm_reg_write=mm_reg_write,
        mm_transfer_size=mm_transfer_size,
        of_alu_op=of_alu_op,
        of_alu_src_a=of_alu_src_a,
        of_alu_src_b=of_alu_src_b,
        of_branch_cond=of_branch_cond,
        of_carry=of_carry,
        of_carry_keep=of_carry_keep,
        of_delay=of_delay,
        of_immediate=of_immediate,
        of_mem_read=of_mem_read,
        of_mem_write=of_mem_write,
        of_operation=of_operation,
        of_program_counter=of_program_counter,
        of_reg_a=of_reg_a,
        of_reg_b=of_reg_b,
        of_reg_d=of_reg_d,
        of_reg_write=of_reg_write,
        of_transfer_size=of_transfer_size,
        # Write back stage forwards
        of_fwd_mem_result=of_fwd_mem_result,
        of_fwd_reg_d=of_fwd_reg_d,
        of_fwd_reg_write=of_fwd_reg_write,
        # Outputs
        ex_alu_result=ex_alu_result,
        ex_reg_d=ex_reg_d,
        ex_reg_write=ex_reg_write,
 
        ex_branch=ex_branch,
        ex_dat_d=ex_dat_d,
        ex_flush_id=ex_flush_id,
        ex_mem_read=ex_mem_read,
        ex_mem_write=ex_mem_write,
        ex_program_counter=ex_program_counter,
        ex_transfer_size=ex_transfer_size,
    )
    toVerilog(ExecuteUnit, **kw)
    toVHDL(ExecuteUnit, **kw)
 
### EOF ###
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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