Signal Connected to Multiple Drivers Help?

Status
Not open for further replies.

tkim20

Newbie level 2
Joined
Nov 24, 2013
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
14
I am trying to make a sequential multiplier. The code is supposed to recieve a product and add each bit of the product at the rising edge of the clock while emitting the corresponding LED. What is the problem?
 

Attachments

  • code.txt
    2.5 KB · Views: 85

I THINK (could be wrong again) that your chain of "IF" statements in PROC1 might be the problem; should be if-elsif. What signal does your error message identify as the culprit?
 

The problem is with the following statements:

DividerSegments <= s;
DividerLEDS <= t;

You are driving these two signals in proc0's if .. else statements and then trying to drive them outside the process again.

proc0: process(DividerCLK, DividerRST)
begin
if (DividerRST = '1') then
DividerLEDS <= "00000000";
DividerSegments <= "00000000";
cnt_dig <= "000";
elsif (rising_edge(DividerCLK)) then
cnt_dig <= cnt_dig + 1;
end if;
end process;

This is multiple drivers for the two signals. Put the final assignment inside the if loop if you can restructure your code. This should solve the multiple drivers issue.
 

vlsi-whiz is correct. I missed that.

But those independent if statements may still cause you problems with inferred latches.
 

yes, for example, no bit of t is ever set to 0. You should add a t <= (others => '0') line (and same for s) at the top of that process. In VHDL and verilog, the nonblocking assignment effectively performs whatever the last assignment was. It is common to use this property to give defaults to the signals in a combinatorial process. This is easy to understand and prevents latches formed by forgetting to assign the signal in all code paths. It can also be used with some synthesis tools (XST/Vivado/Synplify, maybe more) to make mixed resets easier. Any other use is still valid, but can make it difficult to determine the complexity of the logic for any given signal, and can make it easy to misread code that now has a priority encoder spread throughout the process.

Code:
p_label : process ( clk ) is
begin
  if rising_edge(clk) then
    -- defaults
    valid_out <= '0';
    data_out <= data_in;
    -- logic
    -- This logic sends a valid pulse for every other valid_in.
    -- The value of cnt will be retained (unless reset).
    -- The value of "valid_out" will transition back to 0 if these conditions aren't met (due to default)
    if valid_in = '1' then
      if cnt = 1 then
        valid_out <= '1';
      end if;
      cnt <= (cnt + 1) mod 2;
    end if;
    -- resets, sync
    -- this infers a reset on the register "valid_out" and "cnt"
    -- no register is applied to the registers "data_out".  
    -- This style of resets is common in FPGA designs, but not ASICs.
    if rst = '1' then
      cnt <= 0;
      valid_out <= '0';
    end if;
  end if;
end process;

This is a simple process, so the benefits are not that apparent vs:

Code:
p_label : process ( clk ) is
begin
  if rising_edge(clk) then
    if rst = '1' then
      cnt <= 0;
      valid_out <= '0';
    elsif valid_in = '1' then
      if cnt = 1 then
        valid_out <= '1';
      end if;
      cnt <= (cnt + 1) mod 2;
    else
      valid_out <= '0';
    end if;
    data_out <= data_in;
  end if;
end process;

Though the benefits become clear when there is a large mixture of signals with/without resets and/or defaults.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…