SOS! newbie question about synthesizable VHDL : synthesis run successfully but post-synthesis failed

W

walala

Dear all,

I am a student who is learning VHDL... after having tried some adders,
counters design, I began a simple design of my own...

I want the program to get in 6 inputs X(0)-x(5)(11 bits each) at a
time, and do some internal computation, then output a 8x8 matrix, one
row at a clock: (Y(0) to Y(7), 8 bits each, next clock compute the
next Y(0) to Y(7), ...

So I set up a 8-counter: temp1 is a temparory varaiable whose value is
dependent on the counter, when the counter is 0, the output is Y00,
Y01, Y02, Y03, Y04, Y05, Y06, Y07, when the counter is 1, the output
is Y10, Y11, Y12, Y13, Y14, Y15, Y16, Y17, etc...

The top half values of "temp1" are the values we want... but I want to
do some rounding, hence I pick the wanted value + one more bit from
"temp1" to put into "temp" variable, then the output "Y" are
formulated from "temp" via rounding...

The pre-synthesis simulation run perfectly... But post-synthesis
simulation failed, the outputs
became "XXXXXXXXXXXXX"(no values); some internal nodes have "0", some
internal nodes have "1", and the other internal nodes have "X"... but
the
internal nodes were stuck with their values: the "0"s were always "0",
the
"1"s were always "1", the "X"s were always "X"...

I have a feeling that

1) the counter does not work at all;
2) the counter may need to initially set at 0, in simulation we can do
it by variable initial value, but in reality(after synthesis) there is
no way to set initial values in VHDL...
3) some parts are actually not synthesizable, or not synthesize to
what I want, but the Synopsys DC did not tell me...

Can anybody help me out of this swamp?

Thanks a lot,

-Walala

----------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

PACKAGE MYTYPES IS
SUBTYPE INPUT_WORD IS INTEGER RANGE -1024 TO 1023;
SUBTYPE OUTPUT_BYTE IS STD_LOGIC_VECTOR(7 downto 0); -- -128 TO
127;
SUBTYPE TEMP_BYTE IS STD_LOGIC_VECTOR(8 downto 0); -- -256 TO 255;
SUBTYPE INTERNAL_WORD IS INTEGER RANGE -65536 TO 65535;
TYPE INPUT_WORD_ARRAY IS ARRAY(0 TO 5) OF INPUT_WORD;
TYPE OUTPUT_BYTE_ARRAY IS ARRAY(0 TO 7) OF OUTPUT_BYTE;
TYPE TEMP_BYTE_ARRAY IS ARRAY(0 TO 7) OF TEMP_BYTE;
END PACKAGE MYTYPES;


USE work.mytypes.all;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

ENTITY mytry IS
PORT(clk : IN std_logic;
x : IN INPUT_WORD_ARRAY;
y : OUT OUTPUT_BYTE_ARRAY);
END mytry;

ARCHITECTURE flex OF mytry IS

SIGNAL t1, t2, t3, t4, t5, t6, t7: INTERNAL_WORD;

BEGIN

t1<=32*x(0);
t2<=44*x(1);
t3<=38*x(2);
t4<=25*x(3);
t5<=9*x(4);
t6<=7*x(5);
t7<=3*x(1);

p1: PROCESS(clk, t1, t2, t3, t4, t5)
VARIABLE count: INTEGER RANGE 0 TO 8;
VARIABLE i: INTEGER RANGE 0 TO 7;
VARIABLE temp1: INTERNAL_WORD;
VARIABLE temp: TEMP_BYTE_ARRAY;
BEGIN
if rising_edge(clk) then
case count is
when 0 =>
temp1:=t1+t2;
when 1 =>
temp1:=t1+t3;
when 2 =>
temp1:=t1+t4;
when 3 =>
temp1:=t1+t5;
when 4 =>
temp1:=t1-t5;
when 5 =>
temp1:=t1-t4;
when 6 =>
temp1:=t1-t3;
when 7 =>
temp1:=t1-t2;
when others => null;
end case;

count:=count+1;
if count=8 then
count:=0;
end if;

temp(0):=CONV_STD_LOGIC_VECTOR(temp1+t6, 17)(15 downto 7);
temp(1):=CONV_STD_LOGIC_VECTOR(temp1+t7, 17)(15 downto 7);
temp(2):=CONV_STD_LOGIC_VECTOR(temp1-t7, 17)(15 downto 7);
temp(3):=CONV_STD_LOGIC_VECTOR(temp1-t6, 17)(15 downto 7);
temp(4):=CONV_STD_LOGIC_VECTOR(temp1-t6, 17)(15 downto 7);
temp(5):=CONV_STD_LOGIC_VECTOR(temp1-t7, 17)(15 downto 7);
temp(6):=CONV_STD_LOGIC_VECTOR(temp1+t7, 17)(15 downto 7);
temp(7):=CONV_STD_LOGIC_VECTOR(temp1+t6, 17)(15 downto 7);

for i in 0 to 7 loop
if temp(i)(0)='1' then
Y(i)<=temp(i)(8 downto 1) + 1;
else
Y(i)<=temp(i)(8 downto 1);
end if;
end loop;

end if;
END PROCESS;

END flex;
 
T

Technology Consultant

Dear all,

I am a student who is learning VHDL... after having tried some adders,
counters design, I began a simple design of my own...

I want the program to get in 6 inputs X(0)-x(5)(11 bits each) at a
time, [..]

Do you really have 6*11=66 pins to get your data in ?
[..]and do some internal computation, then output a 8x8 matrix, one
row at a clock: (Y(0) to Y(7), 8 bits each,[..]

Do you really have 8*8=64 pins to get your data out ?

altogether:

Are you sure you can have 64+66=130 pins for your data?
[..]next clock compute the
next Y(0) to Y(7), ...
So I set up a 8-counter: temp1 is a temparory varaiable whose value is
dependent on the counter, when the counter is 0, the output is Y00,
Y01, Y02, Y03, Y04, Y05, Y06, Y07, when the counter is 1, the output
is Y10, Y11, Y12, Y13, Y14, Y15, Y16, Y17, etc...

Before that:

Don't you need a reset?

hint: The usual answer to that question is "yes"...

----------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

PACKAGE MYTYPES IS
SUBTYPE INPUT_WORD IS INTEGER RANGE -1024 TO 1023;
SUBTYPE OUTPUT_BYTE IS STD_LOGIC_VECTOR(7 downto 0); -- -128 TO 127;

And why not:
SUBTYPE INPUT_WORD IS STD_LOGIC_VECTOR(11 downto 0); -- -1024 TO 1023;

SUBTYPE TEMP_BYTE IS STD_LOGIC_VECTOR(8 downto 0); -- -256 TO 255;
SUBTYPE INTERNAL_WORD IS INTEGER RANGE -65536 TO 65535;
TYPE INPUT_WORD_ARRAY IS ARRAY(0 TO 5) OF INPUT_WORD;
TYPE OUTPUT_BYTE_ARRAY IS ARRAY(0 TO 7) OF OUTPUT_BYTE;
TYPE TEMP_BYTE_ARRAY IS ARRAY(0 TO 7) OF TEMP_BYTE;
END PACKAGE MYTYPES;


USE work.mytypes.all;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

ENTITY mytry IS
PORT(clk : IN std_logic;

include your reset:

rst : IN std_logic;
x : IN INPUT_WORD_ARRAY;
y : OUT OUTPUT_BYTE_ARRAY);
END mytry;


Define your specs, then post again, we'll be happy to help.

(e-mail address removed)
http://technologyconsultant.gmxhome.de
 
R

Renaud Pacalet

walala said:
Dear all,

I am a student who is learning VHDL... after having tried some adders,
counters design, I began a simple design of my own...

I want the program to get in 6 inputs X(0)-x(5)(11 bits each) at a
time, and do some internal computation, then output a 8x8 matrix, one
row at a clock: (Y(0) to Y(7), 8 bits each, next clock compute the
next Y(0) to Y(7), ...

So I set up a 8-counter: temp1 is a temparory varaiable whose value is
dependent on the counter, when the counter is 0, the output is Y00,
Y01, Y02, Y03, Y04, Y05, Y06, Y07, when the counter is 1, the output
is Y10, Y11, Y12, Y13, Y14, Y15, Y16, Y17, etc...

The top half values of "temp1" are the values we want... but I want to
do some rounding, hence I pick the wanted value + one more bit from
"temp1" to put into "temp" variable, then the output "Y" are
formulated from "temp" via rounding...

The pre-synthesis simulation run perfectly... But post-synthesis
simulation failed, the outputs
became "XXXXXXXXXXXXX"(no values); some internal nodes have "0", some
internal nodes have "1", and the other internal nodes have "X"... but
the
internal nodes were stuck with their values: the "0"s were always "0",
the
"1"s were always "1", the "X"s were always "X"...

I have a feeling that

1) the counter does not work at all;
2) the counter may need to initially set at 0, in simulation we can do
it by variable initial value, but in reality(after synthesis) there is
no way to set initial values in VHDL...
3) some parts are actually not synthesizable, or not synthesize to
what I want, but the Synopsys DC did not tell me...

Can anybody help me out of this swamp?

Certainly yes but, please, try to post a simple and small testcase
instead of your whole design. It's very easy to downsize your design to
a much simpler one that has exactly the same problem. And those that
accept to help you will read 10 lines of spec plus 10 lines of code and
answer in 10 lines. Thanks. Several points are wrong with your process.
I'll tell you what and you'll have a look at a VHDL book or at
comp.lang.vhdl FAQ to understand the why:
1) Your process should be sensitive to clock and async reset only.
2) You don't need to declare a variable I for your loop index.
3) As TechnologyConsultant pointed out you need to reset your counter.
An asynchronous reset example:
process(clk, rst)
VARIABLE count: INTEGER RANGE 0 TO 8;
VARIABLE temp1: INTERNAL_WORD;
VARIABLE temp: TEMP_BYTE_ARRAY;
BEGIN
if rst = '0' then
count := 0;
if rising_edge(clk) then
case count ...
A synchronous reset example:
process(clk)
VARIABLE count: INTEGER RANGE 0 TO 8;
VARIABLE temp1: INTERNAL_WORD;
VARIABLE temp: TEMP_BYTE_ARRAY;
BEGIN
if rising_edge(clk) then
if rst = '0' then
count := 0;
else
case count ...
4) You're using a Synopsys std_something package. You should use
IEEE.NUMERIC_STD instead.

Regards,
 
W

walala

Hi TechnologyConsultant,

thank you for your answer.
Do you really have 6*11=66 pins to get your data in ?

Let's just imagine this design is not a chip itself, it is some module
internal to the chip, hence I guess I can use some parallel bus... (am
I right?)
And why not:
SUBTYPE INPUT_WORD IS STD_LOGIC_VECTOR(11 downto 0); -- -1024 TO 1023;

After I used your "STD_LOGIC_VECTOR(11 downto 0)" instead of the
"INTEGER RANGE -1024 TO 1023",

I got a lot of compilation error,

for instance,

t1<=32*x(0);

where t1 is STD_LOGIC_VECTOR(16 downto 0) and x(0) is
STD_LOGIC_VECTOR(11 downto 0);

The modelsim compiler says:

# ERROR: /home/min/a/xding/source/mytry.vhd(41): No feasible entries
for infix op: "*"
# ERROR: /home/min/a/xding/source/mytry.vhd(41): Type error resolving
infix expression.

what happened? Can you tell me?
 
T

Technology Consultant

Let's just imagine this design is not a chip itself, it is some module
internal to the chip, hence I guess I can use some parallel bus... (am
I right?)

If it's Ok for you, it's Ok for us...
After I used your "STD_LOGIC_VECTOR(11 downto 0)" instead of the
"INTEGER RANGE -1024 TO 1023",

I got a lot of compilation error,

for instance,

t1<=32*x(0);

where t1 is STD_LOGIC_VECTOR(16 downto 0) and x(0) is
STD_LOGIC_VECTOR(11 downto 0);

The modelsim compiler says:

# ERROR: /home/min/a/xding/source/mytry.vhd(41): No feasible entries
for infix op: "*"
# ERROR: /home/min/a/xding/source/mytry.vhd(41): Type error resolving
infix expression.

what happened? Can you tell me?

VHDL is STRONGLY TYPED and the * operand doesn't understand
INTEGER*STD_LOGIC_VECTOR, so you have to convert the STD_LOGIC_VECTOR
to
integer. You can use:

t1<=32*CONV_INTEGER(x(0)); -- Warning: Output overflows in
multiplication

Further, we have tried to understand your program, and we have
rewritten it to this:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Renaud Pacalet: use ieee.numeric_std instead of Synopsys
std_something :
-- USE ieee.numeric_std.ALL;
-- TechCon: ..depending on your tool version..
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

PACKAGE MYTYPES IS
-- TechCon: Good Design Practice: Use STD_LOGIC(_VECTOR) in the
interfaces:
SUBTYPE INPUT_WORD IS STD_LOGIC_VECTOR(11 downto 0); -- -1024 TO
1023;
SUBTYPE OUTPUT_BYTE IS STD_LOGIC_VECTOR(7 downto 0); -- -128 TO
127;
SUBTYPE TEMP_BYTE IS STD_LOGIC_VECTOR(8 downto 0); -- -256 TO 255;
SUBTYPE INTERNAL_WORD IS INTEGER RANGE -65536 TO 65535;
TYPE INPUT_WORD_ARRAY IS ARRAY(0 TO 5) OF INPUT_WORD;
TYPE OUTPUT_BYTE_ARRAY IS ARRAY(0 TO 7) OF OUTPUT_BYTE;
TYPE TEMP_BYTE_ARRAY IS ARRAY(0 TO 7) OF TEMP_BYTE;
END PACKAGE MYTYPES;


USE work.mytypes.all;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Renaud Pacalet: use ieee.numeric_std instead of Synopsys
std_something :
-- USE ieee.numeric_std.ALL;
-- TechCon: ..depending on your tool version..
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;

ENTITY mytry IS
PORT(-- TechCon: Use an Asynchronous Reset:
rst : IN std_logic;
clk : IN std_logic;
-- TechCon: Good Design Practice: Use STD_LOGIC(_VECTOR) in
the interfaces:
x : IN INPUT_WORD_ARRAY;
y : OUT OUTPUT_BYTE_ARRAY);
END mytry;

ARCHITECTURE flex OF mytry IS

SIGNAL t1, t2, t3, t4, t5, t6, t7: INTERNAL_WORD;

BEGIN
-- TechCon: Convert from STD_LOGIC(_VECTOR) to integer before
MULTIPLICATION
t1<=32*CONV_INTEGER(x(0)); -- Warning: Output overflows in
multiplication
t2<=44*CONV_INTEGER(x(1));
t3<=38*CONV_INTEGER(x(2));
t4<=25*CONV_INTEGER(x(3));
t5<= 9*CONV_INTEGER(x(4));
t6<= 7*CONV_INTEGER(x(5));
t7<= 3*CONV_INTEGER(x(1));

-- Renaud Pacalet: Your process should be sensitive to clock and
async reset only:
p1: PROCESS(clk, rst)
VARIABLE count: INTEGER RANGE 0 TO 8;
-- Renaud Pacalet: You don't need to declare a variable I for
your loop index.
-- VARIABLE i: INTEGER RANGE 0 TO 7;
VARIABLE temp1: INTERNAL_WORD;
VARIABLE temp: TEMP_BYTE_ARRAY;
BEGIN
if rst = '0' then
count := 0;
-- TechCon: Use elsif instead of "end if; if "
elsif rising_edge(clk) then
case count is
when 0 =>
temp1:=t1+t2;
when 1 =>
temp1:=t1+t3;
when 2 =>
temp1:=t1+t4;
when 3 =>
temp1:=t1+t5;
when 4 =>
temp1:=t1-t5;
when 5 =>
temp1:=t1-t4;
when 6 =>
temp1:=t1-t3;
when 7 =>
temp1:=t1-t2;
when others => null;
end case;

count:=count+1;
if count=8 then
count:=0;
end if;

temp(0):=CONV_STD_LOGIC_VECTOR(temp1+t6, 17)(15 downto 7);
temp(1):=CONV_STD_LOGIC_VECTOR(temp1+t7, 17)(15 downto 7);
temp(2):=CONV_STD_LOGIC_VECTOR(temp1-t7, 17)(15 downto 7);
temp(3):=CONV_STD_LOGIC_VECTOR(temp1-t6, 17)(15 downto 7);
temp(4):=CONV_STD_LOGIC_VECTOR(temp1-t6, 17)(15 downto 7);
temp(5):=CONV_STD_LOGIC_VECTOR(temp1-t7, 17)(15 downto 7);
temp(6):=CONV_STD_LOGIC_VECTOR(temp1+t7, 17)(15 downto 7);
temp(7):=CONV_STD_LOGIC_VECTOR(temp1+t6, 17)(15 downto 7);

for i in 0 to 7 loop
if temp(i)(0)='1' then
Y(i)<=temp(i)(8 downto 1) + 1;
else
Y(i)<=temp(i)(8 downto 1);
end if;
end loop;

end if;
END PROCESS;

END flex;

We hope that helps you further.

Send us and EMail to (e-mail address removed) if you need more
assistance.

TechCon.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top