-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pull request to a new branch #1
base: mastesr
Are you sure you want to change the base?
Conversation
@myrfy001 all fixed |
rb_link/src/server.rs
Outdated
} | ||
|
||
/// Read the earliest cycle messages sent by the probes labeled as "fifo" and "fired", and organize them into a PipeLineState. | ||
pub fn get_pipeline_state(&mut self) -> PipeLineState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of the Server module? From the name, we think that it should be a module that handles connections, e.g., accept connection, retry connection. But what does the server do after receive a packet should not be included in a module called Server. And maybe there will be many different processing logics, should we put all thoes new logics into the Server module? This is a bad smell in code. Use some design pattern to refactor this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
rb_link/src/server.rs
Outdated
// let probe_infos = self.probe_infos.clone(); | ||
let b2r_cache = self.b2r_cache.clone(); | ||
let r2b_cache = self.r2b_cache.clone(); | ||
thread::spawn(move || { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When will this thread terminated? what will happen if this thread terminated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
README.md
Outdated
$ cd <your bsv projest path> | ||
// add the .a file after the link command | ||
$ <your link command> ../../bluesim-rlib/target/debug/libblue.a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should have a runable command line, maybe the user doesn't known how to link a .a
file to their bluespec simulator. After all, linking a library to simulator is not a normal operation. bluespec also doesn't have much doc about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
bluesim-rlib/src/lib.rs
Outdated
panic!("cycles over flow!"); | ||
} | ||
let mut stream = STREAM.get_or_init(|| { | ||
UnixStream::connect(String::from("/tmp/b2rr2b")).expect("Failed to connect to socket") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, .expect and .unwrap is almost the same. Both of them will panic the process. Rust use Result
to handle errors, so, what's your idea not to use Result to handle errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beacuse i just don't think the errors are recoverable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all examples should have a build script as a playground. It can be a make file or a rust build.rs. No matter which way, we should let the user run the demos using a single command line like 'make'. The example should show the users how to build bsv, how to build probe library, how to link them together, hou to run the upper app to use those probes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
bluesim-rlib/src/lib.rs
Outdated
panic!("cycles over flow!"); | ||
} | ||
let mut stream = STREAM.get_or_init(|| { | ||
UnixStream::connect(String::from("/tmp/b2rr2b")).expect("Failed to connect to socket") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to speed up test, it's common to run multi test process at the same time. A hardcoded local unix-stream will not work when there is multi process running different tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
examples/TenStage/TenStage.bsv
Outdated
|
||
(* synthesize *) | ||
module mkAdderPipeline(Empty); | ||
function gen_fire_probes(Integer x) = mkRProbe(fromInteger(x + 10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does those magic numbers mean?
don't use magic numbers, even in testcases or examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
examples/TenStage/TenStage.bsv
Outdated
|
||
(* synthesize *) | ||
module mkAdderPipeline(Empty); | ||
function gen_fire_probes(Integer x) = mkRProbe(fromInteger(x + 10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by the way, is it possible to use a string as the probe id to make it more meaningful?
rb_link/src/server/mod.rs
Outdated
b2r_cache: Arc::new(Mutex::new(HashMap::new())), | ||
r2b_cache: Arc::new(Mutex::new(HashMap::new())), | ||
} | ||
} | ||
|
||
/// Start a thread to run the server. | ||
/// Create a UnixListener at "/tmp/b2rr2b". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is outdated
bluesim-rlib/src/lib.rs
Outdated
@@ -24,7 +25,11 @@ pub unsafe extern "C" fn get(res_ptr: *mut u8, id: u32, _cycles: u32, size: u32) | |||
panic!("cycles over flow!"); | |||
} | |||
let mut stream = STREAM.get_or_init(|| { | |||
UnixStream::connect(String::from("/tmp/b2rr2b")).expect("Failed to connect to socket") | |||
let socket = match env::var("B2R_SOCKET") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicated code should go into a function
@@ -40,6 +42,7 @@ module mkAdderPipeline(Empty); | |||
probe.put_data(data + 1); | |||
put_times <= put_times + 1; | |||
if(put_times == 9) begin | |||
probe.shut_down_server(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No parentheses here
examples/AdderPipeline/Makefile
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two makefile has a lot in common, can you extract some common part to a seperate file and include them? Suppose you will have many makefile in the future, once you need to change something, you won't need to change every file.
rb_link/src/server/mod.rs
Outdated
|
||
impl B2RServer { | ||
/// make a new server with socket: /tmp/b2rr2b | ||
pub fn new() -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this API should be removed
endmethod | ||
endmodule | ||
|
||
module mkFIFOFProbe#(Bit#(WORD_WIDTH) id, FIFOF#(t) fifo)(Empty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since some id is kept for internal use(e.g., control shutdown), you should check if the user supplied id is conflict with those reserved ids.
/// Cache bidirectional data and send data upon receiving requests. | ||
pub struct B2RServer { | ||
socket_path: String, | ||
b2r_cache: Arc<Mutex<HashMap<u32, VecDeque<B2RMessage>>>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the simulation run a long time, will this buffer overflow or lead to OOM?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getter poped from the cache, i think the message shouldn't wait too long to be processed in debug program.
So I think it won't lead to OOM.
After looking into your implement detail, I found that it seems this framework is a offline-analyse framework. But it should also work in a online-analyse style, that is, you can inject data to simulator on the fly, and analyse simulator state on the fly. For example, some probe can be used as a trigger (you can think it as a conditional breakpoint in software debugger), like when some probe's value is True, or some probes' value do AND logic operation and the result is True, then block the simulator and print some mesage. So, to implement this behivour, the framework shoud be event driven, and you can hook some analyse logic by subscribe to the events. By the way, the offline analyse is also another way to do debug and it can also be kept. |
@myrfy001 fixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We must treat naming seriously. For the name config, it means something that can be tuned. But thoes two things here seems not. Maybe this file should be called consts.rs or something else?
socket_path: String, | ||
running: Arc<AtomicBool>, | ||
cycle: Arc<AtomicU32>, | ||
b2r_cache: Arc<Mutex<HashMap<u32, VecDeque<B2RMessage>>>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use a channel to do cross thread communication? What you did here is almost build a channel by hand and make code verbose.
} | ||
|
||
/// Get all message send by the probe with id. | ||
pub fn get_id_all(&mut self, id: u32) -> Vec<B2RMessage> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, naming!
get_id_all means get all IDs, but this method returns messages instead of IDs.
use std::sync::{Arc, Mutex}; | ||
|
||
/// A getter to get message from the bluesim by id | ||
pub struct IDGetter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming problem again.
|
||
/// Get all the messages sent by the earliest cycle. | ||
/// If there are no messages available, it will return an empty Vec. | ||
pub fn get_cycle_message(&mut self) -> Vec<B2RMessage> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming problem. Why the important "earliest" not show in the method name but show in the comment?
let mut b2r_cache: std::sync::MutexGuard<HashMap<u32, VecDeque<B2RMessage>>> = | ||
self.b2r_cache.lock().expect("Fail to lock b2r_cache"); | ||
|
||
for fifo_id in &self.fifos { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this can be rewrite in rust style using min
instead of for loop?
// the fifo message len must be 2 | ||
assert_eq!(first_message.message.len(), 2); | ||
let b2r_message = messages.pop_front().expect("front error"); | ||
if b2r_message.message[0] == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No magic number here. You should define a struct to represent this kind of message, which has two fields, one for empty and one for full.
If this is a really big project, or message type boost in the future, it will be hard to remember the meaning of each byte index.
/// fire_fules: the fired rules | ||
pub struct PipeLineState { | ||
pub cycle: u32, | ||
pub full_fifos: Vec<u32>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe you should define a new type called ProbeID as u32?
And also, if it stores IDs, then you should show it. Otherwise, when someone read code somewhere else in the code base, and see a struct called full_fifos
, since there is a s
, he can known this field is a Vec or a slice like things. But what is in this slice? He may think they are some struct represent a FIFO object, and won't think they are IDs.
|
||
impl B2RPublisher { | ||
/// Creates a new B2RPublisher instance with the specified socket path. | ||
pub fn new_with(path: &str) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this module works with other modules? It will take the unix stream. What if I want to use b2r_cache and r2b_cache while also using Subscriber framework?
As a framework, different part should be able to be used together, not splited.
No description provided.