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 rocess (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;
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 rocess (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;