VHDL Combinatorial + Sequential + Timing?

Discussion in 'VHDL' started by Jonathan Ross, Oct 7, 2010.

  1. 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...
     
    Jonathan Ross, Oct 7, 2010
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. GomoX
    Replies:
    19
    Views:
    1,731
  2. JSreeniv

    vhdl testbench sequential

    JSreeniv, Nov 15, 2009, in forum: VHDL
    Replies:
    4
    Views:
    2,144
    JimLewis
    Nov 17, 2009
  3. Oliver Mattos
    Replies:
    6
    Views:
    1,684
    Kellyng91
    Apr 5, 2011
  4. Oliver Mattos
    Replies:
    8
    Views:
    1,129
    rickman
    Feb 12, 2011
  5. Oliver Mattos
    Replies:
    0
    Views:
    780
    Oliver Mattos
    Feb 3, 2011
Loading...

Share This Page