Registers (synchronous designs)

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;

Explanation

1. Process

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 syntax:

[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 processAll 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.

Testbench

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;

Explanation

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.

Remember!

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.

*** *** ***

Leave a Reply

Your email address will not be published. Required fields are marked *