Assigning values to concatenated registers

D

Daku

Guest
Could some Verilog guru please help. I am having trouble assigning
values to component registers of
a concatened register:
I have:
parameter MAX = 50;
parameter DATA_WIDTH = 24;

reg [7 : 0] src;
reg [7 : 0] dst;
reg [7 : 0] pri;
reg [7 : 0] srcchk;
reg [7 : 0] dstchk;
reg [7 : 0] prichk;
reg [7 : 0] testpri;

reg [DATA_WIDTH - 1 : 0] pkt;
reg [DATA_WIDTH - 1 : 0] test;
reg [DATA_WIDTH - 1 : 0] DataArray[MAX - 1 : 0];
reg [MAX - 1:0] indexArray;

initial
begin
num = 0;
head = 0;
tail = 0;
toppriority = 0;
currhipriority = 0;
ispriority = 0;
assign pkt = {src, dst, pri};
assign test = {srcchk, dstchk, prichk};
.......
.......
end

always @ (posedge clock)
begin
/* Some conditions to be satisfied */
pkt = DataArray[head];
pkt[23:16] = 1;
pkt[15:8] = 2;
pkt[7:0] = 8'b00000001;
......
end

always @ (negedge clock)
begin
/* Some conditions to be satisfied */
test = DataArray;
prichk = test[7:0];
$display("%b",prichk);

This print statement always gives xxxxxxxx
This is true even if I have :
test = DataArray;
$display("%b", prichk);

What could the problem be ?
Any hints, suggestions would be greatly appreciated. Thanks in advance
for your help.
 
Daku <dakupoto@gmail.com> wrote:
Could some Verilog guru please help. I am having trouble assigning
values to component registers of
(snip)

pkt;
(snip)

assign pkt = {src, dst, pri};
I don't think you want a continuous assign here.

Other than these two continuous assign statements the rest of
your code is ordinary behavioral verilog. The left side of
a continuous assign should be a wire, not a reg. Last I knew
this wouldn't even compile.

A wire should have one value assigned to it through a continuous
assign, or as the output of a module. A reg may have more than
one behavioral (not continuous) assign, though there should only
be one at a time. (With the appropriate definition of one.)

-- glen
 
On Oct 30, 4:41 am, glen herrmannsfeldt wrote:
Daku <dakup...@gmail.com> wrote:
Could some Verilog guru please help. I am having trouble assigning
values to component registers of

(snip)

reg [DATA_WIDTH - 1 : 0] pkt;

(snip)

  assign pkt  = {src, dst, pri};

I don't think you want a continuous assign here.
Too right.
It *will* compile, but I'll buy you a beer if it does
what you expected :)

The assign keyword has two distinct uses in Verilog.

The most common is to have "assign" at the top level
of a module, outside of any procedural code:

assign some_net = some_expression;

This does exactly what Glen indicated: it continuously
evaluates the expression, and drives its value on to
the target net. Effectively it represents a piece of
combinational logic driving the net.

The second form of "assign" is the one that you used,
probably by mistake. It is a PROCEDURAL statement and
therefore lives in an initial or always block. Its
target can be either a net or a variable - it works
for both. At the moment the "assign" is executed,
a continuous driver is set up that drives the value
of the expression on to the target net or variable.
If the expression changes value at any time in the
future, the driven value will update to match. If
you want to stop this driving behaviour at any time
in the future you can do so by means of the "deassign"
statement. In other words, procedural assign/deassign
is somewhat similar to force/release.

There are some interesting uses for procedural assign
in behavioural modelling. I believe that some synthesis
tools have supported it, in some special cases, but it's
not appropriate for synthesis with the majority of
mainstream tools. Here's an example of a model of
a flipflop with asynchronous load, using procedural
continuous assign:

always @(posedge clock)
Q <= D; // Regular flipflop behaviour

// When asyncLoad is active, override the usual
// behaviour and force the preload data on to Q.
// When asyncLoad is deasserted, go back to normal
// flipflop behaviour.
always @(asyncLoad)
if (asyncLoad)
assign Q = asyncLoadData;
else
deassign Q;

In general, Glen's advice is on the money: don't use
procedural assign/deassign; use continuous assign to
drive a net with the result of some combinational
expression; use regular procedural assignment -
WITHOUT the assign keyword!!! - to update the value
of any variable.
--
Jonathan Bromley
 
Jonathan Bromley <spam@oxfordbromley.plus.com> wrote:
(snip, I wrote)

I don't think you want a continuous assign here.

Too right.
It *will* compile, but I'll buy you a beer if it does
what you expected :)

The assign keyword has two distinct uses in Verilog.
(snip on usual continuous assign statements)

The second form of "assign" is the one that you used,
probably by mistake. It is a PROCEDURAL statement and
therefore lives in an initial or always block. Its
target can be either a net or a variable - it works
for both.
When did this get added to verilog? In one of my early
verilog problems, which had both behavioral verilog and
continuous assigns, I had put the continuous assign inside
an always block. The compiler complained about it.

I finally figured out that continuous assignment means the
same thing no matter where it is and moved it out.
It worked and I learned to keep them out of always blocks.

Mostly I write structural verilog, except for registers
(which I try to put in their own module) and state machines.

-- glen
 
On Oct 30, 9:17 am, glen herrmannsfeldt wrote:

When did
[procedural continuous assign]
get added to verilog?
I'm not sure. It certainly existed in the 1995 standard,
and it also appears in my vintage-1991 copy of the OVI 1.0
document.

Of course, it's possible that some tools didn't support it
in the days before the 1995 IEEE standard was widely accepted.

Interestingly, both SystemVerilog (IEEE 1800-2005) and the
draft merged Verilog/SystemVerilog standard (IEEE P1800-2009)
have deprecated the procedural assign/deassign construct,
so it may disappear from some future revision of the
standard. Verilog 1364 is about to disappear anyway,
superseded by the new merged standard 1800. In practice,
of course, tools will continue to support assign/deassign.
--
Jonathan Bromley
 
Thanks for pointing this out - odd I missed it.


On Oct 30, 2:00 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:

(snip)

Too right.
It *will* compile, but I'll buy you a beer if it does
what you expected :)

The assign keyword has two distinct uses in Verilog.

The most common is to have "assign" at the top level
of a module, outside of any procedural code:

assign some_net = some_expression;

This does exactly what Glen indicated: it continuously
evaluates the expression, and drives its value on to
the target net. Effectively it represents a piece of
combinational logic driving the net.

The second form of "assign" is the one that you used,
probably by mistake. It is a PROCEDURAL statement and
therefore lives in an initial or always block. Its
target can be either a net or a variable - it works
for both. At the moment the "assign" is executed,
a continuous driver is set up that drives the value
of the expression on to the target net or variable.
If the expression changes value at any time in the
future, the driven value will update to match. If
you want to stop this driving behaviour at any time
in the future you can do so by means of the "deassign"
statement. In other words, procedural assign/deassign
is somewhat similar to force/release.

There are some interesting uses for procedural assign
in behavioural modelling. I believe that some synthesis
tools have supported it, in some special cases, but it's
not appropriate for synthesis with the majority of
mainstream tools. Here's an example of a model of
a flipflop with asynchronous load, using procedural
continuous assign:

always @(posedge clock)
Q <= D; // Regular flipflop behaviour

// When asyncLoad is active, override the usual
// behaviour and force the preload data on to Q.
// When asyncLoad is deasserted, go back to normal
// flipflop behaviour.
always @(asyncLoad)
if (asyncLoad)
assign Q = asyncLoadData;
else
deassign Q;

In general, Glen's advice is on the money: don't use
procedural assign/deassign; use continuous assign to
drive a net with the result of some combinational
expression; use regular procedural assignment -
WITHOUT the assign keyword!!! - to update the value
of any variable.
--
Jonathan Bromley
 
On Oct 30, 4:17 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
When did this get added to verilog?  In one of my early
verilog problems, which had both behavioral verilog and
continuous assigns, I had put the continuous assign inside
an always block.  The compiler complained about it.
As I understand it, it pre-dates forces on regs. A quasi-continuous
assignment to a reg was the equivalent of a force on a net. You
could only force nets, and you could only quasi-continuous assign
regs.

Users kept trying to force regs, and didn't want to have to use a
different construct to get that effect. They didn't want to have to
know whether something was a net or a reg to know how to force it.
So the capability to force regs was added, taking precedence over a
quasi-continuous assignment to the same reg.

This is just what I have heard from somebody who was around at that
time.
 

Welcome to EDABoard.com

Sponsor

Back
Top