Task: Designing a 8-bit downcounter which takes an initial input value and start the downcount, and when count becomes 8'b0000_0000, it should automatically set to input value.
Ex: If given input is 8'b10010100, counter should start counting down, when value reaches 8'00000000, it should automatically reset to 8'b10010100, and again start downcount repeatedly. For this had written a modified D flip flop using behavioral method, which works as follows: When ld=0, output of d-flip flop q=d1 and q_bar=~d1 and when ld=1, q=d2 and q_bar=~d2 Here d2 stores the initial input values, and ld is being used as switch, i.e. when q=8'b00000000, ld=1 and sets counter output q=d2 and next cycle, ld=0 and takes d1 value.
Modified D-flip flop
module modified_d_flip_flop(q,q_bar,d1,d2,clk,ld
);
input d1,d2,clk,ld;
output q,q_bar;
reg q,q_bar;
always @(posedge clk)
begin
if(ld==0)
begin
q<=d1;
q_bar<=~d1;
end
else if(ld==1)
begin
q<=d2;
q_bar<=~d2;
end
else
begin
q<=q;
q_bar<=q_bar;
end
end
endmodule
Down Counter:
module down_counter(
input [7:0] d,
input clk,
input ld,
output [7:0] q,
output [7:0] q_bar
);
modified_d_flip_flop m_dff1 (.q(q[0]), .q_bar(q_bar[0]), .d1(q_bar[0]), .d2(d[0]), .clk(clk), .ld(ld));
modified_d_flip_flop m_dff2 (.q(q[1]), .q_bar(q_bar[1]), .d1(q_bar[1]), .d2(d[1]), .clk(q[0]), .ld(ld));
modified_d_flip_flop m_dff3 (.q(q[2]), .q_bar(q_bar[2]), .d1(q_bar[2]), .d2(d[2]), .clk(q[1]), .ld(ld));
modified_d_flip_flop m_dff4 (.q(q[3]), .q_bar(q_bar[3]), .d1(q_bar[3]), .d2(d[3]), .clk(q[2]), .ld(ld));
modified_d_flip_flop m_dff5 (.q(q[4]), .q_bar(q_bar[4]), .d1(q_bar[4]), .d2(d[4]), .clk(q[3]), .ld(ld));
modified_d_flip_flop m_dff6 (.q(q[5]), .q_bar(q_bar[5]), .d1(q_bar[5]), .d2(d[5]), .clk(q[4]), .ld(ld));
modified_d_flip_flop m_dff7 (.q(q[6]), .q_bar(q_bar[6]), .d1(q_bar[6]), .d2(d[6]), .clk(q[5]), .ld(ld));
modified_d_flip_flop m_dff8 (.q(q[7]), .q_bar(q_bar[7]), .d1(q_bar[7]), .d2(d[7]), .clk(q[6]), .ld(ld));
endmodule
Down counter Test Bench
module down_counter_tb;
reg [7:0] d;
reg clk;
reg ld;
wire [7:0] q;
wire [7:0] q_bar;
down_counter uut (
.d(d),
.clk(clk),
.ld(ld),
.q(q),
.q_bar(q_bar)
);
always #5 clk = ~clk;
initial begin
clk = 1;
ld = 1;
d = 8'b00000111;
end
initial begin
#20 ld = 0;
#20 ld = 1;
#30 ld = 0;
end
endmodule
Issue: If initial input i.e. d2=8'b11111111, then i am getting the downcounter it works properly for the above code, But if i give some thing like d2=8'10010011, then counter starts from 011, 010, 001 and 111, 110, 101, ........ it counts only the number of high bits from lsb 1, if 0 is encountered next values till msb becomes x.