Skip to content

Commit

Permalink
Merge pull request #15 from 0xPolygonHermez/fractasy_develop
Browse files Browse the repository at this point in the history
Implement zisksim using the new SimOptions
  • Loading branch information
eduadiez authored Jul 23, 2024
2 parents fc98b11 + 2de0be3 commit 6a807f9
Show file tree
Hide file tree
Showing 15 changed files with 342 additions and 206 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
/*.tar.gz
/*.tar.gz
/riscof
48 changes: 48 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'riscv2zisk'",
"cargo": {
"args": [
"build",
"--bin=riscv2zisk"
],
"filter": {
"name": "riscv2zisk",
"kind": "bin"
}
},
"args": ["riscof/riscof_work/rv64i_m/A/src/amoxor.w-01.S/dut/my.elf", "rom.json"],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'ziskemu'",
"cargo": {
"args": [
"build",
"--bin=ziskemu"
],
"filter": {
"name": "ziskemu",
"kind": "bin"
}
},
"args": [
"-e",
"riscof/riscof_work/rv64i_m",
"-l",
"-o",
"output.txt"
],
"cwd": "${workspaceFolder}"
}
]
}
11 changes: 6 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = [
"cli",
"common",
"riscv/riscv2zisk",
"simulator",
"emulator",
"state-machines/main",
"state-machines/mem",
"witness-computation",
Expand Down
9 changes: 5 additions & 4 deletions simulator/Cargo.toml → emulator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[package]
name = "zisksim"
name = "ziskemu"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.5.9", features = ["derive", "env"] }
riscv2zisk = {path="../riscv/riscv2zisk"}

[lib]
name = "zisksim"
name = "ziskemu"
path = "src/lib.rs"

[[bin]]
name = "zisksim"
path = "src/bin/zisksim.rs"
name = "ziskemu"
path = "src/bin/ziskemu.rs"
153 changes: 153 additions & 0 deletions emulator/src/bin/ziskemu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use clap::Parser;
use riscv2zisk::{Riscv2zisk, ZiskRom};
use std::{
fs,
fs::metadata,
path::{Path, PathBuf},
process,
};
use ziskemu::{Emu, EmuOptions};

fn main() {
// Create a emulator options instance based on arguments or default values
let options: EmuOptions = EmuOptions::parse();

// Log the emulator options if requested
if options.verbose {
println!("ziskemu converts an ELF RISCV file into a ZISK rom or loads a ZISK rom file, emulates it with the provided input, and copies the output to console or a file");
println!("{}", options);
}

// INPUT:
// build input data either from the provided input path, or leave it empty (default input)
let input: Vec<u8> = if options.input.is_some() {
// Read input data from the provided input path
let path = std::path::PathBuf::from(options.input.clone().unwrap());
std::fs::read(path).expect("Could not read input file")
} else {
// If no input data is provided, input will remain empty
// This normally means that input data is self-contained in the program
Vec::new()
};

if options.rom.is_some() && options.elf.is_some() {
eprintln!(
"Error parsing arguments: ROM file and ELF file are incompatible; use only one of them"
);
process::exit(1);
} else if options.rom.is_some() {
process_rom_file(options.rom.clone().unwrap(), &input, &options);
} else if options.elf.is_some() {
let elf_file = options.elf.clone().unwrap();
let md = metadata(elf_file.clone()).unwrap();
if md.is_file() {
process_elf_file(elf_file, &input, &options);
} else if md.is_dir() {
process_directory(elf_file, &input, &options);
}
} else {
eprintln!("Error parsing arguments: ROM file or ELF file must be provided");
process::exit(1);
}

// Return successfully
process::exit(0);
}

fn process_directory(directory: String, input: &[u8], options: &EmuOptions) {
let files = list_files(&directory);
for file in files {
if file.contains("dut") && file.ends_with(".elf") {
process_elf_file(file, input, options);
}
}
}

fn process_elf_file(elf_file: String, input: &[u8], options: &EmuOptions) {
// Convert the ELF file to ZisK ROM
let rom: ZiskRom = {
// Create an instance of the RISCV -> ZisK program converter
let rv2zk = Riscv2zisk::new(elf_file, String::new());

// Convert program to rom
let result = rv2zk.run();
if result.is_err() {
println!("Application error: {}", result.err().unwrap());
process::exit(1);
}

// Get the result
result.unwrap()
};

process_rom(&rom, input, options);
}

fn process_rom_file(_rom_file: String, input: &[u8], options: &EmuOptions) {
// TODO: load from file
let rom: ZiskRom = ZiskRom::new();
process_rom(&rom, input, options);
}

fn process_rom(rom: &ZiskRom, input: &[u8], options: &EmuOptions) {
// Create a emulator instance with this rom and input
let mut emu = Emu::new(rom, input.to_owned(), options.clone());

// Run the emulation
emu.run();
if !emu.terminated() {
println!("Emulation did not complete");
process::exit(1);
}

// OUTPUT:
// if requested, save output to file, or log it to console
if options.output.is_some() {
// Get the emulation output as a u8 vector
let output = emu.get_output_8();

// Save the output to file
let output_file = <Option<std::string::String> as Clone>::clone(&options.output).unwrap();
fs::write(output_file, output).expect("Unable to write output file");
}
// Log output to console
else {
// Get the emulation output as a u32 vector
let output = emu.get_output_32();

// Log the output to console
for o in &output {
println!("{:08x}", o);
}
}
}

fn list_files(directory: &String) -> Vec<String> {
let path = Path::new(directory);
let paths = list_files_paths(path);
let mut vec: Vec<String> = Vec::new();
for p in paths {
vec.push(p.display().to_string());
}
vec
}

fn list_files_paths(path: &Path) -> Vec<PathBuf> {
let mut vec = Vec::new();
_list_files(&mut vec, path);
vec
}

fn _list_files(vec: &mut Vec<PathBuf>, path: &Path) {
if metadata(path).unwrap().is_dir() {
let paths = fs::read_dir(path).unwrap();
for path_result in paths {
let full_path = path_result.unwrap().path();
if metadata(&full_path).unwrap().is_dir() {
_list_files(vec, &full_path);
} else {
vec.push(full_path);
}
}
}
}
Loading

0 comments on commit 6a807f9

Please sign in to comment.