2BVDIKM6MIBFWPQVVSETJZN6WXV6YCKBC2CRPVI3DSV75UOR2NGAC
pub clk: CxxrtlSignal<1>,
pub led: CxxrtlSignal<1>,
pub counter: CxxrtlSignal<12>,
pub io_sel: CxxrtlSignal<2>,
pub io_in0: CxxrtlSignal<1>,
pub io_in1: CxxrtlSignal<1>,
pub io_in2: CxxrtlSignal<1>,
pub io_in3: CxxrtlSignal<1>,
pub io_out: CxxrtlSignal<1>,
let clk = handle.get("clock").unwrap().signal();
let led = handle.get("io_led").unwrap().signal();
let counter = handle.get("counter").unwrap().signal();
let io_sel = handle.get("io_sel").unwrap().signal();
let io_in0 = handle.get("io_in0").unwrap().signal();
let io_in1 = handle.get("io_in1").unwrap().signal();
let io_in2 = handle.get("io_in2").unwrap().signal();
let io_in3 = handle.get("io_in3").unwrap().signal();
let io_out = handle.get("io_out").unwrap().signal();
fn test_example() {
let mut blink = Blink::new();
blink.step();
for cycle in 0..1000 {
blink.clk.set(false);
blink.step();
let counter: u16 = blink.counter.get();
assert_eq!(counter, cycle);
blink.clk.set(true);
blink.step();
let counter: u16 = blink.counter.get();
assert_eq!(counter, cycle + 1);
let curr_led: bool = blink.led.get();
assert_eq!(curr_led, (cycle / 128) % 2 == 1);
fn test_mux4() {
let mut dut = Mux4::new();
for s0 in 0..2 {
for s1 in 0..2 {
for i0 in 0..2 {
for i1 in 0..2 {
for i2 in 0..2 {
for i3 in 0..2 {
dut.io_sel.set::<u8>(s1 << 1 | s0);
dut.io_in0.set::<bool>(i0.as_bool());
dut.io_in1.set::<bool>(i1.as_bool());
dut.io_in2.set::<bool>(i2.as_bool());
dut.io_in3.set::<bool>(i3.as_bool());
dut.step();
let out = if s1 == 1 {
if s0 == 1 {
i3
} else {
i2
}
} else {
if s0 == 1 {
i1
} else {
i0
}
};
assert_eq!(dut.io_out.get::<u8>(), out);
}
}
}
}
}
use chisel_tuto::get_handle;
use cxxrtl::{CxxrtlHandle, CxxrtlSignal};
use std::env;
struct Blink {
pub handle: CxxrtlHandle,
pub clk: CxxrtlSignal<1>,
pub led: CxxrtlSignal<1>,
pub counter: CxxrtlSignal<12>,
}
impl Blink {
fn new() -> Self {
let lib = concat!(env!("OUT_DIR"), "/Example.so");
let handle = get_handle(lib);
let clk = handle.get("clock").unwrap().signal();
let led = handle.get("io_led").unwrap().signal();
let counter = handle.get("counter").unwrap().signal();
Self {
handle,
clk,
led,
counter,
}
}
fn step(&mut self) {
self.handle.step()
}
}
#[test]
fn test_example() {
let mut blink = Blink::new();
// blink.step();
for cycle in 0..1000 {
blink.clk.set(false);
blink.step();
let counter: u16 = blink.counter.get();
assert_eq!(counter, cycle);
blink.clk.set(true);
blink.step();
let counter: u16 = blink.counter.get();
let count = cycle + 1;
assert_eq!(counter, count);
let curr_led: bool = blink.led.get();
assert_eq!(curr_led, (count / 128) % 2 == 1);
}
}
use chisel_tuto::get_handle;
use cxxrtl::{CxxrtlHandle, CxxrtlSignal, Vcd};
use std::{env, fs::File};
struct Counter {
pub handle: CxxrtlHandle,
pub clk: CxxrtlSignal<1>,
pub io_inc: CxxrtlSignal<1>,
pub io_amt: CxxrtlSignal<4>,
pub io_tot: CxxrtlSignal<8>,
}
impl Counter {
fn new() -> Self {
let lib = concat!(env!("OUT_DIR"), "/Counter.so");
let handle = get_handle(lib);
let clk = handle.get("clock").unwrap().signal();
let io_inc = handle.get("io_inc").unwrap().signal();
let io_amt = handle.get("io_amt").unwrap().signal();
let io_tot = handle.get("io_tot").unwrap().signal();
Self {
handle,
clk,
io_inc,
io_amt,
io_tot,
}
}
fn step(&mut self) {
self.handle.step()
}
}
#[test]
fn test_counter() {
let mut dut = Counter::new();
const MAX_INT: u8 = 16;
let mut cur_cnt = 0;
let int_wrap_around = |n: u8, max| {
if n > max {
0
} else {
n
}
};
dut.io_inc.set(false);
dut.io_amt.set::<u8>(0);
for _i in 0..5 {
dut.step();
}
// dut.step();
// let mut vcd = Vcd::default();
// vcd.timescale(cxxrtl::TimescaleNumber::One, cxxrtl::TimescaleUnit::Us);
// vcd.add(&dut.handle);
// let mut vcd_file = File::create("counter.vcd").unwrap();
for _i in 0..10 {
let inc = rand::random();
let amt = rand::random::<u8>() % MAX_INT;
dut.io_inc.set::<bool>(inc);
dut.io_amt.set::<u8>(amt);
dut.clk.set(false);
dut.step();
// vcd.sample(i * 2);
dut.clk.set(true);
dut.step();
// vcd.sample(i * 2 + 1);
// vcd.write(&mut vcd_file).unwrap();
cur_cnt = if inc {
int_wrap_around(cur_cnt + amt, 255)
} else {
cur_cnt
};
assert_eq!(dut.io_tot.get::<u8>(), cur_cnt);
}
}
$timescale 1 us $end
$var reg 1 ! clock $end
$var reg 4 " io_amt $end
$var reg 1 # io_inc $end
$var wire 8 $ io_tot $end
$var reg 8 $ io_tot_x $end
$var reg 1 % reset $end
$enddefinitions $end
#0
0!
b0011 "
0#
b00000000 $
0%
#1
1!
#2
0!
b0001 "
#3
1!
#4
0!
b0010 "
#5
1!
#6
0!
b0011 "
#7
1!
#8
0!
b1101 "
1#
#9
1!
b00001101 $
#10
0!
b0000 "
0#
#11
1!
#12
0!
b1010 "
#13
1!
#14
0!
b0011 "
1#
#15
1!
b00010000 $
#16
0!
b1100 "
0#
#17
1!
#18
0!
b1111 "
1#
#19
1!
b00011111 $
import chisel3._
// Example:
//
// This is example of multiplexer 2-to-1 with 'sel' as control signal
// Multiplexed inputs are 'in0' and 'in1'
//
class Mux2 extends Module {
val io = IO(new Bundle {
val sel = Input(UInt(1.W))
val in0 = Input(UInt(1.W))
val in1 = Input(UInt(1.W))
val out = Output(UInt(1.W))
})
io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}
// Problem:
//
// Build a 4-to-1 multiplexer out of three 2-to-1 multiplexers
// The first multiplexer is already done for you
//
class Mux4 extends Module {
val io = IO(new Bundle {
val in0 = Input(UInt(1.W))
val in1 = Input(UInt(1.W))
val in2 = Input(UInt(1.W))
val in3 = Input(UInt(1.W))
val sel = Input(UInt(2.W))
val out = Output(UInt(1.W))
})
val m0 = Module(new Mux2())
m0.io.sel := io.sel(0)
m0.io.in0 := io.in0
m0.io.in1 := io.in1
//Implement below ----------
val m1 = Module(new Mux2())
m1.io.sel := io.sel(0)
m1.io.in0 := io.in2
m1.io.in1 := io.in3
val m2 = Module(new Mux2())
m2.io.sel := io.sel(1)
m2.io.in0 := m0.io.out
m2.io.in1 := m1.io.out
// make the compile process happy, needs to be substituted by the output of the Mux
io.out := m2.io.out
//Implement above ----------
}
import chisel3._
// import Counter._
// Problem:
//
// Counter should be incremented by the 'amt'
// every clock if 'en' is asserted
//
object Counter {
def wrapAround(n: UInt, max: UInt) =
Mux(n > max, 0.U, n)
// Modify below ----------
def counter(max: UInt, en: Bool, amt: UInt): UInt = {
val x = RegInit(0.U(max.getWidth.W))
// x := wrapAround(x + 1.U, max)
when(en) {
x := wrapAround(x + amt, max)
}
x
}
// Modify above ----------
}
class Counter extends Module {
val io = IO(new Bundle {
val inc = Input(Bool())
val amt = Input(UInt(4.W))
val tot = Output(UInt(8.W))
})
io.tot := Counter.counter(255.U, io.inc, io.amt)
}
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",