From 1a34abcca63c34b4d0a9a2bb6dddfcf858d318fa Mon Sep 17 00:00:00 2001 From: TimRudy <3942818+TimRudy@users.noreply.github.com> Date: Sun, 19 Jan 2020 21:31:42 -0500 Subject: [PATCH] More initial - Add generate block labels (~/pull/4) - Fix yosys/Icestudio synthesis error - Add tests related to asynchronous/synchronous set and clear --- includes/helper.v | 4 +- source-7400/74112-tb.v | 193 ++++++++++++++++++++++++++++++++--------- source-7400/74112.v | 26 +++--- source-7400/7473-tb.v | 27 +++--- source-7400/7473.v | 15 ++-- source-7400/7474-tb.v | 164 +++++++++++++++++++++++++++------- source-7400/7474.v | 14 +-- 7 files changed, 322 insertions(+), 121 deletions(-) diff --git a/includes/helper.v b/includes/helper.v index b665e10..ed17016 100644 --- a/includes/helper.v +++ b/includes/helper.v @@ -1,3 +1,3 @@ -`define ASSIGN_UNPACK_ARRAY(PK_LEN, PK_WIDTH, UNPK_DEST, PK_SRC) wire [PK_LEN*PK_WIDTH-1:0] PK_IN_BUS; assign PK_IN_BUS=PK_SRC; genvar unpk_idx; generate for (unpk_idx=0; unpk_idx output 111 + // load second and third blocks, toggle first block, apply clock edge in + // first and second blocks -> output 111 Clk = 3'b100; #7 tbassert(Q == 3'b111, "Test 21"); @@ -272,8 +272,8 @@ begin tbassert(Q == 3'b111, "Test 22"); tbassert(Q_bar == 3'b000, "Test 22"); #0 - // load second and third blocks, toggle first block, apply clock edge in first and - // second blocks -> output 110 + // load second and third blocks, toggle first block, apply clock edge in + // first and second blocks -> output 110 // J = 3'b011; // K = 3'b101; #15 @@ -354,13 +354,13 @@ begin // the following set of tests are for: clear - // clear from 101, not enough time for output to fall/rise + // asynchronous clear from 101, not enough time for output to fall/rise Clear_bar = 3'b000; #2 tbassert(Q == 3'b101, "Test 31"); tbassert(Q_bar == 3'b010, "Test 31"); #5 - // clear from 101 -> output 0s + // asynchronous clear from 101 -> output 0s tbassert(Q == 3'b000, "Test 31"); tbassert(Q_bar == 3'b111, "Test 31"); #150 @@ -385,18 +385,20 @@ begin J = 3'b111; K = 3'b111; #15 - // clear from 011 in contention with toggle (at clock edge in second and third blocks) + // asynchronous clear from 011 in contention with toggle (at clock edge in + // second and third blocks) Clear_bar = 3'b000; Clk = 3'b001; #2 tbassert(Q == 3'b011, "Test 33"); tbassert(Q_bar == 3'b100, "Test 33"); #5 - // clear from 011 in contention with toggle -> output 0s + // asynchronous clear from 011 in contention with toggle -> output 0s tbassert(Q == 3'b000, "Test 33"); tbassert(Q_bar == 3'b111, "Test 33"); #10 - // clear from 011, apply clock edge in first block separately with null effect on output + // asynchronous clear from 011, apply clock edge in first block separately with null effect on + // output Clk[0] = 1'b0; #7 tbassert(Q == 3'b000, "Test 33"); @@ -466,7 +468,7 @@ begin J = 3'b110; K = 3'b101; #40 - // clear from 011 in contention with load and toggle (at clock edge in + // asynchronous clear from 011 in contention with load and toggle (at clock edge in // second and third blocks) Clear_bar = 3'b000; Clk = 3'b001; @@ -474,11 +476,12 @@ begin tbassert(Q == 3'b011, "Test 36"); tbassert(Q_bar == 3'b100, "Test 36"); #5 - // clear from 011 in contention with load and toggle -> output 0s + // asynchronous clear from 011 in contention with load and toggle -> output 0s tbassert(Q == 3'b000, "Test 36"); tbassert(Q_bar == 3'b111, "Test 36"); #10 - // clear from 011, apply clock edge in first block separately with null effect on output + // asynchronous clear from 011, apply clock edge in first block separately with null effect on + // output Clk[0] = 1'b0; #7 tbassert(Q == 3'b000, "Test 37"); @@ -523,7 +526,7 @@ begin tbassert(Q == 3'b111, "Test 39"); tbassert(Q_bar == 3'b000, "Test 39"); #150 - // hold state -> remains preset after preset signal ends + // hold state -> remains set after preset signal ends Preset_bar = 3'b111; #120 tbassert(Q == 3'b111, "Test 40"); @@ -544,7 +547,8 @@ begin J = 3'b111; K = 3'b111; #15 - // preset from 011 in contention with toggle (at clock edge in second and third blocks) + // preset from 011 in contention with toggle (at clock edge in + // second and third blocks) Preset_bar = 3'b000; Clk = 3'b001; #2 @@ -555,13 +559,13 @@ begin tbassert(Q == 3'b111, "Test 41"); tbassert(Q_bar == 3'b000, "Test 41"); #10 - // preset from 011, apply clock edge in first block separately with null effect on output + // preset, apply clock edge in first block separately with null effect on output Clk[0] = 1'b0; #7 tbassert(Q == 3'b111, "Test 41"); tbassert(Q_bar == 3'b000, "Test 41"); #150 - // hold state, second block -> remains preset after preset signal ends + // hold state, second block -> remains set after preset signal ends Preset_bar[1] = 1'b1; #20 tbassert(Q == 3'b111, "Test 42"); @@ -599,7 +603,7 @@ begin tbassert(Q_bar == 3'b110, "Test 43"); #0 // set up different data input values - J = 3'b110; + J = 3'b010; K = 3'b011; #15 // preset third block separately -> output 101 @@ -623,7 +627,7 @@ begin #0 // set up different data input values, load and toggle J = 3'b110; - K = 3'b101; + K = 3'b011; #40 // preset from 010 in contention with load and toggle (at clock edge in // second and third blocks) @@ -643,7 +647,7 @@ begin tbassert(Q == 3'b111, "Test 45"); tbassert(Q_bar == 3'b000, "Test 45"); #70 - // hold state, second block -> remains preset after preset signal ends + // hold state, second block -> remains set after preset signal ends Preset_bar[1] = 1'b1; #20 tbassert(Q == 3'b111, "Test 46"); @@ -667,8 +671,111 @@ begin tbassert(Q == 3'b111, "Test 46"); tbassert(Q_bar == 3'b000, "Test 46"); #0 - Clk[1] = 1'b1; -#50 + Clk = 3'b111; +#15 + + // the following set of tests are for: preset and clear in combination + + // after preset in contention with asynchronous clear, extra preset does not spuriously occur + Preset_bar = 3'b000; +#25 + // clear first and third blocks with clock high -> output 010 + Clear_bar = 3'b010; +#7 + tbassert(Q == 3'b010, "Test 47"); + tbassert(Q_bar == 3'b101, "Test 47"); +#15 + Clear_bar = 3'b111; +#25 + // preset signal ends with null effect on output + Preset_bar = 3'b111; +#15 + tbassert(Q == 3'b010, "Test 47"); + tbassert(Q_bar == 3'b101, "Test 47"); +#0 + J = 3'b010; + K = 3'b101; +#15 + // apply clock pulses with null effect on output + Clk = 3'b001; +#15 + Clk = 3'b111; +#15 + Clk = 3'b010; +#15 + Clk = 3'b111; +#15 + Clk = 3'b000; +#15 + tbassert(Q == 3'b010, "Test 47"); + tbassert(Q_bar == 3'b101, "Test 47"); +#0 + // clear with clock low -> output 0s + Clear_bar = 3'b000; +#10 + tbassert(Q == 3'b000, "Test 48"); + tbassert(Q_bar == 3'b111, "Test 48"); +#20 + Clear_bar = 3'b111; +#10 + Clk = 3'b111; +#20 + // clear with clock transition to low -> output 0s + Clear_bar = 3'b000; +#10 + Clk = 3'b000; +#20 + Clear_bar = 3'b111; +#15 + Clk = 3'b111; +#7 + tbassert(Q == 3'b000, "Test 49"); + tbassert(Q_bar == 3'b111, "Test 49"); +#0 + // set up different data input values + J = 3'b011; + K = 3'b101; +#15 + // after preset then asynchronous clear, extra preset does not spuriously occur + Preset_bar = 3'b000; +#25 + Preset_bar = 3'b111; +#7 + Clk = 3'b000; +#7 + // clear first and third blocks with clock low -> output 010 + Clear_bar = 3'b010; +#7 + tbassert(Q == 3'b010, "Test 50"); + tbassert(Q_bar == 3'b101, "Test 50"); +#15 + Clear_bar = 3'b111; +#25 + Clk = 3'b111; +#15 + // apply clock edge -> output 011 + Clk = 3'b000; +#7 + tbassert(Q == 3'b011, "Test 51"); + tbassert(Q_bar == 3'b100, "Test 51"); +#15 + Clk = 3'b111; +#0 + J = 3'b011; + K = 3'b100; +#15 + // apply clock pulses with null effect on output + Clk = 3'b001; +#15 + Clk = 3'b111; +#15 + Clk = 3'b000; +#15 + Clk = 3'b111; +#15 + tbassert(Q == 3'b011, "Test 51"); + tbassert(Q_bar == 3'b100, "Test 51"); +#0 // the following set of tests are for: hold state and applying clock edge in // each block separately @@ -681,8 +788,8 @@ begin #15 Clk = 3'b111; #15 - tbassert(Q == 3'b101, "Test 47"); - tbassert(Q_bar == 3'b010, "Test 47"); + tbassert(Q == 3'b101, "Test 52"); + tbassert(Q_bar == 3'b010, "Test 52"); #0 // hold state (clocked) with null effect on output 101 J = 3'b000; @@ -692,8 +799,8 @@ begin #25 Clk = 3'b111; #15 - tbassert(Q == 3'b101, "Test 47"); - tbassert(Q_bar == 3'b010, "Test 47"); + tbassert(Q == 3'b101, "Test 52"); + tbassert(Q_bar == 3'b010, "Test 52"); #0 // load same value appearing at the output with null effect on output 101 J = 3'b101; @@ -702,14 +809,14 @@ begin // apply clock edge in third block separately Clk = 3'b011; #20 - tbassert(Q == 3'b101, "Test 48"); - tbassert(Q_bar == 3'b010, "Test 48"); + tbassert(Q == 3'b101, "Test 53"); + tbassert(Q_bar == 3'b010, "Test 53"); #0 // apply clock edge in first and second blocks separately Clk = 3'b000; #20 - tbassert(Q == 3'b101, "Test 48"); - tbassert(Q_bar == 3'b010, "Test 48"); + tbassert(Q == 3'b101, "Test 53"); + tbassert(Q_bar == 3'b010, "Test 53"); #0 Clk = 3'b111; #15 @@ -719,8 +826,8 @@ begin J = 3'b011; K = 3'b101; #75 - tbassert(Q == 3'b101, "Test 49"); - tbassert(Q_bar == 3'b010, "Test 49"); + tbassert(Q == 3'b101, "Test 54"); + tbassert(Q_bar == 3'b010, "Test 54"); #0 Clk = 3'b111; #25 @@ -728,8 +835,8 @@ begin J = 3'bzz0; K = 3'bz01; #50 - tbassert(Q == 3'b101, "Test 49"); - tbassert(Q_bar == 3'b010, "Test 49"); + tbassert(Q == 3'b101, "Test 54"); + tbassert(Q_bar == 3'b010, "Test 54"); #0 // load new value in first block separately J = 3'bz10; @@ -739,8 +846,8 @@ begin #15 Clk = 3'b111; #15 - tbassert(Q == 3'b100, "Test 50"); - tbassert(Q_bar == 3'b011, "Test 50"); + tbassert(Q == 3'b100, "Test 55"); + tbassert(Q_bar == 3'b011, "Test 55"); #0 // load same value appearing at the output with null effect on output J = 3'b100; @@ -749,14 +856,14 @@ begin // apply clock edge in first block separately Clk = 3'b110; #20 - tbassert(Q == 3'b100, "Test 51"); - tbassert(Q_bar == 3'b011, "Test 51"); + tbassert(Q == 3'b100, "Test 56"); + tbassert(Q_bar == 3'b011, "Test 56"); #0 // apply clock edge in second and third blocks, end clock pulse in first block Clk = 3'b001; #40 - tbassert(Q == 3'b100, "Test 52"); - tbassert(Q_bar == 3'b011, "Test 52"); + tbassert(Q == 3'b100, "Test 57"); + tbassert(Q_bar == 3'b011, "Test 57"); #0 Clk = 3'b111; #15 @@ -768,8 +875,8 @@ begin #15 Clk = 3'b111; #15 - tbassert(Q == 3'b100, "Test 53"); - tbassert(Q_bar == 3'b011, "Test 53"); + tbassert(Q == 3'b100, "Test 58"); + tbassert(Q_bar == 3'b011, "Test 58"); #0 // toggle value in first block separately // J = 3'b011; @@ -779,8 +886,8 @@ begin #15 Clk = 3'b111; #15 - tbassert(Q == 3'b101, "Test 54"); - tbassert(Q_bar == 3'b010, "Test 54"); + tbassert(Q == 3'b101, "Test 59"); + tbassert(Q_bar == 3'b010, "Test 59"); #50 $finish; end diff --git a/source-7400/74112.v b/source-7400/74112.v index 15952db..68ebf58 100644 --- a/source-7400/74112.v +++ b/source-7400/74112.v @@ -13,31 +13,25 @@ module ttl_74112 #(parameter BLOCKS = 2, DELAY_RISE = 0, DELAY_FALL = 0) //------------------------------------------------// reg [BLOCKS-1:0] Q_current; -wire [BLOCKS-1:0] Q_next; -genvar i; - -assign Q_next = Q_current; generate + genvar i; for (i = 0; i < BLOCKS; i = i + 1) - begin - always @(negedge Clk[i] or negedge Preset_bar[i] or negedge Clear_bar[i]) + begin: gen_blocks + always @(negedge Clk[i] or negedge Clear_bar[i] or negedge Preset_bar[i]) begin - if (!Preset_bar[i] || !Clear_bar[i]) - begin - if (!Preset_bar[i]) - Q_current[i] <= 1'b1; - else - Q_current[i] <= 1'b0; - end - else if (!Clk[i]) + if (!Clear_bar[i]) + Q_current[i] <= 1'b0; + else if (!Preset_bar[i]) + Q_current[i] <= 1'b1; + else begin if (J[i] && !K[i] || !J[i] && K[i]) Q_current[i] <= J[i]; else if (J[i] && K[i]) - Q_current[i] <= !Q_next[i]; + Q_current[i] <= !Q_current[i]; else - Q_current[i] <= Q_next[i]; + Q_current[i] <= Q_current[i]; end end end diff --git a/source-7400/7473-tb.v b/source-7400/7473-tb.v index 86c2184..d245a58 100644 --- a/source-7400/7473-tb.v +++ b/source-7400/7473-tb.v @@ -256,8 +256,8 @@ begin J = 3'b011; K = 3'b101; #15 - // load second and third blocks, toggle first block, apply clock edge in first and - // second blocks -> output 111 + // load second and third blocks, toggle first block, apply clock edge in + // first and second blocks -> output 111 Clk = 3'b100; #7 tbassert(Q == 3'b111, "Test 21"); @@ -269,8 +269,8 @@ begin tbassert(Q == 3'b111, "Test 22"); tbassert(Q_bar == 3'b000, "Test 22"); #0 - // load second and third blocks, toggle first block, apply clock edge in first and - // second blocks -> output 110 + // load second and third blocks, toggle first block, apply clock edge in + // first and second blocks -> output 110 // J = 3'b011; // K = 3'b101; #15 @@ -351,13 +351,13 @@ begin // the following set of tests are for: clear - // clear from 101, not enough time for output to fall/rise + // asynchronous clear from 101, not enough time for output to fall/rise Clear_bar = 3'b000; #2 tbassert(Q == 3'b101, "Test 31"); tbassert(Q_bar == 3'b010, "Test 31"); #5 - // clear from 101 -> output 0s + // asynchronous clear from 101 -> output 0s tbassert(Q == 3'b000, "Test 31"); tbassert(Q_bar == 3'b111, "Test 31"); #150 @@ -382,18 +382,20 @@ begin J = 3'b111; K = 3'b111; #15 - // clear from 011 in contention with toggle (at clock edge in second and third blocks) + // asynchronous clear from 011 in contention with toggle (at clock edge in + // second and third blocks) Clear_bar = 3'b000; Clk = 3'b001; #2 tbassert(Q == 3'b011, "Test 33"); tbassert(Q_bar == 3'b100, "Test 33"); #5 - // clear from 011 in contention with toggle -> output 0s + // asynchronous clear from 011 in contention with toggle -> output 0s tbassert(Q == 3'b000, "Test 33"); tbassert(Q_bar == 3'b111, "Test 33"); #10 - // clear from 011, apply clock edge in first block separately with null effect on output + // asynchronous clear from 011, apply clock edge in first block separately with null effect on + // output Clk[0] = 1'b0; #7 tbassert(Q == 3'b000, "Test 33"); @@ -463,7 +465,7 @@ begin J = 3'b110; K = 3'b101; #40 - // clear from 011 in contention with load and toggle (at clock edge in + // asynchronous clear from 011 in contention with load and toggle (at clock edge in // second and third blocks) Clear_bar = 3'b000; Clk = 3'b001; @@ -471,11 +473,12 @@ begin tbassert(Q == 3'b011, "Test 36"); tbassert(Q_bar == 3'b100, "Test 36"); #5 - // clear from 011 in contention with load and toggle -> output 0s + // asynchronous clear from 011 in contention with load and toggle -> output 0s tbassert(Q == 3'b000, "Test 36"); tbassert(Q_bar == 3'b111, "Test 36"); #10 - // clear from 011, apply clock edge in first block separately with null effect on output + // asynchronous clear from 011, apply clock edge in first block separately with null effect on + // output Clk[0] = 1'b0; #7 tbassert(Q == 3'b000, "Test 37"); diff --git a/source-7400/7473.v b/source-7400/7473.v index 2fe3203..0d96be1 100644 --- a/source-7400/7473.v +++ b/source-7400/7473.v @@ -12,28 +12,23 @@ module ttl_7473 #(parameter BLOCKS = 2, DELAY_RISE = 0, DELAY_FALL = 0) //------------------------------------------------// reg [BLOCKS-1:0] Q_current; -wire [BLOCKS-1:0] Q_next; -genvar i; - -assign Q_next = Q_current; generate + genvar i; for (i = 0; i < BLOCKS; i = i + 1) - begin + begin: gen_blocks always @(negedge Clk[i] or negedge Clear_bar[i]) begin if (!Clear_bar[i]) - begin Q_current[i] <= 1'b0; - end - else if (!Clk[i]) + else begin if (J[i] && !K[i] || !J[i] && K[i]) Q_current[i] <= J[i]; else if (J[i] && K[i]) - Q_current[i] <= !Q_next[i]; + Q_current[i] <= !Q_current[i]; else - Q_current[i] <= Q_next[i]; + Q_current[i] <= Q_current[i]; end end end diff --git a/source-7400/7474-tb.v b/source-7400/7474-tb.v index efdcbbb..b3a2625 100644 --- a/source-7400/7474-tb.v +++ b/source-7400/7474-tb.v @@ -142,13 +142,13 @@ begin // the following set of tests are for: clear - // clear from 010, not enough time for output to fall/rise + // asynchronous clear from 010, not enough time for output to fall/rise Clear_bar = 3'b000; #2 tbassert(Q == 3'b010, "Test 9"); tbassert(Q_bar == 3'b101, "Test 9"); #5 - // clear from 010 -> output 0s + // asynchronous clear from 010 -> output 0s tbassert(Q == 3'b000, "Test 9"); tbassert(Q_bar == 3'b111, "Test 9"); #150 @@ -171,18 +171,20 @@ begin // set up different data input value D = 3'b010; #15 - // clear from 011 in contention with load (at clock edge in second and third blocks) + // asynchronous clear from 011 in contention with load (at clock edge in + // second and third blocks) Clear_bar = 3'b000; Clk = 3'b110; #2 tbassert(Q == 3'b011, "Test 11"); tbassert(Q_bar == 3'b100, "Test 11"); #5 - // clear from 011 in contention with load -> output 0s + // asynchronous clear from 011 in contention with load -> output 0s tbassert(Q == 3'b000, "Test 11"); tbassert(Q_bar == 3'b111, "Test 11"); #10 - // clear from 011, apply clock edge in first block separately with null effect on output + // asynchronous clear from 011, apply clock edge in first block separately with null effect on + // output Clk[0] = 1'b1; #7 tbassert(Q == 3'b000, "Test 11"); @@ -264,6 +266,8 @@ begin tbassert(Q == 3'b100, "Test 14"); tbassert(Q_bar == 3'b011, "Test 14"); #0 + Clk[1] = 1'b0; +#0 // the following set of tests are for: clear from initial state @@ -271,7 +275,7 @@ begin D = 3'bxxx; #15 // load to initial state - Clk = 3'b000; + // Clk = 3'b000; #15 Clk = 3'b111; #15 @@ -283,13 +287,13 @@ begin Clear_bar = 3'bxxx; Clk = 3'bxxx; #15 - // clear from initial state, not enough time for output to fall/rise + // asynchronous clear from initial state, not enough time for output to fall/rise Clear_bar = 3'b000; #2 tbassert(Q === 3'bxxx, "Test 15"); tbassert(Q_bar === 3'bxxx, "Test 15"); #5 - // clear from initial state -> output 0s + // asynchronous clear from initial state -> output 0s tbassert(Q == 3'b000, "Test 15"); tbassert(Q_bar == 3'b111, "Test 15"); #75 @@ -332,7 +336,7 @@ begin tbassert(Q == 3'b000, "Test 16"); tbassert(Q_bar == 3'b111, "Test 16"); #0 - // hold state, end clock pulses in each block + // hold state, end clock pulse in each block Clk[0] = 1'b0; #7 tbassert(Q == 3'b000, "Test 16"); @@ -347,7 +351,7 @@ begin D = 3'bxxx; #15 // load to initial state - Clk = 3'b000; + // Clk = 3'b000; #15 Clk = 3'b111; #15 @@ -369,7 +373,7 @@ begin tbassert(Q == 3'b111, "Test 17"); tbassert(Q_bar == 3'b000, "Test 17"); #75 - // hold state -> remains preset after preset signal ends + // hold state -> remains set after preset signal ends Preset_bar = 3'b111; #80 tbassert(Q == 3'b111, "Test 18"); @@ -403,7 +407,7 @@ begin // hold state, the clear input takes on a value Clear_bar = 3'b111; #0 - // hold state, end clock pulses in each block + // hold state, end clock pulse in each block Clk[0] = 1'b0; Clk[1] = 1'b0; #7 @@ -442,16 +446,114 @@ begin tbassert(Q == 3'b100, "Test 20"); tbassert(Q_bar == 3'b011, "Test 20"); #5 - // preset first and second blocks separately in contention with load -> output 1s + // preset first and second blocks separately in contention with load (at clock edge in + // first and second blocks) -> output 1s tbassert(Q == 3'b111, "Test 20"); tbassert(Q_bar == 3'b000, "Test 20"); #15 Preset_bar = 3'b111; #25 + Clk = 3'b000; +#15 tbassert(Q == 3'b111, "Test 20"); tbassert(Q_bar == 3'b000, "Test 20"); +#0 + + // the following set of tests are for: preset and clear in combination + + // after preset in contention with asynchronous clear, extra preset does not spuriously occur + Preset_bar = 3'b000; + D = 3'b010; +#25 + // clear first and third blocks with clock low -> output 010 + Clear_bar = 3'b010; +#7 + tbassert(Q == 3'b010, "Test 21"); + tbassert(Q_bar == 3'b101, "Test 21"); +#15 + Clear_bar = 3'b111; +#25 + // preset signal ends with null effect on output + Preset_bar = 3'b111; +#15 + tbassert(Q == 3'b010, "Test 21"); + tbassert(Q_bar == 3'b101, "Test 21"); +#15 + // apply clock pulses with null effect on output + Clk = 3'b110; +#15 + Clk = 3'b000; +#15 + Clk = 3'b101; +#15 + Clk = 3'b000; +#15 + Clk = 3'b111; +#15 + tbassert(Q == 3'b010, "Test 21"); + tbassert(Q_bar == 3'b101, "Test 21"); +#0 + // clear with clock high -> output 0s + Clear_bar = 3'b000; +#10 + tbassert(Q == 3'b000, "Test 22"); + tbassert(Q_bar == 3'b111, "Test 22"); +#20 + Clear_bar = 3'b111; +#10 + Clk = 3'b000; +#20 + // clear with clock transition to high -> output 0s + Clear_bar = 3'b000; +#10 + Clk = 3'b111; +#20 + Clear_bar = 3'b111; +#15 + Clk = 3'b000; +#7 + tbassert(Q == 3'b000, "Test 23"); + tbassert(Q_bar == 3'b111, "Test 23"); +#0 + // set up different data input value + D = 3'b011; +#15 + // after preset then asynchronous clear, extra preset does not spuriously occur + Preset_bar = 3'b000; +#25 + Preset_bar = 3'b111; +#7 + Clk = 3'b111; +#7 + // clear first and third blocks with clock high -> output 010 + Clear_bar = 3'b010; +#7 + tbassert(Q == 3'b010, "Test 24"); + tbassert(Q_bar == 3'b101, "Test 24"); +#15 + Clear_bar = 3'b111; +#25 + Clk = 3'b000; +#15 + // apply clock edge -> output 011 + Clk = 3'b111; +#7 + tbassert(Q == 3'b011, "Test 25"); + tbassert(Q_bar == 3'b100, "Test 25"); #15 Clk = 3'b000; +#15 + // apply clock pulses with null effect on output + Clk = 3'b110; +#15 + Clk = 3'b000; +#15 + Clk = 3'b111; +#15 + Clk = 3'b000; +#15 + tbassert(Q == 3'b011, "Test 25"); + tbassert(Q_bar == 3'b100, "Test 25"); #0 // the following set of tests are for: hold state and applying clock edge in @@ -464,8 +566,8 @@ begin #15 Clk = 3'b000; #15 - tbassert(Q == 3'b101, "Test 21"); - tbassert(Q_bar == 3'b010, "Test 21"); + tbassert(Q == 3'b101, "Test 26"); + tbassert(Q_bar == 3'b010, "Test 26"); #0 // load same value appearing at the output with null effect on output 101 // D = 3'b101; @@ -473,20 +575,20 @@ begin // apply clock edge in third block separately Clk = 3'b100; #20 - tbassert(Q == 3'b101, "Test 21"); - tbassert(Q_bar == 3'b010, "Test 21"); + tbassert(Q == 3'b101, "Test 26"); + tbassert(Q_bar == 3'b010, "Test 26"); #0 // apply clock edge in second block separately Clk = 3'b110; #20 - tbassert(Q == 3'b101, "Test 21"); - tbassert(Q_bar == 3'b010, "Test 21"); + tbassert(Q == 3'b101, "Test 26"); + tbassert(Q_bar == 3'b010, "Test 26"); #0 // apply clock edge in first block separately Clk = 3'b111; #20 - tbassert(Q == 3'b101, "Test 21"); - tbassert(Q_bar == 3'b010, "Test 21"); + tbassert(Q == 3'b101, "Test 26"); + tbassert(Q_bar == 3'b010, "Test 26"); #0 Clk = 3'b000; #15 @@ -495,16 +597,16 @@ begin #7 D = 3'b011; #75 - tbassert(Q == 3'b101, "Test 22"); - tbassert(Q_bar == 3'b010, "Test 22"); + tbassert(Q == 3'b101, "Test 27"); + tbassert(Q_bar == 3'b010, "Test 27"); #0 Clk = 3'b000; #25 // set up different data input value D = 3'bzz0; #50 - tbassert(Q == 3'b101, "Test 22"); - tbassert(Q_bar == 3'b010, "Test 22"); + tbassert(Q == 3'b101, "Test 27"); + tbassert(Q_bar == 3'b010, "Test 27"); #0 // load new value in first block separately D = 3'bz10; @@ -513,8 +615,8 @@ begin #15 Clk = 3'b000; #15 - tbassert(Q == 3'b100, "Test 23"); - tbassert(Q_bar == 3'b011, "Test 23"); + tbassert(Q == 3'b100, "Test 28"); + tbassert(Q_bar == 3'b011, "Test 28"); #0 // load same value appearing at the output with null effect on output D = 3'b100; @@ -522,14 +624,14 @@ begin // apply clock edge in first block separately Clk = 3'b001; #20 - tbassert(Q == 3'b100, "Test 24"); - tbassert(Q_bar == 3'b011, "Test 24"); + tbassert(Q == 3'b100, "Test 29"); + tbassert(Q_bar == 3'b011, "Test 29"); #0 // apply clock edge in second and third blocks, end clock pulse in first block Clk = 3'b110; #40 - tbassert(Q == 3'b100, "Test 25"); - tbassert(Q_bar == 3'b011, "Test 25"); + tbassert(Q == 3'b100, "Test 30"); + tbassert(Q_bar == 3'b011, "Test 30"); #50 $finish; end diff --git a/source-7400/7474.v b/source-7400/7474.v index 7a197ae..3c40104 100644 --- a/source-7400/7474.v +++ b/source-7400/7474.v @@ -12,18 +12,18 @@ module ttl_7474 #(parameter BLOCKS = 2, DELAY_RISE = 0, DELAY_FALL = 0) //------------------------------------------------// reg [BLOCKS-1:0] Q_current; -genvar i; generate + genvar i; for (i = 0; i < BLOCKS; i = i + 1) - begin - always @(posedge Clk[i] or negedge Preset_bar[i] or negedge Clear_bar[i]) + begin: gen_blocks + always @(posedge Clk[i] or negedge Clear_bar[i] or negedge Preset_bar[i]) begin - if (!Preset_bar[i]) - Q_current[i] <= 1'b1; - else if (!Clear_bar[i]) + if (!Clear_bar[i]) Q_current[i] <= 1'b0; - else if (Clk[i]) + else if (!Preset_bar[i]) + Q_current[i] <= 1'b1; + else Q_current[i] <= D[i]; end end