WIP fixing bugs

This commit is contained in:
Jacob Lifshay 2025-12-15 02:48:40 -08:00
parent 84e4fde512
commit d42f010cda
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 17859 additions and 14030 deletions

View file

@ -460,6 +460,7 @@ struct MockExecuteState {
queue: VecDeque<SimValue<ExecuteRetirePipeQueueEntry>>,
used_ids: BTreeSet<SimValue<UInt<12>>>,
retire_seq: RetireSeq,
canceling: bool,
config: PhantomConst<CpuConfig>,
}
@ -469,6 +470,7 @@ impl MockExecuteState {
queue: VecDeque::new(),
used_ids: BTreeSet::new(),
retire_seq: RetireSeq::new(),
canceling: false,
config,
}
}
@ -483,6 +485,7 @@ impl MockExecuteState {
fn do_retire(
&mut self,
entry: SimValue<ExecuteRetirePipeQueueEntry>,
passive: bool,
) -> Result<SimValue<RetireToNextPcInterfacePerInsn<PhantomConst<CpuConfig>>>, String> {
#[hdl(sim)]
let ExecuteRetirePipeQueueEntry {
@ -549,6 +552,18 @@ impl MockExecuteState {
"insn doesn't match expected:\ninsn: {insn:?}\nexpected insn: {expected_insn:?}"
));
}
if let Some(next_insn) = self.queue.front() {
if next_pc != next_insn.insn.pc.as_int() {
self.canceling = true;
if !passive {
println!(
"MockExecuteState: starting canceling {} instruction(s): next_pc={next_pc:#x}, mis-predicted next_pc={next_insn_pc}",
self.queue.len(),
next_insn_pc = next_insn.insn.pc
);
}
}
}
Ok(
#[hdl(sim)]
RetireToNextPcInterfacePerInsn::<_> {
@ -569,16 +584,20 @@ impl MockExecuteState {
#[hdl]
fn try_retire(
&mut self,
passive: bool,
) -> Option<(
SimValue<RetireToNextPcInterfacePerInsn<PhantomConst<CpuConfig>>>,
Result<(), String>,
)> {
if self.canceling {
return None;
}
if self.queue.front()?.cycles_left.as_int() != 0 {
return None;
}
let entry = self.queue.pop_front()?;
let id = entry.insn.id.clone();
Some(match self.do_retire(entry) {
Some(match self.do_retire(entry, passive) {
Ok(v) => (v, Ok(())),
Err(e) => (
#[hdl(sim)]
@ -611,6 +630,16 @@ impl MockExecuteState {
},
);
}
#[hdl]
fn finish_cancel(&mut self) {
println!(
"MockExecuteState: finishing canceling {} instruction(s)",
self.queue.len(),
);
self.queue.clear();
self.used_ids.clear();
self.canceling = false;
}
}
#[hdl_module(extern)]
@ -645,7 +674,7 @@ fn mock_execute_retire_pipe(config: PhantomConst<CpuConfig>) {
.await;
sim.write(
retire_output.next_insn_ids,
retire_output.next_insn_ids.ty().new_sim(0_hdl_u12),
retire_output.next_insn_ids.ty().HdlNone(),
)
.await;
sim.write(
@ -699,7 +728,7 @@ fn mock_execute_retire_pipe(config: PhantomConst<CpuConfig>) {
let mut sim_queue = queue_debug
.ty()
.new_sim(ExecuteRetirePipeQueueEntry.default_sim());
let mut next_insn_ids = retire_output.next_insn_ids.ty().new_sim(0_hdl_u12);
let mut next_insn_ids = retire_output.next_insn_ids.ty().HdlSome.new_sim(0_hdl_u12);
for entry in &state.queue {
ArrayVec::try_push_sim(&mut sim_queue, entry)
.ok()
@ -707,10 +736,20 @@ fn mock_execute_retire_pipe(config: PhantomConst<CpuConfig>) {
let _ = ArrayVec::try_push_sim(&mut next_insn_ids, &entry.insn.id);
}
sim.write(queue_debug, sim_queue).await;
sim.write(retire_output.next_insn_ids, next_insn_ids).await;
sim.write(
retire_output.next_insn_ids,
if state.canceling {
#[hdl(sim)]
(retire_output.next_insn_ids.ty()).HdlNone()
} else {
#[hdl(sim)]
(retire_output.next_insn_ids.ty()).HdlSome(next_insn_ids)
},
)
.await;
let mut retiring = retire_vec_ty.new_sim(&empty_retire_insn);
let mut peek_state = state.clone();
while let Some((peek_retire, result)) = peek_state.try_retire() {
while let Some((peek_retire, result)) = peek_state.try_retire(true) {
if result.is_err() && **ArrayVec::len_sim(&retiring) > 0 {
break;
}
@ -737,7 +776,11 @@ fn mock_execute_retire_pipe(config: PhantomConst<CpuConfig>) {
.await;
sim.write(
from_post_decode.ready,
state.space_available().min(config.get().fetch_width.get()),
if state.canceling {
0
} else {
state.space_available().min(config.get().fetch_width.get())
},
)
.await;
sim.wait_for_clock_edge(cd.clk).await;
@ -752,9 +795,12 @@ fn mock_execute_retire_pipe(config: PhantomConst<CpuConfig>) {
))
}))
);
if state.canceling {
state.finish_cancel();
}
if sim.read_past_bool(retire_output.inner.ready, cd.clk).await {
for _ in 0..**ArrayVec::len_sim(&retiring) {
match state.try_retire() {
match state.try_retire(false) {
Some((_, Ok(_))) => {}
Some((_, Err(e))) => panic!("retire error: {e}"),
None => unreachable!(),
@ -850,7 +896,7 @@ fn test_next_pc() {
};
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
for _cycle in 0..300 {
for _cycle in 0..500 {
sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick");
sim.write_clock(sim.io().cd.clk, true);