Skip to content
code0.HDL

BSV Practice

Build fluency with short Bluespec problems. Edit the code, run it, then submit your solution.

Your drafts and solved problems stay in this browser.

Jump to a chapter

A module and its interface

1 problem

Run the smallest BSV program, a package with one module and one rule, and predict what it prints; then read a module with one register and one value method and the testbench that reads it, run it, and change one thing.

  1. 14VerificationRead a counter valueFind why the value method reports the wrong state and correct it.

Bool, Bit and pure functions

2 problems

Tell a Bool from a Bit#(n), build and take apart bit vectors with concatenation, selection and reduction, and write a pure function that becomes combinational logic where it is called.

  1. 31VerificationComplete a parity frameCompose typed bit fields and derive the frame's parity with a reduction expression.
  2. 32ImplementationSelect a bitwise operationReturn the AND, OR, XOR, or NOR of two 4-bit values according to a 2-bit selector.

Types, widths and explicit conversion

3 problems

See why a sized value never changes width on its own, how an unsized literal takes the width of its target, and which function to call for zero extension, sign extension, truncation and reinterpretation.

  1. 10VerificationNarrow a byte explicitlyFind the rejected implicit narrowing and make the conversion explicit.
  2. 11ImplementationZero-extend a nibbleBuild an 8-bit value by placing zeros above a 4-bit input.
  3. 12VerificationSign-extend a four-bit integerFind why negative inputs lose their sign and correct the conversion.

Selection, case, and the don't-care value

1 problem

Build combinational selection with the ?: operator, case and functions, give every path a value, and use the don't-care value ? only where no one can observe it.

  1. 06ImplementationGuard an unused payload with validPreserve four legal payloads and mark every other command invalid.

Registers and one rule

2 problems

Declare a register with mkReg, write it from one rule with <=, and see that a read inside the rule gives the start-of-cycle value while the written value appears in the next cycle.

  1. 01ImplementationCount with one ruleWrite the register update that makes a rule count once per cycle.
  2. 29VerificationPreserve a register's upper byteFind the whole-register write that loses state and replace it with a selected write.

Guards: hold and stop

1 problem

Use a rule's explicit condition to hold a register, to stop a counter exactly at its limit, and to find the silent gap when the state one rule leaves never satisfies the condition of the next.

  1. 02VerificationStop a rule at its limitFind why a counting rule runs past the limit it was given and correct it.

Rules that share state: atomicity, shadowing and conflicts

3 problems

Put two rules in the same cycle: both fire when they touch different state, a second write to one register shadows the first with a warning, and a genuine conflict needs a read/write cycle; every firing is one atomic transition.

  1. 03ImplementationSplit work across two rulesGive two rules conditions that never overlap so each one fires in its own turn.
  2. 19ImplementationSwap two registers atomicallyUse values from the same rule entry state to swap two registers.
  3. 20VerificationRemove an arbitrary rule conflictFind the two rules that fight over one state and give them exclusive conditions.

Methods: value, Action, ActionValue

4 problems

Tell the three method kinds apart by their result type, call them from rules, and see how a method's own readiness condition decides whether the calling rule fires at all.

  1. 15ImplementationBump a counterImplement the state update performed by one Action-method call.
  2. 16ImplementationCounter with clear and enableImplement one Action method whose clear and enable arguments decide the counter's next state.
  3. 17VerificationIssue the current ticketFind why issued tickets skip the current number and correct the return value.
  4. 33VerificationReturn the current ticketFind why an ActionValue expression returns the next ticket instead of the state it advances.

Readiness, module arguments, and synthesis boundaries

1 problem

Define a module with parameters, arguments and provisos, put a method's readiness condition in its header so that every calling rule stops when it is false, trace a stack through pushes and pops, and meet the conditions an interface needs at a synthesis boundary.

  1. 18VerificationBound a method with readinessAdd the missing method readiness condition so callers stop at the bound.

User-defined types

3 problems

Define the types a design talks about with typedef: a synonym that only renames, an enum of named labels, a struct of named fields, and a tagged union that holds one alternative with its tag; compute their packed widths and read a union with pattern matching.

  1. 22ImplementationAdvance a pipeline stageMove an enum through its stages by label, not by its encoding.
  2. 23VerificationRead a request fieldFind a packed-bit shortcut that reads the wrong part of a request struct.
  3. 24ImplementationRead a Maybe valueUse pattern matching to return a Maybe payload or zero.

State machines with rules

1 problem

Name the states of a design with an enum, keep the current state in a register, write one rule per state whose guards never overlap, and predict a two-state machine cycle by cycle.

  1. 21ImplementationOrder two rule transitionsReplace a scheduling conflict with two explicit atomic state transitions.

Lexical elements

2 problems

How bsc splits source text into tokens, and the exact spelling rules for identifiers, keywords, comments, integer, Real and string literals, and compiler directives.

  1. 04ImplementationDiagnose four integer literalsDiagnose four compiling literal mistakes and restore their required values.
  2. 05VerificationSize the mask literalReplace the all-ones fill literal with an eight-bit mask that keeps only the low four bits.

Packages

3 problems

One file is one package; export decides which names leave it, import brings published names in, and a package boundary is a visibility boundary, not a hardware boundary.

  1. 07ImplementationExpose private state through a methodReport module-private state through the only observation method the package publishes.
  2. 08VerificationGuard a method with a private constantFind why the gate ignores its package-private capacity and restore the constant to the guard.
  3. 09ImplementationDefine a private package constantGive the meter one package-private budget that its guard and both reports agree on.

Variables, loops, and the context of a literal

2 problems

A variable names a value rather than storing it, the declared type decides what an unsized literal means, and a loop with a constant bound unfolds into a fixed amount of hardware during elaboration.

  1. 28ImplementationDefine percent literalsScale whole percentages by ten and define a predicate for their valid literal range.
  2. 30ImplementationCount set bits with control flowUse a statically bounded loop and a conditional to count the set bits in a byte.

Typeclasses and provisos

4 problems

Typeclasses name groups of overloaded operations, instances implement them per type, and provisos state the instances and width relations a polymorphic definition needs, all resolved at compile time with no selection circuit.

  1. 13ImplementationPack a polymorphic valueReturn the packed bits of any value with a Bits proviso.
  2. 25ImplementationImplement a typeclass instanceDefine RequestKind priority behavior used through a polymorphic Priority proviso.
  3. 26ImplementationBuild a width-checked suffixComplete a concatenation whose result width is constrained by an Add proviso.
  4. 27VerificationRepair a hand-written Bits instanceFind the decoding that contradicts the protocol encoding chosen by pack.

Pattern matching

3 problems

Take structured values apart with patterns: constants, variables, wildcards, struct and tagged-union patterns, pattern-matching case, pattern tests in conditions, and match declarations.

  1. 35ImplementationExtract a nested request payloadMatch a tagged packet and bind one field from its struct payload.
  2. 36VerificationReject the boundary opcodeFind an inclusive pattern filter that accepts one payload beyond its range.
  3. 37ImplementationDestructure two tuple fieldsUse match assignment to bind and recombine two typed tuple fields.

Rules as values

1 problem

Build a rule as a Rules value, install it with addRules, and tell the one elaboration-time call apart from the many cycles the installed rule fires on.

  1. 34ImplementationBuild a bounded rule expressionReturn a reusable Rules value that advances a register to a supplied bound.

Finite state machines with StmtFSM

3 problems

Writing a multi-cycle process as a Stmt, running it with mkFSM, and reading its behaviour, one committed step per action in seq, loops with repeat, while and for, waiting with await, overlapping branches with par, and finishing only after a run that was started.

  1. 38ImplementationSequence two FSM stepsBuild a sequential statement whose second action reads the first action's result.
  2. 39VerificationRepeat an FSM action four timesFind why a repeated FSM body stops one iteration before its required count.
  3. 40VerificationFinish only after readinessFind why an FSM reports completion before its awaited work has finished.

FIFOs, split, and the library primitives

3 problems

The library pieces most designs are built from, read as contracts, split and tuples whose boundary comes from the result type, FIFO methods whose implicit conditions make callers wait, FIFOF flags that report readiness as values, and system tasks that exist only in simulation.

  1. 41ImplementationSplit a frame by result widthImplement a method that divides a 12-bit frame into its 4-bit kind and 8-bit payload.
  2. 42ImplementationRemove FIFO entries in arrival orderComplete a queue method that returns and removes the oldest buffered byte.
  3. 43VerificationReport when a FIFOF can accept dataFind why an elastic queue reports that it cannot accept data while empty.

Guiding the compiler with attributes

3 problems

Attributes as requests, proved claims and trusted claims, synthesize and noinline boundaries, port naming with always_ready and always_enabled, the scheduling attributes descending_urgency, execution_order, preempts and the rule assertions, and split, clock, reset and doc attributes.

  1. 44VerificationRepair a false always-ready contractRemove a readiness claim that contradicts a bounded buffer's enqueue method.
  2. 45ImplementationMake an action method always enabledDeclare an unconditional tick method as part of an always-enabled RTL protocol.
  3. 46VerificationRepair a false implicit-condition contractRemove a scheduling assertion contradicted by a queue-dependent rule.

Embedding RTL in a BSV design

3 problems

The import "BVI" contract between typed BSV and external RTL, value and Action method mappings with enable and ready, default_clock and default_reset, schedule relations for every method pair, static parameters, and how to locate a failure in BSC compilation, Verilog elaboration or simulation.

  1. 47ImplementationMap writes into imported RTLComplete the editable value mapping used by an immutable imported-register wrapper.
  2. 48VerificationMap data from imported RTLFind why an editable result mapping hides values from immutable imported RTL.
  3. 49ImplementationSet an imported RTL parameterPass the required initial value through a frozen BVI parameter mapping.

Embedding C in a BSV design

3 problems

Call a C function from BSV with import BDPI: the declaration, the carrier types each side sees, packed and wide values, polymorphic imports, return shapes, and how boundary failures look.

  1. 50ImplementationNarrow a scalar BDPI carrierConvert a 32-bit BSV value to the 8-bit carrier required by an imported C function.
  2. 51VerificationPreserve signed packed bitsFind why a BDPI adapter loses the two's-complement representation of signed BSV values.
  3. 52ImplementationPass a polymorphic vector widthDerive the explicit width argument required by a concrete C boundary.