Functions
READ_SHARED_REGISTER

Overview

The READ_SHARED_REGISTER procedure call allows one or more application modules to read registered data from a shared_register inside the framework module. In order to read from a shared register, an application module identifies the desired register by its REGISTER_ID, which is the first parameter of the READ_SHARED_REGISTER procedure call. Assuming some data has written data to the shared_register, that data is available to be read by any application module that references the REGISTER_ID on state_reg_rec(M).shared_reg after one clock cycle. Thus, the READ_SHARED_REGISTER and WRITE_SHARED_REGISTER API calls implement a multipoint control path mechanism, which allow multiple application modules to read and write to same the shared register simultaneously.

A single application module has the capability of utilizing any number of shared registers. The typical use case for a single application module using multiple shared registers would be to perform data multiplexing. Convenient data multiplexing can be done by making multiple WRITE_SHARED_REGISTER procedure calls on different resource indexes, (M), which correspond to a logical ordering of REGISTER_IDs. The WRITE_SHARED_REGISTER procedure calls are used buffer each piece of data on a different shared register. Subsequently, that data can be selected and read on state_reg_rec(M).shared_reg by using the READ_SHARED_REGISTER procedure call and a counter to cycle through the available REGISTER_IDs.

Register ID

The REGISTER_ID is typically integer valued. This means that the shared register REGISTER_ID can be identified by either a small integer literal, 0, 1, 2, ect., or a module resource value. Using a REGISTER_ID to identify a shared register allows data to be read from any shared register within the framework module regardless of the application module or resource index the READ_SHARED_REGISTER procedure call is made from.

Consider the following procedure calls:

RESOURCE_SELECT( sys_clk, next_state_rec, state_reg_rec );
WRITE_SHARED_REGISTER( this_module + 0, "001", next_state_rec, state_reg_rec );
RESOURCE_SELECT( sys_clk, next_state_rec(1), state_reg_rec(1) );
WRITE_SHARED_REGISTER( this_module + 1, "010", next_state_rec(1), state_reg_rec(1) );
RESOURCE_SELECT( sys_clk, next_state_rec(2), state_reg_rec(2) );
WRITE_SHARED_REGISTER( this_module + 2, "100", next_state_rec(2), state_reg_rec(2) );
RESOURCE_SELECT( sys_clk, next_state_rec(3), state_reg_rec(3) );
READ_SHARED_REGISTER( this_module + state_reg_rec(3).counter(1).value, next_state_rec(3),
state_reg_rec(3) );
CONFIGURE_COUNTER( 0, us(20), no_trans, next_state_rec(3), state_reg_rec(3) );
CONFIGURE_COUNTER( 1, 3, no_trans, next_state_rec(3), state_reg_rec(3), chain );

The WRITE_SHARE_REGISTER procedure call is used to buffer the values of "001", "010", and "100" on shared registers on resource 0, 1, and 2 respectively with corresponding module resource values for REGISTER_ID's. These REGISTER_ID's are set up to be easily iterated through using a chained counter on resource 3 that increments every 20us from values 0, 1, and 2 then repeats. The READ_SHARED_REGISTER procedure call uses this counter value as an offset to the module index to cycle through the values of "001", "010", and "100" on state_reg_rec(3).shared_reg in 20us intervals by accessing the shared registers on resource 0, 1, and 2.

Remarks
The REGISTER_IDs in the above code could have been hardcoded as an integer literals 0, 1, and 2 instead of using the module offset values of this_module + 0, this_module + 1, this_module + 2. However, doing so runs the risk of another application module also using the values of 0, 1, 2,.. ect for REGISTER_IDs and inadvertently sharing the registers that were not meant to be shared, creating hard to find bug. Using offsets values from this_module forces a different application to explicitly call the current application module by its VHDL entity name within the REGISTER_ID before sharing the same shared_register.

Usage Example

Todo:
Add Example Usage

Example API Call(s):

READ_SHARED_REGISTER( this_module,next_state_rec, state_reg_rec );
READ_SHARED_REGISTER( some_module_tb, next_state_rec, state_reg_rec);
READ_SHARED_REGISTER( some_module, next_state_rec, state_reg_rec );

Call Data [ 3 parameters (3 mandatory) ]

Parameters
[in]REGISTER_ID[1] simple index number starting from 0
[out]next_state_rec[2]
[in]state_reg_rec[3]

Return Data

Parameters
[in]state_reg_rec(M).shared_reg: [1] [std_logic_vector]shared control data returned from the framework

Command Reference

Voice and Hotkey Commands:

See also
Shared Register Commands

Command Parameter Mapping

Parameters
[in]REGISTER_ID[1] [integer] "index <integer>"
[out]next_state_rec[2]
[in]state_reg_rec[3]

Command Return Data

Parameters
[in]state_reg_rec(M).shared_reg: [1] [std_logic_vector] "shared register"

Voice/HotKey Command Sequence

SHARED_REGISTER( example_module, input_vector, next_state_rec, state_reg_rec, 10 );

Voice Command HotKey Sequence
"read shared register" rsr
"index some_module" index some_module

Notes and Warnings

Note
1) The use of different REGISTER_IDs allows for 'clustering' of application modules, where different groups of application modules share registers that is not shared by other groups.
2) The REGISTER_ID parameter is overloaded for integer and std_logic_vector types, while data_in is overloaded for std_logic, std_logic_vector, std_logic_vector_array, and integers types.
3) Internally 'OR'ing or 'AND'ing data into the shared register prevents any synthesis error that would occur if there were multiple writers to the same range of bits of the shared register.
4) The default value of the of shared register (either all '1's or '0's) is set by the config file parameter default_shared_register_polarity.

See also
WRITE_SHARED_REGISTER
WRITE_FIFO_DATA
READ_FIFO_DATA

Procedures

  READ_SHARED_REGISTER(
REGISTER_ID: in integer
signal next_state_rec: out NSR
state_reg_rec: in SRR
)
  READ_SHARED_REGISTER(
REGISTER_ID: in integer
signal next_state_rec: out NSR_ARRAY
state_reg_rec: in SRR_ARRAY
)