Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] [Newbie Query] How to handle inherent concurrancy in VHDL

Status
Not open for further replies.

bitprolix

Junior Member level 2
Joined
Sep 19, 2013
Messages
24
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
235
Hi All,

I'm a complete newbie and have just recently(a week back) started learning VHDL. I'm finding it very interesting and challenging as programming in VHDL is very different that other high level programming such as 'C'. I'm reading the on-line materials, but the amount of information that needed to be grasped is very huge, and because of that I'm kind of stuck in a small problem where I know that there is a problem but do not have enough language/semantics skills to fix it. Therefore It would be very helpful to me if you can throw some light here and give me direct or indirect pointers. The problem is as follows:
I've to implement a up-down counter by keeping the following in mind:

i) CLK (in): Clock signal. Counter counts on the rising edge of the clock signal.
ii) RESET(in): Resets the counter to the start address.
iii) ENABLE(in): If the enable signal is 1, counter is functional. Otherwise counter is stopped.
iv) STARTADR(in): Holds the start value of the counter
v) STOPADRR(in): Holds the stop value of the counter.
vi) ADDRESS(in): Represents the current output value of the counter.

The behavioural architecture for such counter is

Code:
architecture RTL of Counter is
signal counter : unsigned ( BIT_WIDTH -1 downto 0 );
begin

Cnt: process 
begin
	wait on CLK until CLK = '1';
	if ( RESET = '1' ) then 
		counter <= STARTADR;
	elsif ( ENABLE = '1' ) and ( counter < STOPADR ) then 
		counter <= counter + 1;
	elsif ( ENABLE = '1' ) and ( counter > STOPADR ) then
		counter <= counter - 1;
	end if;
	ADDRESS <= counter;
end process Cnt;

end RTL;

So far so good, Counter is counting in both directions :smile:

As I've understood, to test my design, I need a test bench which I can simulate using CAD tool. I have been provided a test bench to test this design and in the test bench, i see that there are deliberate introduction of delays and because of which, I see that the counter sometimes misses the rising edge of the CLK signal (please refer the screenshot below, where the counter was not incremented at the rising edge of the CLK signal at 70ns), Now to handle such delays (please refer the testbench code below) or the inherent parallel nature of the design model, how should I fix this ? Also, If possible suggest me the book that you found most useful when you started your career/research in electronic design.


Code:
Test_sequence:  process

    procedure MakeSequence
      ( constant START_VALUE, STOP_VALUE, CYCLES_COUNT : positive ) is
    begin
      wait on Clk until Clk = '1';
      Strt <= conv_unsigned ( START_VALUE, BW ) after 1 ns;
      Stp <= conv_unsigned ( STOP_VALUE, BW ) after 1 ns;
      Rst <= '1' after 1 ns;
      Ena <= '0' after 1 ns;
      wait on Clk until Clk = '1';
      Rst <= '0' after 1 ns;
      wait on Clk until Clk = '1';
      Ena <= '1' after 1 ns;
      for i in 0 to CYCLES_COUNT - 4 loop
        wait on Clk until Clk = '1';
      end loop;
      Ena <= '0' after 1 ns;
      wait on Clk until Clk = '1';
    end MakeSequence;

  begin
    MakeSequence ( 2, 12, 16 ); 
    MakeSequence ( 13, 5, 16 );  
    Strt <= ( others  => '0' ) after 1 ns;
    Stp  <= ( others => '0' ) after 1 ns;
    Halt <= true after 50 ns;
    wait;
  end process Test_sequence;

counter_wave_err.png

Thank you so much for your help.
 

Hi All,

I'm a complete newbie and have just recently(a week back) started learning VHDL. I'm finding it very interesting and challenging as programming in VHDL is very different that other high level programming such as 'C'. I'm reading the on-line materials, but the amount of information that needed to be grasped is very huge, and because of that I'm kind of stuck in a small problem where I know that there is a problem but do not have enough language/semantics skills to fix it. Therefore It would be very helpful to me if you can throw some light here and give me direct or indirect pointers. The problem is as follows:
I've to implement a up-down counter by keeping the following in mind:

i) CLK (in): Clock signal. Counter counts on the rising edge of the clock signal.
ii) RESET(in): Resets the counter to the start address.
iii) ENABLE(in): If the enable signal is 1, counter is functional. Otherwise counter is stopped.
iv) STARTADR(in): Holds the start value of the counter
v) STOPADRR(in): Holds the stop value of the counter.
vi) ADDRESS(in): Represents the current output value of the counter.

The behavioural architecture for such counter is

Code:
architecture RTL of Counter is
signal counter : unsigned ( BIT_WIDTH -1 downto 0 );
begin

Cnt: process 
begin
	wait on CLK until CLK = '1';
	if ( RESET = '1' ) then 
		counter <= STARTADR;
	elsif ( ENABLE = '1' ) and ( counter < STOPADR ) then 
		counter <= counter + 1;
	elsif ( ENABLE = '1' ) and ( counter > STOPADR ) then
		counter <= counter - 1;
	end if;
	ADDRESS <= counter;
end process Cnt;

end RTL;

So far so good, Counter is counting in both directions :smile:

As I've understood, to test my design, I need a test bench which I can simulate using CAD tool. I have been provided a test bench to test this design and in the test bench, i see that there are deliberate introduction of delays and because of which, I see that the counter sometimes misses the rising edge of the CLK signal (please refer the screenshot below, where the counter was not incremented at the rising edge of the CLK signal at 70ns), Now to handle such delays (please refer the testbench code below) or the inherent parallel nature of the design model, how should I fix this ? Also, If possible suggest me the book that you found most useful when you started your career/research in electronic design.


Code:
Test_sequence:  process

    procedure MakeSequence
      ( constant START_VALUE, STOP_VALUE, CYCLES_COUNT : positive ) is
    begin
      wait on Clk until Clk = '1';
      Strt <= conv_unsigned ( START_VALUE, BW ) after 1 ns;
      Stp <= conv_unsigned ( STOP_VALUE, BW ) after 1 ns;
      Rst <= '1' after 1 ns;
      Ena <= '0' after 1 ns;
      wait on Clk until Clk = '1';
      Rst <= '0' after 1 ns;
      wait on Clk until Clk = '1';
      Ena <= '1' after 1 ns;
      for i in 0 to CYCLES_COUNT - 4 loop
        wait on Clk until Clk = '1';
      end loop;
      Ena <= '0' after 1 ns;
      wait on Clk until Clk = '1';
    end MakeSequence;

  begin
    MakeSequence ( 2, 12, 16 ); 
    MakeSequence ( 13, 5, 16 );  
    Strt <= ( others  => '0' ) after 1 ns;
    Stp  <= ( others => '0' ) after 1 ns;
    Halt <= true after 50 ns;
    wait;
  end process Test_sequence;

View attachment 96364

Thank you so much for your help.

you should do :

process(clk)

begin

if rising_edge(clk) then

bla bla la ....

end if;
end process;


also your up/down mecanisem look faulty.
 
I see that the counter sometimes misses the rising edge of the CLK signal (please refer the screenshot below, where the counter was not incremented at the rising edge of the CLK signal at 70ns)
No, you are simply misunderstanding the logic you created. You build an additional delay of one clock cycle by assigning the output inside the clock edge sensitive block.

The simulation is obviously functional (RTL) simulation which doesn't model hardware delays unless they are explicitely defined by delay statements. So all output changes seems to occur exactly at the clock edge with zero delay.

The "wait on" statement is a bit unusual for clock modelling in synthesizable VHDL, although it should be supported by design compilers. "If rising_edge(clk)" is more often used.
 
you should do :

process(clk)

begin

if rising_edge(clk) then

bla bla la ....

end if;
end process;

Thank you for your reply, I changed my design as below:

Code:
entity Counter is
  generic ( BIT_WIDTH   : positive );
  port (
    CLK                 : in bit;
    RESET, ENABLE       : in std_logic;
    STARTADR, STOPADR   : in unsigned ( BIT_WIDTH - 1 downto 0 );
    ADDRESS             : out unsigned ( BIT_WIDTH - 1 downto 0) );
end Counter;

--Register-tranfer level
architecture RTL of Counter is
signal counter : unsigned ( BIT_WIDTH -1 downto 0 );
begin

Cnt: process(CLK) 
begin
	if ( RESET = '1' ) then 
		counter <= STARTADR;
	end if;
	if (clk='1' and clk'event ) then
	   if ( ENABLE = '1' ) and ( counter < STOPADR ) then 
		  counter <= counter + 1;
	   elsif ( ENABLE = '1' ) and ( counter > STOPADR ) then
		  counter <= counter - 1;
	   end if;
	end if;
	ADDRESS <= counter;
end process Cnt;

end RTL;

I couldn't use the rising_edge(CLK) as the CLK in the testbench is defined as "bit", and I've no control over the testbench.

also your up/down mecanisem look faulty.

Can you please tell me the problem here.

- - - Updated - - -

if (clk='1' and clk'event )

Sorry, this would sound naive, but I think I'm confused between the above "clk" and the CLK input signal for my architecture, i.e.

Code:
--Entity
entity Counter is
  generic ( BIT_WIDTH   : positive );
  port (
    CLK                 : in bit;
    RESET, ENABLE       : in std_logic;
    STARTADR, STOPADR   : in unsigned ( BIT_WIDTH - 1 downto 0 );
    ADDRESS             : out unsigned ( BIT_WIDTH - 1 downto 0) );
end Counter;
 

VHDL is case insensitive, so CLK, CLk, ClK, Clk, cLK, cLk, clK, and clk are all the same signals.

You shouldn't break the if into two different if statements (i.e. one for reset and one for the clk) it should have been elsif (clk='1' and clk'event) then. That will give you an asynchronous reset, which means you'll need to include the reset in the process sensitivity list.

I'm finding it very interesting and challenging as programming in VHDL is very different that other high level programming such as 'C'.
This is because VHDL isn't a programming language like C etc. It's a hardware description language, so processes and statements are executed concurrently.

regards
 
VHDL is case insensitive, so CLK, CLk, ClK, Clk, cLK, cLk, clK, and clk are all the same signals.
That explains the code getting compiled :idea:

You shouldn't break the if into two different if statements (i.e. one for reset and one for the clk) it should have been elsif (clk='1' and clk'event) then. That will give you an asynchronous reset, which means you'll need to include the reset in the process sensitivity list.

I added RESET signal in the sensitivity list and now the process part is as follows:

Code:
Cnt: process(CLK, RESET) 
begin
  if ( RESET = '1' ) then 
        counter <= STARTADR;
  elsif (CLK='1' and CLK'event ) then
        if ( ENABLE = '1' ) and ( counter < STOPADR ) then 
              counter <= counter + 1;
	elsif ( ENABLE = '1' ) and ( counter > STOPADR ) then
              counter <= counter - 1;
        end if;
  end if;
  ADDRESS <= counter;
end process Cnt;

end RTL;

But this still seem to be not giving a correct waveform :sad:
 

But this still seem to be not giving a correct waveform :sad:

FvM already mentioned that you've got an extra clock delay on ADDRESS due to having it assigned within the process. Add counter to your wave and you'll see the outputs changing where you're expect them to.

Regards,
 
Last edited:
FvM already mentioned that you've got an extra clock delay on ADDRESS due to having it assigned within the process

Ohh, Sorry, I Couldn't understand what FvM meant by that, but now, As you mentioned, I have moved the assignment operation on ADDRESS to outside of the process, and it works now :grin:

Thank you everyone for helping me. Also one more request, Please suggest me one or two books that you think a beginner must have on VHDL and Digital Modelling and Synthesis.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top