Lib4U

‎"Behind every stack of books there is a flood of knowledge."

RTL Verilog vs VHDL

RTL

Remember this?

Now we are going to look at the principles of RTL coding for synthesis tools.

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 Verilog 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. To show you what we mean by RTL code, let’s consider a simple example.

module AOI (input A, B, C, D, output F);
  assign F = ~((A & B) | (C & D));
endmodule

Yes! The AOI gate that we have used as an example so far has actually been written in RTL form. This means that continuous assignments are a valid way of describing designs for input to RTL synthesis tools. What other code techniques can we use? How about:

module MUX2 (input SEL, A, B, output F);
  input SEL, A, B;
  output F;
  INV G1 (SEL, SELB);
  AOI G2 (SELB, A, SEL, B, FB);
  INV G3 (.A(FB), .F(F));
endmodule

Module instances are also examples of synthesizable RTL statements. However, one of the reasons to use synthesis technology is to be able to describe the design at a higher level of abstraction than using a collection of module instances or low-level binary operators in a continuous assignment. We would like to be able to describe what the design does and leave the consideration of how the design is implemented up to the synthesis tool. This is a first step (and a pretty big conceptual one) on the road to high-level design. We are going to use a feature of the Verilog language that allows us to specify the functionality of a design (the ‘what‘) that can be interpreted by a synthesis tool.

Always blocks

Always blocks are akin to the initial blocks that you have met already in Test Benches. Initial blocks are procedural blocks that contain sequential statements. Initial blocks execute just once. Always blocks on the other hand are always available for execution. This means that the statements inside an always block are executed up until the closing end keyword:

always
begin
  // statements
end

But then they can be executed again! This means that a way of controlling execution through an always block is required. In describing synthesizable designs, a sensitivity list is often used to control execution (we shall see other approaches later).

always @(sensitivity-list)
begin
  // statements
end

The sensitivity list consists of one or more signals. When at least one of these signals changes, the always block executes through to the end keyword as before. Except that now, the sensitivity list prevents the always block from executing again until another change occurs on a signal in the sensitivity list.

The statements inside the always block describe the functionality of the design (or a part of it). Let’s reconsider the AOI gate:

always @(sensitivity-list)
begin
  F = ~((a & b) | (c & d));
end

Instead of a continuous assignment, we now have a procedural assignment to describe the functionality of the AOI gate. Notice that the sensitivity list isn’t valid Verilog code. We need to create a meaningful sensitivity list. How do we decide when to execute the always block? Perhaps a better question is what do we need to do in order to have F change value. Answer: F can only change when at least one of a, b, c ord changes. After all, these are the four inputs to the AOI gate. That’s our sensitivity list:

always @(a or b or c or d)
begin
  F = ~((a & b) | (c & d));
end

Verilog-2001 introduced additional syntax for describing sensitivity lists.

always @(a, b, c, d)

always @(*)

always @*

In the first of these, we have simply replaced the word or with a comma. The other two are equivalent and create an implicit sensitivity list that contains all the signals whose values are read in the statements of the always block. In this example @* or @(*) are equivalent to @(a,b,c,d). When describing combinational logic, it is important to make sure that sensitivity lists are complete; this syntax helps to ensure that this is holds.

Now for the MUX_2 design. In the above code snippet, we simply replaced the continuous assignment with an equivalent always block. We can do the same with the module instances in the MUX_2 design – strip away each instance and replace it with the equivalent always block.

always @(sel)
begin
  selb = ~sel;
end

always @(a or sel or b or selb)
begin
  fb = ~((a & sel) | (b & selb));
end

always @(fb)
begin
  f = ~fb;
end

But we can do better than this. Let’s merge the three always blocks together remembering that in the process (a pun for the VHDL’ers amongst you!) the sensitivity list of the resulting one always block contains only those signals that cause F to change value.

always @(sel or a or b)
begin
  selb = ~sel;
  fb = ~((a & sel) | (b & selb));
  f = ~fb;
end

When writing RTL code, “think functionality, think inputs” is a useful aide memoire in terms of bridging the gap between concept and code. Well, we have already taken care of the inputs as the sensitivity list now consists of only the MUX_2 input ports.

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 aspseudo-code):

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

This can be translated into Verilog code:

if (sel == 1)
  f = a;
else
  f = b;

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

if (sel == 1)

The Verilog language allows for many different kinds of sequential statement. The procedural assignment is one you have already come across not only on this page but also in test benches (assignments to SEL, A and B in the stimulus initial block, 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 Verilog 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. Or in Verilog jargon, a procedural assignment. 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.

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

always @(sel or a or b)
begin
  if (sel == 1)
    f = a;
  else
    f = b;
end

This now enables us to describe a design using a list of continuous assignments, a hierarchy of designs or an always block. Compare the 3 approaches for yourself:

// continuous assignments
assign selb = ~sel;
assign fb = ~((a & sel) | (b & selb));
assign f = ~fb

// a hierarchy of designs
INV G1 (SEL, SELB);
AOI G2 (SELB, A, SEL, B, FB);
INV G3 (.A(FB), .F(F));

// always block
always @(sel or a or b)
begin
  if (sel == 1)
    f = a;
  else
    f = b;
end

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 always blocks is in general compared to module instances and continuous assignments. But you can readily appreciate that the use of just one always block 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!).

Source:

http://www.doulos.com/knowhow/verilog_designers_guide/rtl_verilog/

VHDL

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 aspseudo-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!).

Source:

http://www.doulos.com/knowhow/vhdl_designers_guide/rtl_coding/

One comment on “RTL Verilog vs VHDL

  1. lista de emails
    February 12, 2013

    i agree with your conclusions and will eagerly look forward to your incoming updates. just saying thanks will not just be enough, for the phenomenal clarity in your writing. lista de emails lista de emails lista de emails lista de emails lista de emails

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Virtual Fashion Technology

Virtual Fashion Education

toitocuaanhem

"chúng tôi chỉ là tôi tớ của anh em, vì Đức Kitô" (2Cr 4,5b)

VentureBeat

News About Tech, Money and Innovation

digitalerr0r

Modern art using the GPU

Theme Showcase

Find the perfect theme for your blog.

lsuvietnam

Learn to Learn

Gocomay's Blog

Con tằm đến thác vẫn còn vương tơ

Toán cho Vật lý

Khoa Vật lý, Đại học Sư phạm Tp.HCM - ĐT :(08)-38352020 - 109

Maths 4 Physics & more...

Blog Toán Cao Cấp (M4Ps)

Bucket List Publications

Indulge- Travel, Adventure, & New Experiences

Lib4U

‎"Behind every stack of books there is a flood of knowledge."

The WordPress.com Blog

The latest news on WordPress.com and the WordPress community.

%d bloggers like this: