VHDL Clock Divider – Design and Implementation Guide
vhdl
I dont really understand the below code, for rising edge of the clock a divider of 4 bits will be incremented, so:
0000 -> 0001 -> 0010 -> 0011
For each rising edge of the clock?
What is div(2)?
Best Answer
If you run a simple simulation (which you will need to learn how to do if you're going to be working with VHDL) you'll see that div only updates on the rising edge of the clock. This means that div(0) is 1/2 the clock rate, div(1) is 1/4 the clock rate, and div(2) is 1/8 the clock rate.
Normally, I'm not in the habit of posting code, but the testbench for simulating this is so trivial I might as well. Note: I've replaced the std_logic_vector type on cnt and div with an unsigned type since addition of std_logic_vectors uses non-standard libraries (or VHDL2008).
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity clk_div is
end clk_div;
architecture TB of clk_div is
signal clk : std_logic; -- 200MHz clk
signal cnt : unsigned(2 downto 0) := (others => '0');
signal div : unsigned(3 downto 0) := (others => '0');
begin
--create 200MHz clock
process
begin
clk <= '1'; wait for 2.5 ns;
clk <= '0'; wait for 2.5 ns;
end process;
process(clk)
begin
if rising_edge(clk) then
div <= div + 1;
end if;
end process;
process(div(2))
begin
if rising_edge(div(2)) then
cnt <= cnt + 1;
end if;
end process;
end TB;
Xilinx UCF is a constraints file format. It is used to apply various constraints on the design to the Xilinx tools, including but not limited to pin locations, timing, and area. When mapping your RTL (VHDL) design to a physical device, you will minimally need clocks and pin constraints at the top level, but constraints for real designs can go much further than this. Xilinx has a User Constraints Guide on this subject.
You can use the system clock if it meets your needs. Very often, real designs require clocks at a specific (lower) frequency, or multiple clocks at different frequencies, which is where clock dividers would be used.
A gentle dead tree introduction to VHDL programming for Xilinx I can recommend is this book. I recommended a book, since I have not found online HDL tutorials nearly as concise or complete as those for software. You should also scour Xilinx's online documentation for their tools and the part(s) you're using.
First of all, both doubts (1) & (2) which is actually asking same question
(1) The addition of the program counter is only done at the next clock event [i.e. here it's falling edge], rather than immediately after PCNext has been output.
(2) Do you see how PCNext is only calculated at the falling edge of the clock? Why isn't it calculated immediately after PC <= PCNext?]
Answer: It is because the signal PC is not present in the sensitivity list. As shown in simulation below when I add it in sensitivity list the addition takes place immediately because PCNext <= std_logic_vector(unsigned(PC) + 4); executed concurrently as change on signal PC in sensitivity list invokes process again.
Earlier in your case immediate assignment was no happening till next clock event (which is falling edge of clock present in sensitivity list).
I hope now you will actually understand the sensitivity list and be more careful about it next time.
One more thing you can do is that declare signal PC as variable PC and use blocking assignment := this will also update addition result immediately and also you can learn more about the difference between blocking assignment and Non-blocking assignment.
edit: As Dave Tweed already said to move the statement PCNext <= std_logic_vector(unsigned(PC) + 4); outside the process block altogether will also work.
Best Answer
If you run a simple simulation (which you will need to learn how to do if you're going to be working with VHDL) you'll see that div only updates on the rising edge of the clock. This means that div(0) is 1/2 the clock rate, div(1) is 1/4 the clock rate, and div(2) is 1/8 the clock rate.
Normally, I'm not in the habit of posting code, but the testbench for simulating this is so trivial I might as well. Note: I've replaced the std_logic_vector type on cnt and div with an unsigned type since addition of std_logic_vectors uses non-standard libraries (or VHDL2008).