// ============================================================================ // f194.v — 54F/74F194 4-Bit Bidirectional Universal Shift Register // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F194.txt (1980 Fairchild FAST Data Book, // pages 4-65 ... 4-67) // // Mode select table (data sheet), synchronous on the rising edge of CP: // S1 S0 | Operation // ------+---------------------------------------------------------- // L L | Hold (do nothing) // L H | Shift Right: Q0 <- DSR, Q1 <- Q0, Q2 <- Q1, Q3 <- Q2 // H L | Shift Left: Q0 <- Q1, Q1 <- Q2, Q2 <- Q3, Q3 <- DSL // H H | Parallel Load: Qn <- Pn // // A LOW on MR_n (asynchronous Master Reset) overrides all other inputs and // forces all four outputs LOW. // // Timing values from the data sheet AC Characteristics table, // 54F/74F column (T_A = +25 C, V_CC = +5.0 V, C_L = 15 pF), min:typ:max ns. // // 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. // ============================================================================ `timescale 1ns/100ps module f194 ( input wire mr_n, // asynchronous master reset (active LOW) input wire cp, // clock pulse (active rising edge) input wire s0, // mode control input 0 input wire s1, // mode control input 1 input wire dsr, // serial data input (shift right) input wire dsl, // serial data input (shift left) input wire p0, p1, p2, p3, // parallel data inputs output reg q0, q1, q2, q3 // parallel outputs ); always @(posedge cp or negedge mr_n) begin if (!mr_n) begin q0 <= 1'b0; q1 <= 1'b0; q2 <= 1'b0; q3 <= 1'b0; end else begin case ({s1, s0}) 2'b00: ; // hold 2'b01: begin // shift right (toward Q3) q0 <= dsr; q1 <= q0; q2 <= q1; q3 <= q2; end 2'b10: begin // shift left (toward Q0) q0 <= q1; q1 <= q2; q2 <= q3; q3 <= dsl; end 2'b11: begin // parallel load q0 <= p0; q1 <= p1; q2 <= p2; q3 <= p3; end endcase end end specify // Maximum shift frequency (data sheet: fmax 105 min / 150 typ MHz, // max blank on the sheet), Fig. 2-17 / 2-21. Not a path delay; // recorded here for completeness, applied to no path. specparam fmax_min_mhz = 105; specparam fmax_typ_mhz = 150; // Propagation delay CP to Q_n (data sheet: tPLH 2.0/4.0/7.0, // tPHL 2.0/4.5/9.0 ns), Fig. 2-17, 2-21. specparam tlh_cp_q = 2.0:4.0:7.0; specparam thl_cp_q = 2.0:4.5:9.0; // Propagation delay MR_n to Q_n (data sheet: tPHL 5.0/10/13 ns), // Fig. 2-17, 2-24. Only tPHL exists: MR_n can only drive Q LOW. // Single-delay form (applies to every transition; only 1->0 occurs). specparam thl_mr_q = 5.0:10:13; (cp => q0) = (tlh_cp_q, thl_cp_q); (cp => q1) = (tlh_cp_q, thl_cp_q); (cp => q2) = (tlh_cp_q, thl_cp_q); (cp => q3) = (tlh_cp_q, thl_cp_q); (mr_n => q0) = (thl_mr_q); (mr_n => q1) = (thl_mr_q); (mr_n => q2) = (thl_mr_q); (mr_n => q3) = (thl_mr_q); // AC operating requirements (data sheet, +25 C 5.0 V minima): // ts(H/L) P_n/DSR/DSL to CP 4.0, th(H/L) 0; ts(H/L) S_n to CP 8.0, // th(H/L) 0; tw(H) CP 5.0; tw(L) MR_n 5.0; trec MR_n to CP 7.0 ns. // Icarus Verilog does not support timing checks; kept (guarded) // for simulators that do. `ifndef __ICARUS__ specparam ts_d_h = 4.0; // ts(H) P_n, DSR or DSL to CP specparam ts_d_l = 4.0; // ts(L) P_n, DSR or DSL to CP specparam th_d_h = 0; // th(H) P_n, DSR or DSL to CP specparam th_d_l = 0; // th(L) P_n, DSR or DSL to CP specparam ts_s_h = 8.0; // ts(H) S_n to CP specparam ts_s_l = 8.0; // ts(L) S_n to CP specparam th_s_h = 0; // th(H) S_n to CP specparam th_s_l = 0; // th(L) S_n to CP specparam tw_cp_h = 5.0; // CP pulse width HIGH specparam tw_mr_l = 5.0; // MR_n pulse width LOW specparam trec = 7.0; // recovery time, MR_n to CP $setup(p0, posedge cp, ts_d_h); $setup(p1, posedge cp, ts_d_h); $setup(p2, posedge cp, ts_d_h); $setup(p3, posedge cp, ts_d_h); $setup(dsr, posedge cp, ts_d_h); $setup(dsl, posedge cp, ts_d_h); $hold(posedge cp, p0, th_d_h); $hold(posedge cp, p1, th_d_h); $hold(posedge cp, p2, th_d_h); $hold(posedge cp, p3, th_d_h); $hold(posedge cp, dsr, th_d_h); $hold(posedge cp, dsl, th_d_h); $setup(s0, posedge cp, ts_s_h); $setup(s1, posedge cp, ts_s_h); $hold(posedge cp, s0, th_s_h); $hold(posedge cp, s1, th_s_h); $width(posedge cp, tw_cp_h); $width(negedge mr_n, tw_mr_l); $recovery(posedge mr_n, posedge cp, trec); `endif endspecify endmodule