What is wrong with the following code?

W

willem oosthuizen

I have the following code:

process(aclr_l,clk)
begin
if aclr_l = '0' then
Tx_Clk_Cnt <= (others => '0');
elsif clk'event and clk = '1' then
Tx_Clk_Cnt <= Tx_Clk_Cnt + 1;
Tx_Clk_En <= (others => '0');
for n in 0 to Tx_Clk_En'high loop
if Tx_Clk_Cnt(n downto 0) = (n downto 0 => '1') then
Tx_Clk_En(n) <= '1';
end if;
end loop;
end if;
end process;

Synplify complains:
@E:"F:\designs\development\kreon\ddc_1p0\ddc_1p0\hdl\Clk_gen.vhd":60:35:60:3
5|Couldn't find binding for variable n and points to the n in
(n downto 0 => '1')

What is wrong with this code?
 
W

willem oosthuizen

willem oosthuizen said:
I have the following code:

process(aclr_l,clk)
begin
if aclr_l = '0' then
Tx_Clk_Cnt <= (others => '0');
elsif clk'event and clk = '1' then
Tx_Clk_Cnt <= Tx_Clk_Cnt + 1;
Tx_Clk_En <= (others => '0');
for n in 0 to Tx_Clk_En'high loop
if Tx_Clk_Cnt(n downto 0) = (n downto 0 => '1') then
Tx_Clk_En(n) <= '1';
end if;
end loop;
end if;
end process;

Synplify complains:
@E:"F:\designs\development\kreon\ddc_1p0\ddc_1p0\hdl\Clk_gen.vhd":60:35:60:3
5|Couldn't find binding for variable n and points to the n in
(n downto 0 => '1')

What is wrong with this code?
The following is a solution, but more typing...

begin
if aclr_l = '0' then
Tx_Clk_Cnt <= (others => '0');
Tx_Clk_En <= (others => '0');
elsif clk'event and clk = '1' then
Slice := (others => '1');
Tx_Clk_Cnt <= Tx_Clk_Cnt + 1;
Tx_Clk_En <= (others => '0');
for n in 0 to Tx_Clk_En'high loop
if Tx_Clk_Cnt(n downto 0) = Slice(n downto 0) then
Tx_Clk_En(n) <= '1';
end if;
end loop;
end if;
end process;
 
E

Egbert Molenkamp

Nothing is wrong.
The synthesis tool I use has no problems.

Your work around it OK. Since you don't like the extra code
you could remove one line by declaring a constant (in stead of a variable):
constant Slice : unsigned(Tx_Clk_Cnt'range) := (others=>'1');

Egbert Molenkamp
 
F

FE

Willem,
I don't know why synplify complains about it but leonardo spectrum has no
problem with your code. Make sure that TX_Clk_Cnt and Tx_Clk_En have the
same range (xxx downto 0) .

BTW, you must provide a reset value for Tx_Clk_En.

if aclr_l = '0' then
Tx_Clk_En <= (others => '0'); -- add this line to your code
Tx_Clk_Cnt <= (others => '0');
elsif clk'event and clk = '1' then
....
end if;

regards
fe
 
F

FE

Edgert,
see bellow

Egbert Molenkamp said:
Nothing is wrong.
The synthesis tool I use has no problems.

Your work around it OK. Since you don't like the extra code
you could remove one line by declaring a constant (in stead of a variable):
constant Slice : unsigned(Tx_Clk_Cnt'range) := (others=>'1');

Which line??? Where will you use Slice ???

Willem wants (what he did) :
Tx_Clk_En(0) <= Tx_Clk_Cnt(0);
Tx_Clk_En(1) <= Tx_Clk_Cnt(0) and Tx_Clk_Cnt(1);
Tx_Clk_En(2) <= Tx_Clk_Cnt(0) and Tx_Clk_Cnt(1) and Tx_Clk_Cnt(2);
.....

regards
fe
 
M

Marcus Harnisch

This is disappointing. What has happened to the traditions of this
newsgroup? Three followups and none of them provided a recursive
solution.

function all_set (v : std_logic_vector) return boolean is

begin -- all_set
assert (v'length /= 0)
report "Length of argument to 'all_set()' must be greater than zero!"
severity ERROR;

if (v'length = 1) then
return v(v'high) = '1';
elsif (all_set(v(v'high-1 downto v'low))) then
return v(v'high) = '1';
else
return false;
end if;
end all_set;

Best regards,
Marcus
--
Mint Technology, a division of LSI Logic

Marcus Harnisch <[email protected]>
Tel: +1-781-768-0772
200 West Street, Waltham, MA 02451
 
M

Mike Treseler

Marcus said:
This is disappointing. What has happened to the traditions of this
newsgroup? Three followups and none of them provided a recursive
solution.

I must admit that I didn't understand what the function was
until I saw your description. Well done!

-- Mike Treseler
 
M

Marcus Harnisch

Mike Treseler said:
I must admit that I didn't understand what the function was
until I saw your description. Well done!

Thanks, but what I wrote is in fact a rather verbose implementation of
an or-reduce function[1], and thus at best a partial solution to the
OP's task (see the simple or-reduce used in the original code). I am
afraid *I* just understood what that Willem's code was supposed to
do. Well, it was a long night.

While I'd prefer the following description[2], I couldn't find any
problems with the original code using ModelSim.

process(aclr_l,clk)
begin
if aclr_l = '0' then
Tx_Clk_Cnt <= (others => '0');
elsif clk'event and clk = '1' then
Tx_Clk_Cnt <= Tx_Clk_Cnt + 1;
Tx_Clk_En <= (others => '0');
for n in 0 to Tx_Clk_En'high loop
exit when Tx_Clk_Cnt(n) = '0';
Tx_Clk_En(n) <= '1';
end loop;
end if;
end process;


Best regards,
Marcus

Footnotes:
[1] What's worse is the fact that it is verbose *and* inefficient. A
better implementation of an or-reduce would use a more balanced tree.

[2] I did't add a reset for Tx_Clk_En to keep the two versions as
close as possible.
 
M

Marcus Harnisch

I just found another interesting solution to Willem's task. The
algorithm for a binary addition can be described as "invert all lower
bits up-to and including the first bit with a value of '0' and leave
the others untouched".

When two vectors V and (V+1) are XORed, its turns out that the result
is a vector where all bits that were changed by the addition are set
and the others are not set. However, to get only those lower bits of
the original vector V that were actually set, the entire vector has to
be shifted to the right by one. This requires that we have to maintain
a carry flag for the corner case of all bits in V being set.

,----
| process(aclr_l,clk)
| variable Tx_Clk_Cnt_tmp, Tx_Clk_Cnt_plus_one :
| unsigned(Tx_Clk_Cnt'high + 1 downto Tx_Clk_Cnt'low);
|
| begin
| if aclr_l = '0' then
| Tx_Clk_Cnt <= (others => '0');
| elsif clk'event and clk = '1' then
| Tx_Clk_Cnt_tmp := resize(Tx_Clk_Cnt, Tx_Clk_Cnt_tmp'length);
| Tx_Clk_Cnt_plus_one := Tx_Clk_Cnt_tmp + 1;
|
| Tx_Clk_En <= std_logic_vector(resize(shift_right(Tx_Clk_Cnt_plus_one
| xor Tx_Clk_Cnt_tmp,
| 1),
| Tx_Clk_En'length));
| Tx_Clk_Cnt <= resize(Tx_Clk_Cnt_plus_one, Tx_Clk_Cnt'length);
| end if;
| end process;
`----

Since there are libraries with highly optimzed arithmetic blocks, this
solution might lead to a very efficient netlist.

-- Marcus
 
F

fe

Sorry Egbert, I didn't see Willem's second post. Your post (answer) arrived
(retrieved) before Willem's second post (question) (problem of news server
lag). This is why I didn't understand why you talked about changing a
variable by a constant (no variable in the first Willem's post).

I agree with you, use of a constant is better than a variable but the first
Willem's post was correct too (Synplify is stupid).

regards
fe
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top