In previous posts I showed, how to build OR gate. This was an example of combinational logic. If you look at the code, you will see, that output depends only on present inputs and changes as fast as possible after modifying them. Though you have to know how to build combinational logic and how it works, you won’t create any bigger design only with that. To store data or pipeline the calculations, you have to create synchronous logic, dependent on a clock.
Register. Basic element in FPGA world. Almost every design is built from it. You can create sequential components, pipeline the calculations, detect the edges etc.
Below is presented implementation of a D flip-flop in VHDL:
library ieee; use ieee.std_logic_1164.all; entity dff is port ( clk :in std_logic; d :in std_logic; q :out std_logic ); end dff; architecture dff_rtl of dff is begin reg: process(clk) begin if rising_edge(clk) then q <= d; end if; end process; end dff_rtl;
You can treat it as a box, one compact part of hardware. You can create many processes in an architecture. Process can be connected by signals with other processes or components. Processes in an architecture are executed concurrently, but statements inside a process are executed sequentially. This is why process is useful. There are many constructs which can be placed only inside a process.
[process_label:] process [(sensitivity_list)] declarative_part begin sequential_statement_part end process [process_label];
The process can be divided into three parts:
- sensitivity list – signals in parentheses after word process (separated by commas). The process will be executed only if occurs any event on any signal which is in sensitivity list. In the example, there is only one signal on the list – clk. It means that process will be executed only if the signal clk changes the value.
- declarative part – between sensitivity list and the keyword begin. Here you can declare e.g. local variables, which can’t be seen outside the process.
- sequential statement part – between the keyword begin and end process. All statements in a process are executed sequentially from the first line to the last one. Therefore order of the statements in a process is important.
2. IF statement
It looks more or less like in other languages. The syntax is as following:
if (condition) then sequential_statements elsif (condition) then sequential_statements else sequential_statements end if;
If statement is sequential. It means, that is executed line after line. First condition is checked. If condition is correct, code below this condition is executed, if it is not correct, then checked is next condition.
3. Function rising_edge
One of the basic functions in VHDL. It is mainly used for creating registers.
To test register you have to create testbench file and generate clock signal. Below you can find example.
library ieee; use ieee.std_logic_1164.all; entity tb_dff is end entity; architecture tb_dff_rtl of tb_dff is component dff is port ( clk :in std_logic; d :in std_logic; q :out std_logic ); end component; signal clk :std_logic; signal d :std_logic; signal q :std_logic; constant ClkGenConst :time := 10 ns; begin UUT: dff port map ( clk => clk, d => d, q => q ); ClockGenerator: process begin clk <= '0' after ClkGenConst, '1' after 2*ClkGenConst; wait for 2*ClkGenConst; end process; d <= '1', '0' after 105 ns, '1' after 205 ns; end architecture;
In line 17 clock signal is declared. In line 21 is used constant to store the time value:
constant constant_name : type := value;
Process responsible for generating clock with desired period starts on line 32.
After statement updates the value of the signal after given time.
Wait clause is very useful during testing. It suspends the execution of the process in which it is used until meet the given conditions. It is not synthesizable statement.
All statements in the process are executed sequentially from the first line to the last one. Order of the statements in the process is important. (Not like in the architecture – there, order of statements does not make any difference).
*** *** ***
All source codes used in that post you can find on gitlab.com.
*** *** ***