Design for correct timing

Guest
Hi,

I've ran into this design problem, which I would like to share my
thoughts about with you.
Hopefully, someone would inform me about the "best" or "better" way to
achieve the what I intend to do.

I wrote an FSM that handles memory reads/write from/to a synchronous
RAM module.

To simplify the problem, Let's assume the RAM accepts the following
inputs:
data - a data bus
address - an address bus
read_enable - a read signal
clk - a clock signal

the ram is basically designed like this:
always @(posedge clk)
begin: SYNCHRONOUS_RAM_READ
if (read_enable)
data <= ram[address];
else
data <= 0;
end

the read_enable signal, is generated by my FSM in certain situations.
This is a synchronous positive-edge triggered moore FSM and the signal
is asserted once i enter a certain state, and dis-asserted once i move
to the next state.

I want to achieve a Single Clock-Cycle read however the read_enable
signal is always meta-stable with respect to the ram:

the rising edge of the read-enable signal happens at the same time the
clk signal rises:
My FSM raises the signal (and passes the data) on enterance to the
read state -> positive clk edge
The RAM samples the signal on the positive edge of the clk.

So there's always a race between them: A "setup violation" on the
first clock edge, when the signals are asserted, and a "hold
violation" when the signals are dis-asserted.
(no real violations, of course, i'm just illustrating the races)

I figured out 2 possible solutions:
1. make the read state a multi-cycle state: this is the simplest
solution. just wait another clock cycle inside the state and the data
will be ready: but this won't achieve my goal of a single clock cycle
read.
2. make the RAM sensitive to the negative edge:
always @(negedge clk)
begin: SYNCHRONOUS_RAM_READ
if (read_enable)
data <= ram[address];
else
data <= 0;
end

this will absolutely solve the problem, as both the data and the read
signal will give the ram enough slack to sample them correctly.
(I could also make the FSM transition on negedge, and leave the RAM
posedge sensitive).

My question is though:
Is option 2 a generally recommended way to solve this problem?
Are there better solutions? how is this done correctly?

(I'm dissatisfied with my solution, since generally, i'll be getting
only half the clock period to stabilize my signals... so it might
become a problem if I would ever need to insert additional logic in
between the data paths.)


Thanks for your comments,

Itay
 
itay.gr@gmail.com wrote:

the rising edge of the read-enable signal happens at the same time the
clk signal rises.
A synchronous input changes
slightly *after* the rising clock edge.

Is option 2 a generally recommended way to solve this problem?
No.

Are there better solutions? how is this done correctly?
Standard practice is to use synchronous design techniques and
accept the inherent latency.

-- Mike Treseler
 
On Jul 1, 11:01 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
itay...@gmail.com wrote:
the rising edge of the read-enable signal happens at the same time the
clk signal rises.

A synchronous input changes
slightly *after* the rising clock edge.

Is option 2 a generally recommended way to solve this problem?

No.

Are there better solutions? how is this done correctly?

Standard practice is to use synchronous design techniques and
accept the inherent latency.

-- Mike Treseler
Hi Mike,
I agree that the signal changes slightly after the the clock edge -
however,
that makes the problem even worse,
since there's less chance that the value I would like to get sampled
will be the one that would eventually get sampled.

How would you implement a single-cycle read operation?
I want to pass both the address and the read control line on the first
rising edge of the clock, and have the data ready by the next edge
positive edge.

using a negative edge sensitive ram will get the job done....
but how would "Standard practice synchronous design techniques"
approach this problem?
 
Itay Greenspon wrote:

I agree that the signal changes slightly after the the clock edge -
however,
that makes the problem even worse,
since there's less chance that the value I would like to get sampled
will be the one that would eventually get sampled.
A synchronous input is sampled on the next edge,
not on the edge that produced it.

How would you implement a single-cycle read operation?
That wouldn't be compatible with block ram
so I would have no reason to do that.

I want to pass both the address and the read control line on the first
rising edge of the clock, and have the data ready by the next edge
positive edge.
I can have new ram data on every clock if I like,
but it takes a tick or two of latency for the first one.

using a negative edge sensitive ram will get the job done....
but how would "Standard practice synchronous design techniques"
approach this problem?
A faster clock.

-- Mike Treseler
 
On Jul 2, 6:39 am, Mike Treseler <mike_trese...@comcast.net> wrote:
Itay Greenspon wrote:
I agree that the signal changes slightly after the the clock edge -
however,
that makes the problem even worse,
since there's less chance that the value I would like to get sampled
will be the one that would eventually get sampled.

A synchronous input is sampled on the next edge,
not on the edge that produced it.

How would you implement a single-cycle read operation?

That wouldn't be compatible with block ram
so I would have no reason to do that.

I want to pass both the address and the read control line on the first
rising edge of the clock, and have the data ready by the next edge
positive edge.

I can have new ram data on every clock if I like,
but it takes a tick or two of latency for the first one.

using a negative edge sensitive ram will get the job done....
but how would "Standard practice synchronous design techniques"
approach this problem?

A faster clock.

-- Mike Treseler
Thanks a lot, mike.

Out of curiosity,
Do you have a recommendation for a good book discussing best practices
of synchronous design?
Do you have a reference that explains the problems of using a posedge
- negedge - posedge chain of blocks (to speed things up) ?

-- Itay
 
Itay Greenspon wrote:

Thanks a lot, mike.
Out of curiosity,
Do you have a recommendation for a good book discussing best practices
of synchronous design?
You will find some here:
http://groups.google.com/group/comp.lang.vhdl/search?q=synchronous+description

Here's a short book:
Use one clock per module.
Synchronize all inputs to the module clock.
Use clocked blocks/processes whenever possible.
Write a testbench to verify functionality
Use static timing to verify Fmax.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top