Assigning different bits of the same signal

S

SnakeyJakey

i am struggling to assign values to different bits of the same signal
concurrently eg

signal a : std_logic_vector(31 downto 0) :=
"10101010101010101010101010101010";
signal b : std_logic_vector(31 downto 0) :=
"11111111111111110000000000000000";
signal c : std_logic_vector(31 downto 0);

begin

c(4 downto 0) <= b(4 downto 0);
c(31 downto 5) <= a(31 downto 5);

end;

works find whereas

signal integer1 : integer := 5;

c(integer1-1 downto 0) <= b(integer1-1 downto 0);
c(31 downto integer1) <= a(31 downto integer1);

produces all U when simulated. i cant see why this wouldnt work since
i am assigning to different bit of c. the below does work though

x(integer1-1 downto 0) <= b(integer1-1 downto 0);
y(31 downto integer1) <= a(31 downto integer1);
c <= y(31 downto integer1) & x(integer1-1 downto 0);

which shows that the assignments individually are correct but just seem
not to work concurrently.
eventually i will be using conv_integer instead of defining a seperate
integer signal.

c(conv_integer(t1)-1 downto 0) <= b(conv_integer(t1)-1 downto 0);
c(31 downto conv_integer(t1)) <= a(31 downto conv_integer(t1));

which always seems to add extra errors due to conv_integer not
happening instantly.

i hope my (semi)psuedo vhdl is understandable to everyone. i have
tried with the auth, signed and unsigned librarys but none seem to
work. i am using modelsim to both compile and simulate if that makes a
difference.

hope someone can cope me in the rigth direction.
 
G

ghelbig

I tried your code, and it works just fine here. Your simulator may be
getting confused about some things you chose not to post.
 
S

SnakeyJakey

hmmmm very strange that it works for you. here is the full code if you
could try try it


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;


entity test is

end test;

architecture t of test is
signal t1 : std_logic_vector(2 downto 0) := "010";
signal int1 : integer := 5;
signal int2 : integer;
signal a1 : std_logic_vector(31 downto 0) :=
"10101010101010101010101010101010";
signal b1 : std_logic_vector(31 downto 0);
signal b2 : std_logic_vector(31 downto 0);
signal b3 : std_logic_vector(31 downto 0);
signal b4 : std_logic_vector(31 downto 0);
signal b5 : std_logic_vector(31 downto 0);
signal b6 : std_logic_vector(31 downto 0);
signal b7 : std_logic_vector(31 downto 0);
signal b8 : std_logic_vector(31 downto 0);
signal c : std_logic_vector(31 downto 0) :=
"11111111111111110000000000000000";

begin -- t

b1(4 downto 0) <= c(4 downto 0);
b1(31 downto 5) <= a1(31 downto 5);

b2(int1-1 downto 0) <= c(int1-1 downto 0);
b2(31 downto int1) <= a1(31 downto int1);

b5(conv_integer(t1)-1 downto 0) <= c(conv_integer(t1)-1 downto 0);
b5(31 downto conv_integer(t1)) <= a1(31 downto conv_integer(t1));

b6(conv_integer(t1)-1 downto 0) <= c(conv_integer(t1)-1 downto 0);
b7(31 downto conv_integer(t1)) <= a1(31 downto conv_integer(t1));

b3(int1) <= c(int1);
b3(31) <= '1';

b8 <= a1(31 downto conv_integer(t1)) & c(conv_integer(t1)-1 downto 0);


end t;


from this i get b1, b6, b7, and b8 correct but b2 and b5 are all U's.
if i could narrow it down to modelsim not playin ball that would be
good

thanks
 
M

Mike Treseler

SnakeyJakey said:
from this i get b1, b6, b7, and b8 correct but b2 and b5 are all U's.
if i could narrow it down to modelsim not playin ball that would be
good

Sorry Snakey.
Modelsim is free to evaluate your one-line processes
in any order that it prefers. If you want sequential
code, you need to put those assignments
*inside* of a process, preferably a clocked one.
Good luck.

-- Mike Treseler
 
S

SnakeyJakey

Mike Treseler wrote
If you want sequential code, you need to put those assignments *inside* of a process,

this thing is i dont want it sequential. every statement is valid (as
far as i can see) concurrently. each assignment references different
bits so therefore there is nothing tryin to assign the same bit at the
same time. the same signal yes but different bit, and it is this that
i dont understand why it doesnt work.
 
D

David R Brooks

SnakeyJakey said:
Mike Treseler wrote

this thing is i dont want it sequential. every statement is valid (as
far as i can see) concurrently. each assignment references different
bits so therefore there is nothing tryin to assign the same bit at the
same time. the same signal yes but different bit, and it is this that
i dont understand why it doesnt work.
By "sequential" is meant, "inside a process".
Drive that process with a sensitivity list which names all its incoming
signals, and *no* clock-edge type statements. That process describes
combinatorial logic, which will be evaluated anew when any of its inputs
changes.
The statements inside the process will be evaluated in strict sequence,
with later results replacing earlier ones.
 
S

SnakeyJakey

David said:
The statements inside the process will be evaluated in strict sequence,
with later results replacing earlier ones.

yes this is true but what i am trying to get is that none of the
results *should* be replaced. i totally under if you had this:

a <= b;
a <= c;

that you will get U for a since it is being driven by two sources but
here

a(int1-1 downto 0) <= bc(int1-1 downto 0);
a(31 downto int1) <= c(31 downto int1);

the assignment are directed at different bits within signal a. each bit
is only driven by one source

it is this i dont understand, why when each bit is only driven by one
source do i still get U.


( as mention before this does work though

c(4 downto 0) <= b(4 downto 0);
c(31 downto 5) <= a(31 downto 5);

it seems to be a problem when you have a signal/integer within the
range expression)
 
C

Charles Steinkuehler

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
a(int1-1 downto 0) <= bc(int1-1 downto 0);
a(31 downto int1) <= c(31 downto int1);

the assignment are directed at different bits within signal a. each bit
is only driven by one source

it is this i dont understand, why when each bit is only driven by one
source do i still get U.


( as mention before this does work though

c(4 downto 0) <= b(4 downto 0);
c(31 downto 5) <= a(31 downto 5);

it seems to be a problem when you have a signal/integer within the
range expression)

Is the signal you're using in the range expansion static (ie: constant)?

Have you tried doing this one bit at a time in a for loop? If you're
not wanting to use a process, you can use for/generate:

for index in c'range generate
begin
c(index) <= b(index) when index<int else a(index);
end generate;

I think this should work whether or not "int" is a constant.

- --
Charles Steinkuehler
(e-mail address removed)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)

iD8DBQFEbI2yenk4xp+mH40RAt24AKCGrMLPYalkBizu1T8HciquKt8IBACfYTPC
MG3lQZpJIfJ8piTBcoiG3dE=
=skmJ
-----END PGP SIGNATURE-----
 
K

KJ

it seems to be a problem when you have a signal/integer within the
range expression)

Why is it a signal anyway? Since it's simply set to 5 it seems like it
should've been defined as a constant in which case it will work just
fine.

When you say that b2 is 'U' is this only at t=0? Or does the 'U' go
away if you run it for a bit longer (like even just 1 ns)? I'm
guessing that the 'U' is only at t=0. If that's the case, then take a
look at the two stripped down code snippets...

-- This code snippet is somewhat along the lines of what you have.
signal int1 : integer := 5;
begin
b2(int1-1 downto 0) <= c(int1-1 downto 0);
end;

-- This code snippet is an equivalent representation (By 'equivalent' I
mean that the VHDL simulators are legally allowed to interpret it this
and conform to the VHDL standard.
signal int1 : integer;
begin
int1 <= 5;
b2(int1-1 downto 0) <= c(int1-1 downto 0);
end;

But now take a look at this second formulation a bit. Since both
statements in the second snippet are concurrent when the simulator
first attempts to evaluate b2, int1 has no initial value assigned just
yet so everything in b2 should be 'U' since the upper end of the range
is not yet known. Once the simulator evaluates int1 and sets it to 5
then b2 should end up getting re-evaluated. All of this should happen
at t=0 but not necessarily on the exact same simulation delta which is
why I asked if the 'U' only shows up at t=0 or does it persist out to
say 1 ns?

I don't think int1 will take on the value of 5 until the end of the
first simulation delta (i.e. t=0, delta = 1). So it won't be until the
start of the next simulation delta time (i.e. t=0, delta = 2) that the
proper bits of b2 will be driven.

I'm guessing a bit on this one though...

KJ
 
M

Mike Treseler

SnakeyJakey said:
this thing is i dont want it sequential. every statement is valid (as
far as i can see) concurrently. each assignment references different
bits so therefore there is nothing tryin to assign the same bit at the
same time. the same signal yes but different bit, and it is this that
i dont understand why it doesnt work.

Each of your parallel assignment pairs are like
two d-flops with outputs shorted together and
with separate "clocks" guaranteed to be skewed
by at least one delta cycle.
from this i get b1, b6, b7, and b8 correct but b2 and b5 are all U's.

The question is not why is b2 and b5 all U's,
it is how were you lucky enough to get expected
data on b1.

Since you have that one lined up, try
reversing the signal declarations for b2 and b1.
I'll bet you a buck that b1 will stop "working".

Also I think your int1, t1, conversions are a red herring.

So, consider a process if you intend to simulate gates.

-- Mike Treseler
 
S

SnakeyJakey

Mike said:
Each of your parallel assignment pairs are like
two d-flops with outputs shorted together

if we look at it like that wouldnt it be a FF for every bit in the
range? and then there is no shorting since they do not access the same
bits
Why is it a signal anyway? Since it's simply set to 5 it seems like it
should've been defined as a constant in which case it will work just
fine.

it is only constant in this simplified example. in my real code it is a
changing signal.
When you say that b2 is 'U' is this only at t=0? Or does the 'U' go
away if you run it for a bit longer
i added a simple clocking process so that i could see the results after t=0

i have added a simple clocking process to check that it isnt just a t=0
but it has the same results, see image for wave output
http://img117.imageshack.us/img117/1017/wave6sc.png

adding the following process though

assign_process : process (clk_i)
begin
b9(int1-1 downto 0) <= c(int1-1 downto 0);
b9(31 downto int1) <= a1(31 downto int1);
end process;

does produce the correct value. i know that when it is in a process it
is being evaluated sequencially and even if the ranges did over lap the
second statement would overwrite the first but once again i have to
stay these ranges do not overlap and hence *should* be able to be done
concurrently
 
D

David R Brooks

SnakeyJakey said:
yes this is true but what i am trying to get is that none of the
results *should* be replaced. i totally under if you had this:

a <= b;
a <= c;

that you will get U for a since it is being driven by two sources but
here

a(int1-1 downto 0) <= bc(int1-1 downto 0);
a(31 downto int1) <= c(31 downto int1);

the assignment are directed at different bits within signal a. each bit
is only driven by one source

it is this i dont understand, why when each bit is only driven by one
source do i still get U.


( as mention before this does work though

c(4 downto 0) <= b(4 downto 0);
c(31 downto 5) <= a(31 downto 5);

it seems to be a problem when you have a signal/integer within the
range expression)
Aha! The problem is (I think), that "int1" is itself a signal, ie a
changeable value (I mustn't say "variable" value, must I? :)
Consider what the synthesiser will have to do: since it must cater for
all (legal) values of int1, it has to provide a mux (or similar) for
every bit position, in *both* assignments.
Now, each assignment will in fact, synthesise as a separate process
(concurrent statements are only syntactic sugar coating processes). That
means each bit of "a" will see two processes driving it. Voila: bus
contention & undefined outputs.

Your original example:
x(integer1-1 downto 0) <= b(integer1-1 downto 0);
y(31 downto integer1) <= a(31 downto integer1);
c <= y(31 downto integer1) & x(integer1-1 downto 0);
works, because each process (ie concurrent statement) drives a different
signal, & each signal is driven by just one process. I suspect it still
infers latches (a waste of logic) for the unwanted bits of "x" & "y",
but then, they're ignored.

I would use a real process, myself.
 
K

KJ

Hmmm....I had a long winded reply sent earlier but it doesn't look like
it made it so I'll try again. The 'problem' with the following two
statements when 'int1' is a signal is that both statements are always
driving the entire b2 bus.

b2(int1-1 downto 0) <= c(int1-1 downto 0); -- Statement 1
b2(31 downto int1) <= a1(31 downto int1); -- Statement 2

The key is to realize that since int1 is a signal that can vary from 0
to 31 then, both statement 1 and statement 2 can potentially drive all
32 bits of b2. You don't know which bits until you actually run it,
but step back and ask yourself what the compiler should do in this
situation? In other words, before you run it, what can you say about
which bits of b2 will be driven by statement 1 and/or statement 2?

What you'll see is that *prior to actually running* all you can say is
that both statements can potentially be driving any or all of the 32
bits of b2. From the perspective of the compiler then (i.e. before
running the simulation or synthesis) this means that statement 1 and
statement 2 both actively drive b2 at ALL times. Understanding that is
the key to this whole thing, so don't go any further until you really
do understand that.

Now, since both statement 1 and statement 2 are both actively driving
b2 then ask yourself if int1 = 5 then what is statement 1 driving bits
31 downto 5 on b2? At first glance it seems that it is nothing but
what it really is, is that you haven't defined what should be driven on
to bits 31 downto 5 of b2 from statement 1....this means they are
undefined...which is a 'U'....which is what you're seeing.

Doing the same for statement 2 you'll see that bits 4 downto 0 (again
int1 = 5) are not specified, therefore undefined, which is a 'U'. This
means that at all times, between the two statements, all 32 bits of b2
are being actively driven to a 'U' by one of the statements. Since 'U'
overrides everything when it comes to resolving std_logic drivers you
get that all 32 bits are always 'U'.

Like I said, the key to this is understanding that both statements 1
and 2 are defining equations for all 32 bits of b2 since, prior to
actually running or synthesizing, you don't know which bits will be
used so it needs to be 'ready' to drive any and all bits.

Hope this helps. Interesting problem!

KJ
 
J

James Unterburger

So far no one's said the three magic words: longest static prefix.
I suggest you read 6.1 and 12.6.1.
 
M

Mike Treseler

James said:
So far no one's said the three magic words: longest static prefix.
I suggest you read 6.1 and 12.6.1.

Yes, and see also
http://www.eda.org/comp.lang.vhdl/FAQ1.html#drivers
which explains:

"in the case of a process, there is a maximum of one driver per signal
driven, no matter how many assignments to that signal appear within the
process"

There is no such limit for parallel assignments.

-- Mike Treseler
 

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,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top