// ============================================================================ // f161.v — 54F/74F161 Synchronous Presettable 4-Bit Binary Counter // (Asynchronous Master Reset) // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F161.txt (1980 Fairchild FAST Data Book, // pages 4-31 ... 4-33, shared data sheet with the 'F163) // // Modes of operation, in order of precedence (data sheet Mode Select table): // 1. MR_n LOW : asynchronous master reset — all Q // forced LOW immediately, independent // of CP, overriding all other inputs // 2. PE_n LOW : synchronous parallel load of Pn on // the next rising CP edge // 3. MR_n, PE_n HIGH, CEP & CET HIGH : count up on the rising CP edge // 4. CEP or CET LOW : hold // // Count sequence is modulo-16 binary: 0..15, then 15 -> 0 (no illegal // states). // // TC = Q0 & Q1 & Q2 & Q3 & CET — HIGH only in state 15. // // 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). That table lists TYP values // only (the Min/Max columns are blank), so each specparam carries the typ // value alone, as noted per row. // // 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 f161 ( input wire mr_n, // master reset (asynchronous, active LOW) input wire cp, // clock pulse (active rising edge) input wire p0, // parallel data input 0 input wire p1, // parallel data input 1 input wire p2, // parallel data input 2 input wire p3, // parallel data input 3 input wire cep, // count enable parallel input wire cet, // count enable trickle input wire pe_n, // parallel enable (active LOW) output wire q0, // flip-flop output 0 output wire q1, // flip-flop output 1 output wire q2, // flip-flop output 2 output wire q3, // flip-flop output 3 output wire tc // terminal count ); // Counter state. All output delays come from the specify block below, // so this model keeps the internal transitions at zero delay. reg [3:0] cnt; always @(posedge cp or negedge mr_n) begin if (!mr_n) cnt <= 4'd0; // asynchronous master reset else if (!pe_n) cnt <= {p3, p2, p1, p0}; // synchronous parallel load else if (cep && cet) cnt <= cnt + 4'd1; // count up, modulo-16 binary // else: CEP or CET LOW — hold end assign q0 = cnt[0]; assign q1 = cnt[1]; assign q2 = cnt[2]; assign q3 = cnt[3]; // Terminal count, data sheet logic equation: // TC = Q0 · Q1 · Q2 · Q3 · CET (HIGH only in state 15) assign tc = cet & cnt[0] & cnt[1] & cnt[2] & cnt[3]; specify // All delays are data-sheet TYP values only: the 54F/74F +25 C, // 5.0 V, C_L = 15 pF AC Characteristics table leaves the Min/Max // columns blank. // Propagation delay CP to Q_n, Load input HIGH (tPLH 6.0, tPHL // 7.5 ns typ); the "Load input LOW" rows list the same values. specparam tlh_cp_q = 6.0; specparam thl_cp_q = 7.5; // Propagation delay CP to TC (tPLH 12, tPHL 8.0 ns typ) specparam tlh_cp_tc = 12.0; specparam thl_cp_tc = 8.0; // Propagation delay CET to TC (tPLH 6.5, tPHL 6.5 ns typ) specparam tlh_cet_tc = 6.5; specparam thl_cet_tc = 6.5; // Propagation delay MR_n to Q_n (tPHL 10 ns typ; MR_n can only // drive Q LOW) specparam thl_mr_q = 10.0; (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); (cp => tc) = (tlh_cp_tc, thl_cp_tc); (cet => tc) = (tlh_cet_tc, thl_cet_tc); (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) Pn to CP 5.0, th(H/L) 0; ts(H/L) PE_n to CP 12, th 0; // ts(H/L) CEP/CET to CP 9.0, th 0; tw(H) CP 5.0, tw(L) CP 5.0; // tw(L) MR_n 10; trec MR_n to CP 6.0 ns. // Icarus Verilog does not support timing checks; kept (guarded) // for simulators that do. `ifndef __ICARUS__ specparam ts_p = 5.0; specparam th_p = 0; specparam ts_pe = 12.0; specparam th_pe = 0; specparam ts_ce = 9.0; specparam th_ce = 0; specparam tw_cp_h = 5.0; specparam tw_cp_l = 5.0; specparam tw_mr_l = 10.0; specparam trec_mr = 6.0; $setup(p0, posedge cp, ts_p); $setup(p1, posedge cp, ts_p); $setup(p2, posedge cp, ts_p); $setup(p3, posedge cp, ts_p); $hold(posedge cp, p0, th_p); $hold(posedge cp, p1, th_p); $hold(posedge cp, p2, th_p); $hold(posedge cp, p3, th_p); $setup(pe_n, posedge cp, ts_pe); $hold(posedge cp, pe_n, th_pe); $setup(cep, posedge cp, ts_ce); $setup(cet, posedge cp, ts_ce); $hold(posedge cp, cep, th_ce); $hold(posedge cp, cet, th_ce); $width(posedge cp, tw_cp_h); $width(negedge cp, tw_cp_l); $width(negedge mr_n, tw_mr_l); $recovery(posedge mr_n, posedge cp, trec_mr); `endif endspecify endmodule