Loading files
This 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
dbfa8e081This file is pinned to the selected release. Download the original to open it in your design tool.