Expand description
The decode engine as an accelerator function of the Open FPGA Stack on the Intel PAC D5005.
afu_sources writes the files an OFS partial-reconfiguration build of the card’s FIM takes
(afu_synth_setup -s hw/rtl/sources.txt <build dir>, then afu_synth):
• ofs_plat_afu, the boundary with the Platform Interface Manager: host channel 0 as Avalon-MM MMIO and host
memory in pClk, every local-memory bank as Avalon-MM in its own EMIF clock (its ECC lanes carried as data at
LocalMemoryLine::DataAndEcc576, holding each line’s SECDED(72,64) check bytes at
LocalMemoryLine::Data512Secded), the compute clock the user clock the AFU JSON asks for;
• logos_d5005_shell, every platform port flat in its own clock, the only paths between clocks the dual-clock
FIFOs logos_dcfifo_mlab and logos_dcfifo_m20k (Gray pointers through two-register synchronizers);
• the stream engines (a reader and a writer on each memory channel’s one port, and on the host memory port’s
two; on SECDED lines the line coder at each bank’s port and the decoder in one registered stage behind it,
logos_secded.v from secded_verilog, the code secded_line and secded_read define), the registers
(REGISTERS: the OFS feature header at word 0, the AFU ID, a command doorbell, the last status record), and
the bring-up core (Op): fills and checks of every channel at full rate, copies between host memory and a
channel, and on SECDED lines flips injected into the lines written and the words corrected and lost, so every
path is proven on the card before the decode engine takes the core’s ports;
• the AFU JSON, the timing constraints of every FIFO crossing (the recipe the FIM’s own syn/setup/dcfifo.sdc
applies), the clock-domain map CLOCK_DOMAINS_FILE the CDC gate reads, and the C header a driver includes;
• the host side: sw/logos_hal.h, the device a host program drives (its MMIO words, buffers the accelerator
reaches by I/O address, its user clock), its OPAE 2.12 backend for the card and its physical backend
(sw/logos_hal_pci.c: the VF’s BAR and command word from sysfs, buffers in huge pages at their physical
addresses, for a host with no IOMMU), sw/logos_core.h, the core’s commands as a program rings them,
sw/logos_receipt.c, the bring-up receipt (identity, every channel filled and checked alone and all at once
with its bandwidth, a wrong seed seen, a host buffer’s round trip through a channel, on SECDED lines every
channel’s code proven by injected flips) as one JSON object, and sw/logos_load.c, the image loader (a weight
image the image writer made copied onto the channels at their full line width, read back against its files
with every tile’s check word checked, and with --self-test a damaged line found in its tile and the tile
loaded again);
• the simulation of all of it: sim/logos_d5005_cosim.v, the shell with four memory channels on four unrelated
clocks behind each the ChannelModel the configuration names (sim/logos_avmm_memory_model.v, a memory that
waits at random, or sim/logos_ddr4_channel_model.v, a DDR4-2400 channel timed by the controller model of
codegen_sva::ddr4_jedec), and the same backend over a simulator (sim/logos_hal_sim.h), Icarus Verilog’s
VPI (sim/logos_hal_vpi.c) or Verilator’s DPI-C (sim/logos_hal_dpi.c, the top built with LOGOS_DPI), so a
program that runs on the card runs unchanged against the RTL, the simulation stepping only while the program
waits on an MMIO access;
• on the engine build, sw/logos_step.c, the program that runs a model on the engine one token a step from what
write_engine_program wrote, and sim/logos_engine_gated.v, the engine a simulation runs in place of
hw/rtl/logos_engine.v: the same engine with its core’s clock gated to the user cycles the core acts in
(rtl::engine::simulation_twin).
The platform’s widths are the D5005 FIM’s (src/top/ofs_d5005.ini, ipss/mem/includes/ofs_fim_emif_cfg_pkg.sv):
four banks of 2^27 lines, 512 data bits and 64 ECC bits a line on a 72-bit DDR4-2400 bus whose controller has ECC
off, bursts of up to 64 lines; host channel lines of 512 bits at 51 address bits, MMIO words of 64 bits at 15.
Structs§
- AfuConfig
- The accelerator a build makes.
- AfuFile
- One emitted file: its path under the AFU’s root and its text.
- Engine
Program - What a host program runs a model on the engine build with, one token-row a step: written by
write_engine_programasengine.txt, beside the engine’s tables, the memory image and the embedding table. - Register
- One 64-bit register of the MMIO space.
- Secded
Read - A bus line read back: its data, each word corrected where its codeword shows one flipped bit, and bit
wofcorrectedand ofuncorrectablethe verdict on wordw.
Enums§
- Access
- How the host reaches a register.
- Channel
Model - What stands behind each memory channel in the co-simulation.
- Local
Memory Line - What a local-memory line carries to the AFU.
- Op
- The bring-up core’s commands.
Constants§
- AFU_
UUID - Every accelerator the engine builds for the card is found by this UUID: the name-based UUID of
logicaffeine:d5005:decode-engine(the first 16 bytes of its SHA-256, version 5). - BANKS
- Memory banks the D5005 FIM gives the AFU.
- BANK_
ADDRESS_ BITS - Bits of a bank’s line address.
- BANK_
BURST_ BITS - Bits of a bank’s burst count.
- CLOCK_
DOMAINS_ FILE - The clock-domain map’s path among
afu_sources. - COMPUTE_
CLOCK_ VERILOG - The user clock divided by
DIVIDE(even), as marks in the user clock: a register toggled everyDIVIDE / 2user clock edges (the divided clock, a level that clocks nothing);fedgeandfmidhigh in the user cycles that end with its rising and falling edges, where the shell’s compute side and an engine’s core step and an engine’s step boundary takes the engine’s values; and a reset asserted with the user clock’s and released in the user clock at the second divided rising edge after it. - ENGINE_
COMPUTE_ DIVIDE - ENGINE_
SETTINGS - An engine build’s project settings, as Tcl its build sources (
hw/rtl/logos_settings.tcl, named in sources.txt asQI:). The engine’s memories of thirty-two words or fewer read without a register after them are in MLABs checking no read-during-write (rtl::ram::RAMSTYLE,LOGOS_RAMSTYLE_ASYNC), which Quartus Prime Pro otherwise leaves untimed between an MLAB’s write and a read of the same word: timed, a word read in the clock after its write is the one written, as the RTL reads it. - ENGINE_
USER_ CLOCK_ MHZ - The user clock an engine build asks for, MHz, and the divide its compute clock is: the reference engine’s single-cycle units close at that period on the 1SX280.
- ERROR_
COMMAND_ DROPPED - ERRORS bit 0: a doorbell rang with the command FIFO full, and was dropped.
- FIFO_
SIDE_ REGISTERS - The registers of a FIFO’s side: its pointer, the other side’s pointer crossing in and its binary, its RAM, and on the read side the word and valid it holds.
- FIM_
STATIC_ EXERCISERS - The FIM’s static exercisers’ file list, as sources.txt names it for a flat build (
QI:, so Quartus sources it): underOFS_ROOTDIR, the FIM source tree the FIM’s build runs from, which OPAE’s rtl_src_config expands. - HOST_
ADDRESS_ BITS - Bits of a host channel line address and of its line.
- HOST_
LINE_ BITS - MARK_
LEAD - The user clocks a divided build’s compute-clock marks and compute-side reset release come out of the divider late: registers of no reset between the divider and the marks’ tens of thousands of loads, which the retimer may move along the wire and the last of which Quartus copies beside them.
- MMIO_
WORD_ ADDRESS_ BITS - Bits of an MMIO word address (64-bit words of an 18-bit byte space).
- REGISTERS
- The register map: the OFS AFU feature header (type 1, end of the list, no next feature) and the AFU ID at words 0 to 4, as every OFS AFU carries them, then the engine’s.
- SECDED_
CHECKS - The codeword position of bit
jof a word’s check byte: the overall parity, then the Hamming checks at the powers of two, ascodegen_sva::scratchpad_rtlplaces them. - SECDED_
WORDS - Words of a channel line, each its own SECDED(72,64) codeword.
- STATUS_
OK - The status code of a completed command, and of one whose op the core does not know.
- STATUS_
RUNNING - The code of a running command’s progress record: the core cuts one every
2^HBof its cycles in which the command’s lines, its host lines or the engine’s sequencer moved, so a host waits while a long command moves. - STATUS_
UNKNOWN_ OP
Functions§
- afu_
sources - Every file of the accelerator under
cfg. - compute_
fifo_ sides - The sides of the shell’s dual-clock FIFOs that step at the compute clock’s step, from the shell’s text: each FIFO
instance’s name and its side,
'w'its writes’ and'r'its reads’, clocked by the user clock under the compute side’s enable (cce, a channel’suce). Every other side runs on its own clock or every user cycle. - cosim_
user_ clock_ ps - The user clock’s period in the co-simulation, picoseconds: the clock the AFU JSON asks for, the shell dividing it as the build divides it, so a divided build’s compute side meets its memory channels at the ratio it does on the card.
- hybrid_
shell_ verilog - The shell of a hybrid engine build at the engine’s divide, with the fast ports’ writes when
recurrence: the shellafu_sourceswrites for an engine whose streaming unit is built so. - job_
listing - The job listing of a step whose jobs past the host’s embedding are
jobs(the engine’s job table, assuper::machine::encodelays them intable0.bin): a “jobword ” line a job, job 0 the host’s embedding at word 0 and job j the table’s jobs[j - 1]at the word the table opens it at, its kind itsDebugtext cut at 240 characters.sw/logos_step.cprofiles a step by it (LOGOS_PROFILE), a job at a time. - job_
listing_ of job_listingof the program indirread back from its job table (table0.bin, a word a 64-byte line) alone: for a program written before programs carried their listing.- secded_
check_ byte - The ECC lane holding word
w’s check byte: bus byte64 + 7 − w. The controller’s 576-bit word is either the memory burst’s eight beats of 72 DQ pins each (bus bition pini mod 72), or its eight beats of the 64 data pins beneath the eight beats of the eight ECC pins (data bition pini mod 64, ECC biteon pin64 + e mod 8). Under either, wordw‘s data bits and ECC lane7 − wlie on 72 different pins, so a failing pin flips one bit of each codeword, which the code corrects; pairing wordwwith lanewholds only under the second. Were the bus word each group of eight pins’ beats in turn, no grouping of whole bytes would hold under all three. - secded_
line - A channel line as the bus holds it: its 64 data bytes where they are, then the eight ECC lanes, word
w’s check byte at lanesecded_check_byte(w). - secded_
read - What the shell makes of a bus line it reads: each word’s codeword reassembled from its data bits and its check
byte and decoded as
scratchpad_rtl::decodedecodes it. - secded_
verilog logos_secded.v: the line coder and decoder, every parity a mask of a word’s data bits read offencode’s codewords, every correction the data bit whose codeword position the syndrome names.- shell_
verilog - The Verilog every simulation of the shell reads: the shell and all it instantiates, in order.
- write_
contexts_ program write_hybrid_program, greedy whengreedy(write_greedy_program), for an engine ofcontextssequencer contexts (super::rtl::engine::Streaming::contexts): the machine’s sequences dealt over them, sequence s in context s modcontextsas its row s /contexts, the store laid for a context’s rows — an error unless the sequences fill every context alike.- write_
engine_ program - Write the program
machine— assuper::machine::Machine::newleft it, its regions empty — runs on the engine build overmap, a flat map (super::physical::PhysicalMap::flat: the reference engine reads its weights a line at a time through the card port), intodir:engine.txt,table<k>.binfor the engine’s static tables (0 the step’s jobs after the host’s embedding, 2 the slots, 3 the tensors, 4 the rotary tables, 5 the blocks), a 64-byte line an entry,jobs.txtthe step’s job listing (job_listing),channel<k>.binthe memory image, andembed.bin, every token’s embedding asf32. - write_
greedy_ program write_hybrid_programwith a greedy head: the head’s stream entry asks the streaming unit for each row’s arg-max of its logits rather than the logits, and the store is laid greedy (super::machine::StoreLayout::greedy), so a row’s read-back is one beat however wide the vocabulary and the store holds many rows. An error when the head’s matrix is not one the unit streams.- write_
hybrid_ program - Write the program
machineruns on the hybrid engine build overmap, a hybrid map (super::physical::PhysicalMap::hybrid: the matrices the machine streams in their image at each channel’s start, the memory compacted bycompactionwith the streamed tensors’ stream entries after it, the space the engine’s card port reads), for a streaming unit built forset, the image’s tiles read fromweights: the fileswrite_engine_programwrites, every address the engine reads in the flat space wherecompactionfinds it.