Skip to content
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

Help Needed with Bluesim Integration and Accessing After-Elaboration Representation #743

Open
uv-xiao opened this issue Oct 22, 2024 · 2 comments

Comments

@uv-xiao
Copy link

uv-xiao commented Oct 22, 2024

I am exploring a cycle-level (quasi-cycle-accurate) simulator and believe that the rule abstraction of BS fits the task. I want to conduct some trials using BS designs represented as "an elaborated module plus a schedule that has been computed" as mentioned in #468.

I understand that the code under src/bluesim provides APIs and data structures for Bluesim, but I am struggling to find how Bluesim integrates with the BS representation. I suspect that this might be located under src/comp, but I am not sure since I know nothing about Haskell and cannot understand the pretty codes.

Additionally, I believe that the representation corresponds to .ba files; however, these files are not human-readable.

Could you please provide suggestions or documentation references that could help me access and understand this representation?

Thank you for your assistance!

@quark17
Copy link
Collaborator

quark17 commented Oct 24, 2024

For each module in a BH/BSV design, the compiler (BSC) produces an internal representation for the module and its schedule. From this representation, BSC can generate a Verilog module that implements the BH/BSV module. The conversion from the internal representation to Verilog is implemented in BSC's source code, in src/comp/. If the BH/BSV design instantiates modules from BSC's library, the generated Verilog may instantiate submodules that are defined in src/Verilog*/.

In the Verilog implementation, each Verilog module is responsible for its own scheduling. The scheduling of the design happens through the cooperation of these local schedulers.

Bluesim is slightly different. For each module modname, BSC generates files modname.{h,cxx} that define a C++ class for the module. This class does not include any scheduling. Instead, BSC collects the schedulers from all the modules and merges them into one global scheduler. For a design with topmodname as the root, BSC generates the files model_topmodname.{h,cxx} containing a C++ class that instantiates the model as a whole and defines the global scheduler. This model does not run on its own, though; it just provides the state and hooks for executing the schedulers which execute the rules. To drive the model, you use the Bluesim kernel, defined in the src/bluesim/ directory. The generated C++ files import some of the files from that directory, so that they can provide the expected hooks; the directory also defines data types used by the generated code (as you mentioned). If the BH/BSV design instantiates modules from BSC's library, then the generated C++ classes may instantiate classes defined in src/bluesim/ (similar to how Verilog library modules are defined in src/Verilog*/). So the src/bluesim/ directory contains both the driver (the kernel) and the library modules. As with the conversion to Verilog, the conversion from BSC's internal representation to C++ files is defined in BSC's source code in src/comp/.

BSC executes as a sequence of stages: first, parsing stages read in the file; then stages do type checking; then compilation proceeds separately for each module, and a final .bo file is written, representing the file and any references to generated modules. The compilation for each module is in stages: elaboration of the code and some optimization stages; then scheduling stages; then code generaton stages. The Verilog and Bluesim generation each have their own sequences of stages -- if we drew a picture of the module compilation stages, it would be a Y shape, with separate branches for Verilog and Bluesim. The .ba file records the internal representation of the module (and its schedule) at this branch point. So you are right to consider the .ba as a possible place for you to interface.

The BSC source code in src/comp/ is structured in this sequence format, so understanding that can make the code easier to read. The top-level file is bsc.hs. I have already written more information about this, which you can read here (on the mailing list for discussing the BSC source code): https://groups.io/g/bsc-dev/message/14

There is also some information on .ba and .bo files on this GitHub discussion: #575 (comment)

In the src/comp/ directory, there is code for a tool called dumpba, which can be used to print the binary .ba file in a human-readable form. However, it may not print all the information from the file -- if you find it is missing anything, we can try to correct that. This tool is not built by default. But if you go to the directory and run make install-utils, it should build and install it. Also, the .ba file only contains the local scheduler; you probably want to use the combined global scheduler, so you may need to get information from BSC at a later stage.

You can direct BSC to dump information between each stage, using the -d flags. This should be described in the writing that I linked to above. For example, the flag -dATS should show you the internal representation for the module at the backend branch point (but without the schedule). You can use -dschedule to print information after scheduling, but there is also the -show-schedule flag for more user-friendly output (that I think is directed to a file).

The stages for the Bluesim branch are defined in files beginning with Sim (src/comp/Sim*.hs). You can see the sequence of these stages in bsc.hs if you look for the function genModuleC, which defines the steps for generating the C++ code for a module. It goes through the steps of simexpand, simDepend, simPackageOpt, simMakeCBlocks, simCOpt, simBlocksToC, and then writing the files. That first stage, SimExpand, includes the merging of the separate schedules into one global combined schedule. The SimPackageOpt stage might be a good point to interface at; the next stage, SimMakeCBlocks, converts the high-level representation into an intermediate representation (CBlocks) that's closer to the target C++ code (and SimBlocksToC converts that finally to C++ code).

@uv-xiao
Copy link
Author

uv-xiao commented Oct 25, 2024

Thank you for your patient explanation! Your guidance has been incredibly helpful.

I will look at the BSC source codes under src/comp as you suggested and try the dumpba tool along with the other flags to see immediate results during compilation.

I’ll also explore the links you provided for more detailed instructions. If I encounter any further issues, I'll be sure to reach out here for assistance again.

Thanks once more for your support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants