2011-10-26 08:02:47 +02:00
|
|
|
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
|
|
|
|
{
|
2011-11-10 08:18:14 +01:00
|
|
|
val io = new ioALU();
|
|
|
|
|
2011-10-26 08:02:47 +02:00
|
|
|
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(
|
2011-11-10 08:18:14 +01:00
|
|
|
DW_64 -> out64(63,0),
|
2011-10-26 08:02:47 +02:00
|
|
|
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)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
}
|