Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
rsim
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Per Lindgren
rsim
Commits
1382c580
Commit
1382c580
authored
4 years ago
by
Per Lindgren
Browse files
Options
Downloads
Patches
Plain Diff
refactor
parent
d9f97a50
No related branches found
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/bitarr.rs
+124
-0
124 additions, 0 deletions
src/bitarr.rs
src/lib.rs
+3
-0
3 additions, 0 deletions
src/lib.rs
src/main.rs
+71
-53
71 additions, 53 deletions
src/main.rs
src/signal.rs
+7
-158
7 additions, 158 deletions
src/signal.rs
with
205 additions
and
211 deletions
src/bitarr.rs
0 → 100644
+
124
−
0
View file @
1382c580
use
std
::
cell
::
Cell
;
use
std
::
convert
::
TryFrom
;
use
std
::
convert
::{
From
,
Into
};
use
std
::
fmt
;
use
std
::
ops
::{
BitAnd
,
BitOr
,
Deref
,
DerefMut
,
Index
,
Range
};
use
std
::
string
::
String
;
#[derive(Debug,
PartialEq,
Clone)]
pub
struct
BitArr
<
const
N
:
usize
>
(
pub
[
bool
;
N
]);
// operations on BitArr
impl
<
const
N
:
usize
>
BitArr
<
N
>
{
pub
fn
sign_zero_ext
<
const
M
:
usize
>
(
&
self
,
b
:
bool
)
->
BitArr
<
M
>
{
let
msb
=
if
b
{
self
.0
[
N
-
1
]
}
else
{
false
};
let
mut
res
=
[
msb
;
M
];
res
[
0
..
N
]
.copy_from_slice
(
&
self
.0
);
BitArr
(
res
)
}
pub
fn
sign_ext
<
const
M
:
usize
>
(
&
self
)
->
BitArr
<
M
>
{
self
.sign_zero_ext
(
true
)
}
pub
fn
zero_ext
<
const
M
:
usize
>
(
&
self
)
->
BitArr
<
M
>
{
self
.sign_zero_ext
(
false
)
}
}
impl
<
const
N
:
usize
>
DerefMut
for
BitArr
<
N
>
{
fn
deref_mut
(
&
mut
self
)
->
&
mut
Self
::
Target
{
&
mut
self
.0
}
}
impl
<
const
N
:
usize
>
Deref
for
BitArr
<
N
>
{
type
Target
=
[
bool
;
N
];
fn
deref
(
&
self
)
->
&
Self
::
Target
{
&
self
.0
}
}
impl
<
const
N
:
usize
>
fmt
::
Binary
for
BitArr
<
N
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
let
mut
s
=
String
::
new
();
for
i
in
self
.0
.iter
()
.rev
()
{
s
.push
(
if
*
i
{
'1'
}
else
{
'0'
});
}
write!
(
f
,
"{}"
,
s
)
}
}
// Convert a u8 to BitArr<N>
// panic: N is too small to fit all true bits of u8
// if N is larger than 8, other bits set zero
impl
<
const
N
:
usize
>
From
<
u8
>
for
BitArr
<
N
>
{
fn
from
(
u
:
u8
)
->
Self
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
8
{
let
b
=
u
&
(
1
<<
i
);
if
b
!=
0
{
bs
[
i
]
=
true
}
}
BitArr
(
bs
)
}
}
// Convert a BitArr<N> to u8
// panic: if N > 8
// if N <= 8 upper bits are set 0
impl
<
const
N
:
usize
>
From
<
BitArr
<
N
>>
for
u8
{
fn
from
(
bs
:
BitArr
<
N
>
)
->
Self
{
assert!
(
N
<=
8
);
let
mut
b
=
0u8
;
for
i
in
0
..
N
{
if
bs
[
i
]
{
b
|
=
1
<<
i
}
}
b
}
}
// operations on bit array
impl
<
const
N
:
usize
>
BitAnd
for
&
BitArr
<
N
>
{
type
Output
=
BitArr
<
N
>
;
// rhs is the "right-hand side" of the expression `a & b`
fn
bitand
(
self
,
rhs
:
Self
)
->
Self
::
Output
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
self
.0
.len
()
{
bs
[
i
]
=
self
.0
[
i
]
&
rhs
.0
[
i
]
}
BitArr
(
bs
)
}
}
impl
<
const
N
:
usize
>
BitOr
for
&
BitArr
<
N
>
{
type
Output
=
BitArr
<
N
>
;
// rhs is the "right-hand side" of the expression `a & b`
fn
bitor
(
self
,
rhs
:
Self
)
->
Self
::
Output
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
self
.0
.len
()
{
bs
[
i
]
=
self
.0
[
i
]
|
rhs
.0
[
i
]
}
BitArr
(
bs
)
}
}
#[test]
mod
test
{
#[test]
fn
extensions
()
{
let
a
:
BitArr
<
2
>
=
0b10u8
.into
();
let
ze
:
BitArr
<
4
>
=
a
.zero_ext
();
let
se
:
BitArr
<
4
>
=
a
.sign_ext
();
assert!
(
ze
==
0b0010u8
.into
());
assert!
(
se
==
0b1110u8
.into
());
}
}
This diff is collapsed.
Click to expand it.
src/lib.rs
+
3
−
0
View file @
1382c580
mod
bitarr
;
mod
signal
;
mod
signal
;
pub
use
bitarr
::
*
;
pub
use
signal
::
*
;
pub
use
signal
::
*
;
// pub struct Component {
// pub struct Component {
...
...
This diff is collapsed.
Click to expand it.
src/main.rs
+
71
−
53
View file @
1382c580
...
@@ -70,8 +70,8 @@ use rsim::*;
...
@@ -70,8 +70,8 @@ use rsim::*;
// two input mux
// two input mux
struct
Mux
<
'a
,
const
N
:
usize
>
{
struct
Mux
<
'a
,
const
N
:
usize
>
{
ins
:
(
Signal
<
'a
,
N
>
,
Signal
<
'a
,
N
>
),
ins
:
(
Signal
<
'a
,
N
>
,
Signal
<
'a
,
N
>
),
sel
:
&
'a
Signal
<
'a
,
1
>
,
sel
:
Signal
<
'a
,
1
>
,
out
:
&
'a
Signal
<
'a
,
N
>
,
out
:
Signal
<
'a
,
N
>
,
}
}
impl
<
'a
,
const
N
:
usize
>
Eval
for
Mux
<
'a
,
N
>
{
impl
<
'a
,
const
N
:
usize
>
Eval
for
Mux
<
'a
,
N
>
{
...
@@ -83,6 +83,64 @@ impl<'a, const N: usize> Eval for Mux<'a, N> {
...
@@ -83,6 +83,64 @@ impl<'a, const N: usize> Eval for Mux<'a, N> {
}
}
}
}
// zero extend
struct
ZeroExt
<
'a
,
const
N
:
usize
,
const
M
:
usize
>
{
ins
:
Signal
<
'a
,
N
>
,
out
:
Signal
<
'a
,
M
>
,
}
impl
<
'a
,
const
N
:
usize
,
const
M
:
usize
>
Eval
for
ZeroExt
<
'a
,
N
,
M
>
{
fn
eval
(
&
self
)
->
()
{
let
mut
res
=
BitArr
([
false
;
M
]);
res
[
0
..
N
]
.clone_from_slice
(
&*
self
.ins
.r
());
self
.out
.w
(
res
);
}
}
#[test]
fn
test_zero_ext
()
{
let
mut
ins
:
BitArr
<
2
>
=
0b10u8
.into
();
println!
(
"ins {:b}"
,
ins
);
let
mut
out
:
BitArr
<
4
>
=
0
.into
();
let
ze
=
ZeroExt
{
ins
:
Signal
::
new
(
&
mut
ins
),
out
:
Signal
::
new
(
&
mut
out
),
};
ze
.eval
();
println!
(
"ze.out {:b}"
,
ze
.out
);
}
// sign extend
struct
SignExt
<
'a
,
const
N
:
usize
,
const
M
:
usize
>
{
ins
:
Signal
<
'a
,
N
>
,
out
:
Signal
<
'a
,
M
>
,
}
impl
<
'a
,
const
N
:
usize
,
const
M
:
usize
>
Eval
for
SignExt
<
'a
,
N
,
M
>
{
fn
eval
(
&
self
)
->
()
{
let
mut
res
=
BitArr
([
self
.ins
.r
()[
N
-
1
];
M
]);
res
[
0
..
N
]
.clone_from_slice
(
&*
self
.ins
.r
());
self
.out
.w
(
res
);
}
}
#[test]
fn
test_sign_ext
()
{
let
mut
ins
:
BitArr
<
2
>
=
0b10u8
.into
();
println!
(
"ins {:b}"
,
ins
);
let
mut
out
:
BitArr
<
4
>
=
0
.into
();
let
se
=
SignExt
{
ins
:
Signal
::
new
(
&
mut
ins
),
out
:
Signal
::
new
(
&
mut
out
),
};
se
.eval
();
println!
(
"ze.out {:b}"
,
se
.out
);
}
fn
main
()
{
fn
main
()
{
let
mut
in1
:
BitArr
<
2
>
=
0b10u8
.into
();
// [false, true];
let
mut
in1
:
BitArr
<
2
>
=
0b10u8
.into
();
// [false, true];
println!
(
"{:?}"
,
in1
);
println!
(
"{:?}"
,
in1
);
...
@@ -97,56 +155,34 @@ fn main() {
...
@@ -97,56 +155,34 @@ fn main() {
let
mut
sel
=
[
false
];
let
mut
sel
=
[
false
];
let
sel
=
Signal
::
new
(
&
mut
sel
);
let
sel
=
Signal
::
new
(
&
mut
sel
);
let
mut
out
=
[
false
,
false
];
let
mut
out
=
[
false
,
false
];
let
out
=
Signal
::
new
(
&
mut
out
);
let
out
=
&
Signal
::
new
(
&
mut
out
);
// let out0: Signal<1> = out.view(0, 1);
let
out0
:
Signal
<
1
>
=
out
.view
(
0
,
1
);
// let out1: Signal<1> = out.view(1, 2);
let
out1
:
Signal
<
1
>
=
out
.view
(
1
,
2
);
let
m
=
Mux
{
let
m
=
Mux
{
ins
:
(
Signal
::
new
(
&
mut
in1
),
Signal
::
new
(
&
mut
in2
)),
ins
:
(
Signal
::
new
(
&
mut
in1
),
Signal
::
new
(
&
mut
in2
)),
sel
:
&
sel
,
sel
:
sel
,
out
,
out
,
};
};
println!
(
"m.out {:b}"
,
m
.out
);
println!
(
"m.out {:b}"
,
m
.out
);
m
.eval
();
m
.eval
();
sel
.w
(
BitArr
([
false
]));
m
.
sel
.w
(
BitArr
([
false
]));
m
.eval
();
m
.eval
();
println!
(
"m.out {:b}"
,
m
.out
);
println!
(
"m.out {:b}"
,
m
.out
);
sel
[
0
]
.set
(
false
);
m
.
sel
[
0
]
.set
(
false
);
sel
.w
(
BitArr
([
false
]));
m
.
sel
.w
(
BitArr
([
false
]));
// sel.store_slice(&[false]);
m
.eval
();
m
.eval
();
println!
(
"m.out {:?}"
,
m
.out
);
println!
(
"m.out {:?}"
,
m
.out
);
println!
(
"out0 {:b}"
,
&
out0
);
//
println!("out0 {:b}", out0);
println!
(
"out1 {:b}"
,
&
out1
);
//
println!("out1 {:b}", out1);
let
p
=
&
m
.out
[
0
..
1
];
let
p
=
&
m
.out
[
0
..
1
];
let
m
:
Signal
<
2
>
=
m
.out
[
0
..
2
]
.into
();
let
m
:
Signal
<
2
>
=
m
.out
[
0
..
2
]
.into
();
}
}
// #[derive(Debug)]
// struct Mux<'a, const I: usize, const S: usize, const N: usize> {
// inputs: [&'a Signal<N>; I],
// sel: &'a Signal<S>,
// output: Signal<N>,
// }
// impl<'a, const I: usize, const S: usize, const N: usize> Eval for Mux<'a, I, S, N> {
// fn eval(&self) {
// let s: u8 = self.sel.clone().into();
// println!("s {}", s);
// let o = self.inputs[s as usize];
// self.output.store.set(o.store.get())
// }
// }
// impl<'a, const I: usize, const S: usize, const N: usize> fmt::Binary for Mux<'a, I, S, N> {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// fmt::Binary::fmt(&self.output, f)
// }
// }
// fn main() {
// fn main() {
// let s1: Signal<8> = 0b10101u8.into();
// let s1: Signal<8> = 0b10101u8.into();
...
@@ -178,24 +214,6 @@ fn main() {
...
@@ -178,24 +214,6 @@ fn main() {
// }
// }
// #[derive(Debug)]
// struct AndIn<'a> {
// a: &'a Signal,
// b: &'a Signal,
// }
// #[derive(Debug)]
// struct And<'a> {
// inputs: AndIn<'a>,
// output: Signal,
// }
// impl<'a> Eval for And<'a> {
// fn eval(&mut self) {
// self.output = (self.inputs.a & self.inputs.b).clone()
// }
// }
// fn main() {
// fn main() {
// let a: Signal = 1u8.into();
// let a: Signal = 1u8.into();
// let b: Signal = 2u8.into();
// let b: Signal = 2u8.into();
...
...
This diff is collapsed.
Click to expand it.
src/signal.rs
+
7
−
158
View file @
1382c580
...
@@ -5,92 +5,7 @@ use std::fmt;
...
@@ -5,92 +5,7 @@ use std::fmt;
use
std
::
ops
::{
BitAnd
,
BitOr
,
Deref
,
DerefMut
,
Index
,
Range
};
use
std
::
ops
::{
BitAnd
,
BitOr
,
Deref
,
DerefMut
,
Index
,
Range
};
use
std
::
string
::
String
;
use
std
::
string
::
String
;
#[derive(Debug,
PartialEq,
Clone)]
use
crate
::
bitarr
::
*
;
pub
struct
BitArr
<
const
N
:
usize
>
(
pub
[
bool
;
N
]);
impl
<
const
N
:
usize
>
DerefMut
for
BitArr
<
N
>
{
fn
deref_mut
(
&
mut
self
)
->
&
mut
Self
::
Target
{
&
mut
self
.0
}
}
impl
<
const
N
:
usize
>
Deref
for
BitArr
<
N
>
{
type
Target
=
[
bool
;
N
];
fn
deref
(
&
self
)
->
&
Self
::
Target
{
&
self
.0
}
}
impl
<
const
N
:
usize
>
fmt
::
Binary
for
BitArr
<
N
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
let
mut
s
=
String
::
new
();
for
i
in
self
.0
.iter
()
.rev
()
{
s
.push
(
if
*
i
{
'1'
}
else
{
'0'
});
}
write!
(
f
,
"{}"
,
s
)
}
}
// Convert a u8 to BitArr<N>
// panic: N is too small to fit all true bits of u8
// if N is larger than 8, other bits set zero
impl
<
const
N
:
usize
>
From
<
u8
>
for
BitArr
<
N
>
{
fn
from
(
u
:
u8
)
->
Self
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
8
{
let
b
=
u
&
(
1
<<
i
);
if
b
!=
0
{
bs
[
i
]
=
true
}
}
BitArr
(
bs
)
}
}
// Convert a BitArr<N> to u8
// panic: if N > 8
// if N <= 8 upper bits are set 0
impl
<
const
N
:
usize
>
From
<
BitArr
<
N
>>
for
u8
{
fn
from
(
bs
:
BitArr
<
N
>
)
->
Self
{
assert!
(
N
<=
8
);
let
mut
b
=
0u8
;
for
i
in
0
..
N
{
if
bs
[
i
]
{
b
|
=
1
<<
i
}
}
b
}
}
// operations on bit array
impl
<
const
N
:
usize
>
BitAnd
for
&
BitArr
<
N
>
{
type
Output
=
BitArr
<
N
>
;
// rhs is the "right-hand side" of the expression `a & b`
fn
bitand
(
self
,
rhs
:
Self
)
->
Self
::
Output
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
self
.0
.len
()
{
bs
[
i
]
=
self
.0
[
i
]
&
rhs
.0
[
i
]
}
BitArr
(
bs
)
}
}
impl
<
const
N
:
usize
>
BitOr
for
&
BitArr
<
N
>
{
type
Output
=
BitArr
<
N
>
;
// rhs is the "right-hand side" of the expression `a & b`
fn
bitor
(
self
,
rhs
:
Self
)
->
Self
::
Output
{
let
mut
bs
=
[
false
;
N
];
for
i
in
0
..
self
.0
.len
()
{
bs
[
i
]
=
self
.0
[
i
]
|
rhs
.0
[
i
]
}
BitArr
(
bs
)
}
}
// representation of stateful signal
// representation of stateful signal
#[derive(Debug,
PartialEq,
Clone)]
#[derive(Debug,
PartialEq,
Clone)]
...
@@ -124,11 +39,11 @@ impl<'a, const N: usize> Signal<'a, N> {
...
@@ -124,11 +39,11 @@ impl<'a, const N: usize> Signal<'a, N> {
}
}
// not sure if we should support this
// not sure if we should support this
//
pub fn store_slice(&self, a: &[bool]) {
pub
fn
store_slice
(
&
self
,
a
:
&
[
bool
])
{
//
for (i, v) in self.store.iter().enumerate() {
for
(
i
,
v
)
in
self
.store
.iter
()
.enumerate
()
{
//
v.set(a[i])
v
.set
(
a
[
i
])
//
}
}
//
}
}
// create a view of the signal
// create a view of the signal
// for now this view provides both reading and writing
// for now this view provides both reading and writing
...
@@ -166,7 +81,7 @@ impl<'a, const N: usize> Deref for Signal<'a, N> {
...
@@ -166,7 +81,7 @@ impl<'a, const N: usize> Deref for Signal<'a, N> {
// prints the value of a signal
// prints the value of a signal
// perhaps we should enforce reading the signal into a bit array first
// perhaps we should enforce reading the signal into a bit array first
impl
<
'a
,
const
N
:
usize
>
fmt
::
Binary
for
&
Signal
<
'a
,
N
>
{
impl
<
'a
,
const
N
:
usize
>
fmt
::
Binary
for
Signal
<
'a
,
N
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
let
mut
s
=
String
::
new
();
let
mut
s
=
String
::
new
();
for
i
in
self
.store
.iter
()
.rev
()
{
for
i
in
self
.store
.iter
()
.rev
()
{
...
@@ -187,72 +102,6 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> {
...
@@ -187,72 +102,6 @@ impl<'a, const N: usize> fmt::Binary for &Signal<'a, N> {
// }
// }
// }
// }
// // operations on signal
// impl<'a, const N: usize> BitAnd for Signal<'a, N> {
// type Output = Signal<'a, N>;
// // rhs is the "right-hand side" of the expression `a & b`
// fn bitand(self, rhs: Self) -> Self::Output {
// // let mut bs = [false; N];
// // let a = self.store.get();
// // let b = rhs.store.get();
// // for i in 0..self.store.get().len() {
// // bs[i] = a[i] & b[i]
// // }
// // Signal {
// // store: Cell::new(bs),
// // }
// }
// }
// impl<const N: usize> BitOr for &Signal<N> {
// type Output = Signal<N>;
// // rhs is the "right-hand side" of the expression `a & b`
// fn bitor(self, rhs: Self) -> Self::Output {
// let mut bs: Signal<N> = Signal::new();
// for i in 0..self.store.len() {
// bs.store[i] = self.store[i] | rhs.store[i]
// }
// bs
// }
// }
// impl<const N: usize> From<Signal<N>> for u8 {
// fn from(s: Signal<N>) -> u8 {
// // check that it fits u8
// assert!(N < 8);
// let mut u = 0;
// let a = s.store.get();
// for i in 0..N {
// u |= if a[i] { 1 << i } else { 0 }
// }
// u
// }
// }
// impl From<u32> for Signal {
// fn from(u: u32) -> Self {
// let mut bs = Signal::new();
// for i in 0..32 {
// bs.push(u & (1 << i) != 0)
// }
// bs
// }
// }
// impl From<Signal> for u32 {
// fn from(b: Signal) -> u32 {
// let mut u = 0;
// for (n, b) in b.0.iter().enumerate() {
// u |= if *b { 1 << n } else { 0 }
// }
// u
// }
// }
// #[test]
// #[test]
// fn test_partial_eq() {
// fn test_partial_eq() {
// let b: Signal = 12345u32.into();
// let b: Signal = 12345u32.into();
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment