Confusion between Behavioural and Dataflow model Programs in VHDL

Analon picture Analon · Sep 8, 2013 · Viewed 35.8k times · Source

I'm using the textbook "VHDL: Programming By Example" by Douglas L Perry, Fourth Edition. He gave an example of the Dataflow programming model in page 4:

Code I:

ENTITY mux IS
PORT ( a, b, c, d : IN BIT;
s0, s1 : IN BIT;
x, : OUT BIT);
END mux;
ARCHITECTURE dataflow OF mux IS
SIGNAL select : INTEGER;
BEGIN
select <= 0 WHEN s0 = ‘0’ AND s1 = ‘0’ ELSE
          1 WHEN s0 = ‘1’ AND s1 = ‘0’ ELSE
          2 WHEN s0 = ‘0’ AND s1 = ‘1’ ELSE
          3;
x <= a AFTER 0.5 NS WHEN select = 0 ELSE
     b AFTER 0.5 NS WHEN select = 1 ELSE
     c AFTER 0.5 NS WHEN select = 2 ELSE
     d AFTER 0.5 NS;
END dataflow;

Now in page 17, Code II

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY mux4 IS
PORT ( i0, i1, i2, i3, a, b : IN std_logic;
PORT ( i0, i1, i2, i3, a, q : OUT std_logic);
END mux4;
ARCHITECTURE mux4 OF mux4 IS
SIGNAL sel: INTEGER;
BEGIN
WITH sel SELECT
q <= i0 AFTER 10 ns WHEN 0,
q <= i1 AFTER 10 ns WHEN 1,
q <= i2 AFTER 10 ns WHEN 2,
q <= i3 AFTER 10 ns WHEN 3,
q <= ‘X’ AFTER 10 ns WHEN OTHERS;
sel <= 0 WHEN a = ‘0’ AND b = ‘0’ ELSE
       1 WHEN a = ‘1’ AND b = ‘0’ ELSE
       2 WHEN a = ‘0’ AND b = ‘1’ ELSE
       3 WHEN a = ‘1’ AND b = ‘1’ ELSE
       4;
END mux4;

This is supposed to be a behavioural model, as per the same textbook. Aside from the differences in variable name, the only major difference I see here is that there is an extra statement

WITH sel SELECT

in the second case, and small syntax differences. This Code II is concurrent. But from other sources in the internet(listed below), I've seen that a behavioural model is supposed to be sequential. Which one should I believe?

Now from some other sources of the internet, the definition of these models are as follows:

Behavioral – Circuit is described as an i/o relationship using sequential statements inside a process.

Dataflow – Circuit is described using concurrent statements

-San Jose State university

Behavioral – describes how the output is derived from the inputs using structured statements.

Dataflow – describes how the data flows.

-University of Akron College of Engineering

Here I do not understand what structured statements mean.

in Behaviour level, process keyword is present

in dataflow level , concurrent statement (<=) is present


This was seen in an online forum.

Is process statement compulsory for Behavioural model?

What is the actual difference between codes I and II? According to the author, they have different models, dataflow and behavioural. I cannot see how this is possible. What should I believe?

Lastly, in Perry D L, Page 45, 46:

LIBRARY IEEE;
USE IEEE.std_logic_1164ALL;
ENTITY mux IS
PORT (i0, i1, i2, i3, a, b : IN std_logic;
PORT (q : OUT std_logic);
END mux;
ARCHITECTURE better OF mux IS
BEGIN
PROCESS ( i0, i1, i2, i3, a, b )
VARIABLE muxval : INTEGER;
BEGIN
muxval := 0;
IF (a = ‘1’) THEN
muxval := muxval + 1;
END IF;
IF (b = ‘1’) THEN
muxval := muxval + 2;
END IF;
CASE muxval IS
WHEN 0 =>
q <= I0 AFTER 10 ns;
WHEN 1 =>
q <= I1 AFTER 10 ns;
WHEN 2 =>
q <= I2 AFTER 10 ns;
WHEN 3 =>
q <= I3 AFTER 10 ns;
WHEN OTHERS =>
NULL;
END CASE;
END PROCESS;
END better;

This is a sequential version of MUX. According to the other definitions, this is supposed to be behavioural, but the author does not state so. Could you clear up my confusion regarding these models?

Answer

Brian Drummond picture Brian Drummond · Sep 8, 2013

Don't look for a mathematically rigorous description of these terms; they are a lot vaguer than that, loose classifications that can overlap.

"Dataflow" I think is fairly clear here; it DOES describe the flow of data, and it describes it in terms of concurrent statements. But I would add that each concurrent statement is woken by changes on its inputs and delivers its outputs; therefore (the important bit:) there is no correspondence between the order of things happening and the order of elements in the source code. In that respect it has a lot in common with functional programming. And both the first two models are dataflow; in (I) the elements are in logical order while (II) is not.

"Behavioural" SHOULD be fairly clear too - it simply describes a circuit in terms of its behaviour.

But it is not in general opposed to dataflow - though your San Jose quote is somewhat correct - behavioural descriptions are commonly sequential simply because the sequential paradigm (inside a VHDL process) is common and familiar to programmers. Even so, the behaviour of several such processes interacting with each other is ... dataflow.

Behavioral then is NOT correctly opposed to dataflow. It is more correctly opposed to RTL (Register Transfer Level) and structural which have fairly clear meanings.

A structural description consists of a number of building block (gates, multiplexers, entire CPUs) and the signals interconnecting them : a textual block diagram (perhaps auto-generated from a graphical one). As such it can be either the lowest level (see frequent questions here about making an adder out of gates!) or the highest level (connecting CPU to memory, peripherals, etc).

An RTL description is fairly low level; it describes the transfer and operations on data between storage elements (registers) and is common inside a process; it is rather like an assembly language listing from a (behavioural) C program.

Lastly - too many descriptions and too many extraneous details get in the way of doing a proper design job. Look at the task in hand, extract its essence, and implement that.

A multiplexer selects one of a collection of input elements according to the index of the element you want. The most natural form of index is usually an integer type, rarely including negative indices, and the most natural form of collection in VHDL is ... an array.

So why not write

ENTITY mux IS
  PORT ( a, b, c, d : in BIT;
         sel        : in natural range 0 to 3;
         x          : out BIT);
END mux;
ARCHITECTURE simple OF mux IS
SIGNAL values : array (0 to 3) of BIT;
BEGIN
   values <= a & b & c & d;
   x      <= values(sel);   -- after 0.5 ns; if you need to model timing!
END simple;

or better, make "values" an input port...