Scheduler TX Module

Overview

Scheduler_tx is a transmit scheduler that prepares address and payload pairs for the HotRIO master transmit datapath. The module supports two normal transmit modes:

  • Per-slave payload mode, where each slave has its own payload and valid input.

  • Single shared payload mode, where the same payload is transmitted to each slave address in a round-robin sequence.

The scheduler also supports a priority broadcast transaction. A broadcast request is latched on a rising edge and is transmitted before the next normal round-robin item when the downstream HotRIO master Tx Module requests new data.

The output interface is request driven. The scheduler only changes tx_addr_o, tx_payload_o, tx_valid_o, and tx_is_broadcast_o when next_data_req_i is asserted while the internal FSM is in the RUN state.

This module provides address and payload to the HotRIO master Tx Module which periodically sends payloads to a configurable set of slave devices. The scheduler hides the address sequencing and payload selection logic from the transmit datapath.

It does the following functionalities :

  • Polling and addressing multiple slave devices using sequential addresses.

  • Sending the same command or payload to all slaves in a round-robin manner.

  • Sending slave-specific payloads after all slave payloads have been captured.

  • Inserting a broadcast message with priority over normal scheduled traffic.

The module is intended to sit between payload-producing logic and HotRIO Master Tx Module. The later consumes the current output transaction and then pulses next_data_req_i to request the next transaction.

Detailed portlist

scheduler_txclk_istd_logicrstn_istd_logicen_istd_logicnext_data_req_istd_logicfirst_slave_addr_istd_logic_vector(hotrio_addr_width_c -...addr_update_istd_logictx_payload_arr_ipayload_array_t(0 tonum_slaves_g - 1)tx_payload_valid_arr_istd_logic_vector(num_slaves_g - 1 downto 0)shared_payload_istd_logic_vector(hotrio_payload_width_c...shared_payload_valid_istd_logicbroadcast_trigger_istd_logicbroadcast_addr_istd_logic_vector(hotrio_addr_width_c -...broadcast_payload_istd_logic_vector(hotrio_payload_width_c...tx_addr_ostd_logic_vector(hotrio_addr_width_c -...tx_payload_ostd_logic_vector(hotrio_payload_width_c...tx_valid_ostd_logictx_is_broadcast_ostd_logic

Generics

Name

Description

Type

Default

num_slaves_g

choose the number of slave addresses and the number of payload input ports to be generated

positive range 1 to 256

16

single_payload_g

choose false if the same payload has to be sent to all the slaves

boolean

false

Input signals


IN ports

Name

Description

Type

clk_i

tx clock of the pcs

std_logic

rstn_i

active low reset, synchronous to `clk_i`

std_logic

en_i

module enable. when not asserted, the fsm is forced to idle and output valid flags are deasserted.

std_logic

next_data_req_i

request pulse from the hotrio master.

std_logic

first_slave_addr_i

base address used to generate the internal contiguous slave address table.

std_logic_vector(hotrio_addr_width_c - 1 downto 0)

addr_update_i

rising-edge controlled request to reload the internal address table

std_logic

tx_payload_arr_i

array of payload values, one payload per slave index.

payload_array_t(0 to num_slaves_g - 1)

tx_payload_valid_arr_i

per-slave valid vector.

std_logic_vector(num_slaves_g - 1 downto 0)

shared_payload_i

shared payload input (used when single_payload_g = true)

std_logic_vector(hotrio_payload_width_c - 1 downto 0)

shared_payload_valid_i

valid signal for shared payload input

std_logic

broadcast_trigger_i

rising edge trigger to send broadcast packets

std_logic

broadcast_addr_i

address used for the pending broadcast transaction.

std_logic_vector(hotrio_addr_width_c - 1 downto 0)

broadcast_payload_i

payload used for the pending broadcast transaction.

std_logic_vector(hotrio_payload_width_c - 1 downto 0)

Output signals


OUT ports

Name

Description

Type

tx_addr_o

scheduled transmit address.

std_logic_vector(hotrio_addr_width_c - 1 downto 0)

tx_payload_o

scheduled transmit payload.

std_logic_vector(hotrio_payload_width_c - 1 downto 0)

tx_valid_o

valid output for the the payload and address output

std_logic

tx_is_broadcast_o

broadcast indication output

std_logic

Source Dependencies

The design uses the following special packages:

Package

Purpose

work.globals

Provides project-specific constants and types such as HOTRIO_ADDR_WIDTH_C, HOTRIO_PAYLOAD_WIDTH_C, payload_array_t, and array_slv8 and other shared constants and types.

Generics

Generic

Type / Range

Default

Description

NUM_SLAVES_G

POSITIVE RANGE 1 TO 64

16

Defines the number of slave entries handled by the scheduler. This generic sizes the address table, per-slave payload array, valid vector, and round-robin index range.

SINGLE_PAYLOAD_G

BOOLEAN

FALSE

Selects the normal payload scheduling mode. When TRUE, the same shared payload is used for every slave address. When FALSE, each slave uses its own payload captured from tx_payload_arr_i.

Generic Use Cases

NUM_SLAVES_G

Use this generic to scale the scheduler to the number of addressed slave endpoints in the system. For example, if the master must address eight slaves, set NUM_SLAVES_G => 8. The module then generates eight sequential addresses starting from first_slave_addr_i.

The generated address for slave index i is:

slave_addrs_s(i) = first_slave_addr_i + i
SINGLE_PAYLOAD_G

Use this generic to choose between two scheduling styles:

  • FALSE: each slave has a dedicated payload. This is suitable when every slave must receive different data.

  • TRUE: all slaves receive the same payload. This is suitable for common commands, common configuration values, or repeated writes to a contiguous slave range.

Internal Architecture

Reset Behavior

When rstn_i = '0' on a rising clock edge:

  • fsm_s is set to IDLE.

  • idx_s is reset to 0.

  • Per-slave payload registers are cleared.

  • valid_seen_s is cleared.

  • broadcast_pending_s is cleared.

  • Output registers are cleared and marked invalid.

  • Edge-detection history registers are cleared.

Enable Behavior

When en_i is not asserted:

  • The FSM is forced to IDLE.

  • tx_valid_s is deasserted.

  • tx_is_broadcast_s is deasserted.

The design continues to sample edge-detection history at the end of the clocked process when not in reset. Broadcast latching and per-slave payload capture are evaluated before the enable check.

Address Table Generation

The address table is generated in the LOAD_ADDR state:

FOR i IN 0 TO NUM_SLAVES_G - 1 LOOP
  slave_addrs_s(i) <= STD_LOGIC_VECTOR(
    unsigned(first_slave_addr_i) + to_unsigned(i, HOTRIO_ADDR_WIDTH_C)
  );
END LOOP;

After the table is loaded:

  • idx_s is reset to 0.

  • Outputs are marked invalid.

  • The FSM advances to RUN.

Payload Capture

In per-slave payload mode, valid payloads are captured continuously whenever SINGLE_PAYLOAD_G = FALSE:

IF tx_payload_valid_arr_i(i) = '1' THEN
  payload_reg_s(i) <= tx_payload_arr_i(i);
  valid_seen_s(i)  <= '1';
END IF;

Once a payload has been seen for a slave, its corresponding valid_seen_s bit remains asserted until reset. The module therefore waits for initial payload availability from all slaves before transmitting normal per-slave traffic.

Finite State Machine

IDLE State

The IDLE state is the inactive entry point of the scheduler.

Actions performed:

  • Deasserts tx_valid_s.

  • Deasserts tx_is_broadcast_s.

  • Advances to LOAD_ADDR when the module is enabled.

This state ensures that the scheduler does not emit a valid transaction before the address table has been initialized.

LOAD_ADDR State

The LOAD_ADDR state generates the internal address table. Each slave address is derived from first_slave_addr_i plus the slave index.

Actions performed:

  • Generates slave_addrs_s(0) through slave_addrs_s(NUM_SLAVES_G - 1).

  • Resets idx_s to 0.

  • Deasserts tx_valid_s.

  • Deasserts tx_is_broadcast_s.

  • Advances to RUN.

This state is entered after IDLE and whenever addr_update_i has a rising edge while the FSM is in RUN.

RUN State

The RUN state is the active scheduling state. In this state, the scheduler responds to address updates, transmit requests, broadcast requests, and normal payload availability.

Priority order inside RUN:

  1. Rising edge of addr_update_i.

  2. next_data_req_i from the HotRIO Master Tx.

  3. Pending broadcast transaction.

  4. Normal round-robin transaction.

Address Update Priority

If addr_update_i has a rising edge, the scheduler:

  • Moves to LOAD_ADDR.

  • Deasserts tx_valid_s.

  • Deasserts tx_is_broadcast_s.

Address update has priority over both broadcast and normal traffic.

Broadcast Scheduling

A rising edge on broadcast_trigger_i sets broadcast_pending_s. The pending broadcast is emitted on the next next_data_req_i request while the FSM is in RUN and no address update is taking priority.

Broadcast output actions:

  • tx_addr_s is loaded from broadcast_addr_i.

  • tx_payload_s is loaded from broadcast_payload_i.

  • tx_valid_s is asserted.

  • tx_is_broadcast_s is asserted.

  • broadcast_pending_s is cleared.

Broadcast traffic does not advance the normal round-robin index.

Single Shared Payload Scheduling

When SINGLE_PAYLOAD_G = TRUE, normal scheduling uses shared_payload_i for every slave address.

On next_data_req_i = '1':

  • If shared_payload_valid_i = '1':

    • tx_addr_s is loaded with slave_addrs_s(idx_s).

    • tx_payload_s is loaded with shared_payload_i.

    • tx_valid_s is asserted.

    • tx_is_broadcast_s is deasserted.

    • idx_s advances to the next slave, wrapping to 0 after the last slave.

  • If shared_payload_valid_i = '0':

    • tx_valid_s is deasserted.

    • tx_is_broadcast_s is deasserted.

    • idx_s does not advance.

Per-Slave Payload Scheduling

When SINGLE_PAYLOAD_G = FALSE, normal scheduling uses the internal payload_reg_s array.

On next_data_req_i = '1':

  • If all_valid_s = '1':

    • tx_addr_s is loaded with slave_addrs_s(idx_s).

    • tx_payload_s is loaded with payload_reg_s(idx_s).

    • tx_valid_s is asserted.

    • tx_is_broadcast_s is deasserted.

    • idx_s advances to the next slave, wrapping to 0 after the last slave.

  • If all_valid_s = '0':

    • tx_valid_s is deasserted.

    • tx_is_broadcast_s is deasserted.

    • idx_s does not advance.

Round-Robin Index Operation

The round-robin index selects the current slave for normal traffic. It advances only after a normal transaction is emitted.

0 -> 1 -> 2 -> ... -> NUM_SLAVES_G - 1 -> 0

The index is reset to 0:

  • During reset.

  • When the address table is loaded in LOAD_ADDR.

The index is not advanced by:

  • Broadcast transactions.

  • Invalid shared payload cycles.

  • Per-slave mode cycles where not all payloads have been seen.

  • Address update cycles.