Parallel load Up Down Counter And Shift Register
Let us understand up-down counter and shift register using one verilog with parallel load capability.
Features:
- 16 bit parallel load
- 16 bit programmable up-down counter
- Synchronous reset
- Programmable left-right shift
SINGNAL NAME IN/OUT DESCRIPTION
Din 16 bit In For parallel load
nReset In Synchronous reset, active low
Clk In Clock
Load In Enables synchronous parallel load
Count In Enables counting
Shift In Enables shift operation
Up In Control for up counting
Dn In Control for down counting
Right In Control for Right shifting
Left In Control for Left shifting
Qout 16 bit Out For parallel readout
Sout-lsb Out Serial out – LSB
Sout-msb Out Serial out - MSB
Verilog Code:-
module counter_shift_reg ( nReset, din, Clk, Load, Count, Shift, Up, Dn, Right, Left, Qout, Sout_lsb, Sout_msb ); input nReset,Clk; input Load, Count, Shift, Up, Dn; input Right, Left; input [15:0] din; output Sout_lsb, Sout_msb; output reg [15:0] Qout; reg [15:0] temp; wire Sout_lsb, Sout_msb; ////16 bit Programable counter always @(posedge Clk) begin if(nReset==1'b0) Qout <= 0; else if(Load) Qout <=din; else if((Count && Up) == 1'b1 ) Qout <= Qout +1; else if((Count && Dn) == 1'b1) Qout <= Qout - 1; else Qout <= Qout; end ///Left shift and Right Shift always @(posedge Clk) begin if(nReset==1'b0) begin temp <= 0; end else if(Load) temp <= din; else if ((Shift && Left)==1'b1) begin temp <= temp<<1; end else if ((Shift && Right) == 1'b1) temp <= temp >> 1; else temp <= temp; end assign Sout_lsb = Right ? temp[0] : 0; assign Sout_msb = Left ? temp[15] : 0; endmodule
Testbench:-
module counter_shift_tb; output reg nReset,Clk; output reg Load,Count,Shift,Up,Dn; output reg Right,Left; output reg [15:0] din; input Sout_lsb,Sout_msb; input [15:0] Qout; counter_shift_reg counter_shift(nReset,din,Clk,Load,Count,Shift,Up,Dn,Right,Left,Qout,Sout_lsb,Sout_msb); initial Clk=1'b0; always #5 Clk = ~Clk; initial begin $monitor($time,"nReset=%b,din=%b,Clk=%b,Load=%b,Count=%b,Shift=%b,Up=%b,Dn=%b,Right=%b,Left=%b,Qout=%b,Sout_lsb=%b,Sout_msb=%b",nReset,din,Clk,Load,Count,Shift,Up,Dn,Right,Left,Qout,Sout_lsb,Sout_msb); nReset=1'b0; #15 nReset=1;Load=1;din=16'b0000000000000001; #30 Load=0;Count=1;Up=1;Dn=0;Shift=0;Right=0;Left=0; #40 Load=1;din=16'b0000000000001111;Up=0;Count=0; #45 Load=0;Count=1;Up=0;Dn=1;Shift=0;Right=0;Left=0; #65 Load=1;din=16'b1000000000001111; #75 Load=0;Shift=1;Right=1;Up=0;Dn=0; #85 Load=1;din=16'b1111000000000001;Right=0; #95 Load=0;Shift=1;Left=1;Up=0;Dn=0; #1000 $finish; end initial begin $dumpfile("counter_shift_tb.vcd"); $dumpvars(0,counter_shift_tb); end endmodule
Please note that we have used $dumpfile and $dumpvars to view vcd file using gtkwave in testbench.Gtkwave is used to view waveform.