Virtual Integrated Circuits
Changelog
This library is a Integrated Circuit Emulator backend that can simulate interactions between multiple chips.
Note that for now there is only Digital circuit emulation, Analog signals will be implemented later.
You start by creating a Board, and then you add Traces or Sockets, and then you plug Chips and link Pins together to form a virtual circuit.
You can then run the circuit to emulate the chips and links between them.
This library is a Backend emulator, it means that there is no GUI (yet) to create boards.
Features
- Build Boards with chips and traces between them
- Simulate the board for a certain duration with a certain step, it's also possible to run it in realtime !
- Save and load the board to backup your design or continue your simulation later
Available Built-in Chips
- Generator
- Buttons
- Logic Gates (And, Or, Not)
- Clocks
- Memory (RAM, ROM)
- CPU (right now there is only one fictional CPU)
Contributing
This project is open to any contribution, from code reviewing to direct contribution !
You can :
- Suggest or Improve current code
- Suggest or Add new features
- Suggest or Add new built-in chips
- Any initiative is welcome !
example usage
use virt_ic::chip::gates::GateAnd;
use virt_ic::chip::generators::Generator;
use virt_ic::chip::Chip;
use virt_ic::{Board,State};
use std::time::Duration;
fn main() {
let mut board = Board::new();
let gen = board.new_socket_with(Box::new(Generator::new()));
let and_gate = board.new_socket_with(Box::new(GateAnd::new()));
{
let trc = board.new_trace();
trc.borrow_mut().connect(gen.borrow_mut().get_pin(Generator::VCC).unwrap());
trc.borrow_mut().connect(and_gate.borrow_mut().get_pin(GateAnd::VCC).unwrap());
}
{
let trc = board.new_trace();
trc.borrow_mut().connect(gen.borrow_mut().get_pin(Generator::GND).unwrap());
trc.borrow_mut().connect(and_gate.borrow_mut().get_pin(GateAnd::GND).unwrap());
}
{
let trc = board.new_trace();
trc.borrow_mut().connect(and_gate.borrow_mut().get_pin(GateAnd::A_AND_B).unwrap());
trc.borrow_mut().connect(and_gate.borrow_mut().get_pin(GateAnd::D).unwrap());
}
board.run_during(Duration::from_secs(1), Duration::from_millis(100));
println!("ABC:\tA&B\tA&B&C");
let a_b = and_gate.borrow_mut().get_pin_state(GateAnd::A_AND_B).as_bool();
println!("000:\t{}\t{}", a_b, and_gate.borrow_mut().get_pin_state(GateAnd::C_AND_D).as_bool());
and_gate.borrow_mut().set_pin_state(GateAnd::A, &State::High);
and_gate.borrow_mut().set_pin_state(GateAnd::B, &State::High);
and_gate.borrow_mut().set_pin_state(GateAnd::C, &State::Low);
board.run_during(Duration::from_secs(1), Duration::from_millis(100));
let a_b = and_gate.borrow_mut().get_pin_state(GateAnd::A_AND_B).as_bool();
println!("110:\t{}\t{}", a_b, and_gate.borrow_mut().get_pin_state(GateAnd::C_AND_D).as_bool());
and_gate.borrow_mut().set_pin_state(GateAnd::C, &State::High);
board.run_during(Duration::from_secs(1), Duration::from_millis(100));
let a_b = and_gate.borrow_mut().get_pin_state(GateAnd::A_AND_B).as_bool();
println!("111:\t{}\t{}", a_b, and_gate.borrow_mut().get_pin_state(GateAnd::C_AND_D).as_bool());
and_gate.borrow_mut().set_pin_state(GateAnd::A, &State::Low);
and_gate.borrow_mut().set_pin_state(GateAnd::B, &State::Low);
and_gate.borrow_mut().set_pin_state(GateAnd::C, &State::High);
board.run_during(Duration::from_secs(1), Duration::from_millis(100));
let a_b = and_gate.borrow_mut().get_pin_state(GateAnd::A_AND_B).as_bool();
println!("001:\t{}\t{}", a_b, and_gate.borrow_mut().get_pin_state(GateAnd::C_AND_D).as_bool());
}
Documentation
Take a look at the generated documentation.
Examples
See examples :
- readme : Same example as provided in this readme
- ram-test : A simple test of a RAM chip
- cpu-test : A simple circuit containing a minimal setup running a CPU processing factorial of 5