P4C
The P4 Compiler
Loading...
Searching...
No Matches
ActionData::PackingConstraint Class Reference

#include <action_format.h>

Public Member Functions

 PackingConstraint (int rg, safe_vector< PackingConstraint > &pc)
 
int bit_rotation_position (int bit_width, int init_bit, int final_bit, int init_bit_comp) const
 
bool can_rotate (int bit_width, int init_bit, int final_bit) const
 
bool can_rotate_in_range (LocalPacking &lp, le_bitrange open_range, int &final_bit) const
 
PackingConstraint expand (int current_size, int expand_size) const
 
int get_granularity () const
 
safe_vector< PackingConstraintget_recursive_constraints () const
 
bool is_rotational () const
 
PackingConstraint merge (const PackingConstraint &pc, const LocalPacking &lp, const LocalPacking &pc_lp) const
 
void rotate (RotationInfo &ri, int init_bit, int final_bit)
 

Friends

std::ostream & operator<< (std::ostream &out, const PackingConstraint &pc)
 

Detailed Description

Recursive Constraint indicating how data can be moved and rotated in the ActionDataRAMSection. This is due to the multiple levels of action data headed to potentially different sizes of ALU operations. Please read the RamSection comments for further details.

Member Function Documentation

◆ bit_rotation_position()

int ActionData::PackingConstraint::bit_rotation_position ( int bit_width,
int init_bit,
int final_bit,
int init_bit_comp ) const

Given that a rotation can happen where bit position at init bit will rotate to the bit position at the final bit, determine the location of where init_bit_comp will rotate to.

◆ can_rotate()

bool ActionData::PackingConstraint::can_rotate ( int bit_width,
int init_bit,
int final_bit ) const

The function tests if the packing information returns the following:

  • Can the bit at the init_bit position can be rotated to the final_bit position

This is talked about in the comments over the PackingConstraint::rotate section, but the constraints can be rotated recursively.

◆ can_rotate_in_range()

bool ActionData::PackingConstraint::can_rotate_in_range ( LocalPacking & lp,
le_bitrange open_range,
int & final_bit ) const

This check verifies that the data (summarized in the LocalPacking) can be rotated into the bit data into the open_range. The function also calculates the position of the final bit, in which the first set bit in the lp.bit_in_use can be rotated into for the rotate function.

The test is done as a two-parter.

  1. Can the RAM section be rotated to constraint where the first bit of the open_range (called under_rotate).
  2. If it cannot be rotated to this section, then rotate one more section and try again, (called over_rotate).

The goal of this is to keep data as close as possible to the lsb of the RAM section.

This works well with an example:

Say again, you have a 16 bit, byte-by-byte rotational constraints, with data packed from bits 0:3. Let's now provide some potential ranges.

Test for open_range 4:11:

  • In a byte by byte rotation, the initial byte rotation is 0. We then recurse to the bit granularity and find that we can rotate the first byte, bit by bit, so that the bits end up a bits 4:7

Test for open_range 5:11:

  • In this case, the under_rotation will fail, as only 3 bits are available in that byte but after a rotation to the next byte, then this will fit.

This is all based on the idea that the algorithm is trying to pack data as close to the lsb.

◆ merge()

PackingConstraint ActionData::PackingConstraint::merge ( const PackingConstraint & pc,
const LocalPacking & lp,
const LocalPacking & pc_lp ) const

Essentially to merge constraints:

When merging a bit-by-bit rotational section with a non bit-by-bit rotational section, the RAM section is not bit-by-bit rotational.

When merging two bit-by-bit rotational RAM sections, the merged RAM section is also bit-by-bit rotational

When merging two bit-by-bit rotational RAM sections that are different sizes:

  1. The merged section rotational_granularity is the size of the smaller slot size
  2. Any recursive constraint containing data from the larger section is not bit-by-bit rotational. Thus if a recursive constraint contains data from the smaller section, it is not bit-by-bit rotational if that section also contains data from the larger section.

This is displayed in the gtests for CrossSizeMerge as well as the Google Doc notes.

‍Recursive constraints should only be merged, if the data was to merge

◆ rotate()

void ActionData::PackingConstraint::rotate ( RotationInfo & ri,
int init_bit,
int final_bit )

The rotation function both rotates the constraints as well as the data bit-by-bit so that the data bit at the init_bit position can will be at the final_bit position. This function recurses down the constraint levels so that the only the relevant portion to rotate will have been rotated.

Let's set up the following scenario:

16 bit data, that is byte by byte rotational, and each byte is bit by bit rotational The data is arg1[3:0] at RAM bit 3:0 and arg2[3:0] at RAM bit 11:8:

The init_bit and final_bit are 0, 12. After the rotation: arg2[3:0] will be at RAM bit [3:0] arg1[3:0] will be at RAM bit [15:12]

This is because both bytes are rotated, but only the byte at the final bit is rotated.