Problem with initialising a signed signal

Z

Zheyu.Gao

Hi, I am having a problem which I can not initialise a signed signal
with this expression

signal c_x,c_y,n_x,n_y:signed(6 downto 0);

c_x <= "0000000";

I have also tried

c_x<=signed'("0000000");

but both don't work, the simulation always show c_x=UUUUUUU.

code is
below---------------------------------------------------------------------------------


-- vdp draw block
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
--USE ieee.std_logic_arith.ALL;
--USE work.vdp_pack.ALL;
--USE work.utility_pack.ALL;

entity draw_block is
port(
-- clock and reset
clk: in std_logic;
reset: in std_logic;
-- interface with Host Processor
dav: in std_logic;
hdb: in std_logic_vector( 15 downto 0 );
hdb_busy: out std_logic;
-- interface with RCB
ack: in std_logic;
drawpixel: out std_logic;
flush: out std_logic;
x: out std_logic_vector( 5 downto 0 );
y: out std_logic_vector( 5 downto 0 );
pen: out std_logic_vector( 1 downto 0 )
);
end draw_block;

architecture rtl of draw_block is

----------------------------------------------
-- FSMs type definition
----------------------------------------------
type fsm_1_type is (init,preparing, operating, finish );
type fsm_2_type is (start,drawing,done);

----------------------------------------------
-- control source for FSMs
----------------------------------------------
signal n_state_fsm1, c_state_fsm1: fsm_1_type;
signal n_state_fsm2, c_state_fsm2: fsm_2_type;
signal fsm2_en : std_logic;
----------------------------------------------
-- data source for drawing and clearscreen
----------------------------------------------
--signal c_x,c_y,n_x,n_y: STD_LOGIC_VECTOR(5 downto 0);
signal c_x,c_y,n_x,n_y:signed(6 downto 0);
signal op: STD_LOGIC_VECTOR(1 downto 0);
signal d_x,d_y : integer range -1 to 1;




begin

state_reg: process (clk,reset)
begin
if (reset='1') then
c_state_fsm1 <= init;
c_state_fsm2 <= done;
elsif (clk'event and clk='1') then
c_state_fsm1 <= n_state_fsm1;
if fsm2_en = '1' then
c_state_fsm2 <= n_state_fsm2;
end if;
end if;
end process state_reg;

comb_logic_fsm1: process(c_state_fsm1,c_state_fsm2,dav)
begin
case c_state_fsm1 is

when init => hdb_busy <= '0';
fsm2_en <= '0';
c_x <= signed'("0000000"); -- here is the
problem, when c_state_fsm1= init, which is the state in simulation,
but c_x still = UUUUUUU.
c_y <= signed'("0000000");
--if dav='0' then
-- n_state_fsm1 <= init;
if dav ='1' then
n_state_fsm1 <= preparing;
--n_state_fsm2 <= start;
n_x<=signed('0'&hdb(7 downto 2));
n_y<=signed('0'&hdb(13 downto 8));
op<=hdb(15 downto 14);
pen<=hdb(1 downto 0);
else
n_state_fsm1 <= init;
end if;

when preparing => hdb_busy <= '1';
fsm2_en <= '0';
n_state_fsm1 <= operating;
--n_state_fsm2 <= start;

when operating => hdb_busy <= '1';
fsm2_en <= '1';
if c_state_fsm2= done then
n_state_fsm1 <= finish;
else
n_state_fsm1 <= operating;
end if;

when finish => hdb_busy <= '0';
fsm2_en <= '0';
if dav='0' then
n_state_fsm1 <= finish;
elsif dav ='1' then
n_state_fsm1 <= preparing;
--n_state_fsm2 <= start;
n_x<=signed('0'&hdb(7 downto 2));
n_y<=signed('0'&hdb(13 downto 8));
op<=hdb(15 downto 14);
pen<=hdb(1 downto 0);
end if;

when others =>
Null;
end case;
end process;

comb_logic_fsm2: process(c_state_fsm1,c_state_fsm2,op,ack)
begin

case c_state_fsm2 is

when start => drawpixel<='0';
flush <='0';
if c_x /= n_x and c_x /= n_x then
x<=std_logic_vector(c_x(5 downto 0));
y<=std_logic_vector(c_y(5 downto 0));
if c_state_fsm1=operating then
n_state_fsm2<= drawing;
end if;
else
n_state_fsm2<= done;
end if;


when drawing =>
case op is
when "00" =>
c_x<=n_x;
c_y<=n_y;
n_state_fsm2<= done;
when "01" =>
if ack='1' then
drawpixel<='1';
c_x<=c_x+d_x; --update
c_y<=c_y+d_y;--update
n_state_fsm2<= start;
else
n_state_fsm2<= drawing;
end if;

when "10" =>

when "11" =>
flush <='1';
n_state_fsm2<= done;
when others =>
Null;

end case;

when done => drawpixel<='0';
flush <='0';

when others =>
Null;
end case;

end process;

offset_cal :process (c_state_fsm1,c_state_fsm2,c_x,c_y,n_x,n_y)
variable Dx,Dy :signed(6 downto 0);
variable err,d_err1,d_err2 :signed(6 downto 0);
variable x1,y1,x2,y2 : integer range -1 to 1;
variable octant: std_logic_vector(2 downto 0);

begin
if (c_state_fsm1 = preparing) and (c_state_fsm2 = start) then
Dx:=n_x - c_x;
Dy:=n_y - c_y;
err:="0000000";
if Dx>0 then
octant(2):='1';
else
octant(2):='0';
end if;
if Dy>0 then
octant(1):='1';
else
octant(1):='0';
end if;
if abs(Dx)>abs(Dy) then
octant(0):='1';
else
octant(0):='0';
end if;
end if;

--octant:=(Dx>0)&(Dy>0)&(abs(Dx)>abs(Dy));
case octant is

when "111" =>
x1:=1; y1:=1; x2:=1; y2:=0;
d_err1:=Dy-Dx; d_err2:=Dy;
when "110" =>
x1:=0; y1:=1; x2:=1; y2:=1;
d_err1:=-Dx; d_err2:=Dy-Dx;
when "010" =>
x1:=-1; y1:=1; x2:=0; y2:=1;
d_err1:=-Dy-Dx; d_err2:=-Dx;
when "011" =>
x1:=-1; y1:=0; x2:=-1; y2:=1;
d_err1:=Dy; d_err2:=-Dy-Dx;
when "001" =>
x1:=-1; y1:=-1; x2:=-1; y2:=0;
d_err1:=-Dy+Dx; d_err2:=-Dy;
when "000" =>
x1:=0; y1:=-1; x2:=-1; y2:=-1;
d_err1:=Dx; d_err2:=-Dy+Dx;
when "100" =>
x1:=1; y1:=-1; x2:=0; y2:=-1;
d_err1:=Dy+Dx; d_err2:=Dx;
when "101" =>
x1:=1; y1:=0; x2:=1; y2:=-1;
d_err1:=Dy; d_err2:=Dy+Dx;
when others =>
null;
end case;

if c_state_fsm2 = start then
if abs(err+d_err1)<abs(err+d_err2)then
d_x<=x1; d_y<=y1; err:=err+d_err1;
else
d_x<=x2; d_y<=y2; err:=err+d_err2;
end if;

end if;


end process ;

end;
 
T

Tricky

It is because you have C_x and C_y assigned in 2 separate processes.
You should not do this in most designs, signals should be kept within
a single process.

There are also several other major errors with the code:
Incomplete sensitivity lists:
You are missing hdb from comb_logic_fsm1
(n_x, n_y, c_x, c_y, d_x, d_y) from comb_logic_fsm2 in addition to
having signals in the list that should not be there

Many signals are not assigned in every single case in the asynchronous
process - this leads to transparent latches. This is probably as a
result of the first point.
 
K

KJ

Hi, I am having a problem which I can not initialise a signed signal

The problem is that you're assigning to signal 'c_x' in two processes:
comb_logic_fsm1 and comb_logic_fsm2. While you're tracing through fsm1 and
seeing where it should be assigning '0' to all bits, fsm2 is assigning 'U'
to all bits. This gets resolved to be 'U' by the simulator.

If this is intended to be synthesized into a real device, your synthesis
tool will stop with an error because c_x has two drivers

Lastly, use of combinatorial processes for synthesizable code is not
recommended.

Kevin Jennigns
 
Z

Zheyu.Gao

It is because you have C_x and C_y assigned in 2 separate processes.
You should not do this in most designs, signals should be kept within
a single process.

There are also several other major errors with the code:
Incomplete sensitivity lists:
You are missing hdb from comb_logic_fsm1
(n_x, n_y, c_x, c_y, d_x, d_y) from comb_logic_fsm2 in addition to
having signals in the list that should not be there

Many signals are not assigned in every single case in the asynchronous
process - this leads to transparent latches. This is probably as a
result of the first point.

Hi, Tricky

Thank you for the reply, so if I don't include the
c_x <= signed'("0000000");
c_y <= signed'("0000000");
in the comb_logic_fsm1, only have them in the other process, How do I
initialise the C_x, C_y when reset=1?
 
Z

Zheyu.Gao

The problem is that you're assigning to signal 'c_x' in two processes:
comb_logic_fsm1 and comb_logic_fsm2.  While you're tracing through fsm1 and
seeing where it should be assigning '0' to all bits, fsm2 is assigning 'U'
to all bits.  This gets resolved to be 'U' by the simulator.

If this is intended to be synthesized into a real device, your synthesis
tool will stop with an error because c_x has two drivers

Lastly, use of combinatorial processes for synthesizable code is not
recommended.

Kevin Jennigns

Hi, KJ

Thank you for the reply, so if I don't include the
c_x <= signed'("0000000");
c_y <= signed'("0000000");
in the comb_logic_fsm1, only have them in the other process, How do I
initialise the C_x, C_y when reset=1?
 
K

KJ

Hi, KJ

Thank you for the reply, so if I don't include the
c_x <= signed'("0000000");
c_y <= signed'("0000000");
in the comb_logic_fsm1, only have them in the other process, How do I
initialise the C_x, C_y when reset=1?

1. You'll have to decide which process generates these outputs. It
can only come out of one, no more, no less. Re-write your code
appropriately to accomplish that.

2. If this design is intended to be implemented in hardware, then
strongly consider abandoning your use of unclocked processes. The
code you've posted contains several examples of why one should
(almost) never use such beasts since they will lead to a situation
where simulation says one thing, but the synthesized hardware does
something else because it is not truly able to implement your
description accurately. Make every process be of the form of your
'state_reg' process (although I would further recommend removing the
asynchronous reset as well, make the reset be inside the "if
(clk'event and clk='1') then...". Also you need to make sure that the
reset signal itself has been synchronized before using it...so you get
down to something like the following...
process(clock)
begin
if rising_edge(clock) then
reset_synchronized <= reset; -- Use 'reset' nowhere else
if (reset_synchronized = '1') then
-- Reset things that need resetting here
else
-- The rest of your logic goes here
end if;
end if;
end process;

Kevin Jennings
 
T

Tricky

Hi, KJ

Thank you for the reply, so if I don't include the
c_x <= signed'("0000000");
c_y <= signed'("0000000");
in the comb_logic_fsm1, only have them in the other process, How do I
initialise the C_x, C_y when reset=1?

2 options:

1. combine the 2 state machines into 1.
2. have fsm2 as a controlling signal inside fsm1.
so for every state, you'd same something like:
if fsm2 = drawing and op = "00" then
c_x <= "0000001";
else
c_x <= "1000000";
end if;

etc.

Ideally, you'd move over from the dual process (clocked and
asynchronous) state machine architecture to the single process clocked
one. Would make synthesis easier, and probably a bit safer.
 
A

Andy

Asynchronous vs synchronous reset has nothing to do with his problem.
Many systems require known outputs even in the absence of a clock
signal. A properly designed asyncrhonous reset is the only way to
achieve that.

I agree wholeheartedly with avoiding combinatorial processes if at all
possible. Use of variables within clocked processes can make it easier
to express complex or repetitive combinatorial logic within a clocked
process.

Andy
 
K

KJ

Asynchronous vs synchronous reset has nothing to do with his problem.

I didn't say that it did. Point #2, which you're replying to, was a
list of additional things that I think the OP should consider doing.
Many systems require known outputs even in the absence of a clock
signal.

Many systems do not though...

Kevin Jennings
 
A

Andy

I didn't say that it did.  Point #2, which you're replying to, was a
list of additional things that I think the OP should consider doing.


Many systems do not though...

Kevin Jennings

Kevin,

Sorry, I mistated my objection. I do not necessarily prefer either
sync or async resets unless the required behavior dictates one over
the other. Most of my projects require the behavior of an async reset,
but others' may not. I also know that too many individuals assume that
synchronization of the reset signal is only required if you implement
sync reset. Proper synchronization (of the deasserting edge) of an
async reset signal is no more difficult than that for sync resets, if
you know you have to do it in the first place.

However, all the other issues in #2 had to do with advantages of one
coding representation over another, without affecting actual circuit
behavior. Recommending a change from async to sync reset is such a
change in behavior, and should only be considered if supported by the
required behavior. Not knowing the requirements, it is impossible to
say which is preferable.

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top