2
votes

I'm trying to write a code that will detect a rising edge on din signal and will raise dout for 5 clock cycles after that happens. I keep on getting different errors while compiling and I'm not sure what they mean. I think I lack a basic understanding of some concepts in VHDL but sadly looking online and did not help me much. I still don't have a feeling of what actions are acceptable by the software.

In my code I currently have a rising edge detector at the 1st process which raises dout to logic high. The second process checks if dout is high and while so counts down from 5 to 0 and on 0 sets dout to logic low.

This does not compile and returns the following errors:

Error (10028): Can't resolve multiple constant drivers for net "count[2]" at rise_ext.vhd(31)

Error (10029): Constant driver at rise_ext.vhd(17)

Error (10028): Can't resolve multiple constant drivers for net "count[1]" at rise_ext.vhd(31)

Error (10028): Can't resolve multiple constant drivers for net "count[0]" at rise_ext.vhd(31)

Error (10028): Can't resolve multiple constant drivers for net "dout" at rise_ext.vhd(31)

Error (10029): Constant driver at rise_ext.vhd(19)

Error (12153): Can't elaborate top-level user hierarchy

Error: Quartus II 32-bit Analysis & Synthesis was unsuccessful. 7 errors, 2 warnings Error: Peak virtual memory: 326 megabytes Error: Processing ended: Sat Jan 11 13:13:38 2014 Error: Elapsed time: 00:00:04 Error: Total CPU time (on all processors): 00:00:02

Error (293001): Quartus II Full Compilation was unsuccessful. 9 errors, 2 warnings

    entity rise_ext is
    port ( clk:    in  bit ;
           resetN: in  bit ;
           din:    in  bit ;
           count:  buffer integer range 0 to 6 ;
           dout:   buffer bit ) ;
end rise_ext ;

architecture arc_rise_ext of rise_ext is
    signal s1 , s2 : bit ;
begin
    process ( resetN, clk )
    begin
        if resetN = '0' then
           dout <= '0' ;
           count <= 5 ;
        elsif clk'event and clk = '1' then
              s1 <= din ;
              s2 <= s1  ;
              dout <= not s1 and s2 ;
        end if ;
    end process ;

    process ( clk, dout )
    begin
        if clk'event and clk = '1' then
           if dout = '1' then
              if count > 0 then
                 count <= count - 1 ;
              else
                 dout <= '0' ;
                 count <= 5 ;
              end if;
          end if ;
        end if ;
    end process ;
end arc_rise_ext ;

Any help will be appreciated!

I changed all the data types to std_logic and finished the code, still I get these errors...

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity rise_ext is
    port ( clk:    in  std_logic ;
           resetN: in  std_logic ;
           din:    in  std_logic ;
           count:  buffer integer range 0 to 6 ;
           dout:   buffer std_logic ) ;
end rise_ext ;

architecture arc_rise_ext of rise_ext is
    signal s1 , s2 : std_logic ;
begin
    process ( resetN, clk )
    begin
        if resetN = '0' then
           dout <= '0' ;
            count <= 6 ;
        elsif rising_edge(clk) then
              s1 <= din ;
              s2 <= s1  ;
              dout <= not s1 and s2 ;
        end if ;
    end process ;

    process ( clk )
    begin
        if rising_edge(clk) then
           if dout = '1' then
               count <= 5 ;
            end if ;
        end if ;
    end process ;

    process ( clk )
    begin
        if rising_edge(clk) then
           if count = 0 then
                count <= 6 ;
                dout <= '0' ;
            else
               count <= count - 1 ;
            end if ;
        end if ;
    end process ;
end arc_rise_ext ;
2
Did it simulate correctly? From these errors I'm guessing not...user_1818839
Is there a possibility it will simulate correctly and not compile? I can check with multisim...user34920
checked - can't simulate with multisimuser34920
why can't simulate with multisim?user_1818839

2 Answers

6
votes

You have dout and count assigned in both processes. Neither are resolved signals.

From IEEE Std 1076-1993:

12.6.1 Drivers

Every signal assignment statement in a process statement defines a set of drivers for certain scalar signals. There is a single driver for a given scalar signal S in a process statement, provided that there is at least one signal assignment statement in that process statement and that the longest static prefix of the target signal of that signal assignment statement denotes S or denotes a composite signal of which S is a subelement. Each such signal assignment statement is said to be associated with that driver. Execution of a signal assignment statement affects only the associated driver(s).

This essentially means you are duplicating both count and dout.

There are many ways to model the behavior of dout and count you desire. Bifurcating their operation across two processes based on starting and ending events isn't one of them. That would require three processes, one for the making event, one for the breaking event and one for the clocked storage. You'd likely need separate events for operating count.

3
votes

As you seem new to VHDL, keep this rule in mind:

You can only drive a signal from one process.

You need to rearrange your logic so that a given signal is only driven from one process. Don't try to get around this. Use the std_ulogic type and the compiler will tell you when you get it wrong very early on.

So in your case, you need to move the 'resetting' part which drive count into the process which does the incrementing of count.


Now, when you've built up some experience, you'll find there are times when you need to have multiple drivers on a single signal. This is used when modelling the outside of chips (I2C buses, tristate memory buses and the like). But not for 'inside the chip' code.