0

I have a binary string like "11000110". I'm trying to XOR all bits together.

I have this code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity e_circuit is
  generic(n : INTEGER:=8);
  port(
    d1:in std_logic_vector(n-1 downto 0);
    result:out std_logic
  );
end e_circuit;

architecture structure of e_circuit is
    signal temp:std_logic;
begin

    temp<=d1(0);
    loop1:for i in 1  to n-1 generate
        temp<= d1(i) or d1(i-1);
    end generate;
    result<=temp;
end structure;

But, when I try to compile it, I get the error below:

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

What does it mean? How can I fix it?

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Mamo YZ
  • 61
  • 1
  • 8
  • 3
    See these similar questions: [here](http://stackoverflow.com/questions/20296276/and-all-elements-of-an-n-bit-array-in-vhdl), and [here](http://stackoverflow.com/questions/25368402/bit-to-bit-xor-with-same-input-vector-in-vhdl) – callyalater Mar 01 '16 at 22:03
  • 2
    VHDL 2008 now has reduction operators: `signal data : std_logic_vector(7 downto 0); signal parity : std_logic; ... parity <= xor data;` See [here](http://www.synthworks.com/papers/VHDL_2008_end_of_verbosity_2013.pdf) – callyalater Mar 01 '16 at 22:12
  • 2
    You have assigned the signal `temp` at several locations in your code (and none of them is masked by an `if ... generate`). Each assignment makes up a driver. – Martin Zabel Mar 01 '16 at 22:14
  • 3
    Think about it, every iteration of your for loop assigns to temp and you assign to temp before that. That is the equivalent of just taking the output and wiring them all together without any combination circuitry. (VHDL "executes" in parallel.) – callyalater Mar 01 '16 at 22:16
  • @callyalater I would never recommend VHDL'08 syntax for synthesis. I have read today the Vivado Synthesis Guide and wondered how many things are not supported. – Martin Zabel Mar 01 '16 at 22:23
  • @MartinZabel Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/105057/discussion-between-callyalater-and-martin-zabel). – callyalater Mar 01 '16 at 22:29
  • 1
    Okay, I couldn't resist. Where's the XOR from the question title? Also you can use a loop statement with a variable intermediary result in a process statement or a function (not named XOR) for those synthesis environments not supporting -2008, wherein you'd use a loop parameter along the lines of `d1'range`, which is derived from `n`. –  Mar 01 '16 at 23:53

2 Answers2

1

This means that you are assigning to a signal (temp) multiple times (tying their outputs together directly) without any combinational circuit or if clause. When the synthesizer synthesizes the resulting circuit, all of the statements in the for...generate statement get executed simultaneously. Here are some solutions you can try:

First, you can use the VHDL-2008 reduction operator:

result <= xor d1;

Or, if your synthesizer doesn't support that, create a function to do it for you:

function xor_reduct(slv : in std_logic_vector) return std_logic is
  variable res_v : std_logic := '1';  -- Null slv vector will also return '1'
begin
  for i in slv'range loop
    res_v := res_v xor slv(i);
  end loop;
  return res_v;
end function;

And call it in your corresponding architecture:

result <= xor_reduct(d1);

Or do the circuit manually, (with temp being a std_logic_vector of the same size as d1:

temp(0) <= d1(0);
gen: for i in 1 to n-1 generate
    temp(i) <= temp(i-1) xor d1(i);
end generate; 
result <= temp(n-1);
callyalater
  • 3,102
  • 8
  • 20
  • 27
  • Your *Or do the circuit manually* looks identical to the OP's code which didn't synthesize. The block statement for each generate parameter value will have it's own elaborated process for the concurrent assignment statement, while a functional call is an expression in a process resulting in a faster executing model. All concurrent statements devolve into processes and/or processes and block statements during elaboration. –  Mar 02 '16 at 01:44
  • Because each assignment of temp depends on temp, this produces a chained xor instead of assigning lots of different signals to temp, and should synthesize. I also provided a different way underneath that assigns to a std_logic_vector instead of just a std_logic. – callyalater Mar 02 '16 at 02:09
  • It will look almost identical because he was very close. – callyalater Mar 02 '16 at 02:11
  • 1
    If it won't synthesize (or simulate) with an OR it won't with an XOR either. Same assignments to a single 'bit' with concurrent assignment statements. –  Mar 02 '16 at 02:36
  • I tried the synthesis on my machines right now and it worked. – callyalater Mar 02 '16 at 03:05
  • Then so should his other than OR/XOR. –  Mar 02 '16 at 03:30
  • There is an important difference: his never references temp on the right side of the assignment. – callyalater Mar 02 '16 at 04:12
  • I think the confusion is here, that you repeated the wrong implementation (but with XOR) in the last section. I stumbled over this too. I suggest to omit the repetition, or indicate it more clearly. – Martin Zabel Mar 02 '16 at 06:35
  • I updated the answer to use only a std_logic_vector in the reduction instead of both. – callyalater Mar 02 '16 at 14:45
  • I think this line ```variable res_v : std_logic := '1';``` should be ```variable res_v : std_logic := '0';```. Otherwise, NOT of the first bit is XORed. – efe373 Apr 05 '22 at 14:23
0

What does it mean?

You have concurrently assigned the signal temp at several locations in your code (and none of them is masked by an if ... generate). Each concurrent assignment makes up a driver.

The for generate repeats the concurrent statements inside the block for each value of i within the given range. Thus, for n = 8, your code is similar to:

temp <= d1(0);
temp <= d1(1) or d1(1-1);
temp <= d1(2) or d1(2-1);
temp <= d1(3) or d1(3-1);
temp <= d1(4) or d1(4-1);
temp <= d1(5) or d1(5-1);
temp <= d1(6) or d1(6-1);
temp <= d1(7) or d1(7-1);

Thus, you have connected 8 drivers to temp. The first is the input d1(0) and the others or the outputs of 7 OR gates.

The posted error message is reported only with the old parser of ISE for Spartan-3 like devices. You should switch to the new one. Right click on Synthesize -> Properties -> Synthesis Options. The set option "Other XST Command Line Options" to

-use_new_parser YES

Then, you get a more meaningful error message:

ERROR:HDLCompiler:636 - "/home/zabel/tmp/xor_reduction/e_circuit.vhdl" Line 23: Net is already driven by input port .

Line 23 is the one within the for ... generate statement.


How can I fix it?

At first, your code has to use an XOR instead of OR. ISE does not support the XOR reduction operator from VHDL'08, thus, you have to describe it manually. One solution is to use sequential statements within a process, which has also been suggested by @user1155120 in the comments:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity e_circuit is
    generic(n : INTEGER := 8);
    port(d1     : in  std_logic_vector(n-1 downto 0);
         result : out std_logic);
end e_circuit;

architecture structure of e_circuit is
begin
    process(d1)
        variable temp : std_logic;
    begin
        temp := d1(0);
        for i in 1 to n-1 loop
            temp := temp xor d1(i);
        end loop;
        result <= temp;
    end process;
end structure;

Here, the variable temp is updated sequentially during the execution of the process (like in an imperative software programming language). The final value is then assigned to the signal result.

I have also omitted all VHDL packages which are not required.

Martin Zabel
  • 3,589
  • 3
  • 19
  • 34