1
\$\begingroup\$

I'm trying implement structural implementation of ring counter. I get this error:

ERROR:Xst:528 - Multi-source in Unit <ringcounter> on signal <count<3>>; this signal is connected to multiple drivers.

I could simulate it successfully.This module is a part of the project I'm implementing!..

Here is my VHDL code:

entity DFF is
    Port (
      reset : in STD_LOGIC;
      clk : in  STD_LOGIC;
      D : in  STD_LOGIC;
      Q : out  STD_LOGIC);
end DFF;

architecture Behavioral of DFF is
begin

    process(clk,reset)
    begin
        if reset = '1' then
            Q <= '0';    -- clear register
        elsif (clk'event and clk = '1') then
            Q<=D; --positive edge of clock is used
        end if;
    end process;

end Behavioral;

--Code for ring counter

entity ringcounter is
  Port ( reset : in STD_LOGIC;
         clk : in  STD_LOGIC;
         count : out  STD_LOGIC_VECTOR (3 downto 0));
end ringcounter;

architecture Behavioral of ringcounter is

    signal q0,q1,q2,q3 : STD_LOGIC : = '0'; ---initialising the signals

    --signal temp :STD_LOGIC :       = '1'; --not using it as of now.

    component DFF is
        Port ( reset : in STD_LOGIC;
              clk : in  STD_LOGIC;
               D : in  STD_LOGIC;
               Q : out  STD_LOGIC);
    end component;

begin

    q3<= '1';

    DFF1: DFF port map(reset,clk,q3,q0);

    DFF2: DFF port map(reset,clk,q0,q1);

    DFF3: DFF port map(reset,clk,q1,q2);

    DFF4: DFF port map(reset,clk,q2,q3);

    count <= q3&q2&q1&q0;

end Behavioral;

Whats going wrong?

edit

I did the changes as suggested but while simulating, the output are not getting updated for ring counter output even though I specify clock! The output is still undefined!

below is the modified code

entity DFF is
    Port ( reset : in STD_LOGIC;
           clk : in  STD_LOGIC;
           D : in  STD_LOGIC;
           Q : out  STD_LOGIC);
end DFF;

architecture Behavioral of DFF is
begin

    process(clk,reset)
    begin
        if reset='1' then
            Q <= '0';    -- clear register
        elsif (clk'event and clk='1') then
            Q<=D; --positive edge of clock is used
        end if;
    end process;

end Behavioral;


------------CODE OF RING COUNTER-----------------------

entity ringcounter is
    Port ( reset : in STD_LOGIC;
           clk : in  STD_LOGIC;
           count : out  STD_LOGIC_VECTOR (3 downto 0));
end ringcounter;

architecture Behavioral of ringcounter is

    signal q0,q1,q2 : STD_LOGIC := '0'; ---initialising the signals

    signal q3 :STD_LOGIC := '1';

    component DFF is
        Port ( reset : in STD_LOGIC;
               clk : in  STD_LOGIC;
               D : in  STD_LOGIC;
               Q : out  STD_LOGIC);
    end component;

begin

    DFF1: DFF port map(reset,clk,q3,q0);

    DFF2: DFF port map(reset,clk,q0,q1);

    DFF3: DFF port map(reset,clk,q1,q2);

    DFF4: DFF port map(reset,clk,q2,q3);

    count <= q3&q2&q1&q0;

end Behavioral;

yes I did specify reset. That time it'll only set the value to zero and no transition happens which is very obviously seen as I tried inserting a flip flop with preset input which will pump a 1 value to the flipflops ring!..I'm just simulating it. How do I make the value to shift after reset/preset?Am I missing some procedure?...

SO the problem now is How do I initialize all the flipflops and start shifting after, in sequence using the simulator??...

I have tried using behavior model not using DFF. Below is the codefor the same.

entity ringCounter_BehaviorModel is

Port ( CLK : in  STD_LOGIC;

       CLR : in  STD_LOGIC;

       Q : inout  STD_LOGIC_VECTOR (3 downto 0);

       NQ : inout  STD_LOGIC_VECTOR (3 downto 0));

end ringCounter_BehaviorModel;

architecture Behavioral of ringCounter_BehaviorModel is

begin

process(CLK, CLR)

begin if (CLR ='0') then

          Q<= "1000";                   

      elsif (CLR ='1') then

if CLK'event and CLK='1' then

        Q(0) <= Q(3);

        for i in 0 to 2 loop

        Q(i+1) <= Q(i);

        end loop;

    end if;

end if;

end process;

end Behavioral;

My question is when I simulate it I force the value of clr to 0 in order to initialise the counter to 1000 and I give clock signal to the clock input. After I click on run I could see the values of Q as 1000 but the values remains same even when I observe the clock pulse varying between 0 and 1.

when I rerun all the values are lost and I have to force the values all over again..

In the case of clr = '1' initialization doesn't happen and no hope of shifting the desired values. Am I missing somepoint in procedure or should I modify the code or will the observation made is just fine in case of simuation?

So the summary of problem remains still same and is just that to initialise the ring counter and start rotating around the system.

\$\endgroup\$
3
  • \$\begingroup\$ Could you be more specific to where the error has come from - what tool are you using Xilinx ISE or Altera Quartus or similar. \$\endgroup\$
    – Dean
    Commented Apr 24, 2014 at 9:17
  • \$\begingroup\$ on your edit - have you specified a reset? Initializing the q3 signal at the declaration won't do anything for simulation as it is driven by a DFF instance. \$\endgroup\$
    – fru1tbat
    Commented Apr 24, 2014 at 16:59
  • \$\begingroup\$ 1) Are you setting clr to 1 after the initial clock pulse during your test? if it stays at 1, the if clk edge never "wins" 2) You do not need the elsif CLR='1', it is implicit because otherwise we would take the if CLR='0' path 3) You should generally avoid inout except when instantiating top-level bidirectional buses, use out in the port declaration and use signals internally, e.g. signal q_int : std_logic_vector(3 downto 0); and at the bottom, Q <= q_int; 4) The better way to handle this rotation would be q_int <= q_int(2 downto 0) & q_int(3) inside the if clk edge. \$\endgroup\$
    – ajs410
    Commented Apr 28, 2014 at 14:54

3 Answers 3

3
\$\begingroup\$

Inside ringcounter, q3 is being assigned by both the concurrent assignment q3<='1' and DFF4. You can't have both at the same time.

\$\endgroup\$
1
  • \$\begingroup\$ I'm not sure that will have the intended effect. The DFFs are all chained together in a ring - how can one be initialized in ringcounter on reset without adding a second driver? \$\endgroup\$
    – fru1tbat
    Commented Apr 24, 2014 at 12:43
1
\$\begingroup\$

You're doing unnecessary work. You shouldn't have to create a DFF primitive. The synther is smart enough to turn a std_logic_vector that is "clocked" so to speak (i.e. surrounded by a process block with clk in the sensitivity list), into a collection of DFFs.

Get rid of the DFF primitive, make a std_logic_vector instead, and then in ringcounter, make a process that on reset, (your reset is async, BTW, in case that makes a difference to you) loads your std_logic_vector with the default value that you want (e.g. "1000"). And then on a rising clock edge, it rotates every element of the ring counter to the left.

If you have trouble doing this, I can check back later and show you how it is done. But I'd rather let you try to figure it out on your own, first.

\$\endgroup\$
1
  • \$\begingroup\$ I have tried the menthod mentioned by you. Where I use a clear signal to initial the flip flop and on rising edge of clock to move around the data. \$\endgroup\$
    – user40295
    Commented Apr 27, 2014 at 5:30
0
\$\begingroup\$

As apalopohapa's answer indicates, your problem is multiple drivers on the same signal. The statement q3 <= '1' is always active - it's not just an initialization. Since you're using std_logic and not std_ulogic, this is not technically an error, and the simulator will run it just fine (possibly with unintended results, though sometimes the problem will be masked because it happens to resolve to something that works).

If you want your counter to start at "1000" after reset and rotate every clock (which it looks like you do), one way would be to modify DFF so that it can optionally preset Q to '1' instead of always resetting it to '0'. You could do this by adding either a preset input or a generic or something that sets its initialization value. There are other approaches that would work as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.