32 async input model problem

J

john

Guest
Hello, anybody with more experience in this stuff have any clue how to do
the following:
I have 32 input signals and need to detect the positive and negative edges
and count them. All signals are asynchronous. there is of course a fpga
synchronous clk available which has a high frequency.
Changes of the inputs should be reflected in a 32 bit register.
Anybody an example which fits in a spartan3 without placing errors?
 
Just use a two clock mode in verilog! Clock1 and Clock2 are always different in signal strengths, then posedge Clock1 and posedge Clock2 can provide dual phase clocking as used in DDR.
 
In article <j9gtjt$t3t$1@usenet.uva.nl>, john <info@microsoft.com> wrote:
Hello, anybody with more experience in this stuff have any clue how to do
the following:
I have 32 input signals and need to detect the positive and negative edges
and count them. All signals are asynchronous. there is of course a fpga
synchronous clk available which has a high frequency.
Changes of the inputs should be reflected in a 32 bit register.
Anybody an example which fits in a spartan3 without placing errors?
What is "high frequency?" More than about 4X the highest frequency
component of your 32 inputs?

If so, synchronize all 32 inputs to your fpga clock. Then compare
the current synchronized state to the previous state to look for edges.

Short and sweet (if not clear) verilog:

reg [ 3 * 32 - 1 : 0 ] d_reg; // Stage 0, 1 syncronization
// Stage 2, last value
always @( posedge clk )
d_reg <= { d_reg, d };

wire [ 31 : 0 ] posedge_detect = d_reg[ 1 * 32 +: 32 ] & ~d_reg[ 2 * 32 +: 32 ];
// Shorthand for current value = 1, last value = 0

wire [ 31 : 0 ] negedge_detect = ~( d_reg[ 1 * 32 +: 32 ] ) & d_reg[ 2 * 32 +: 32 ];
// Shorthand for current value = 0, last value = 1


Regards,
Mark
 
In article <j9h83f$m84$1@speranza.aioe.org>,
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
Mark Curry <gtwrek@sonic.net> wrote:
In article <j9gtjt$t3t$1@usenet.uva.nl>, john <info@microsoft.com> wrote:
<snip>

Short and sweet (if not clear) verilog:

reg [ 3 * 32 - 1 : 0 ] d_reg; // Stage 0, 1 syncronization
// Stage 2, last value

I would have used three separate registers, but this should be fine.
Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner. But my FPGA tools don't support it yet....
(sigh). The above is the "Verilog-2000" equivalent of what I want to do.
Also, makes the indexing below easier in SV.

always @( posedge clk )
d_reg <= { d_reg, d };

wire [ 31 : 0 ] posedge_detect = d_reg[1*32 +: 32] & ~d_reg[2*32 +: 32];
wire [ 31 : 0 ] negedge_detect = ~( d_reg[1*32 +: 32] ) & d_reg[2*32 +: 32];

In SV, with the above decleration of d_reg:

wire [ 31 : 0 ] posedge_detect = d_reg[ 1 ] & ~d_reg[ 2 ];
wire [ 31 : 0 ] negedge_detect = ( ~d_reg[ 1 ] ) & d_reg[ 2 ];

--Mark
 
Mark Curry <gtwrek@sonic.net> wrote:
In article <j9gtjt$t3t$1@usenet.uva.nl>, john <info@microsoft.com> wrote:
(snip)
I have 32 input signals and need to detect the positive and negative edges
and count them.
(snip)
What is "high frequency?" More than about 4X the highest frequency
component of your 32 inputs?

If so, synchronize all 32 inputs to your fpga clock. Then compare
the current synchronized state to the previous state to look
for edges.

Short and sweet (if not clear) verilog:

reg [ 3 * 32 - 1 : 0 ] d_reg; // Stage 0, 1 syncronization
// Stage 2, last value
I would have used three separate registers, but this should be fine.

always @( posedge clk )
d_reg <= { d_reg, d };

wire [ 31 : 0 ] posedge_detect = d_reg[ 1 * 32 +: 32 ] & ~d_reg[ 2 * 32 +: 32 ];
// Shorthand for current value = 1, last value = 0

wire [ 31 : 0 ] negedge_detect = ~( d_reg[ 1 * 32 +: 32 ] ) & d_reg[ 2 * 32 +: 32 ];
I think you can detect both at once.

The OP wanted to count them. I thought he meant the total (sum),
but maybe separately. In either case, it is just more logic.

-- glen
 
In article <j9heoh$9l7$1@speranza.aioe.org>,
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
Mark Curry <gtwrek@sonic.net> wrote:
In article <j9h83f$m84$1@speranza.aioe.org>,
Mark Curry <gtwrek@sonic.net> wrote:

(snip)
reg [ 3 * 32 - 1 : 0 ] d_reg; // Stage 0, 1 syncronization

(snip, then I wrote)
I would have used three separate registers, but this should be fine.

Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner.

Does reg [31:0] d_reg[0:2];

work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.
No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.

In SystemVerilog terms it's a packed vs. unpacked array. Your declaration
(matching valid Verilog-1995) is an "unpacked" array. Assignment to/from
unpacked arrays can only be done on a matched type. Packed arrays have a
well-defined assignment to/from a wide vector. So my assignment
works.

--Mark
 
Mark Curry <gtwrek@sonic.net> wrote:
In article <j9h83f$m84$1@speranza.aioe.org>,
Mark Curry <gtwrek@sonic.net> wrote:
(snip)
d_reg; // Stage 0, 1 syncronization
(snip, then I wrote)
I would have used three separate registers, but this should be fine.

Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner.
Does reg [31:0] d_reg[0:2];

work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

But my FPGA tools don't support it yet....
(snip)

;
wire [ 31 : 0 ] negedge_detect = ( ~d_reg[ 1 ] ) & d_reg[ 2 ];
or:

wire [ 31 : 0 ] edge_detect = d_reg[ 1 ] ^ d_reg[ 2 ];

Then into a pipelined carry-save adder tree and accumulator.

-- glen
 
In article <j9hjm0$m4p$1@speranza.aioe.org>,
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
Mark Curry <gtwrek@sonic.net> wrote:

(snip)
I would have used three separate registers, but this should be fine.

Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner.

(snip, then I wrote)
Does reg [31:0] d_reg[0:2];

work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.

Oh, I hadn't notice that one. I mostly try to write
structural verilog, and put registers in their own module.
How about:

{d_reg[2],d_reg[1]} <= {d_reg[1],d_reg[0]};

or even:

d_reg[2] <= d_reg[1];
d_reg[1] <= d_reg[0];

(Yes, it looks too much like the software solution.)
Sure it'd work, I think. But...

We do a lot of reuse in our group. It's probably
not much higher level than you use. But problems
come down to doing 1, 2, or many things.
So, your solution fails my "do "N" things easily
part. To change it to "N" registers, I change
the declaration only (actually, I make "N" a parameter).

reg [ N - 1 : 0 ] [ 31 : 0 ] d_reg;
The one line:
d_req <= { d_reg, d };

Works for any value of N greater than zero. Just my way of thinking. No
the OP didn't need anything that complicated. Just my way
of looking at the problem... Kind of like you always try to use
matrices in matlab instead of vectors and for loops. Sorta.

--Mark
 
Mark Curry <gtwrek@sonic.net> wrote:

(snip)
I would have used three separate registers, but this should be fine.

Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner.
(snip, then I wrote)
;

work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.
Oh, I hadn't notice that one. I mostly try to write
structural verilog, and put registers in their own module.
How about:

{d_reg[2],d_reg[1]} <= {d_reg[1],d_reg[0]};

or even:

d_reg[2] <= d_reg[1];
d_reg[1] <= d_reg[0];

(Yes, it looks too much like the software solution.)

In SystemVerilog terms it's a packed vs. unpacked array. Your declaration
(matching valid Verilog-1995) is an "unpacked" array. Assignment to/from
unpacked arrays can only be done on a matched type. Packed arrays have a
well-defined assignment to/from a wide vector. So my assignment
works.
I still have the books from the Verilog 1995 days, though I might
have learned a few new features since.

-- glen
 
On 10 Nov 2011 21:57:16 GMT, Mark Curry wrote:


;
work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.

In SystemVerilog terms it's a packed vs. unpacked array. Your declaration
(matching valid Verilog-1995) is an "unpacked" array. Assignment to/from
unpacked arrays can only be done on a matched type.
In SV-2009, you could legitimately do...

reg [31:0] d_reg[0:2];
...
d_reg <= {d_reg[1:2], d};

The curly-bracket expression is an "unpacked array
concatenation"; note that it has no leading apostrophe,
as it is NOT an assignment-pattern.

UACs allow you to build an unpacked array value from
fragments that can be either individual elements or
other arrays, providing you meet certain requirements.

However, I don't know how complete the tool support
is for this feature. When I last looked, about a year
ago, most tools weren't yet supporting it.
--
Jonathan Bromley
 
In article <htqob7lcf25km2s9isc920kh6bpvigatdm@4ax.com>,
Jonathan Bromley <spam@oxfordbromley.plus.com> wrote:
On 10 Nov 2011 21:57:16 GMT, Mark Curry wrote:


Does reg [31:0] d_reg[0:2];
work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.

In SystemVerilog terms it's a packed vs. unpacked array. Your declaration
(matching valid Verilog-1995) is an "unpacked" array. Assignment to/from
unpacked arrays can only be done on a matched type.

In SV-2009, you could legitimately do...

reg [31:0] d_reg[0:2];
...
d_reg <= {d_reg[1:2], d};

The curly-bracket expression is an "unpacked array
concatenation"; note that it has no leading apostrophe,
as it is NOT an assignment-pattern.

UACs allow you to build an unpacked array value from
fragments that can be either individual elements or
other arrays, providing you meet certain requirements.

Threads beginning to drift. But hey, this newsgroup's practically
dead....

One would assume that the UAC result must form
the entire array for the type-checking to pass. No implicit
extension or truncation. What about the individual elements?
There's probably some rules there too.. You show "slices" of arrays
elements working. Hmm.. I'd be wary about using these until I understood
all the "certain requirements." And multi-dimensional versions of these
just start to make my head spin. But then I'm wary even about
even using the "signed" vector types for similar reasons... There's
little gotchas in there.

Thanks for the look forward at new features of the language.

Mark
 
Mark Curry wrote:

In the meantime I already figured out that this was the way to go. Anyway
thanks a lot for the help!


In article <j9hjm0$m4p$1@speranza.aioe.org>,
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
Mark Curry <gtwrek@sonic.net> wrote:

(snip)
I would have used three separate registers, but this should be fine.

Actually, what I want to use is:
reg [ 2 : 0 ] [ 31 : 0 ] d_reg;

The Systemverilog is much cleaner.

(snip, then I wrote)
Does reg [31:0] d_reg[0:2];

work? That would normally be used for memories (RAM or ROM),
but the tools might figure it out.

No it wouldn't work fully, as the assignment:
d_req <= { d_reg, d };
would fail.

Oh, I hadn't notice that one. I mostly try to write
structural verilog, and put registers in their own module.
How about:

{d_reg[2],d_reg[1]} <= {d_reg[1],d_reg[0]};

or even:

d_reg[2] <= d_reg[1];
d_reg[1] <= d_reg[0];

(Yes, it looks too much like the software solution.)

Sure it'd work, I think. But...

We do a lot of reuse in our group. It's probably
not much higher level than you use. But problems
come down to doing 1, 2, or many things.
So, your solution fails my "do "N" things easily
part. To change it to "N" registers, I change
the declaration only (actually, I make "N" a parameter).

reg [ N - 1 : 0 ] [ 31 : 0 ] d_reg;
The one line:
d_req <= { d_reg, d };

Works for any value of N greater than zero. Just my way of thinking. No
the OP didn't need anything that complicated. Just my way
of looking at the problem... Kind of like you always try to use
matrices in matlab instead of vectors and for loops. Sorta.

--Mark
 

Welcome to EDABoard.com

Sponsor

Back
Top