P4C
The P4 Compiler
Loading...
Searching...
No Matches
InstructionMemory Struct Referenceabstract

#include <instruction_memory.h>

Inheritance diagram for InstructionMemory:
[legend]

Classes

struct  Use
 

Public Member Functions

bool alloc_always_run_instr (const IR::MAU::Table *tbl, Use &alloc, bitvec current_bv)
 
bool allocate_imem (const IR::MAU::Table *tbl, Use &alloc, PhvInfo &phv, bool gw_linked, ActionData::FormatType_t format_type, SplitAttachedInfo &sai)
 
bool find_row_and_color (bitvec current_bv, gress_t gress, int &row, int &color, bool &first_noop, bool has_unalloc_temp=false)
 
const BFN::Alloc2Dbase< bitvec > & imem_slot_inuse (gress_t gress) const
 
virtual BFN::Alloc2Dbase< bitvec > & imem_slot_inuse (gress_t gress)=0
 
const BFN::Alloc2Dbase< cstring > & imem_use (gress_t gress) const
 
virtual BFN::Alloc2Dbase< cstring > & imem_use (gress_t gress)=0
 
bool is_noop_slot (int row, int color)
 
bool shared_instr (const IR::MAU::Table *tbl, Use &alloc, bool gw_linked)
 
void update (const IR::MAU::Table *tbl)
 
void update (cstring name, const TableResourceAlloc *alloc, const IR::MAU::Table *tbl)
 
void update (cstring name, const TableResourceAlloc *alloc, gress_t gress)
 
void update (cstring name, const Use &alloc, gress_t gress)
 
void update_always_run (const Use &alloc, gress_t gress)
 

Static Public Member Functions

static InstructionMemorycreate ()
 

Public Attributes

std::set< cstringatcam_updates
 
std::map< const IR::MAU::ActionData *, const Use * > shared_action_profiles
 
const IMemSpecspec
 

Static Public Attributes

static constexpr int NOOP_COLOR = 0
 
static constexpr int NOOP_ROW = 0
 

Protected Member Functions

 InstructionMemory (const IMemSpec &s)
 
 InstructionMemory (const InstructionMemory &)=delete
 
InstructionMemoryoperator= (const InstructionMemory &)=delete
 

Detailed Description

Algorithms for the allocation of the Instruction Memory. The Instruction Memory is defined in the uArch section 6.1.10.3 Action Instruction Memory.

The instruction memory is a 32 row x (PHV ALUs) per gress memory. Each action in P4 corresponds to a single RAM row in the IMEM. Each slot of a row corresponds to the instruction for that particular ALU. A noop instruction for an ALU is an all 0 encoded instruction. Thus an action in the P4 code coordinates to a single line in the instruction memory. For all PHVs that a particular action writes, the slots on that row will have the corresponding action, and for all PHVs that the particular action doesn't write, a noop, encoded as all 0s will let the PHV pass directly through. These instructions are called VLIW instructions, as one RAM line coordinates to hundreds of individual ALU instructions.

When a stage decides which actions to run, the RAM lines containing these actions are all ORed together to make a single instruction to be run by the ALUs. This is the root of action dependency. If two actions in the same packet operate on the same ALU, then their corresponding instruction opcodes will be ORed together, causing the instruction to be garbled and incorrect. (N.B. There is a possibility of removing action dependencies, if it is known that this ORing won't have any semantic change to the instruction)

Each instruction memory line has two colors. Two actions can be stored per RAM line as the actions on that RAM line can have a different color. This will only work if the intersection of the PHV writes for these actions are an empty set, as each individual ALU instruction can be marked a certain color.

Furthermore, actions can be shared across multiple tables, as long as the action opcodes are identical. The main corner case for this is a noop action, which usually appears in several tables. In both gresses, currently, the algorithm always reserves the first imem slot with the 0 color to be noop. Gateways that inhibit can potentially run an action as well, if the pfe for the imem is always defaulted on. Thus when the payload is all 0s, the instruction just runs a noop

Member Function Documentation

◆ shared_instr()

bool InstructionMemory::shared_instr ( const IR::MAU::Table * tbl,
Use & alloc,
bool gw_linked )

If two tables share an action profile, then the instruction memory location can be the exact same across both tables. However, the mem code for the instructions may need to differ.

Say for example, we had two tables {t1, t2} share an action profile that had the same 4 actions, {a1, a2, a3, a4 }. Four actions would require two bits of RAM line per entry. Let's say however, that one of the tables, with an action profile, i.e t2, is linked with a gateway. A gateway requires an action_instruction_adr_map_data entry as well, as the gateway goes through the hit pathway.

Thus in our example, t2 would require 5 instruction entries, and thus 3 bits of indirection, while t1 would only require 2 bits. Furthermore, if the gateway goes to row 0, then the an action encoding in t2 wouldn't fit within the 2 bits.

This function is to share the instruction memory line, while determining the correct memcode per action.