improve ALU and fix revealed emulator bug
This commit is contained in:
parent
82700cad72
commit
96c78829b4
@ -20,72 +20,40 @@ class rocketDpathALU extends Component
|
|||||||
{
|
{
|
||||||
val io = new ioALU();
|
val io = new ioALU();
|
||||||
|
|
||||||
val out64 =
|
// ADD, SUB
|
||||||
MuxCase(Fix(0, 64), Array(
|
val sub = (io.fn === FN_SUB) || (io.fn === FN_SLT) || (io.fn === FN_SLTU)
|
||||||
(io.fn === FN_ADD) -> (io.in1 + io.in2).toFix,
|
val adder_rhs = Mux(sub, ~io.in2, io.in2)
|
||||||
(io.fn === FN_SUB) -> (io.in1 - io.in2).toFix,
|
val adder_out = (io.in1 + adder_rhs + sub.toUFix)(63,0)
|
||||||
(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(
|
// SLT, SLTU
|
||||||
DW_64 -> out64(63,0),
|
val less = Mux(io.in1(63) === io.in2(63), adder_out(63), io.in1(63))
|
||||||
DW_32 -> Cat(Fill(32, out64(31)), out64(31,0)).toFix)).toUFix;
|
val lessu = Mux(io.in1(63) === io.in2(63), adder_out(63), io.in2(63))
|
||||||
|
|
||||||
|
// SLL, SRL, SRA
|
||||||
|
val sra = (io.fn === FN_SRA)
|
||||||
|
val shright = sra || (io.fn === FN_SR)
|
||||||
|
val shin_hi_32 = Mux(sra, Fill(32, io.in1(31)), UFix(0,32))
|
||||||
|
val shin_hi = Mux(io.dw === DW_64, io.in1(63,32), shin_hi_32)
|
||||||
|
val shin_r = Cat(shin_hi, io.in1(31,0))
|
||||||
|
val shin = Mux(shright, shin_r, Reverse(shin_r))
|
||||||
|
val shout_r = (Cat(sra & shin_r(63), shin).toFix >>> io.shamt)(63,0)
|
||||||
|
|
||||||
|
val out64 = Wire { Bits(64) }
|
||||||
|
switch(io.fn)
|
||||||
|
{
|
||||||
|
is(FN_ADD) { out64 <== adder_out }
|
||||||
|
is(FN_SUB) { out64 <== adder_out }
|
||||||
|
is(FN_SLT) { out64 <== less }
|
||||||
|
is(FN_SLTU) { out64 <== lessu }
|
||||||
|
is(FN_AND) { out64 <== io.in1 & io.in2 }
|
||||||
|
is(FN_OR) { out64 <== io.in1 | io.in2 }
|
||||||
|
is(FN_XOR) { out64 <== io.in1 ^ io.in2 }
|
||||||
|
is(FN_SL) { out64 <== Reverse(shout_r) }
|
||||||
|
}
|
||||||
|
out64 <== shout_r
|
||||||
|
|
||||||
|
val out_hi = Mux(io.dw === DW_64, out64(63,32), Fill(32, out64(31)))
|
||||||
|
io.out := Cat(out_hi, out64(31,0)).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)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,23 @@ object FillInterleaved
|
|||||||
def apply(n: Int, in: Bits) =
|
def apply(n: Int, in: Bits) =
|
||||||
{
|
{
|
||||||
var out = Fill(n, in(0))
|
var out = Fill(n, in(0))
|
||||||
for (i <- 1 until in.width)
|
for (i <- 1 until in.getWidth)
|
||||||
out = Cat(Fill(n, in(i)), out)
|
out = Cat(Fill(n, in(i)), out)
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Reverse
|
||||||
|
{
|
||||||
|
def apply(in: Bits) =
|
||||||
|
{
|
||||||
|
var out = in(in.getWidth-1)
|
||||||
|
for (i <- 1 until in.getWidth)
|
||||||
|
out = Cat(in(in.getWidth-i-1), out)
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Mux1H(n: Int, w: Int) extends Component
|
class Mux1H(n: Int, w: Int) extends Component
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
|
Loading…
Reference in New Issue
Block a user