Skip to content

ofb_pkg: Architecture and Design Description

1. Structure

ofb_pkg is a single VHDL package (hdl/ofb_pkg/src/ofb_pkg.vhd) without entities. The module also holds the register map package ofb_regs_pkg, generated by tools/regmap.py (see the MIB architecture, section 3), and the pulse crossing ofb_cc_pulse.

Section Content
Characters and words Char_t (8 bit), Word_t (32 bit, character 0 in bits 7:0), WordK_t (one K flag per character), K flag patterns KCtrl_c, KData_c, KPad_c
K-codes K0_0_c to K30_7_c and names by function (CharComma_c, CharEop_c, ...)
Control word symbols Sym<Name>_c for every entry of ECSS Table 5-12
Fixed control words WordSkip_c, WordIdle_c, WordInit1_c, WordInit2_c, WordInvInit1_c, WordInvInit2_c, WordPad_c, WordRetry_c, WordRxErr_c
Fields Capability bit indices, LOS_Cause values, EBF status bits, sequence number polarity bit
Word functions wordInit3, wordStandby, wordLostSignal, wordActive, wordAlign, wordSdf, wordEdf, wordSbf, wordEbf, wordSif, wordFct, wordAck, wordNack, wordFull
CRC crc16Update, crc8Update, crc8Word3, seeds, polynomials, olo_base_crc settings
PRBS prbsWord, prbsNextState (reference model), olo_base_prbs settings

2. Data formats

A word is transmitted character 0 first. The K flag of character i is bit i of WordK_t:

Bits 31:24 23:16 15:8 7:0
Character 3 2 1 0 (sent first)
Example: SKIP D31.3 D31.3 D14.6 K28.7
Example: EDF CRC_MS CRC_LS SEQ_NUM K28.0

3. CRC

Both CRCs process the least significant bit of each character first. Implemented bit-serially with the reflected polynomial (0x8408 for CRC-16, 0xE0 for CRC-8) they directly give the CRC value as ECSS defines it (Figures 5-45 and 5-47), without output reflection or XOR. The K flag is not part of the CRC; a K-code contributes its data value.

olo_base_crc computes the same values with Polynomial_g = 0x1021 / 0x07, InitialValue_g = seed, BitOrder_g = ByteOrder_g = "LSB_FIRST" and BitflipOutput_g = true. Partial last words use In_Be (for example the EDF word, of which only characters 0 and 1 are covered).

4. PRBS

The ECSS random number generator (Figure 5-41) is a Galois LFSR: the output is D15, the register shifts towards D15 and the output is fed back into D0, D3, D4 and D5. prbsWord returns the next 32 output bits (bit 0 first, which is the least significant bit of character 0) and prbsNextState the register after these 32 steps.

olo_base_prbs is a Fibonacci LFSR whose output is its state. It produces the same sequence with the reciprocal polynomial x^16 + x^13 + x^12 + x^11 + 1 (PrbsPolynomial_c) and the state 0xFFE8 (PrbsSeed_c), which holds the first 16 bits of the ECSS sequence. With BitsPerSymbol_g = 32, bit 0 of Out_Data is the first bit. Loading PrbsSeed_c through State_New / State_Set re-seeds the generator (data scrambling re-seeds at every data frame, ECSS 5.7.6.2.1d).

5. Timing and behaviour

The functions are pure and synthesisable; crc8Word3 and the word functions unroll to combinational logic.

6. Pulse crossing ofb_cc_pulse

Per pulse bit a two-phase handshake (no latch, every path between the clock domains starts at a register):

            In_Clk                          |              Out_Clk
                                            |
 In_Pulse -> Want = In_Pulse or Pend        |
             Fire = Want and (Req = Ack)    |
             Req  <= Req xor Fire  (TMR) ---+-> olo_ft_cc_bits -> ReqOut -+-> Out_Pulse = ReqOut xor Last
             Pend <= Want and not Fire (TMR)|                            |   Last <= ReqOut (TMR)
             Ack  <- olo_ft_cc_bits <-------+----------------------------+
  • A pulse toggles the request level when no transfer is in progress (request equal to acknowledge), otherwise it is stored as pending (Pend) and toggles the request once the acknowledge returns. Further pulses during the same transfer merge with the pending one.
  • The output side emits one pulse per change of the synchronised request level and returns the level as acknowledge.
  • Round trip: at most 5 input and 4 output clock cycles (request register and the input register of olo_ft_cc_bits, two synchronising stages per direction, alignment to the other clock), so pulses 5 input plus 5 output clock cycles apart are never pending. Latency of an output pulse: at most 3 input plus 4 output clock cycles.
  • Req, Pend and Last are triplicated; every copy loads the voted value, so a flipped copy is corrected in the next cycle. Synthesis attributes of the Open Logic attribute packages (dont_touch, dont_merge, preserve, syn_preserve, syn_keep) prevent merging of the copies, syn_radhardlevel = none prevents vendor TMR insertion.
  • olo_ft_cc_reset couples the resets: a reset of either side resets both; request, acknowledge and Last restart from 0, so a reset creates no output pulse.

ofb_cc_pulse differs from olo_ft_cc_pulse of Open Logic (a toggle crossing with the semantics of olo_base_cc_pulse) in the pending pulse: a second pulse during a transfer is kept and sent afterwards, where olo_ft_cc_pulse merges pulses closer than its minimum spacing. Earlier versions of olo_ft_cc_pulse were built from a set/reset latch per copy, which the FPGA tools map to a transparent latch whose gate and data both follow the input pulse.