Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17254 Discussions

Can't resolve multiple constant drivers?

Altera_Forum
Honored Contributor II
3,055 Views

I'm really confused. I'm trying to make a barrel rotator but Quartus is complaining about my VHDL. 

 

This is the line it points to: SIGNAL alu: STD_LOGIC_VECTOR(15 DOWNTO 0); 

but I see nothing wrong with that statement. 

Basically I take my input, do a left and right rotate, and use my mux to decide whether I want to select either of those shifts or no shift at all, and go through the stages. I'm pretty sure I made my mux correctly, but I really am lost now. 

 

ARCHITECTURE Structure OF ShiftRegister IS SIGNAL alu: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempL: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempR: STD_LOGIC_VECTOR(15 DOWNTO 0); COMPONENT busmux4to1 PORT ( selectIn: IN STD_LOGIC_VECTOR(1 DOWNTO 0); a: IN STD_LOGIC_VECTOR(15 DOWNTO 0); b: IN STD_LOGIC_VECTOR(15 DOWNTO 0); c: IN STD_LOGIC_VECTOR(15 DOWNTO 0); d: IN STD_LOGIC_VECTOR(15 DOWNTO 0); e: OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ); END COMPONENT; BEGIN alu<=aluIn; --4 rotation tempL<=alu(11 DOWNTO 0) & alu(15 DOWNTO 12); tempR<=alu(3 DOWNTO 0) & alu(15 DOWNTO 4); stage0: busmux4to1 PORT MAP(shiftRight & shift(2),alu,tempL,alu,tempR,alu); --2 rotation tempL<=alu(13 DOWNTO 0) & alu(15 DOWNTO 14); tempR<=alu(1 DOWNTO 0) & alu(15 DOWNTO 2); stage1: busmux4to1 PORT MAP(shiftRight & shift(1),alu,tempL,alu,tempR,alu); --1 rotation tempL<=alu(14 DOWNTO 0) & alu(15); tempR<=alu(0) & alu(15 DOWNTO 1); stage2: busmux4to1 PORT MAP(shiftRight & shift(0),alu,tempL,alu,tempR,alu); aluOut<=alu; END Structure;
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
1,685 Views

Hello, 

 

in the shown code, not only alu, but also tempL and tempR have multiple drivers. In concurrent code part, you are not allowed to make multiple assignment to a signal. 

 

I assume, you are intending a process, but it must coded as such. Furthermore, you can't use the multiplexer component in a process, but you could use a similar function instead. For temporary results, you must variables with variable assignment operator ":=". It would be allowed to make multiple assignments to a signal as in the example, but not with the intended effect of creating an intermediate result. 

 

Regards, 

Frank
0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

I don't understand why I can't do that. Do I need a process statement or something? Why can't I use a mux? This all just seems arbitrary

0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Well, it compiles now, I just made a new signal everytime

0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Well now it seems like nothing is happening. Shifting right shifts the wrong amounts and shifting left doesn't work at all.  

 

Can anyone spot anything glaring? 

ENTITY ShiftRegister IS PORT (aluIn : IN STD_LOGIC_VECTOR(15 DOWNTO 0); shift : IN STD_LOGIC_VECTOR(2 DOWNTO 0);--rotate amount shiftRight : IN STD_LOGIC;--if 1, right, if 0, left aluOut : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)--rotated output ); END ShiftRegister; ARCHITECTURE Structure OF ShiftRegister IS SIGNAL alu1: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL alu2: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL alu3: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempL1: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempR1: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempL2: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempR2: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempL3: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tempR3: STD_LOGIC_VECTOR(15 DOWNTO 0); COMPONENT busmux4to1 PORT ( selectIn: IN STD_LOGIC_VECTOR(1 DOWNTO 0); a: IN STD_LOGIC_VECTOR(15 DOWNTO 0); b: IN STD_LOGIC_VECTOR(15 DOWNTO 0); c: IN STD_LOGIC_VECTOR(15 DOWNTO 0); d: IN STD_LOGIC_VECTOR(15 DOWNTO 0); e: OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ); END COMPONENT; BEGIN --4 rotation tempL1<=aluIn(11 DOWNTO 0) & aluIn(15 DOWNTO 12); tempR1<=aluIn(3 DOWNTO 0) & aluIn(15 DOWNTO 4); stage0: busmux4to1 PORT MAP(shiftRight & shift(2),aluIn,tempL1,aluIn,tempR1,alu1); --2 rotation tempL2<=alu1(13 DOWNTO 0) & alu1(15 DOWNTO 14); tempR2<=alu1(1 DOWNTO 0) & alu1(15 DOWNTO 2); stage1: busmux4to1 PORT MAP(shiftRight & shift(1),alu1,tempL2,alu1,tempR2,alu2); --1 rotation tempL3<=alu2(14 DOWNTO 0) & alu2(15); tempR3<=alu2(0) & alu2(15 DOWNTO 1); stage2: busmux4to1 PORT MAP(shiftRight & shift(0),alu2,tempL3,alu2,tempR3,alu3); aluOut<=alu3; END Structure;
0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Hello, 

 

 

--- Quote Start ---  

Well now it seems like nothing is happening. Shifting right shifts the wrong amounts and shifting left doesn't work at all. 

--- Quote End ---  

 

 

according to Quartus timing simulation the code seems to work correct. May be you're operating it too fast? 

 

However, using a rotate function from numeric_std package, you get functional equivalent code that is somewhat shorter. Typecasts are needed cause the function isn't defined for std_logic_vector. 

 

library ieee; use ieee.std_logic_1164.all; USE ieee.numeric_std.all; -- .... ARCHITECTURE Structure OF Multi2 IS BEGIN aluOut <= std_logic_vector(ROTATE_LEFT(UNSIGNED(aluIn), TO_INTEGER(UNSIGNED(shift)))) WHEN shiftRight = '0' else std_logic_vector(ROTATE_RIGHT(UNSIGNED(aluIn), TO_INTEGER(UNSIGNED(shift)))); END Structure; 

 

Interestingly, Quartus synthesis ignores the multiple steps in your code, collapsing it to an single bit rotation, thus both variants are requiring identical LE count and have identical timing. You can examine XROR and XROL definition in library numeric_std.vhd to see how bit rotation can be coded in a compact way. 

 

Regards, 

Frank
0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

I shortened my code to this: 

BEGIN --4 rotation stage0: busmux4to1 PORT MAP(shiftRight & shift(2),aluIn,aluIn(11 DOWNTO 0) & aluIn(15 DOWNTO 12),aluIn,aluIn(3 DOWNTO 0) & aluIn(15 DOWNTO 4),alu1); --2 rotation stage1: busmux4to1 PORT MAP(shiftRight & shift(1),alu1,alu1(13 DOWNTO 0) & alu1(15 DOWNTO 14),alu1,alu1(1 DOWNTO 0) & alu1(15 DOWNTO 2),alu2); --1 rotation stage2: busmux4to1 PORT MAP(shiftRight & shift(0),alu2,alu2(14 DOWNTO 0) & alu2(15),alu2,alu2(0) & alu2(15 DOWNTO 1),aluOut); END Structure; 

 

I can't make it any shorter b/c I'm not allowed to use the rotate command (only structural vhdl allowed). Here's a picture of the results I'm dealing with (its a functional simulation, not timing). The relevant things to look at are aluInputA and aluOutput. ctrl_optype tells if its left or right shift (6 is left, 7 is right) and shiftamt is binary representation of how much to rotate by. Its hard to see from the picture but all of the left shifts didn't occur and all of the right shifts were by only one bit 

 

http://img165.imageshack.us/img165/8480/resultsps3.png
0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

I can't duplicate any of the errors!

0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Perhaps it's my use of muxes? I'm trying to redo my 2:1 mux but I'm having trouble getting it to compile. 

 

ARCHITECTURE Behavior OF VHDLMux21 IS SIGNAL output : STD_LOGIC_VECTOR(15 downto 0); PROCESS(a,b,s) BEGIN IF s = '0' THEN output <= a; ELSE output <= b; END IF; END PROCESS; c <= output; END Behavior;
0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Did you try my *.vhd and *.vwf?

0 Kudos
Altera_Forum
Honored Contributor II
1,685 Views

Thanks that was helpful. Realized my mux was wrong although I'm still not sure why. I ended up doing my own mux. Thanks for the help though.

0 Kudos
Reply