Glancing back to the original design we see that the remaining element that we need is a single bit memory to hold the carry out from one stage of addition to become the carry in to the next stage. This seems like a job for a simple D-type flip-flop such as half of a 7474. It is very simple to code the basic D-type latch behavior
module flop(d, clk, q); input d, clk; output q; reg q; wire d, clk; always @(posedge clk); q = d; endmodule // flop |
but we also need to handle asynchronous set and reset inputs that take priority, as can be seen in the truth table for the 7474. I think that we can do this with negative edge triggers on reset and clear, like this.
// dflop74 is a description of one of the two positive-edge // triggered D-type flip-flops from a 7474. These have // asynchronous, negative true, set and reset inputs. // module dflop(d, clk, set, reset, q, qbar); input d, clk, set, reset; output q; reg q; wire d, clk, set, reset; /* reset is asynchronous to clock*/ always @(negedge reset) begin if (set) begin q = 0; qbar = 1; end else begin q = 1; qbar = 1; end end /* set only differs in sign */ always @(negedge set) begin if (reset) begin q = 1; qbar = 0; end else begin q = 1; qbar = 1; end end /* Data are copied on positive clock edge */ always @(posedge clk) begin if (reset & set) begin q = d; qbar = !d; end end endmodule // dflop74 |
The test uses registers for the input and control signals and runs the flip-flop through most of its states.
// Test module for dflop74, one of the flip flops in // a 7474. They have asynchronous set and reset // inputs and transfer the data to q on the positive // edge of the clock. // module test; reg setbar = 1; reg clrbar = 1; reg in = 0; reg clock = 0; /* Reset at time 8 for 4 then at time 20 for 10 */ initial begin # 8 clrbar = 0; # 4 clrbar = 1; # 8 clrbar = 2; # 10 clrbar = 3; # 60 $stop; end /* Set at time 14 for 2 then at time 24 for 10 */ initial begin # 14 setbar = 0; # 2 setbar = 1; # 8 setbar = 2; # 10 setbar = 3; end /* Raise d early then lower while in reset then set */ initial begin # 1 in = 1; # 21 in = 0; # 15 in = 1; # 10 in = 0; end /* Make a regular pulsing clock. */ always #5 clock = !clock; wire q, qbar; dflop74 f1(in, clock, setbar, clrbar, q, qbar); initial $monitor("At time %t, in = %d, q = %d, qbar=%d", $time, in, q, qbar); initial begin $dumpfile("test74.vcd"); $dumpvars(0,test); end endmodule // test |
We see that the output changes exactly as it should.
NOTE the GtkWave naturally orders the signal alphabetically but you can slide them around in the Signals window to re-order them.