VHDL Combinatorial + Sequential + Timing?

J

Jonathan Ross

Technical specifications first: I'm using the most recent Xilinx tools
(12.2, 12.3), ISE/XST/Timing Analyzer, and I'm designing for the
Virtex-6.

As per the XST documentation I've inferred a single port Read-First
Block RAM which, of course, is clock triggered. It looks a lot like
this (some variable names and code that can't possibly be part of the
critical path have been changed or removed):

ConvertedAddress <=
CONV_INTEGER( UNSIGNED( AddressConversion( AddressIn,
ConversionFactor ) ) );

PROCESS(CLK) IS
VARIABLE ReadRecord, WriteRecord : BRAMRecord;
VARIABLE ReadRaw, WriteRaw : BRAMRaw;
BEGIN
IF RISING_EDGE(CLK) AND RESET = '0' THEN
Result <= Ready;
ReadRaw := BRAM(ConvertedAddress);
WriteRaw := RecordToRaw(
( Field1 => Field1In,
Field2 => Field2In,
Field3 =>
Field3Generator( Field3In ) ) );
IF Operation = Write THEN
BRAM(ConvertedAddress) <= WriteRaw;
END IF;

ReadRecord := RawToRecord( ReadRaw );

Field1Out <= ReadRecord.Field1;
Field2Out <= ReadRecord.Field2;

IF ReadRecord.Field3 = '0' THEN
Result <= Result1;
ELSIF ReadRecord.Field1 = Field1In THEN
Result <= Result2;
ELSE
Result <= Result3;
END IF;
END IF;
END PROCESS;

Because it won't let me infer a block ram using records (it inferred
distributed RAM when I tried that) I convert my record to and from an
SLV using the RawToRecord and RecordToRaw functions. Now when I wrote
this I thought the following would happen:

1. Before the clock cycle begins the consumer of the entity would
input AddressIn and would set the enumeration typed Operation signal
to either Read or Write. Before the clock cycle begins AddressIn would
have AddressConversion applied to it and ConvertedAddress would be
stable.
2. Rising edge of clock cycle - as long as RESET is low (inactive) the
inferred Block RAM would begin work on ConvertedAddress for reading,
and if Operation = Write it would write in a value as well. The Block
RAM is significantly faster than my clock cycle which is set to 8
nanoseconds, so this should complete well before the clock cycle ends.
3. BEFORE the end of this clock cycle, Field1 and Field2 are set, and
Result is set to one of three values based on the priority encoder in
the process.

Now when I synthesize this it fails timing, and the analysis gives me
the following critical path:

Timing constraint: TS_clk125 = PERIOD TIMEGRP "clk125" 8 ns HIGH 50%;
147168714 paths analyzed, 210840 endpoints analyzed, 3006 failing
endpoints
3006 timing errors detected. (3006 setup errors, 0 hold errors, 0
component switching limit errors)
Minimum period is 11.172ns.

--------------------------------------------------------------------------------
Slack: -3.172ns (requirement - (data path - clock
path skew + uncertainty))
Source: Project/ValueOverride_19_15_BRB1 (FF)
Destination: Project/RAM_GEN[7].RAM_inst/Result_1 (FF)
Requirement: 8.000ns
Data Path Delay: 11.022ns (Levels of Logic = 8)
Clock Path Skew: -0.044ns (1.591 - 1.635)
Source Clock: clk125 rising at 0.000ns
Destination Clock: clk125 rising at 8.000ns
Clock Uncertainty: 0.106ns

Clock Uncertainty: 0.106ns ((TSJ^2 + DJ^2)^1/2) / 2 + PE
Total System Jitter (TSJ): 0.070ns
Discrete Jitter (DJ): 0.199ns
Phase Error (PE): 0.000ns

Maximum Data Path at Slow Process Corner: Project/
ValueOverride_19_15_BRB1 to Project/RAM_GEN[7].RAM_inst/Result_1
Location Delay type Delay(ns) Physical
Resource
Logical
Resource(s)
-------------------------------------------------
-------------------
SLICE_X74Y187.CQ Tcko 0.337 Project/
ValueOverride_19_15_BRB4
Project/
ValueOverride_19_15_BRB1
SLICE_X118Y213.C3 net (fanout=526) 2.781 Project/
ValueOverride_19_15_BRB1
SLICE_X118Y213.CMUX Tilo 0.192 N4638
Project/
_n1876_inv1_rstpot
SLICE_X103Y211.D6 net (fanout=96) 0.959 N5118
SLICE_X103Y211.D Tilo 0.068 Project/
RAMTableField1In<28>
Project/
Mmux_Field1In<7>211
SLICE_X115Y216.D4 net (fanout=10) 0.903 Project/
Field1In<7><28>
SLICE_X115Y216.D Tilo 0.068 Project/
RAM_GEN[7].RAM_inst/Mxor_ConvertedAddress<1>_xo<0>2
Project/
RAM_GEN[7].RAM_inst/Mxor_ConvertedAddress<1>_xo<0>3
SLICE_X127Y220.C4 net (fanout=1) 0.922 Project/
RAM_GEN[7].RAM_inst/Mxor_ConvertedAddress<1>_xo<0>2
SLICE_X127Y220.C Tilo 0.068 N29019
Project/
RAM_GEN[7].RAM_inst/Mxor_ConvertedAddress<1>_xo<0>6
SLICE_X138Y220.C2 net (fanout=520) 1.352 Project/
RAM_GEN[7].RAM_inst/ConvertedAddress<1>
SLICE_X138Y220.BMUX Topcb 0.417 Project/
RAM_GEN[7].RAM_inst/N242
Project/
RAM_GEN[7].RAM_inst/Mram_BRAM120/C
Project/
RAM_GEN[7].RAM_inst/Mram_BRAM120/F7.B
Project/
RAM_GEN[7].RAM_inst/Mram_BRAM120/F8
SLICE_X133Y223.D2 net (fanout=1) 0.895 Project/
RAM_GEN[7].RAM_inst/N242
SLICE_X133Y223.DMUX Tilo 0.191 Project/
RAM_GEN[7].RAM_inst/Field1Out<43>
Project/
RAM_GEN[7].RAM_inst/inst_LPM_MUX5911
SLICE_X125Y223.C6 net (fanout=2) 0.565 Project/
RAM_GEN[7].RAM_inst/_n0484<59>
SLICE_X125Y223.DMUX Topcd 0.538 Project/
RAM_GEN[7].RAM_inst/BUS_0001_Field1In[47]_equal_16_o
Project/
RAM_GEN[7].RAM_inst/Mcompar_BUS_0001_Field1In[47]_equal_16_o_lut<14>
Project/
RAM_GEN[7].RAM_inst/Mcompar_BUS_0001_Field1In[47]_equal_16_o_cy<15>
SLICE_X113Y221.D5 net (fanout=2) 0.696 Project/
RAM_GEN[7].RAM_inst/BUS_0001_Field1In[47]_equal_16_o
SLICE_X113Y221.CLK Tas 0.070 Project/
RAM_GEN[7].RAM_inst/Result<1>
Project/
RAM_GEN[7].RAM_inst/Mmux_PWR_500_o_GND_2830_o_mux_17_OUT21
Project/
RAM_GEN[7].RAM_inst/Result_1
-------------------------------------------------
---------------------------
Total 11.022ns (1.949ns
logic, 9.073ns route)
(17.7% logic,
82.3% route)

Now in reality this path should be two clock cycles. The first path
should begin at "Project/ValueOverride_19_15_BRB1 (FF) " and end at
when ConvertedAddress is being applied to the Block RAM, and the
second should be from where the Block RAM starts until "Project/
RAM_GEN[7].RAM_inst/Result_1 (FF) ". The block RAM clearly starts on
the rising edge of a block cycle...

So the question is am I fundamentally misunderstanding VHDL, or did I
simply do something silly so that it's actually trying to infer an
asynchronous Block RAM? I have a synth running where I don't include
RESET in my if statement where I check for a RISING_EDGE, but that
will take several hours before I find out if it worked or not...
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top