Tuesday 2 September 2014

Developing & Delivering KnowHow

RTL Coding

We've now seen how to use processes to describe a MUX_2 design. However, the coding approach used was somewhat low-level, in that the code consisted of binary operators.

In order to adopt high-level design principles, it is necessary to try and describe a design at a higher level of abstraction. This means thinking about the functionality of the design rather than its implementation. This allows the synthesis tool to optimize the functionality you have specified, leaving you to describe what the design does, whilst the synthesis tool's job is to implement the design how it sees fit in order to create the optimal implementation. The style of coding required for synthesis tools is known as RTL coding.

Most commercially available synthesis tools expect to be given a design description in RTL form. RTL is an acronym for register transfer level. This implies that your VHDL code describes how data is transformed as it is passed from register to register. The transforming of the data is performed by the combinational logic that exists between the registers. Don't worry! RTL code also applies to pure combinational logic - you don't have to use registers.

Using processes in RTL descriptions is particularly appropriate for input to a synthesis tool. For example, using component instances implies a level of structure in the design. This can sometimes be advantageous particularly on a large design but for a 2-input multiplexer...

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity MUX2 is
  port (SEL, A, B: in STD_LOGIC;
  F : out STD_LOGIC);
end;

architecture BEHAVIOUR of MUX2 is

begin
  -- descibed using a single process
end; 

For the functionality, let's get conceptual. If sel is a logic 1, a is routed through to the f output. On the other hand if sel is a logic 0, b is routed through to the f output. Rather than think about routing one of the inputs through to the output let's think about the output getting one of the inputs, and let's write the text on separate lines depending upon whether we are making a decision or performing an action (sometimes referred to as pseudo-code):

if sel is logic 1
  f gets a
otherwise
  f gets b

This can be translated into VHDL code:

if sel = '1' then
  f <= a;
else
  f <= b;
end if;

Now before we go any further, we'll just take this code snippet a line at a time.

if sel = '1'

The VHDL language allows for many different kinds of sequential statement. The sequential signal assignment is a signal assignment that can appear inside a process. You have already come across this statement in the Processes page (assignment to F in the combined process, if you remember). Here's another: the if statement. Actually this line is part of the if-else statement that is the entire code snippet. if is a VHDL keyword. After the if keyword you have a conditional expression, in this case sel = '1' - does sel have the value logic 1? If so...

f <= a;

f gets the value on the a input. But what if sel is not logic 1?

else

Otherwise (assume sel is logic 0 - more on this assumption later)...

f <= b;

f gets the value on the b input.

end if;

simply denotes the end of the if-else statement.

So, as it turns out, we have described the funcionality of the MUX_2 design using a single sequential statement, the if-else statement. In each branch of this if-else statement, there is an additional sequential statement, either assigning a to f, or b to f, depending upon the value of sel. But we have to remember that sequential statements always live inside a process, so...

process (sel, a, b)
begin
  if sel = '1' then
    f <= a;
  else
    f <= b;
  end if;
end

This now enables us to describe a design using a list of concurrent signal assignments, a hierarchy of designs (using component instances) or a process. Compare the 3 approaches for yourself:

  -- concurrent signal assignments
  selb <=  not sel;
  fb <= not((a and sel) or (b and selb));
  f <= not fb;
  -- a hierarchy of designs
  G1: INV port map (SEL, SELB);
  G2: AOI port map (SELB, A, SEL, B, FB);
  G3: INV port map (FB, F);
  -- process
  process (sel, a, b)
  begin
    if sel = '1' then
      f <= a;
    else
      f <= b;
    end if;
  end process;

And of course you can mix'n'match coding styles if you wish. On a simple design, such as a MUX_2 it is perhaps not apparent how succinct the use of processes is in general compared to component instances and concurrent signal assignments. But you can readily appreciate that the use of just one process in this design is enabling us to describe the design in terms of its functionality without regard to the implementation. You can describe what you want without having to worry about how you are going to implement the design (because you don't have to - that's the synthesis tool's job!).

Go on! Read the MUX_2 design into your synthesis tool and have a play...

Prev Next

Your e-mail comments are welcome - send email

Copyright 1995-2002 Doulos

Privacy Policy Site Map Contact Us