When multiple clients share access to the same resource, it’s good to push much of the access control logic out into the clients, because it reduces communication and can be powered-down with the client.
The control logic is a finite-state machine (FSM), specifically, a finite state transducer, which can be expressed as a combination of three pure functions; let me call them reset, machine, and observe.
STATE s; INSTR instruction; always_ff @(posdedge clk or posedge rst) if (rst) s <= reset() else s <= machine(s, instruction); assign out = observe(s);
To ensure support by the lowest common denominator of tools, the functions and types would today be imported from a package, and the instruction type can usually be kept simple; for example, if all you ever need to do is write to a shared register, then an instruction could be as simple as a boolean and a value.
But in the long run, as ever more complex functionality is pushed out to clients, the SystemVerilog-2005 LRM already provides a couple useful constructs that aren’t yet implemented by many tools.
- Functions can be defined in a main module, then exported to the clients via a connecting modport.
- Instructions can be expressed with tagged unions.