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.