My vhdl code for the d-type flipflop with asynchronous reset and synchronous enable is shown below but there are other ways of implementing this.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ckt_dFF is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
loadEn : in STD_LOGIC;
D_in : in STD_LOGIC;
D_out : out STD_LOGIC);
end ckt_dFF;
architecture Behavioral of ckt_dFF is
begin
process (rst, clk)
begin
if rst = '1' then
D_out <= '0';
elsif clk'event and clk = '1' then
if loadEn = '1' then
D_out <= D_in; end if;
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------------
THE LIBRARY:
It is a must for me to include the library ieee. The package std_logic_1164 identifies multilevel logic, std_logic_arith for unsigned and signed data types, also for comparison and arithmetic computations. It is also used to enable data type conversion (from logic vector to integer for instance). std_logic_unsigned enables operations on std_logic_vector data types, treating them as unsigned.
Some of these packages are not needed for the particular code above. However, as placed there by default, I just leave them there.
THE ENTITY
The entity declaration contains the entity name and the interface for your circuit; that is, the input and output ports. An entity in vhdl is very much like a block in the circuit. And so to distinguish that block from the other blocks in the schematic, you give it an <entity_name>. It is followed by the port declaration which list the I/O ports and their respective signal modes and signal types. The entity declaration follows the following structure:
----------------------------------------------------------------------------------
entity entity_name is
Port ( port_name
end entity_name;
----------------------------------------------------------------------------------
One can list the ports in one line so long as their signal modes and signal types are the same.
Please note the placements of semicolons. As you go through vhdl, you will know when to terminate a line with a semicolon and when not to.
Signal Modes
Signal modes can be in, out, inout, or buffer. I dwell mostly on in and out. inout and buffer are bidirectional ports. They sometimes cause data to become unstable so I use 'signals' (more on this later) instead.
Signal Types
Most data types I use on the port declaration are std_logic and std_logic_vector but there are others as well like integer, etc.
From the d-flipflop code, the input ports are 'clk' which represents the clock, 'rst' which is the asynchronous reset, 'loadEn' which is the synchronous enable of the circuit and of course 'D_in' and 'D_out' which are the input and output ports, respectively.
Architecture
The architecture is a representation of how the circuit must behave. It may also contain the contents of the design unit. Just like the entity, it must have a name followed by the entity to which it is attached. The structure is shown below.
----------------------------------------------------------------------------------
architecture
begin
(code)
.
.
.
end ;
----------------------------------------------------------------------------------
From the d-flipflop code, within the architecture body, you can see that when 'rst' is high, the output is D_out is zero. At the rising edge of the clock, implied by the clause clk'event and clk = '1' (which can also be written as rising_edge(clk)), when loadEn is high, whatever is in the input port D_in is passed to the output port D_out.
The rst is asynchronous meaning it is independent of the clock. Whether the clock is high or low, once rst is '1' the output port will have zero as its output. loadEn is dependent on the clock. When loadEn is high at the falling edge of the clock, the circuit will wait for the rising edge of the clock before executing the statement
D_out <= D_in;
Process
VHDL is concurrent meaning statements are executed in parallel. In order to force the code to be sequential, like in the d-FF code where the circuit is clocked, process is used. The process must contain the sensitivity list for which you want your signals to watch out. Whenever there is a change on any of the signals in the sensitivity list, the circuit will execute the process. In the d-FF code, whenever rst and clk changes, the process is carried out. I did not include loadEn in the sensitivity list since it is dependent on the clock clk anyway. Like architecture, the body of the process also enclosed with begin and end. A process can be labeled with any logical name. This is important especially if you have several processes within an architecture. This makes debugging easy.
process_label : process (sensitivity_list)
Simulation results
As shown below, even if loadEn is not included in the sensitivity list as seen on my code, the waves behaved accordingly since it (loadEn) is synchronous. I had set the simulation to run up to 2000 ns. Notice also the lag of D_out with respect to the timing of D_in. This is due to the circuit waiting for the rising edge of the clock clk.
References:
(1) Pedroni, V., Circuit Design with VHDL, The MIT Press, 2004.
(2) Pellerin, D. and Taylor, D., VHDL Made Easy, Prentice Hall PTR, 1996.
Process
VHDL is concurrent meaning statements are executed in parallel. In order to force the code to be sequential, like in the d-FF code where the circuit is clocked, process is used. The process must contain the sensitivity list for which you want your signals to watch out. Whenever there is a change on any of the signals in the sensitivity list, the circuit will execute the process. In the d-FF code, whenever rst and clk changes, the process is carried out. I did not include loadEn in the sensitivity list since it is dependent on the clock clk anyway. Like architecture, the body of the process also enclosed with begin and end. A process can be labeled with any logical name. This is important especially if you have several processes within an architecture. This makes debugging easy.
Simulation results
As shown below, even if loadEn is not included in the sensitivity list as seen on my code, the waves behaved accordingly since it (loadEn) is synchronous. I had set the simulation to run up to 2000 ns. Notice also the lag of D_out with respect to the timing of D_in. This is due to the circuit waiting for the rising edge of the clock clk.
References:
(1) Pedroni, V., Circuit Design with VHDL, The MIT Press, 2004.
(2) Pellerin, D. and Taylor, D., VHDL Made Easy,
No comments:
Post a Comment