owr_pkg: Architecture and Design Description¶
1. Contents¶
| File | Content |
|---|---|
src/owr_pkg.vhd |
Character kinds Kind*_c, control types Ctrl*_c, N-Char format NChar_t, link states State*_c, error causes Cause*_c, credit limits, broadcast code fields BcType*_c and BcKind*_c, nominal times of ECSS 5.4.8, 5.4.10 and 5.5.7, functions timeCycles, initDivider, parityBit, xorReduce |
src/owr_regs_pkg.vhd |
Register map (generated by tools/regmap.py) |
src/owr_cc_pulse.vhd |
Pulse crossing without latch: two-phase handshake over olo_ft_cc_bits, one output pulse of one cycle per input pulse (section 4) |
2. Character encoding¶
| Kind | Bits on the line (first bit left) | Length |
|---|---|---|
| Data character | P 0 D0 D1 D2 D3 D4 D5 D6 D7 | 10 |
| FCT | P 1 0 0 | 4 |
| EOP | P 1 0 1 | 4 |
| EEP | P 1 1 0 | 4 |
| ESC | P 1 1 1 | 4 |
| Null | ESC FCT: P 1 1 1 0 1 0 0 | 8 |
| Broadcast code | ESC data character: P 1 1 1 1 0 B0 .. B7 | 14 |
The control type constants hold the type bits with bit 0 as the first bit sent: CtrlEop_c = "10" is sent as 0, 1.
parityBit(prev, flag) returns the parity bit P that makes prev XOR P XOR flag = '1'.
3. Data-Strobe far-end model (tb/)¶
owr_tb_ds_pkg defines the character encoding and the protected type of the control object; owr_tb_farend_pkg
holds the object FarEnd_v with, per model instance, a transmit queue, the bit period,
the transmit mode (off with controlled reset, Nulls when idle, silent when idle), the fault injection requests, a
receive log of characters with their start time, a log of edges and error counters. owr_tb_ds_bfm is the model: its
transmitter encodes the queued characters with its own implementation of ECSS 5.4.3 and 5.4.4 and waits the bit
period between bits; its receiver wakes on every edge of data or strobe, recovers a bit on every change of data XOR
strobe, searches the first Null and decodes the characters. Both work in continuous time and do not use the clock of
the port.
4. Pulse crossing owr_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,PendandLastare 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_resetcouples the resets: a reset of either side resets both; request, acknowledge andLastrestart from 0, so a reset creates no output pulse.
olo_ft_cc_pulse of Open Logic is not used: it is 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, so the end of the pulse races the closing of the
latch, and the path through the latch is not timed.