Digital clock is a popular assignment topic for students of FPGA courses in universities. What I have shared here is a basic version of a digital clock. The clock will start ticking as soon as the FPGA is programmed with the bit file. There is no option to set the time or pause the clock etc.. But I believe, it is still a great code to learn many important VHDL topics. If you are looking for an advanced digital clock, then check out this digital clock with time setting feature.
What can you learn from this code?
If you are a beginner in VHDL, try to understand the following concepts used in this code.
- How to generate a low frequency clock from a high a frequency clock? For example how can you generate a 1 second clock from a 100 Mhz clock.
- How does nested if else's work in VHDL?
- When does signals get updated with their newly assigned values?
- How to write a testbench for your design?
- How to instantiate a VHDL component with entity instantiation and name association.
- How to use wait for statement in testbenches?
Without further ado, let me share the code for the simple digital clock.
digital_clock.vhd:
-- library declarations library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- entity declaration entity digital_clock is generic (CLOCK_FREQ : integer := 100_000_000); --system clock frequency is customizable via this generic
port (Clk : in std_logic; seconds : out unsigned(5 downto 0); --6 bit seconds output minutes : out unsigned(5 downto 0); --6 bit minutes output hours : out unsigned(4 downto 0) --5 bit hours output ); end digital_clock; architecture Behavioral of digital_clock is -- declaring internal signals signal sec,min,hour : integer range 0 to 60 :=0; signal count : integer :=1; signal clk_1sec : std_logic :='0'; begin --the internal signals are type casted from integer to unsigned type. seconds <= to_unsigned(sec,6); minutes <= to_unsigned(min,6); hours <= to_unsigned(hour,5); --generates a clock of period 1 second and duty cycle 50%. process(Clk) begin if(rising_edge(Clk)) then count <= count+1; if(count = CLOCK_FREQ/2) then --half way across the count, the clock is toggled. clk_1sec <= not clk_1sec; count <=1; end if; end if; end process; --increment and reset seconds, minutes and hours of the digital clock. process(clk_1sec) --period of clk_1sec is 1 second. begin if(rising_edge(clk_1sec)) then sec <= sec+ 1; if(sec = 59) then sec<=0; --seconds is reset to zero after it counts 60 times. min <= min + 1; --min is incremented when seconds count 60 times. if(min = 59) then hour <= hour + 1; --hours is incremented when minutes count 60 times. min <= 0; --minutes is reset to zero after it counts 60 times. if(hour = 23) then hour <= 0; --hours is reset to zero after it counts 24 times. end if; end if; end if; end if; end process; end Behavioral;
I believe that the code is well commented and needs no further explanation. If you dont understand something, feel free to leave a comment.
Remember the following points when using this design.
- Set the generic parameter, CLOCK_FREQ, with the frequency of the clock available in your FPGA.
- There are three unsigned output signals, one each for seconds, minutes and hours. They can be mapped to LED's on the board. If you want to display the values on seven segment displays on board, you would need to do few more steps. Check out this post for the same.
Testbench : tb_digital_clock.vhd
-- library declarations library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --entity for testbench is always empty entity tb_digital_clock is end tb_digital_clock; architecture Behav of tb_digital_clock is --temporary signals, constants etc are declared here constant CLOCK_FREQ : integer := 100_000_000; --Frequency of the system clock. 100 Mhz is 1 followed by 8 zeros. --What does the below constant do? --Inside "System_Clock_Generation" process, we are waiting for 1 ns after incrementing count. --In one second, there are 10^9 "1 nanoseconds". --If the CLOCK_FREQ is high we dont need to wait too long before toggling the Clock signal. --Thats why we are dividing 10^9 by CLOCK_FREQ. constant CLOCK_COUNTS_IN_NS : integer := 1000_000_000/CLOCK_FREQ; --used for creating the clock with any frequency. signal Clock : std_logic := '0'; signal secs : unsigned(5 downto 0); signal mins : unsigned(5 downto 0); signal hrs : unsigned(4 downto 0); signal count : integer := 1; begin --This type of instantiation is known as "entity instantiation with name association" --Instantiating digital clock entity Digi_Clock : entity work.digital_clock --generic map(CLOCK_FREQ => CLOCK_FREQ) -- uncomment this line and comment next line for implementing on fpga. generic map(CLOCK_FREQ => 10) -- comment this line and uncomment above line for implementing on fpga. port map(Clk => Clock, seconds => secs, minutes => mins, hours => hrs); --generates a clock signal of frequency CLOCK_FREQ and duty cycle 50%. System_Clock_Generation : process begin if(count = CLOCK_COUNTS_IN_NS/2) then Clock <= not Clock; --toggle the clock signal after the count variable reaches mid point. count <= 1; else count <= count + 1; end if; wait for 1 ns; --wait for 1 nano second before going through the "process" again. end process; end Behav;
The testbench is well commented as well, so I will spare you from further explanations. The code was simulated using modelsim software. I have shared relevant parts of the simulation waveform below:
Nice code... But I only want to ask one ques, say i have to set clock manually. How will that can be done..
ReplyDeleteawsome! but how will it look like if i want the results to be displayed on the LCD
ReplyDeletei still don't understand how to generate the necessary clock frequency. For 100 MHz clock, why you wait for 'count' till 50000000 instead of 100000000?
ReplyDeletewe are counting for half cycle and changing the value to the high state again
Delete@timmy : look at the code snippet carefully.What we are doing here is that a signal 'clk' is toggled whenever the count reaches 50m(50 million). This means that
ReplyDeleteclk='1' for 50m clock cycles of clk1.
then clk='1' for 50m clock cycles of clk1.and this toggling goes on.
In effect, one clock cycle of clk = 100m clock cycles of clk1.
I hope now you understand.
can u postt the testbench for it?
ReplyDeletehey....how can we adjust the time of this clock?? i mean if we press the BTN1 it should increment or decrement the minutes.....do you have a sample code for this..??
ReplyDeleteHey...do you ppl have a code which can adjust the time of the clock using its different buttons or switches??i mean if switch/button is pressed it increment or decrements the time??kindly help out
ReplyDelete@Uzar : This is the basic code for the clock. I dont have the code for the time setting part.
ReplyDeletehi i wnt vhdl code for interfacing gsm and gpsm modem to fpga
ReplyDeletecan u send me another code for digital clock
ReplyDeletehi can u send me another code for digital clock
ReplyDeletehow to set mode pin in clock using vhdl code?
ReplyDeletecan anyone help to write a vhdl program for analog to digital converter
ReplyDeleteHi. Sorry for this newbie question. Why do you use integer type for sec,min,hour and then convert to std_logic_vector? Why aren´t sec,min,hour declared as std_logic_vector in the beginning?
ReplyDeleteRegards,
Maia
what value i am supposed to give as/ for "clk1"...?? i mean what is input here precisely if i want to see simulation wave-forms for tis program?? ...reply ASAP....im in so hurry....plz....
ReplyDeletehey what as an input i am supposed to put here in "clk1"???...reply ASAP....i want to see simulation waveforms in xilinx and model sim also...plz reply ASAP........
ReplyDeleteplease post code for a Stop Watch, which displays the time in three decimal digits, and counts from 00.0 to 99.9 seconds and wraps around. It contains a synchronous clear signal, clr, which
ReplyDeletereturns the count to 00.0, and an enable signal, go, which enables and suspends the
counting. This design is basically a BCD (binary-coded decimal) counter, which counts
in BCD format. Our Broad has a 100-MHz clock;
Your code doesn't work. The time increments from 22:58:59 to 00:00:00 due to crappy coding.
ReplyDeleteWhat should be input parameters while creating testbench? What should be clock high and low time,input setup time,output valid delay,offset,initial length of testbench in nanoseconds????
ReplyDeleteplz reply asap...coz m not getng op waveform
how will it look like if i want the results to be displayed on the LCD??
ReplyDeletefor that u have to create UCF file for display.and need to refresh the LCD pannel at very low time like 50msec such that it has to keep on updating.
DeleteHey...just for curiosity...I wanted to extend the concept to show date,month and year also....but actly finding some problem with month identification...can anyone help????
ReplyDeletehi
ReplyDeletewhy in vhdl i need to write
if sec = 59 then sec <= 0
while in verilog, to get same result, i need to write
if (sec == 60) begin sec = 0 end
can you give explanation?
hi!
Deletesec, min and hour were declared as signals and not variables. A signal will take a full clock cycle to change and so, the value zero will be passed to sec in the following clock circle where the value was actually supposed to be 60.
Hey anyone know how can we record time ? Does anyone have code for that ?
ReplyDeleteHiii.....plz tell me how to burn this code on fpga
ReplyDeletehello, i want to design a circuit in which 2 counters will count simultaneously such that first counter will count from 0 to 7, after that second counter will count 1, again first counter will count 0 to 7 and second counter will count 2.
ReplyDeleteYou can do it in a very similar way as in this digital clock code. try to understand how this code works and I am sure you can do it yourself. I also help students for a fee in their projects.
DeleteHello, I've some troubles with this code, can U help me pls?
ReplyDeleteParsing architecture of entity .
ERROR:HDLCompiler:841 - "C:\Users\Tom\Desktop\VSB\1. semestr\PHP\projekty\Clock_project\clk.vhd" Line 46: Expecting type std_logic for .
ERROR:HDLCompiler:841 - "C:\Users\Tom\Desktop\VSB\1. semestr\PHP\projekty\Clock_project\clk.vhd" Line 47: Expecting type std_logic for .
ERROR:HDLCompiler:841 - "C:\Users\Tom\Desktop\VSB\1. semestr\PHP\projekty\Clock_project\clk.vhd" Line 48: Expecting type std_logic for .
ERROR:HDLCompiler:854 - "C:\Users\Tom\Desktop\VSB\1. semestr\PHP\projekty\Clock_project\clk.vhd" Line 41: Unit ignored due to previous errors.
VHDL file C:\Users\Tom\Desktop\VSB\1. semestr\PHP\projekty\Clock_project\clk.vhd ignored due to errors
This comment has been removed by the author.
ReplyDeleteHi, can some one send me the block diagram of digital clock. like how can we make it to display it on VGA. I have VGA code and clock code but i dont know how to combine them together.
ReplyDeleteCan you write a code to connect LED Xilinx board , please answer me as soon as you can .thank you
ReplyDeleteHello please can you send test file ??
ReplyDeletelet me ask, how to communicate with real time block in Cylone IV
ReplyDeleteI want vhdl code for generating clock frequency of 26.6Mhz and 16Mhz from 80Mhz frequency
ReplyDeletesee this post: https://vhdlguru.blogspot.com/2013/08/fractional-clock-division-dual-modulus.html
DeleteHow to run this code?
ReplyDeletepost test bench as well for this code
ReplyDelete