1
0
Fork 0
rocket-chip/rocket/src/main/scala/dpath_alu.scala

92 lines
3.0 KiB
Scala

package Top {
import Chisel._
import Node._;
import Constants._
import Instructions._
class ioALU extends Bundle(){
val dw = UFix(1, 'input);
val fn = UFix(4, 'input);
val shamt = UFix(6, 'input);
val in2 = UFix(64, 'input);
val in1 = UFix(64, 'input);
val out = UFix(64, 'output);
}
class rocketDpathALU extends Component
{
val io = new ioALU();
val out64 =
MuxCase(Fix(0, 64), Array(
(io.fn === FN_ADD) -> (io.in1 + io.in2).toFix,
(io.fn === FN_SUB) -> (io.in1 - io.in2).toFix,
(io.fn === FN_SLT) -> (io.in1.toFix < io.in2.toFix), //(io.in1 < io.in2)
(io.fn === FN_SLTU) -> (io.in1 < io.in2).toFix,
(io.fn === FN_AND) -> (io.in1 & io.in2).toFix,
(io.fn === FN_OR) -> (io.in1 | io.in2).toFix,
(io.fn === FN_XOR) -> (io.in1 ^ io.in2).toFix,
(io.fn === FN_SL) -> (io.in1 << io.shamt).toFix,
(io.fn === FN_SR && io.dw === DW_64) -> (io.in1 >> io.shamt).toFix,
(io.fn === FN_SR && io.dw === DW_32) -> (Cat(Fix(0, 32),io.in1(31, 0)).toUFix >> io.shamt),
(io.fn === FN_SRA) -> (io.in1.toFix >>> io.shamt)));
io.out := MuxLookup(io.dw, Fix(0, 64), Array(
DW_64 -> out64(63,0),
DW_32 -> Cat(Fill(32, out64(31)), out64(31,0)).toFix)).toUFix;
}
/*
class IoDpathALU extends Bundle {
val in0 = Bits(32,'input);
val in1 = Bits(32,'input);
val fn = Bits(4,'input);
val out = Bits(32,'output);
}
class DpathALU extends Component {
val io = new IoDpathALU();
val adder_in0 = MuxCase(io.in0,Array(
((io.fn === FN_SUB) | (io.fn === FN_SLT) | (io.fn === FN_SLTU)) -> (~io.in0)));
val adder_in1 = io.in1;
val adder_cin = MuxCase(Bits(0),Array(
((io.fn === FN_SUB) | (io.fn === FN_SLT) | (io.fn === FN_SLTU)) -> Bits(1)));
// Need to make the same width?
val adder_out = Cat(Bits(0,1),adder_in1).toUFix + Cat(Bits(0,1),adder_in0).toUFix + adder_cin.toUFix;
//adder_out := (adder_in1.toUFix + adder_in0.toUFix + adder_cin.toUFix);
// Determine if there is overflow
val overflow = (io.in0(31) ^ io.in1(31)) & (adder_out(32) != io.in0(31));
val compare_yes = MuxLookup(io.fn,Bits(0),Array(
// If unsigned, do subtraction, and if the result is negative, then slt=true
FN_SLTU -> ~adder_out(32),
// If signed, do subtraction, and if the result is negative, then slt=true as well
// But if there is bad overflow (operands same sign and result is a different sign),
// then need to flip
FN_SLT -> ~(adder_out(32) ^ overflow)));
io.out := MuxLookup(io.fn,Fix(0),Array(
FN_ADD -> adder_out,
FN_SUB -> adder_out,
FN_SLT -> compare_yes,
FN_SLTU -> compare_yes,
FN_AND -> (io.in0 & io.in1),
FN_OR -> (io.in0 | io.in1),
FN_XOR -> (io.in0 ^ io.in1),
FN_SL -> (io.in1 << io.in0(4,0).toUFix),
FN_SR -> (io.in1 >> io.in0(4,0).toUFix),
FN_SRA -> (io.in1.toFix >> io.in0(4,0).toUFix)
));
}
*/
}