Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
LEAP provides standard I/O services similar to the usual POSIX methods, though the interface is broken down into request/response pairings needed by synchronous hardware. To connect to STDIO, instantiate a STDIO node using mkStdIO(). A STDIO node automatically connects itself to a ring of nodes on which messages are passed to the host. Unlike software, a STDIO node is allocated for a fixed data size. All objects passed to printf must correspond to the size of the node instance. This is rarely a limitation, since the formatting string retains the usual flexibility.
STDIO is implemented in stdio-local.bsv. All STDIO interface methods are described at the top of the file.
Key differences from the software version:
- Strings are not passed from FPGA to host directly. Instead, a global string table is generated at compile time. Strings are passed as global string handles.
- printf accepts a variable size argument list, but the arguments are passed as a list. LEAP provides a list() function that takes an arbitrary number of comma separated objects (of the same type) and returns a list of the objects.
A simple hello world example is provided in source:“trunk/modules/leap/examples/hello-world/hello-world.bsv”. In the example, a STDIO node is allocated:
STDIO#(Bit#(32)) stdio <- mkStdIO();
a string is declared:
let msg <- getGlobalStringUID("Hello, World! This is hardware speaking.\n");
and the message is generated in a rule:
A more complicated example, using more of the interface, is in stdio-example.bsv.
For convenience, an instance of STDIO designed for debugging is available as mkStdIO_Debug(). When the static AWB parameter STDIO_ENABLE_DEBUG is 0, the mkStdIO_Debug() node does nothing and generates no logic. When STDIO_ENABLE_DEBUG is non-zero, the node behaves like a typical STDIO node. HAsim modules use mkStdIO_Debug() to add in-line debugging code without having to protect each use with an explicit predicate.
STDIO_ENABLE_DEBUG is enabled (1) by default. This is because LEAP provides a wrapper for STDIO that dynamically enables or disables the printf and fprintf methods. The mkStdIO_CondPrintf module takes two parameters: a STDIO node and the bit index of the conditional printing mask. The state of the conditional printing mask is set at run time by the —stdio-cond-printf-mask command line switch. When the specified mask bit is one, printing is enabled. When zero, the printf and fprintf methods do nothing. The mask may also be changed in the middle of a run from software by calling STDIO_SERVER_CLASS::GetInstance()→SetCondMask().
Each instance of a mkStdIO_CondPrintf contains a local buffer. Because of the buffer, two separate rules that each write to a unique mkStdIO_CondPrintf instance may be scheduled in parallel even when the mkStdIO_CondPrintf instances share a single STDIO instance. Of course the rules may conflict dynamically when printing is enabled. The conditional printing wrapper uses far fewer resources than a full STDIO node.