So I would like to open the discussion here as to how we get these modules constructed in a way so they can be happy bed fellows. There are a number of issues such as memory usage, shared resources such as inter-core streaming channels and core ports, as well as managing the way these modules interact. A safe way would be to state all shared resources being passed in. This isn't an issue for ports and to a degree streaming channels but could pose issues with memory for example. But lets put the memory issue aside for the moment and imagine how it could work. I would imagine that the main thread provides a supervisor thread, this helps us structure the problem and also provides a nice model for any subsequent shared resources. It also enables some basic module life-cycle management of the modules and the possibility of dealing with errant modules.Project Overview
Inspired by the successful OpenCores idea, this project aims to provide an opensource commons of reuseable modules or components to run on the event driven model. I did initial think about calling it OpenXcores but figured that that was just a little too cheeky, also I think OpenThreads expresses how many of these modules will interact via using threads rather than more declarative nature of HDLs in the FPGAS world.
How we make these contributions reusable and so they can slot together will be the ongoing conversation until we draft the basic APIs which allow this to happen for version 0.1. In addition I am creating a git repository to hold the code and documentation so bear with me on that. For now this is just a place holder for the idea
Best way to start in my opinion is with some code examples so here is my first pass of pseudo code for module foo which would be called by the supervisor (main perhaps in a Par):
Code: Select all
#define RESET 1;
#define START 2;
#define STOP 3;
#define READY 0;
void foo_mod(chanend control, chanend tick, struct config)
int Status = READY;
foo_config(config);
while(1) {
tick <: status;//let supervisor know your ok, keep ticking
select {
case control :> mode :
switch(mode){ // decode supervisor instructions to change mode
case RESET : // Reset state of module
reset_foo();
status = RESET;
break;
case START : // start modules main function
start_foo();
status = START;
break;
case STOP : // Stop main function + threads, clean up used resources & return
release_foo();
status = STOP;
return state;
}
break;
case process_foo_port_inputs();// deal with other timers or port inputs could be multiple selects of select functions
break;
case process_foo_channel_inputs();// Deal with any other input channel work, like streaming channels from other threads.
break;
...
default:
process_foo_outputs();// deal with actual production and outputs to other ports or channels
}
}
The module then uses a non blocking select arrangement to either do its normal operation, or it responds to commands from the supervisor over the control channel. On receiving supervisory mode commands it switch into the relevant modes. In this case I am assuming simple modes like start and stop. IT also supports resetting of state via a rest command which could be handy in some situations.
Anyhow its just a starter to get the juices flowing, what do you think, is this a good way of doing it, can it be improved what about the other issues around dynamic storage etc..?
Lets work it out?