ZhaoCake
ZhaoCake

Reputation: 1

"unresolved import <my crates in project>" in Rust. Suspected to be caused by circular dependencies, but still reported an error after modification

I am using Rust to write a RiscV instruction set simulator, but it failed during the implementation of instruction decoding and execution. Because I encountered an issue while importing my inst and register in cpu.rs. Strangely, if there is a syntax error in cpu.rs, it will not trigger this ' unreleased import ' error.

cpu.rs

This is the GitHub repository address for my code. Please guide me on how to modify my code.

https://github.com/ZhaoCake/cakemu_rv

Previously, I discovered that some cpu.rs functions were used in my inst.rs (because the execution part of the instruction set simulator needs to call functions to change the values of the simulated memory and registers), and I believe this is where the loop dependency caused the import package to fail. Later, I modified it to return a DecodedInst struct from the decode_instruction function in inst.rs to complete the execution steps in cpu.rs (I also considered returning a closure, but failed, as I have done in my previous commits).

After modifying in the current way, I think there should be no functions from cpu.rs or register.rs in my inst.rs, but the problem still exists and I cannot solve it.

cpu.rs

use crate::debugger::Debugger;
use crate::inst::{decode_instruction, BranchOp, NextPc, Operation, RegOp};
use crate::loader::Loader;
use crate::memory::Memory;
use crate::register::RegisterFile;

pub struct Cpu {
    registers: RegisterFile,
    pc: u32,
    memory: Memory,
    debugger: Debugger,
}

impl Cpu {
    pub fn new(memory_size: usize) -> Self {
        Self {
            registers: RegisterFile::new(),
            pc: 0,
            memory: Memory::new(memory_size),
            debugger: Debugger::new(),
        }
    }

    pub fn step(&mut self) -> Result<(), &'static str> {
        let raw_inst = self.fetch()?;
        let decoded = decode_instruction(raw_inst)?;

        self.debugger
            .trace_instruction(self.pc, raw_inst, "TODO: add disassembly");

        match decoded.op {
            Operation::RegWrite { rd, value } => {
                self.registers.write(rd, value);
            }
            Operation::RegImmOp { rd, rs1, imm, op } => {
                let rs1_val = self.registers.read(rs1);
                let result = match op {
                    RegOp::Add => rs1_val.wrapping_add(imm as u32),
                    RegOp::Sll => rs1_val << (imm & 0x1f),
                    RegOp::Slt => ((rs1_val as i32) < imm) as u32,
                    RegOp::Sltu => (rs1_val < imm as u32) as u32,
                    RegOp::Xor => rs1_val ^ (imm as u32),
                    RegOp::Srl => rs1_val >> (imm & 0x1f),
                    RegOp::Sra => ((rs1_val as i32) >> (imm & 0x1f)) as u32,
                    RegOp::Or => rs1_val | (imm as u32),
                    RegOp::And => rs1_val & (imm as u32),
                    _ => return Err("Unsupported RegImmOp"),
                };
                self.registers.write(rd, result);
            }
...

main structure in inst.rs

#[derive(Debug)]
pub enum InstType {
    R, I, S, B, U, J
}

#[derive(Debug)]
pub struct Operands {
    pub rd: usize,
    pub rs1: usize,
    pub rs2: usize,
    pub imm: i32,
}

#[derive(Debug)]
pub enum Operation {
    RegWrite { rd: usize, value: u32 },
    RegRegOp { rd: usize, rs1: usize, rs2: usize, op: RegOp },
    RegImmOp { rd: usize, rs1: usize, imm: i32, op: RegOp },
    Branch { rs1: usize, rs2: usize, offset: i32, op: BranchOp },
    Jump { rd: usize, offset: i32 },
    Load { rd: usize, rs1: usize, offset: i32, size: usize },
    Store { rs1: usize, rs2: usize, offset: i32, size: usize },
}

#[derive(Debug)]
pub enum RegOp {
    Add, Sub, And, Or, Xor, Slt, Sltu, Sll, Srl, Sra,
}

#[derive(Debug, Clone)]
pub enum BranchOp {
    Eq, Ne, Lt, Ge, Ltu, Geu,
}

#[derive(Debug)]
pub struct DecodedInst {
    pub op: Operation,
    pub next_pc: NextPc,
}

#[derive(Debug)]
pub enum NextPc {
    Plus4,
    Jump(i32),
    Branch { cond: BranchOp, rs1: usize, rs2: usize, offset: i32 },
}

the decode instruction function in inst.rs:

pub fn decode_instruction(inst: u32) -> Result<DecodedInst, &'static str> {
    let opcode = inst & 0x7f;
    let funct3 = (inst >> 12) & 0x7;
    let funct7 = (inst >> 25) & 0x7f;

    match opcode {
        0x37 => {  // LUI
            let ops = Operands::decode(inst, InstType::U);
            Ok(DecodedInst {
                op: Operation::RegWrite { rd: ops.rd, value: (ops.imm as u32) & 0xfffff000 },
                next_pc: NextPc::Plus4,
            })
        },
...
        _ => Err("Unknown opcode"),
    }
}

I am so sorry for that I forgot to show error info.

❯ cargo check
    Checking riscv-emu v0.1.0 (/home/zhaocake/WorkSpace/RISCV/cakemu_rv)
warning: unused import: `std::fs::File`
 --> src/loader/mod.rs:1:5
  |
1 | use std::fs::File;
  |     ^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused imports: `Read` and `self`
 --> src/loader/mod.rs:2:15
  |
2 | use std::io::{self, Read};
  |               ^^^^  ^^^^

warning: `riscv-emu` (lib) generated 2 warnings (run `cargo fix --lib -p riscv-emu` to apply 2 suggestions)
error[E0432]: unresolved import `crate::inst`
 --> src/cpu.rs:2:12
  |
2 | use crate::inst::{decode_instruction, BranchOp, NextPc, Operation, RegOp};
  |            ^^^^
  |            |
  |            unresolved import
  |            help: a similar path exists: `riscv_emu::inst`

error[E0432]: unresolved import `crate::register`
 --> src/cpu.rs:5:12
  |
5 | use crate::register::RegisterFile;
  |            ^^^^^^^^
  |            |
  |            unresolved import
  |            help: a similar path exists: `riscv_emu::register`

For more information about this error, try `rustc --explain E0432`.
warning: `riscv-emu` (bin "riscv-emu") generated 2 warnings (2 duplicates)
error: could not compile `riscv-emu` (bin "riscv-emu") due to 2 previous errors; 2 warnings emitted

Upvotes: 0

Views: 26

Answers (0)

Related Questions