forked from libre-chip/cpu
unit::alu_branch: convert *MOp functions to hdl_module
This commit is contained in:
parent
42056ce6b5
commit
a3898e8c13
5 changed files with 155663 additions and 115637 deletions
|
|
@ -26,13 +26,20 @@ use fayalite::{
|
|||
};
|
||||
use std::{collections::HashMap, ops::RangeTo};
|
||||
|
||||
#[hdl]
|
||||
fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
||||
global_state: Expr<GlobalState>,
|
||||
pc: Expr<UInt<64>>,
|
||||
mop: Expr<AddSubMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn add_sub<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let pc: UInt<64> = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<AddSubMOp<PRegNum<C>, PRegNum<C>, SrcCount>> =
|
||||
m.input(TraceAsString[AddSubMOp[PRegNum[config]][PRegNum[config]][SrcCount::SIZE]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
#[hdl]
|
||||
|
|
@ -42,7 +49,7 @@ fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
src1_is_carry_in,
|
||||
invert_carry_in,
|
||||
add_pc,
|
||||
} = mop;
|
||||
} = *mop;
|
||||
#[hdl]
|
||||
let AluCommonMOp::<_, _, _, _> {
|
||||
common,
|
||||
|
|
@ -111,8 +118,7 @@ fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
},
|
||||
));
|
||||
|
||||
#[hdl]
|
||||
let int_fp: UInt<64> = wire();
|
||||
let int_fp = output.int_fp;
|
||||
|
||||
#[hdl]
|
||||
let x86_cf = wire();
|
||||
|
|
@ -201,12 +207,10 @@ fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
}
|
||||
}
|
||||
#[hdl]
|
||||
let flags = wire();
|
||||
#[hdl]
|
||||
match flags_mode {
|
||||
FlagsMode::PowerISA(_) => {
|
||||
connect(
|
||||
flags,
|
||||
output.flags,
|
||||
PRegFlagsPowerISA::from_view(PRegFlagsPowerISAView {
|
||||
unused: ViewUnused::splat(false.to_expr()),
|
||||
xer_ca: pwr_ca,
|
||||
|
|
@ -222,7 +226,7 @@ fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
}
|
||||
FlagsMode::X86(_) => {
|
||||
connect(
|
||||
flags,
|
||||
output.flags,
|
||||
PRegFlagsX86::from_view(PRegFlagsX86View {
|
||||
unused: ViewUnused::splat(false.to_expr()),
|
||||
cf: x86_cf,
|
||||
|
|
@ -237,32 +241,44 @@ fn add_sub<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
);
|
||||
}
|
||||
}
|
||||
let retval = #[hdl]
|
||||
PRegValue { int_fp, flags };
|
||||
retval.to_trace_as_string()
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn logical_flags<C: PhantomConstCpuConfig>(
|
||||
global_state: Expr<GlobalState>,
|
||||
mop: Expr<LogicalFlagsMOp<PRegNum<C>, PRegNum<C>>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn logical_flags<C: Type + PhantomConstCpuConfig>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<LogicalFlagsMOp<PRegNum<C>, PRegNum<C>>> =
|
||||
m.input(TraceAsString[LogicalFlagsMOp[PRegNum[config]][PRegNum[config]]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode: _ } = global_state;
|
||||
LogicalFlagsMOp::operation(mop, src_values.map(|v| *v)).to_trace_as_string()
|
||||
connect(
|
||||
output,
|
||||
LogicalFlagsMOp::operation(*mop, src_values.map(|v| *v)).to_trace_as_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
||||
global_state: Expr<GlobalState>,
|
||||
mop: Expr<LogicalMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn logical<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<LogicalMOp<PRegNum<C>, PRegNum<C>, SrcCount>> =
|
||||
m.input(TraceAsString[LogicalMOp[PRegNum[config]][PRegNum[config]][SrcCount::SIZE]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
#[hdl]
|
||||
let LogicalMOp::<_, _, _> { alu_common, lut } = mop;
|
||||
let LogicalMOp::<_, _, _> { alu_common, lut } = *mop;
|
||||
#[hdl]
|
||||
let AluCommonMOp::<_, _, _, _> {
|
||||
common,
|
||||
|
|
@ -287,8 +303,6 @@ fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
let lut4_output = wire();
|
||||
connect(lut4_output, Lut4::output(lut, lhs.int_fp, rhs.int_fp));
|
||||
#[hdl]
|
||||
let logical_result: TraceAsString<PRegValue> = wire();
|
||||
#[hdl]
|
||||
let x86_sf = wire();
|
||||
#[hdl]
|
||||
match flags_mode {
|
||||
|
|
@ -303,13 +317,13 @@ fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
cr_gt,
|
||||
cr_eq,
|
||||
so,
|
||||
} = PRegFlags::view::<PRegFlagsPowerISA>(logical_result.flags);
|
||||
} = PRegFlags::view::<PRegFlagsPowerISA>(output.flags);
|
||||
unused.clear();
|
||||
connect(xer_ca, false);
|
||||
connect(xer_ca32, false);
|
||||
connect(xer_ov, false);
|
||||
connect(xer_ov32, false);
|
||||
let signed_result = logical_result.int_fp.cast_to_static::<SInt<64>>();
|
||||
let signed_result = output.int_fp.cast_to_static::<SInt<64>>();
|
||||
connect(cr_lt, signed_result.cmp_lt(0i64));
|
||||
connect(cr_eq, signed_result.cmp_eq(0i64));
|
||||
connect(cr_gt, !(cr_lt | cr_eq));
|
||||
|
|
@ -325,29 +339,29 @@ fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
af,
|
||||
pf,
|
||||
df,
|
||||
} = PRegFlags::view::<PRegFlagsX86>(logical_result.flags);
|
||||
} = PRegFlags::view::<PRegFlagsX86>(output.flags);
|
||||
unused.clear();
|
||||
connect(cf, false);
|
||||
connect(zf, logical_result.int_fp.cmp_eq(0u64));
|
||||
connect(zf, output.int_fp.cmp_eq(0u64));
|
||||
connect(sf, x86_sf);
|
||||
connect(of, false);
|
||||
connect(af, false);
|
||||
connect(pf, logical_result.int_fp[..8].parity_even());
|
||||
connect(pf, output.int_fp[..8].parity_even());
|
||||
connect(df, false);
|
||||
}
|
||||
}
|
||||
let connect_output = |width, signed| {
|
||||
connect(x86_sf, logical_result.int_fp[width - 1]);
|
||||
connect(x86_sf, output.int_fp[width - 1]);
|
||||
if signed {
|
||||
connect(
|
||||
logical_result.int_fp,
|
||||
output.int_fp,
|
||||
lut4_output
|
||||
.cast_to(SInt[width])
|
||||
.cast_to_static::<UInt<64>>(),
|
||||
);
|
||||
} else {
|
||||
connect(
|
||||
logical_result.int_fp,
|
||||
output.int_fp,
|
||||
lut4_output
|
||||
.cast_to(UInt[width])
|
||||
.cast_to_static::<UInt<64>>(),
|
||||
|
|
@ -358,9 +372,9 @@ fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
match output_integer_mode {
|
||||
OutputIntegerMode::Full64 => connect_output(64, false),
|
||||
OutputIntegerMode::DupLow32 => {
|
||||
connect(x86_sf, logical_result.int_fp[31]);
|
||||
connect(x86_sf, output.int_fp[31]);
|
||||
let v = lut4_output.cast_to_static::<UInt<32>>();
|
||||
connect_any(logical_result.int_fp, v | (v << 32));
|
||||
connect_any(output.int_fp, v | (v << 32));
|
||||
}
|
||||
OutputIntegerMode::ZeroExt32 => connect_output(32, false),
|
||||
OutputIntegerMode::SignExt32 => connect_output(32, true),
|
||||
|
|
@ -369,7 +383,6 @@ fn logical<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
OutputIntegerMode::ZeroExt8 => connect_output(8, false),
|
||||
OutputIntegerMode::SignExt8 => connect_output(8, true),
|
||||
}
|
||||
logical_result
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
|
|
@ -438,16 +451,22 @@ fn funnel_shift<W: Size, A: Size>(
|
|||
funnel_shift_retval
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn shift_rotate<C: PhantomConstCpuConfig>(
|
||||
global_state: Expr<GlobalState>,
|
||||
mop: Expr<ShiftRotateMOp<PRegNum<C>, PRegNum<C>>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn shift_rotate<C: Type + PhantomConstCpuConfig>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<ShiftRotateMOp<PRegNum<C>, PRegNum<C>>> =
|
||||
m.input(TraceAsString[ShiftRotateMOp[PRegNum[config]][PRegNum[config]]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
#[hdl]
|
||||
let ShiftRotateMOp::<_, _> { alu_common, mode } = mop;
|
||||
let ShiftRotateMOp::<_, _> { alu_common, mode } = *mop;
|
||||
#[hdl]
|
||||
let AluCommonMOp::<_, _, _, _> {
|
||||
common,
|
||||
|
|
@ -561,8 +580,7 @@ fn shift_rotate<C: PhantomConstCpuConfig>(
|
|||
} else {
|
||||
connect(masked, shifted_rotated);
|
||||
}
|
||||
#[hdl]
|
||||
let int_fp: UInt<64> = wire();
|
||||
let int_fp = output.int_fp;
|
||||
fn connect_int_fp_cast<T: IntType + StaticType>(int_fp: Expr<UInt<64>>, masked: Expr<UInt<64>>)
|
||||
where
|
||||
UInt<64>: CastToImpl<T>,
|
||||
|
|
@ -587,27 +605,28 @@ fn shift_rotate<C: PhantomConstCpuConfig>(
|
|||
OutputIntegerMode::ZeroExt8 => connect_int_fp_cast::<UInt<8>>(int_fp, masked),
|
||||
OutputIntegerMode::SignExt8 => connect_int_fp_cast::<SInt<8>>(int_fp, masked),
|
||||
}
|
||||
let retval = #[hdl]
|
||||
PRegValue {
|
||||
int_fp,
|
||||
flags: PRegFlags::zeroed(), // TODO: compute flags
|
||||
};
|
||||
retval.into_trace_as_string()
|
||||
connect(output.flags, PRegFlags::zeroed()); // TODO: compute flags
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
||||
global_state: Expr<GlobalState>,
|
||||
mop: Expr<CompareMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn compare<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<CompareMOp<PRegNum<C>, PRegNum<C>, SrcCount>> =
|
||||
m.input(TraceAsString[CompareMOp[PRegNum[config]][PRegNum[config]][SrcCount::SIZE]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
#[hdl]
|
||||
let CompareMOp::<_, _, _> {
|
||||
common,
|
||||
compare_mode,
|
||||
} = mop;
|
||||
} = *mop;
|
||||
let config = common.dest.unit_num.config.ty();
|
||||
let (lhs, rhs) = match SrcCount::VALUE {
|
||||
1 => (
|
||||
|
|
@ -624,9 +643,7 @@ fn compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
2 => (src_values[0], src_values[1]),
|
||||
_ => todo!(),
|
||||
};
|
||||
#[hdl]
|
||||
let compare_result = wire();
|
||||
connect(compare_result, PRegValue::zeroed().to_trace_as_string());
|
||||
connect(output, PRegValue::zeroed().to_trace_as_string());
|
||||
|
||||
#[hdl]
|
||||
let lhs_casted: SInt<65> = wire();
|
||||
|
|
@ -640,25 +657,37 @@ fn compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
#[hdl]
|
||||
let x86_flags = wire();
|
||||
let zero_reg = PRegNum[config].const_zero();
|
||||
|
||||
#[hdl]
|
||||
let add_sub_for_flags = instance(add_sub(config));
|
||||
#[hdl]
|
||||
let add_sub::<_, _> {
|
||||
global_state: add_sub_for_flags_global_state,
|
||||
pc: add_sub_for_flags_pc,
|
||||
mop: add_sub_for_flags_mop,
|
||||
src_values: add_sub_for_flags_src_values,
|
||||
output: add_sub_for_flags_output,
|
||||
} = add_sub_for_flags;
|
||||
connect(add_sub_for_flags_global_state, global_state);
|
||||
connect(add_sub_for_flags_pc, 0u64);
|
||||
connect(
|
||||
x86_flags,
|
||||
add_sub(
|
||||
global_state,
|
||||
0u64.to_expr(),
|
||||
AddSubMOp::add_sub_i(
|
||||
zero_reg,
|
||||
repeat(zero_reg, ConstUsize),
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
x86_sub_mode,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
[rhs, lhs, PRegValue::zeroed().to_trace_as_string()].to_expr(),
|
||||
)
|
||||
.flags,
|
||||
*add_sub_for_flags_mop,
|
||||
AddSubMOp::add_sub_i(
|
||||
zero_reg,
|
||||
repeat(zero_reg, ConstUsize),
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
x86_sub_mode,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
);
|
||||
connect(
|
||||
add_sub_for_flags_src_values,
|
||||
[rhs, lhs, PRegValue::zeroed().to_trace_as_string()],
|
||||
);
|
||||
connect(x86_flags, add_sub_for_flags_output.flags);
|
||||
|
||||
#[hdl]
|
||||
let power_isa_flags = wire();
|
||||
|
|
@ -690,8 +719,8 @@ fn compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
connect(rhs_casted, do_cast(rhs.int_fp));
|
||||
#[hdl]
|
||||
match flags_mode {
|
||||
FlagsMode::PowerISA(_) => connect(compare_result.flags, power_isa_flags),
|
||||
FlagsMode::X86(_) => connect(compare_result.flags, x86_flags),
|
||||
FlagsMode::PowerISA(_) => connect(output.flags, power_isa_flags),
|
||||
FlagsMode::X86(_) => connect(output.flags, x86_flags),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -717,24 +746,31 @@ fn compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
compare_result
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn branch<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
||||
global_state: Expr<GlobalState>,
|
||||
pc: Expr<UInt<64>>,
|
||||
fallthrough_pc: Expr<UInt<64>>,
|
||||
predicted_next_pc: Expr<UInt<64>>,
|
||||
mop: Expr<BranchMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
config: C,
|
||||
) -> (
|
||||
Expr<TraceAsString<PRegValue>>,
|
||||
Expr<NextPcPredictorOp<C>>,
|
||||
Expr<HdlOption<UnitCausedCancel<C>>>,
|
||||
) {
|
||||
#[hdl_module]
|
||||
fn branch<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let pc: UInt<64> = m.input();
|
||||
#[hdl]
|
||||
let fallthrough_pc: UInt<64> = m.input();
|
||||
#[hdl]
|
||||
let predicted_next_pc: UInt<64> = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<BranchMOp<PRegNum<C>, PRegNum<C>, SrcCount>> =
|
||||
m.input(TraceAsString[BranchMOp[PRegNum[config]][PRegNum[config]][SrcCount::SIZE]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
#[hdl]
|
||||
let predictor_op: NextPcPredictorOp<C> = m.output(NextPcPredictorOp[config]);
|
||||
#[hdl]
|
||||
let caused_cancel: HdlOption<UnitCausedCancel<C>> =
|
||||
m.output(HdlOption[UnitCausedCancel[config]]);
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
#[hdl]
|
||||
|
|
@ -746,7 +782,7 @@ fn branch<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
pc_relative,
|
||||
is_call,
|
||||
is_ret,
|
||||
} = mop;
|
||||
} = *mop;
|
||||
#[hdl]
|
||||
let CommonMOp::<_, _, _, _, _> {
|
||||
prefix_pad: _,
|
||||
|
|
@ -850,11 +886,9 @@ fn branch<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
connect(next_pc, fallthrough_pc);
|
||||
};
|
||||
#[hdl]
|
||||
let cancel = wire(HdlOption[UnitCausedCancel[config]]);
|
||||
#[hdl]
|
||||
if next_pc.cmp_ne(predicted_next_pc) {
|
||||
connect(
|
||||
cancel,
|
||||
caused_cancel,
|
||||
HdlSome(
|
||||
#[hdl]
|
||||
UnitCausedCancel::<C> {
|
||||
|
|
@ -865,13 +899,16 @@ fn branch<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
),
|
||||
);
|
||||
} else {
|
||||
connect(cancel, cancel.ty().HdlNone());
|
||||
};
|
||||
let fallthrough_pc_value = #[hdl]
|
||||
PRegValue {
|
||||
int_fp: fallthrough_pc,
|
||||
flags: PRegFlags::zeroed_sim(),
|
||||
connect(caused_cancel, caused_cancel.ty().HdlNone());
|
||||
};
|
||||
connect(
|
||||
*output,
|
||||
#[hdl]
|
||||
PRegValue {
|
||||
int_fp: fallthrough_pc,
|
||||
flags: PRegFlags::zeroed_sim(),
|
||||
},
|
||||
);
|
||||
#[hdl]
|
||||
let call_stack_op = wire();
|
||||
#[hdl]
|
||||
|
|
@ -890,29 +927,33 @@ fn branch<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
|
|||
} else {
|
||||
connect(cond_br_taken_opt, HdlNone());
|
||||
}
|
||||
(
|
||||
fallthrough_pc_value.into_trace_as_string(),
|
||||
connect(
|
||||
predictor_op,
|
||||
#[hdl]
|
||||
NextPcPredictorOp::<_> {
|
||||
call_stack_op,
|
||||
cond_br_taken: cond_br_taken_opt,
|
||||
config,
|
||||
},
|
||||
cancel,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn read_special<C: PhantomConstCpuConfig>(
|
||||
global_state: Expr<GlobalState>,
|
||||
pc: Expr<UInt<64>>,
|
||||
mop: Expr<ReadSpecialMOp<PRegNum<C>, PRegNum<C>>>,
|
||||
src_values: Expr<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<TraceAsString<PRegValue>> {
|
||||
#[hdl_module]
|
||||
fn read_special<C: Type + PhantomConstCpuConfig>(config: C) {
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
#[hdl]
|
||||
let mop: TraceAsString<ReadSpecialMOp<PRegNum<C>, PRegNum<C>>> =
|
||||
m.input(TraceAsString[ReadSpecialMOp[PRegNum[config]][PRegNum[config]]]);
|
||||
#[hdl]
|
||||
let src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }> = m.input();
|
||||
#[hdl]
|
||||
let output: TraceAsString<PRegValue> = m.output();
|
||||
|
||||
#[hdl]
|
||||
let GlobalState { flags_mode } = global_state;
|
||||
// TODO: finish
|
||||
PRegValue::zeroed().to_trace_as_string()
|
||||
connect(*output, PRegValue::zeroed());
|
||||
}
|
||||
|
||||
#[hdl_module]
|
||||
|
|
@ -975,68 +1016,193 @@ pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
|
|||
#[hdl]
|
||||
match mop {
|
||||
AluBranchMOp::<_, _>::AddSub(mop) => {
|
||||
connect(
|
||||
dest_value,
|
||||
add_sub(global_state, mop_instance.pc, mop, src_values),
|
||||
);
|
||||
#[hdl]
|
||||
let add_sub = instance(add_sub(config));
|
||||
#[hdl]
|
||||
let add_sub::<_, _> {
|
||||
global_state: global_state_,
|
||||
pc,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = add_sub;
|
||||
connect(global_state_, global_state);
|
||||
connect(pc, mop_instance.pc);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::AddSubI(mop) => {
|
||||
connect(
|
||||
dest_value,
|
||||
add_sub(global_state, mop_instance.pc, mop, src_values),
|
||||
);
|
||||
#[hdl]
|
||||
let add_sub_i = instance(add_sub(config));
|
||||
#[hdl]
|
||||
let add_sub::<_, _> {
|
||||
global_state: global_state_,
|
||||
pc,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = add_sub_i;
|
||||
connect(global_state_, global_state);
|
||||
connect(pc, mop_instance.pc);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::LogicalFlags(mop) => {
|
||||
connect(dest_value, logical_flags(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let logical_flags = instance(logical_flags(config));
|
||||
#[hdl]
|
||||
let logical_flags::<_> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = logical_flags;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::Logical(mop) => {
|
||||
connect(dest_value, logical(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let logical = instance(logical(config));
|
||||
#[hdl]
|
||||
let logical::<_, _> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = logical;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::LogicalI(mop) => {
|
||||
connect(dest_value, logical(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let logical_i = instance(logical(config));
|
||||
#[hdl]
|
||||
let logical::<_, _> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = logical_i;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::ShiftRotate(mop) => {
|
||||
connect(dest_value, shift_rotate(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let shift_rotate = instance(shift_rotate(config));
|
||||
#[hdl]
|
||||
let shift_rotate::<_> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = shift_rotate;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::Compare(mop) => {
|
||||
connect(dest_value, compare(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let compare = instance(compare(config));
|
||||
#[hdl]
|
||||
let compare::<_, _> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = compare;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::CompareI(mop) => {
|
||||
connect(dest_value, compare(global_state, mop, src_values));
|
||||
#[hdl]
|
||||
let compare_i = instance(compare(config));
|
||||
#[hdl]
|
||||
let compare::<_, _> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = compare_i;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
AluBranchMOp::<_, _>::Branch(mop) => {
|
||||
let (dest_value_, predictor_op_, caused_cancel_) = branch(
|
||||
global_state,
|
||||
mop_instance.pc,
|
||||
fallthrough_pc,
|
||||
mop_instance.predicted_next_pc,
|
||||
mop,
|
||||
src_values,
|
||||
config,
|
||||
);
|
||||
connect(dest_value, dest_value_);
|
||||
#[hdl]
|
||||
let branch = instance(branch(config));
|
||||
#[hdl]
|
||||
let branch::<_, _> {
|
||||
global_state: global_state_,
|
||||
pc: pc_,
|
||||
fallthrough_pc: fallthrough_pc_,
|
||||
predicted_next_pc,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
predictor_op: predictor_op_,
|
||||
caused_cancel: caused_cancel_,
|
||||
} = branch;
|
||||
connect(global_state_, global_state);
|
||||
connect(pc_, mop_instance.pc);
|
||||
connect(fallthrough_pc_, fallthrough_pc);
|
||||
connect(predicted_next_pc, mop_instance.predicted_next_pc);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
connect(predictor_op, predictor_op_);
|
||||
connect(caused_cancel, caused_cancel_);
|
||||
}
|
||||
AluBranchMOp::<_, _>::BranchI(mop) => {
|
||||
let (dest_value_, predictor_op_, caused_cancel_) = branch(
|
||||
global_state,
|
||||
mop_instance.pc,
|
||||
fallthrough_pc,
|
||||
mop_instance.predicted_next_pc,
|
||||
mop,
|
||||
src_values,
|
||||
config,
|
||||
);
|
||||
connect(dest_value, dest_value_);
|
||||
#[hdl]
|
||||
let branch_i = instance(branch(config));
|
||||
#[hdl]
|
||||
let branch::<_, _> {
|
||||
global_state: global_state_,
|
||||
pc: pc_,
|
||||
fallthrough_pc: fallthrough_pc_,
|
||||
predicted_next_pc,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
predictor_op: predictor_op_,
|
||||
caused_cancel: caused_cancel_,
|
||||
} = branch_i;
|
||||
connect(global_state_, global_state);
|
||||
connect(pc_, mop_instance.pc);
|
||||
connect(fallthrough_pc_, fallthrough_pc);
|
||||
connect(predicted_next_pc, mop_instance.predicted_next_pc);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
connect(predictor_op, predictor_op_);
|
||||
connect(caused_cancel, caused_cancel_);
|
||||
}
|
||||
AluBranchMOp::<_, _>::ReadSpecial(mop) => {
|
||||
connect(
|
||||
dest_value,
|
||||
read_special(global_state, mop_instance.pc, mop, src_values),
|
||||
);
|
||||
#[hdl]
|
||||
let read_special = instance(read_special(config));
|
||||
#[hdl]
|
||||
let read_special::<_> {
|
||||
global_state: global_state_,
|
||||
mop: mop_,
|
||||
src_values: src_values_,
|
||||
output,
|
||||
} = read_special;
|
||||
connect(global_state_, global_state);
|
||||
connect(*mop_, mop);
|
||||
connect(src_values_, src_values);
|
||||
connect(dest_value, output);
|
||||
}
|
||||
}
|
||||
connect(
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
83979
crates/cpu/tests/expected/rename_execute_retire_head_n1_real.vcd
generated
83979
crates/cpu/tests/expected/rename_execute_retire_head_n1_real.vcd
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue