// ============================================================================ // f245.v — 54F/74F245 Octal Bidirectional Transceiver (3-State Inputs/Outputs) // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F245.txt (1985 Fairchild FAST Data Book, // pages 4-158 ... 4-159; the 1980 data book carries the 'F245 in its // Section 3 selection guide only. Released data sheet.) // // Eight channels, each a back-to-back pair of non-inverting 3-state buffers // between the bidirectional bus pins A0..A7 and B0..B7. A single T//R input // selects which buffer of the pair is active (HIGH = Transmit = A -> B, // LOW = Receive = B -> A); /OE gates both directions, HIGH disabling every // buffer to High-Z regardless of T//R. // // Truth table (per channel): // OE_n=L, TR=L -> B drives A (A = B); // OE_n=L, TR=H -> A drives B (B = A); // OE_n=H -> both sides High-Z. // // Unlike 'F242/'F243, there is no independent-enable hazard here: T//R is a // single select bit, so exactly one direction (or neither, under /OE HIGH) // can ever be active. See src/f242.v's and src/f243.v's header comments for // the full backstory on why the T//R-style transceivers are structurally // immune to the both-directions-enabled contention 'F242/'F243 carry. // // Timing values from the data sheet AC Characteristics table, T_A = +25 C, // V_CC = +5.0 V, C_L = 50 pF column, min:typ:max ns. The sheet's second // column, 74F over the commercial T_A/V_CC range, gives min/max only: // // tPLH/tPHL (An to Bn or Bn to An) 2.5 / 7.0 ns / 2.5 / 7.0 ns // tPZH (Output Enable Time) 3.0 / 8.0 ns // tPZL (Output Enable Time) 3.5 / 9.0 ns // tPHZ (Output Disable Time) 3.0 / 7.5 ns // tPLZ (Output Disable Time) 2.0 / 7.5 ns // // A single Prop Delay row in the data sheet covers both directions (An to Bn // and Bn to An share the same figures) — the buffers are symmetric. // // DC CHARACTERISTICS gives ICCH/ICCL/ICCZ power-supply-current figures only; // this project's models don't simulate current draw. // // Ports are scalar and named after the data sheet pin names: Icarus Verilog // does not fully support multi-bit (parallel) specify path connections, so // vector ports would get incorrect per-bit delays. Each bus pin is a path // DESTINATION in one direction and a SOURCE in the other, so the specify // block carries one statement per scalar pin per direction. // ============================================================================ `timescale 1ns/100ps module f245 ( input wire oe_n, // output enable (active LOW) input wire tr, // direction select: H = A->B (Transmit), L = B->A (Receive) inout wire a0, a1, a2, a3, a4, a5, a6, a7, // bus A (bidirectional) inout wire b0, b1, b2, b3, b4, b5, b6, b7 // bus B (bidirectional) ); // A -> B (Transmit, non-inverting), active when OE_n LOW and TR HIGH wire drive_ab = ~oe_n & tr; // B -> A (Receive, non-inverting), active when OE_n LOW and TR LOW wire drive_ba = ~oe_n & ~tr; assign b0 = drive_ab ? a0 : 1'bz; assign b1 = drive_ab ? a1 : 1'bz; assign b2 = drive_ab ? a2 : 1'bz; assign b3 = drive_ab ? a3 : 1'bz; assign b4 = drive_ab ? a4 : 1'bz; assign b5 = drive_ab ? a5 : 1'bz; assign b6 = drive_ab ? a6 : 1'bz; assign b7 = drive_ab ? a7 : 1'bz; assign a0 = drive_ba ? b0 : 1'bz; assign a1 = drive_ba ? b1 : 1'bz; assign a2 = drive_ba ? b2 : 1'bz; assign a3 = drive_ba ? b3 : 1'bz; assign a4 = drive_ba ? b4 : 1'bz; assign a5 = drive_ba ? b5 : 1'bz; assign a6 = drive_ba ? b6 : 1'bz; assign a7 = drive_ba ? b7 : 1'bz; specify // T_A = +25 C, V_CC = +5.0 V, C_L = 50 pF, min:typ:max ns. // Prop Delay An to Bn or Bn to An (data sheet: tPLH 2.5/4.2/6.0, // tPHL 2.5/4.6/6.0) — one row covers both directions. specparam tlh = 2.5:4.2:6.0; specparam thl = 2.5:4.6:6.0; // Output Enable Time (data sheet: tPZH 3.0/5.3/7.0, tPZL 3.5/6.0/8.0) specparam tzh = 3.0:5.3:7.0; specparam tzl = 3.5:6.0:8.0; // Output Disable Time (data sheet: tPHZ 3.0/5.0/6.5, tPLZ 2.0/5.0/6.5) specparam thz = 3.0:5.0:6.5; specparam tlz = 2.0:5.0:6.5; // A -> B direction: bus B pins are the path destinations (a0, tr, oe_n => b0) = (tlh, thl, tlz, tzh, thz, tzl); (a1, tr, oe_n => b1) = (tlh, thl, tlz, tzh, thz, tzl); (a2, tr, oe_n => b2) = (tlh, thl, tlz, tzh, thz, tzl); (a3, tr, oe_n => b3) = (tlh, thl, tlz, tzh, thz, tzl); (a4, tr, oe_n => b4) = (tlh, thl, tlz, tzh, thz, tzl); (a5, tr, oe_n => b5) = (tlh, thl, tlz, tzh, thz, tzl); (a6, tr, oe_n => b6) = (tlh, thl, tlz, tzh, thz, tzl); (a7, tr, oe_n => b7) = (tlh, thl, tlz, tzh, thz, tzl); // B -> A direction: the same physical pins, opposite roles — // bus A pins are the path destinations (b0, tr, oe_n => a0) = (tlh, thl, tlz, tzh, thz, tzl); (b1, tr, oe_n => a1) = (tlh, thl, tlz, tzh, thz, tzl); (b2, tr, oe_n => a2) = (tlh, thl, tlz, tzh, thz, tzl); (b3, tr, oe_n => a3) = (tlh, thl, tlz, tzh, thz, tzl); (b4, tr, oe_n => a4) = (tlh, thl, tlz, tzh, thz, tzl); (b5, tr, oe_n => a5) = (tlh, thl, tlz, tzh, thz, tzl); (b6, tr, oe_n => a6) = (tlh, thl, tlz, tzh, thz, tzl); (b7, tr, oe_n => a7) = (tlh, thl, tlz, tzh, thz, tzl); endspecify endmodule