rtl/execute.py
def ArithmeticLogicUnit():
    """The primary arithmetic/logic unit for Geode."""

    io = Io({
        'op0': Input(Bits(C['core-width'])),
        'op1': Input(Bits(C['core-width'])),
        'alu_inst': Input(Bits(AluInsts.width)),
        'result': Output(Bits(C['core-width'])),
        'flags': Output(alu_flags)
    })

    zero = Wire(Bits(C['core-width']))
    shift_op = Wire(Bits(1))

    #
    # To make checking for overflow easy, all arithmetic operations are
    # performed on 2 x core-width (sign extended) data.
    #

    op0_ex = Cat([zero, io.op0])
    op1_ex = Cat([zero, io.op1])

    #
    # N.B. For all RV32I instructions, the shamt is actually only 5 bits. For
    # 64 bit instructions, it's 6 bits. It's safe to always extract a 6-bit
    # shamt because 32 bit instructions all coincidentally leave io.op1(6)
    # set to zero, anyway.
    #

    shamt = io.op1(5, 0)

    #
    # For a real ALU, add / sub operations would likely be combined to only use
    # a single adder, negating the second operand for subtractions.
    #

    and_result = op0_ex & op1_ex
    or_result = op0_ex | op1_ex
    add_result = op0_ex + op1_ex
    sub_result = op0_ex - op1_ex
    sll_result = io.op0 << shamt
    srl_result = io.op0 >> shamt

    result = Wire(Bits(C['core-width'] * 2))
    io.result <<= result(C['core-width'] - 1, 0)

    result <<= 0

    io.flags.zero <<= (result == 0)
    io.flags.sign <<= result(result.width - 1, result.width - 1)
    io.flags.overflow <<= BitOrReduce(result(result.width - 1, C['core-width']))

    #
    # The following essentially produces a mux that selects an output produced
    # by this ALU based on the inst requested.
    #

    with io.alu_inst == AluInsts.AND:
        result <<= and_result

    with io.alu_inst == AluInsts.OR:
        result <<= or_result

    with io.alu_inst == AluInsts.ADD:
        result <<= add_result

    with io.alu_inst == AluInsts.SUB:
        result <<= sub_result

    with io.alu_inst == AluInsts.SLL:
        result <<= Cat([zero, sll_result])

    with io.alu_inst == AluInsts.SRL:
        result <<= Cat([zero, srl_result])

    NameSignals(locals())
The primary arithmetic/logic unit for Geode.
The primary arithmetic/logic unit for Geode.
The primary arithmetic / logic unit for Geode .
def ArithmeticLogicUnit():
    io = Io({
        'op0': Input(Bits(C['core-width'])),
        'op1': Input(Bits(C['core-width'])),
        'alu_inst': Input(Bits(AluInsts.width)),
        'result': Output(Bits(C['core-width'])),
        'flags': Output(alu_flags)
    })
    zero = Wire(Bits(C['core-width']))
    shift_op = Wire(Bits(1))
     To make checking for overflow easy, all arithmetic operations are
     performed on 2 x core-width (sign extended) data.
    op0_ex = Cat([zero, io.op0])
    op1_ex = Cat([zero, io.op1])
     N.B. For all RV32I instructions, the shamt is actually only 5 bits. For
     64 bit instructions, it's 6 bits. It's safe to always extract a 6-bit
     shamt because 32 bit instructions all coincidentally leave io.op1(6)
     set to zero, anyway.
    shamt = io.op1(5, 0)
     For a real ALU, add / sub operations would likely be combined to only use
     a single adder, negating the second operand for subtractions.
    and_result = op0_ex & op1_ex
    or_result = op0_ex | op1_ex
    add_result = op0_ex + op1_ex
    sub_result = op0_ex - op1_ex
    sll_result = io.op0 << shamt
    srl_result = io.op0 >> shamt
    result = Wire(Bits(C['core-width'] * 2))
    io.result <<= result(C['core-width'] - 1, 0)
    result <<= 0
    io.flags.zero <<= (result == 0)
    io.flags.sign <<= result(result.width - 1, result.width - 1)
    io.flags.overflow <<= BitOrReduce(result(result.width - 1, C['core-width']))
     The following essentially produces a mux that selects an output produced
     by this ALU based on the inst requested.
    with io.alu_inst == AluInsts.AND:
        result <<= and_result
    with io.alu_inst == AluInsts.OR:
        result <<= or_result
    with io.alu_inst == AluInsts.ADD:
        result <<= add_result
    with io.alu_inst == AluInsts.SUB:
        result <<= sub_result
    with io.alu_inst == AluInsts.SLL:
        result <<= Cat([zero, sll_result])
    with io.alu_inst == AluInsts.SRL:
        result <<= Cat([zero, srl_result])
    NameSignals(locals())
def ArithmeticLogicUnit ( ) : io = Io ( { 'op0' : Input ( Bits ( C [ 'core-width' ] ) ) , 'op1' : Input ( Bits ( C [ 'core-width' ] ) ) , 'alu_inst' : Input ( Bits ( AluInsts . width ) ) , 'result' : Output ( Bits ( C [ 'core-width' ] ) ) , 'flags' : Output ( alu_flags ) } ) zero = Wire ( Bits ( C [ 'core-width' ] ) ) shift_op = Wire ( Bits ( 1 ) ) op0_ex = Cat ( [ zero , io . op0 ] ) op1_ex = Cat ( [ zero , io . op1 ] ) shamt = io . op1 ( 5 , 0 ) and_result = op0_ex & op1_ex or_result = op0_ex | op1_ex add_result = op0_ex + op1_ex sub_result = op0_ex - op1_ex sll_result = io . op0 << shamt srl_result = io . op0 >> shamt result = Wire ( Bits ( C [ 'core-width' ] * 2 ) ) io . result <<= result ( C [ 'core-width' ] - 1 , 0 ) result <<= 0 io . flags . zero <<= ( result == 0 ) io . flags . sign <<= result ( result . width - 1 , result . width - 1 ) io . flags . overflow <<= BitOrReduce ( result ( result . width - 1 , C [ 'core-width' ] ) ) with io . alu_inst == AluInsts . AND : result <<= and_result with io . alu_inst == AluInsts . OR : result <<= or_result with io . alu_inst == AluInsts . ADD : result <<= add_result with io . alu_inst == AluInsts . SUB : result <<= sub_result with io . alu_inst == AluInsts . SLL : result <<= Cat ( [ zero , sll_result ] ) with io . alu_inst == AluInsts . SRL : result <<= Cat ( [ zero , srl_result ] ) NameSignals ( locals ( ) )
The primary arithmetic/logic unit for Geode.
The primary arithmetic / logic unit for Geode .
"""The primary arithmetic/logic unit for Geode.""" # # To make checking for overflow easy, all arithmetic operations are # performed on 2 x core-width (sign extended) data. # # # N.B. For all RV32I instructions, the shamt is actually only 5 bits. For # 64 bit instructions, it's 6 bits. It's safe to always extract a 6-bit # shamt because 32 bit instructions all coincidentally leave io.op1(6) # set to zero, anyway. # # # For a real ALU, add / sub operations would likely be combined to only use # a single adder, negating the second operand for subtractions. # # # The following essentially produces a mux that selects an output produced # by this ALU based on the inst requested. #