Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Assignment of signal to same signal VHDL

Status
Not open for further replies.

CataM

Advanced Member level 4
Joined
Dec 23, 2015
Messages
1,275
Helped
314
Reputation
628
Reaction score
312
Trophy points
83
Location
Madrid, Spain
Activity points
8,409
Hello guys,

I am facing an "X" error on the test bench of a signal but I do not know why.

I believe it could be because of the following:

Code:
signal a: unsigned (9 downto 0) := whatever..
signal someSIGNAL: std_logic;

a <= a+1 when someSIGNAL='1' else a;

Does that produce some kind of error ?

Or could it be the following ?
Code:
a <= a+1 when rising_edge(someSIGNAL) else a;

Thank you in advance !
 
Last edited:

unless you are omitting some code, someSIGNAL is always x. what did you expect to happen here? the when statement cannot resolve.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Xs occur when you have multiple drivers on the same signal.
Please post the whole code.

Also

a <= a+1 when rising_edge(someSIGNAL) else a;

Is meaningless in hardware. You're asking for an action on A outside of the rising edge of the clock, which wont synthesise.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Here is the whole code and explanation of what I am trying to do.

I have successfully managed to draw the objects on the screen VGA 640x480 with Spartan-3 board.

The next step is to make them move, which is where I got the error "XXXXXX..." on the signal OUTbordeIZQ_pelota because is the only for the one I made the test bench, so I believe the same problem would apply for the rest of signals in the same position.

Let's focus on that signal.

The "signal OUTbordeIZQ_pelota" represents the left border of the circular "ball" I am trying to move i.e. change its position 1 pixel to the right every 60 Hz.
NOTE: the circular ball is drawn as a circle (see its bit map) but I am treating its position as a 16x16 square, so OUTbordeIZQ_pelota = top left border of the square.

Here is the picture of the thing. The module I am goingo to show the code is on the right pointed with arrow.



Here is the code. I have written what things worked 100% to make it easier for you. Problem starts when introducing speed to change position to the "ball" and on assigning that position to the ball.

NOTE: OUTbordeIZQ_pelota is assigned from bordeIZQ_pelota at the very end of the code for test bench purpose. In the code, follow the signal "bordeIZQ_pelota".

THE CODE:

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity objetos is
	PORT (
		OUTbordeIZQ_pelota: out std_logic_vector(9 downto 0); --just for TEST BENCH
		OUTpulso_60Hz: out std_logic;                                     -- just for TEST BENCH
		hC:			in std_logic_vector(9 downto 0);--horizontal counter
		vC:			in std_logic_vector(9 downto 0);--vertical counter
		displayON:	in std_logic;--tels when can be drawn
		clr:			in std_logic;
		mover: 		in std_logic_vector(3 downto 0);--moves the object vertically and horizontally
		rgb:	 		out std_logic_vector(2 downto 0)
		);
end objetos;
---------------

architecture Behavioral of objetos is
--HBP = horizontal back porch, HSP=horizontal sync pulse/same with Vertical
constant OFFSET_H:	integer :=160;-- HBP+HSP+HFP=offset horizontal
constant OFFSET_V:	integer :=41;-- VBP+VSP+VFP=offset vertical

--the WALL OBJECT
constant ANCHO_PARED:		integer :=20;--this is width of the wall
constant bordeIZQ_pared:	integer :=30+OFFSET_H; --where the wall is placed horizontally

--the BALL object
constant l:	integer :=16; 
constant bordeIZQinicial_pelota		:integer :=520+OFFSET_H;
constant bordeARRIBAinicial_pelota	:integer :=(480/2-l/2)+OFFSET_V;--initial position
signal bordeIZQ_pelota:		unsigned(hC'range) :=to_unsigned(bordeIZQinicial_pelota,hC'length); --where the ball is placed horizontally
signal bordeARRIBA_pelota:	unsigned(vC'range) :=to_unsigned(bordeARRIBAinicial_pelota,vC'length); --where the ball is placed vertically
signal velPelota_h :	integer :=1;--speed of ball horizontally
signal velPelota_v : integer :=0;-- speed of ball vertically

--The BAR object
constant ANCHO_RAQUETA: 		integer :=8;
constant LARGO_RAQUETA: 		integer :=70;
constant bordeIZQinicial_raqueta :integer :=600+OFFSET_H;--Initial position of the bar
signal bordeIZQ_raqueta:		unsigned(hC'range) :=to_unsigned(bordeIZQinicial_raqueta,hC'length);
constant bordeARRIBAinicial_raqueta :integer :=(480/2-LARGO_RAQUETA/2)+OFFSET_V;
signal bordeARRIBA_raqueta:	unsigned(vC'range) :=to_unsigned(bordeARRIBAinicial_raqueta,vC'length);
constant vel_raqueta: integer :=1;

--Signals wchich tell when the Wall, ball or bar can be drawn
signal paredON: std_logic;
signal pelotaON: std_logic;
signal raquetaON: std_logic;

signal hCounter,vCounter: unsigned(hC'range);--this are the counters in unsigned
 signal pulso_60Hz: std_logic;--because of this pulse I have problema on test bench
--This pulse is used to change the position of the ball,barr i.e. every 60 Hz

--The ball as a circle
type circumferencia is array(natural range <>) of std_logic_vector(0 to 15);
constant circulo: circumferencia(0 to 15) :=
(
	"0000111111110000",
	"0001111111111000",
	"0011111111111100",
	"0111111111111110",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"1111111111111111",
	"0111111111111110",
	"0011111111111100",
	"0001111111111000",
	"0000111111110000"
);

begin
hCounter <= unsigned(hC);
vCounter <= unsigned(vC);

process(clr)--All objects to their initial position
begin
if clr='1' then
		bordeIZQ_pelota <= to_unsigned(bordeIZQinicial_pelota,hC'length);--left border of ball
		bordeARRIBA_pelota <= to_unsigned(bordeARRIBAinicial_pelota,vC'length);--top border of ball
		bordeIZQ_raqueta <= to_unsigned(bordeIZQinicial_raqueta,hC'length);--left border of bar
		bordeARRIBA_raqueta <= to_unsigned(bordeARRIBAinicial_raqueta,vC'length);--high border of bar
	end if;
end process;

[B]--Tell when the wall,ball,bar is ON (THIS WORKS WELL)[/B]	
paredON <= '1' when ((hCounter >= bordeIZQ_pared) and (hCounter < bordeIZQ_pared + ANCHO_PARED) and displayON='1') else '0';
pelotaON <= '1' when (((hCounter >= bordeIZQ_pelota) and (hCounter < bordeIZQ_pelota + l)) and ((vCounter >= bordeARRIBA_pelota) and (vCounter < bordeARRIBA_pelota + l)) and displayON='1' and circulo(to_integer(vCounter - bordeARRIBA_pelota))(to_integer(hCounter - bordeIZQ_pelota))='1') else '0'; -- ESTE ES PARA pelota circumferencia
raquetaON <= '1' when (((hCounter >= bordeIZQ_raqueta) and (hCounter < bordeIZQ_raqueta + ANCHO_RAQUETA)) and ((vCounter >= bordeARRIBA_raqueta) and (vCounter < bordeARRIBA_raqueta + LARGO_RAQUETA)) and displayON='1') else '0';

[B]--Assignment of “rgb” depending which object is ON (THIS WORKS WELL)[/B]
process(paredON,pelotaON,raquetaON,displayON)
begin
	if displayON = '0' then
		rgb <= "000"; --no mandar señal al "rgb"
	else -- es ELSE y no ELSIF por si se cumplen 2 o mas a la vez, priorizar a una de ellas
		if paredON ='1' then
			rgb <="010"; --color verde a la PARED
		elsif pelotaON ='1' then
			rgb <="110"; --color amarillio a la PELOTA
		elsif raquetaON = '1' then
			rgb <="001"; --color azul a la RAQUETA
		else
			rgb <="100"; --color rojo al FONDO DE LA PANTALLA
		end if;
	end if;
end process;

[B]--How I get the 60Hz pulse[/B]
pulso_60Hz <= '1' when (vCounter = 519 and hCounter = 0 ) else '0';--the time to take this pulse off is the time it takes hCounter to increment i.e. the hCounter increments at 25MHz freq

[B]--Move the barr up,down,left,right (HERE MIGHT BE PROBLEM)[/B]
process(pulso_60Hz,mover(1),mover(0),mover(2),mover(3))
begin
	[B]bordeARRIBA_raqueta <= bordeARRIBA_raqueta; --leave it as it was if no pulse[/B]
	[B]bordeIZQ_raqueta <= bordeIZQ_raqueta;[/B]
	if pulso_60Hz'event and pulso_60Hz = '1' then
		if mover(1)='1' and (bordeARRIBA_raqueta - vel_raqueta > OFFSET_V) then
			bordeARRIBA_raqueta <= bordeARRIBA_raqueta-vel_raqueta;--mover hacia arriba
		elsif mover(0)='1' and (bordeARRIBA_raqueta+LARGO_RAQUETA+vel_raqueta < OFFSET_V+479) then 
			bordeARRIBA_raqueta <= bordeARRIBA_raqueta+vel_raqueta;--mover hacia abajo
		elsif mover(2)='1' and (bordeIZQ_raqueta+ANCHO_RAQUETA+vel_raqueta < OFFSET_H+679) then
			bordeIZQ_raqueta <= bordeIZQ_raqueta+vel_raqueta;--mover hacia la derecha
		elsif mover(3)='1' and (bordeIZQ_raqueta-vel_raqueta > bordeIZQ_pared+ANCHO_PARED) then
			bordeIZQ_raqueta <= bordeIZQ_raqueta-vel_raqueta;--mover hacia la izquierda
		end if;
	end if;
end process;

[B]--HERE STARTS the MOVEMENT OF THE BALL[/B]

--space=initial space + speed (here will change the position of the ball)
bordeIZQ_pelota <= bordeIZQ_pelota + velPelota_h when (pulso_60Hz='1') else bordeIZQ_pelota;
bordeARRIBA_pelota <= bordeARRIBA_pelota + velPelota_v when (pulso_60Hz='1') else bordeARRIBA_pelota;

--here change the direction of the speed of the ball depending on the collision with objects
process(bordeIZQ_pelota,bordeARRIBA_pelota,bordeARRIBA_raqueta,bordeIZQ_raqueta,velPelota_h,velPelota_v)
begin
	velPelota_h <= velPelota_h;
	velPelota_v <= velPelota_v;
	
	if (bordeARRIBA_pelota <= 0 + OFFSET_V) or (bordeARRIBA_pelota+l >= 479+OFFSET_V) then
		velPelota_v <= (-1)*velPelota_v;
	--collision with WALL
	elsif bordeIZQ_pelota <= bordeIZQ_pared + ANCHO_PARED then
		velPelota_h <= (-1)*velPelota_h;
	--collision with BAR
	elsif (bordeIZQ_pelota+l >= bordeIZQ_raqueta) and (bordeIZQ_pelota+l <= bordeIZQ_raqueta+ANCHO_RAQUETA) then
		if (bordeARRIBA_pelota >= bordeARRIBA_raqueta) and (bordeARRIBA_pelota+l <= bordeARRIBA_raqueta+LARGO_RAQUETA) then
			velPelota_h <= (-1)*velPelota_h;
		end if;
	end if;	
end process;

[B]--collision with the right limit of the game => put the ball on its initial posiition[/B]
process (bordeIZQ_pelota)--each time the ball moves i.e. changes its horizontal reference position
begin
	[B]bordeIZQ_pelota <= bordeIZQ_pelota;--THIS IS CORRECT? [/B]
	[B]bordeARRIBA_pelota <= bordeARRIBA_pelota;[/B]
	if bordeIZQ_pelota+l >= 639 + OFFSET_H then
		bordeIZQ_pelota <= to_unsigned(bordeIZQinicial_pelota,hC'length);
		bordeARRIBA_pelota <= to_unsigned(bordeARRIBAinicial_pelota,vC'length);
	end if;
end process;

[B]--THIS IS JUST for TEST BENCH purpose[/B]
OUTbordeIZQ_pelota <= std_logic_vector(bordeIZQ_pelota);
OUTpulso_60Hz <= pulso_60Hz;
end Behavioral;
 
Last edited:

I HAVE SOLVED THE PROBLEM !

As I am a beginner in VHDL, I still think as in software.
The problem obviously was what you guys said. A signal can only be assigned in one process, not multiple processes.

So the solution was to create another signal (an auxiliary signal).

As I am a beginner, could you guys answer me the following questions which are related to this?

1) Why one can only assign something to a signal only in one process ? The signal is just to communicante within the Architecture, is not an output...

2) If I want to make another process which detects when the ball hits the right limit of the screen which resets the position of the ball, another auxiliary signal must be used. Is that the correct approach ? If I want to introduce 10 different features to my game, do I have to add 1 auxiliary signal for each feature ? Is that how it works ?

3) I have the following code which works well.
Code:
pulso_60Hz <= '1' when (vCounter = 519 and hCounter = 0 ) else '0';

bordeIZQ_pelotaNEXT <= bordeIZQ_pelota + velPelota_h when (pulso_60Hz='1') else bordeIZQ_pelota;

If I add this to the "bordeIZQ_pelotaNEXT" gives me error. why ?
Code:
bordeIZQ_pelotaNEXT <= bordeIZQ_pelota + velPelota_h when [B]rising_edge(pulso_60Hz)[/B] else bordeIZQ_pelota;

It says this:

Signal bordeIZQ_pelotaNEXT cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
 
Last edited:

bordeIZQ_pelota is assigned in a process and in a stand alone assignement:

here:
Code:
bordeIZQ_pelota <= bordeIZQ_pelota + velPelota_h when (pulso_60Hz='1') else bordeIZQ_pelota;

and here:

Code:
--collision with the right limit of the game => put the ball on its initial posiition
process (bordeIZQ_pelota)--each time the ball moves i.e. changes its horizontal reference position
begin
	bordeIZQ_pelota <= bordeIZQ_pelota;--THIS IS CORRECT? 
	bordeARRIBA_pelota <= bordeARRIBA_pelota;
	if bordeIZQ_pelota+l >= 639 + OFFSET_H then
		bordeIZQ_pelota <= to_unsigned(bordeIZQinicial_pelota,hC'length);
		bordeARRIBA_pelota <= to_unsigned(bordeARRIBAinicial_pelota,vC'length);
	end if;
end process;

You cannot assign it in both places.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Yes, and in the process(clr) at the very beginning of the Architecture. Could you tell me why is that an error ?
 

Yes, and in the process(clr) at the very beginning of the Architecture. Could you tell me why is that an error ?

You answered yourself earlier, because you think in terms of software. VHDL is not software.

Driving a signal from multiple processes or assignments is the equvalent of shorting the outputs of multiple gates and FFs together. The end result is unknown as one or more outputs could be driving the shared signal to different logic levels.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Yes, and in the process(clr) at the very beginning of the Architecture. Could you tell me why is that an error ?

Its not an error in VHDL, it's an error in hardware - you're wiring two signals together and because each one is driving a different value you get X = Unknown.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Thank you both !

Could you give me some insight about question 3) in post #5 ?
 

Signal bordeIZQ_pelotaNEXT cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

"Trying to implement a register that doesn't hold the state between clock edges" could be a clearer message.

Synthesizable register descriptions need to follow specific templates. They are explained in many VHDL tutorials and text books. The well-known DFF template:

Code:
process ( CLK, RESET) begin
  if RESET = ’1’ then
    Q <= ’0’;
  elsif rising_edge(CLK) then
    Q <= DATA;
  end if;
end process;
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top