Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
92595157eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright 2019- RSD contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
//
// 32bit ARM ALU
//
import BasicTypes::*;
import MicroOpTypes::*;
import OpFormatTypes::*;
import PipelineTypes::*;
typedef struct packed
{
logic carry;
DataPath data;
} IntAdderResult;
// 加算機
// inv がアサートされたオペランドはビット反転を行う
module IntAdder(
output
IntAdderResult dst,
logic overflowOut,
input
DataPath srcA, logic invA,
DataPath srcB, logic invB,
logic carryIn
);
function automatic DataPath Inv(
input DataPath src, logic inv
);
return inv ? ~src : src;
endfunction
DataPath tmpA, tmpB;
always_comb begin
tmpA = Inv( srcA, invA );
tmpB = Inv( srcB, invB );
dst = tmpA + tmpB + carryIn;
overflowOut =
( dst.data[DATA_WIDTH-1] ^ tmpA[DATA_WIDTH-1] ) &&
( dst.data[DATA_WIDTH-1] ^ tmpB[DATA_WIDTH-1] );
end
endmodule
module IntALU(
output
DataPath aluDataOut,
input
IntALU_Code aluCode,
DataPath fuOpA_In,
DataPath fuOpB_In
);
IntAdderResult opDst;
DataPath opA;
DataPath opB;
SignedDataPath signedOpA;
SignedDataPath signedOpB;
IntAdderResult adderDst;
DataPath adderInA; logic adderInvInA;
DataPath adderInB; logic adderInvInB;
logic adderInCarry;
logic adderOutOverflow;
IntAdder adder(
.dst(adderDst),
.srcA(adderInA),
.invA(adderInvInA),
.srcB(adderInB),
.invB(adderInvInB),
.carryIn(adderInCarry),
.overflowOut(adderOutOverflow)
);
`define Add( a, ia, b, ib, c ) begin \
adderInA = a; \
adderInvInA = ia; \
adderInB = b; \
adderInvInB = ib; \
adderInCarry = c; \
opDst = adderDst; \
end \
`define Logic( a ) begin \
adderInA = '0; \
adderInvInA = FALSE; \
adderInB = '0; \
adderInvInB = FALSE; \
adderInCarry = 0; \
opDst = { 1'b0, (a) }; \
end \
// Operation
always_comb begin
opA = fuOpA_In;
opB = fuOpB_In;
signedOpA = '0;
signedOpB = '0;
case( aluCode )
// AND 論理積
default: `Logic( opA & opB )
// EOR 排他的論理和
AC_EOR: `Logic( opA ^ opB )
// SUB 減算
// a - b = a + ~b + 1
AC_SUB: `Add( opA, FALSE, opB, TRUE, 1 )
// ADD 加算
AC_ADD: `Add( opA, FALSE, opB, FALSE, 0 )
// SLT 比較 Rd = if Rs1 < Rs2 then 1 else 0
AC_SLT : begin
signedOpA = opA;
signedOpB = opB;
`Logic( { 31'h0, ( signedOpA < signedOpB) } )
end
// SLTU 符号なし比較
AC_SLTU: `Logic( { 31'h0, ( opA < opB ) } )
// ORR (包含的)論理和 Rd := Rn OR shifter_operand
AC_ORR: `Logic( opA | opB )
`ifdef RSD_ENABLE_ZBA
// sh1add
AC_SH1ADD: `Add( opA << 1, FALSE, opB, FALSE, 0 )
// sh2add
AC_SH2ADD: `Add( opA << 2, FALSE, opB, FALSE, 0 )
// sh3add
AC_SH3ADD: `Add( opA << 3, FALSE, opB, FALSE, 0 )
`endif
`ifdef RSD_ENABLE_ZICOND
// czero.eqz
AC_EQZ: `Logic( { ( opB == 32'h0) ? 32'h0 : opA} )
// czero.nez
AC_NEZ: `Logic( { ( opB != 32'h0) ? 32'h0 : opA} )
`endif
endcase
aluDataOut = opDst.data;
end
endmodule : IntALU