Asynchronous With Select and When Else Statements

Discussion in 'VHDL' started by Cory Shol, May 15, 2013.

  1. Cory Shol

    Cory Shol Guest

    Hi everyone,

    I am coding up a project to route and control Gigabit ethernet.

    Basically the FPGA receives MDIO communication from Processor 1 or Processor 2( Both masters, only one can be master at a time).

    The logic decides based on a priority and a keep alive signal which master controls the MDIO bus.

    Now I have the handling for who is master of the system and keep alive signal etc...

    My question lies with the Asynchronous With Select and When Else Statements:

    my code looks something like below: (Keep in mind MDIO communication is BIDIRECTIONAL, I have a pull up on the mdio_proc1 pin)

    The question is about the Nested When else in the the With select statement:

    with arb_select_proc1_iso & smi_control select
    mdio_proc1 <= ('Z' when (direction = '0' or mdio_device_data = '1') else '0') when "001",
    arb_proc1_out_iso when "100",
    arb_proc1_out_iso when "101",
    arb_proc1_out_iso when "110",
    arb_proc1_out_iso when "111",
    'Z' when others;

    with arb_select_proc2_iso & smi_control select
    mdio_proc2 <= ('Z' when (direction = '0' or mdio_device_data = '1') else '0') when "010",
    arb_proc2_out_iso when "100",
    arb_proc2_out_iso when "101",
    arb_proc2_out_iso when "110",
    arb_proc2_out_iso when "111",
    'Z' when others;

    This comes up with the error in Xilinx:
    ERROR:HDLParsers:164 - "C:/workspace/head/Smm_xilinx_tb/smm/smm.vhd" Line 325. parse error, unexpected WHEN, expecting COMMA or CLOSEPAR
    ERROR:HDLParsers:164 - "C:/workspace/head/Smm_xilinx_tb/smm/smm.vhd" Line 333. parse error, unexpected WHEN, expecting COMMA or CLOSEPAR

    So I try this:

    mdio_bus <= 'Z' when (direction = '0' or mdio_device_data = '1') else '0';

    with arb_select_proc1_iso & smi_control select
    mdio_proc1 <= mdio_bus when "001",
    arb_proc1_out_iso when "100",
    arb_proc1_out_iso when "101",
    arb_proc1_out_iso when "110",
    arb_proc1_out_iso when "111",
    'Z' when others;

    with arb_select_proc2_iso & smi_control select
    mdio_mezz <= mdio_bus when "010",
    arb_proc2_out_iso when "100",
    arb_proc2_out_iso when "101",
    arb_proc2_out_iso when "110",
    arb_proc2_out_iso when "111",
    'Z' when others;

    and I get the warning:

    WARNING:Xst:2042 - Unit smm: 2 internal tristates are replaced by logic (pull-up yes): mdio_bus, mdio_proc_data.


    Are there any other ways to do what I want to do??
    Cory Shol, May 15, 2013
    #1
    1. Advertising

  2. Cory Shol

    Andy Guest

    You need to break up the assignments into a separate with-select assignmentfor the data, followed by a when-else assignment for the tri-state buffer.

    You might try to see if XST has a "tri-state push" option, but I doubt it will work for your code anyway.

    BTW, the statements you are using are not called "asynchronous" (a functionof the logic expressed), but are called "concurrent" (a function of when the statement is executed). Concurrent assignment statements can infer synchronous registers, as in the following:

    q <= d when rising_edge(clk);

    Andy
    Andy, May 15, 2013
    #2
    1. Advertising

  3. Cory Shol

    Cory Shol Guest

    On Wednesday, May 15, 2013 9:50:02 AM UTC-5, Cory Shol wrote:
    > Hi everyone,
    >
    >
    >
    > I am coding up a project to route and control Gigabit ethernet.
    >
    >
    >
    > Basically the FPGA receives MDIO communication from Processor 1 or Processor 2( Both masters, only one can be master at a time).
    >
    >
    >
    > The logic decides based on a priority and a keep alive signal which master controls the MDIO bus.
    >
    >
    >
    > Now I have the handling for who is master of the system and keep alive signal etc...
    >
    >
    >
    > My question lies with the Asynchronous With Select and When Else Statements:
    >
    >
    >
    > my code looks something like below: (Keep in mind MDIO communication is BIDIRECTIONAL, I have a pull up on the mdio_proc1 pin)
    >
    >
    >
    > The question is about the Nested When else in the the With select statement:
    >
    >
    >
    > with arb_select_proc1_iso & smi_control select
    >
    > mdio_proc1 <= ('Z' when (direction = '0' or mdio_device_data = '1') else '0') when "001",
    >
    > arb_proc1_out_iso when "100",
    >
    > arb_proc1_out_iso when "101",
    >
    > arb_proc1_out_iso when "110",
    >
    > arb_proc1_out_iso when "111",
    >
    > 'Z' when others;
    >
    >
    >
    > with arb_select_proc2_iso & smi_control select
    >
    > mdio_proc2 <= ('Z' when (direction = '0' or mdio_device_data = '1') else '0') when "010",
    >
    > arb_proc2_out_iso when "100",
    >
    > arb_proc2_out_iso when "101",
    >
    > arb_proc2_out_iso when "110",
    >
    > arb_proc2_out_iso when "111",
    >
    > 'Z' when others;
    >
    >
    >
    > This comes up with the error in Xilinx:
    >
    > ERROR:HDLParsers:164 - "C:/workspace/head/Smm_xilinx_tb/smm/smm.vhd" Line 325. parse error, unexpected WHEN, expecting COMMA or CLOSEPAR
    >
    > ERROR:HDLParsers:164 - "C:/workspace/head/Smm_xilinx_tb/smm/smm.vhd" Line 333. parse error, unexpected WHEN, expecting COMMA or CLOSEPAR
    >
    >
    >
    > So I try this:
    >
    >
    >
    > mdio_bus <= 'Z' when (direction = '0' or mdio_device_data = '1') else '0';
    >
    >
    >
    > with arb_select_proc1_iso & smi_control select
    >
    > mdio_proc1 <= mdio_bus when "001",
    >
    > arb_proc1_out_iso when "100",
    >
    > arb_proc1_out_iso when "101",
    >
    > arb_proc1_out_iso when "110",
    >
    > arb_proc1_out_iso when "111",
    >
    > 'Z' when others;
    >
    >
    >
    > with arb_select_proc2_iso & smi_control select
    >
    > mdio_mezz <= mdio_bus when "010",
    >
    > arb_proc2_out_iso when "100",
    >
    > arb_proc2_out_iso when "101",
    >
    > arb_proc2_out_iso when "110",
    >
    > arb_proc2_out_iso when "111",
    >
    > 'Z' when others;
    >
    >
    >
    > and I get the warning:
    >
    >
    >
    > WARNING:Xst:2042 - Unit smm: 2 internal tristates are replaced by logic (pull-up yes): mdio_bus, mdio_proc_data.
    >
    >
    >
    >
    >
    > Are there any other ways to do what I want to do??


    Yeah when I meant Asynchronous I meant not using a clock. I would never write Q <= d when rising_edge(clk); I would rather put it in a process and use an if statement etc...

    Could you give me an example of what you mean by Break up the assignments into a seperate with-select assignment for the data, followed by a when-else assignment for the tri-state buffer.
    Cory Shol, May 15, 2013
    #3
  4. Cory Shol

    Andy Guest

    "I would never write Q <= d when rising_edge(clk); I would rather put itin a process and use an if statement etc... "

    I don't use the concurrent clocked assignment alot, but for the occasional single register or two, a process is just more code to do the same thing with no benefit. The concurrent assignment is slightly less efficient in simulation, but for a single register here and there, the impact is nil.

    If you want an asynchronous reset on the register:

    q <= '0' when rst = '1'
    else d when rising_edge(clk);

    After looking at your OP again, the synthesis tool is complaining about an internal tri-state on mdio_bus (and some other signal you don't describe). It assumes pull-up logic, meaning that if no driver is enabled, the result is '1', and it replicates that behavior with logic gates, since FPGA's no longer provide internal tri-state drivers (they are only available on IO pins).

    Is mdio_bus supposed to be an inout port on the FPGA device? If so, and yousynthesize this at the module level (without IO insertion), it may implement differently than if synthesized as part of a whole design.

    As to an example (but after reading your OP, I don't think it would solve the problem), I will leave that as "an exercise for the student" with the following hint: Code the multiplexer in a with-select statement, assigning anintermediate signal (no tristate). Code the tri-state buffer in a when-else statement using the intermediate signal.

    Andy
    Andy, May 16, 2013
    #4
  5. Cory Shol

    Cory Shol Guest

    On Thursday, May 16, 2013 8:40:50 AM UTC-5, Andy wrote:
    > "I would never write Q <= d when rising_edge(clk); I would rather put it in a process and use an if statement etc... "
    >
    >
    >
    > I don't use the concurrent clocked assignment alot, but for the occasional single register or two, a process is just more code to do the same thing with no benefit. The concurrent assignment is slightly less efficient in simulation, but for a single register here and there, the impact is nil.
    >
    >
    >
    > If you want an asynchronous reset on the register:
    >
    >
    >
    > q <= '0' when rst = '1'
    >
    > else d when rising_edge(clk);
    >
    >
    >
    > After looking at your OP again, the synthesis tool is complaining about an internal tri-state on mdio_bus (and some other signal you don't describe).. It assumes pull-up logic, meaning that if no driver is enabled, the result is '1', and it replicates that behavior with logic gates, since FPGA's nolonger provide internal tri-state drivers (they are only available on IO pins).
    >
    >
    >
    > Is mdio_bus supposed to be an inout port on the FPGA device? If so, and you synthesize this at the module level (without IO insertion), it may implement differently than if synthesized as part of a whole design.
    >
    >
    >
    > As to an example (but after reading your OP, I don't think it would solvethe problem), I will leave that as "an exercise for the student" with the following hint: Code the multiplexer in a with-select statement, assigning an intermediate signal (no tristate). Code the tri-state buffer in a when-else statement using the intermediate signal.
    >
    >
    >
    > Andy


    I understand what you were talking about, but I didn't understand how that was going to change anything in my problem.

    mdio_proc1 and mdio_proc2 are the I/O bidirectional pins in the top module..
    I want mdio_proc1 and mdio_proc2 to behave like mdio_bus when it is selected.

    For example:

    The pre existing code only had the capabilities of one master in the system, therefore mdio_proc1 looked like below. This statement says:
    if direction is towards the Slave devices from the processor than release the bidirectional I/O. Else if Direction from the slave to the processor than either the output will be pulled up or driven to '0'.

    mdio_proc1 <= 'Z' when (direction = '0' or mdio_device_data = '1') else '0';

    Now attached to my FPGA is another master.

    The slave devices can only be controlled by proc1 or proc2. Therefore I want to add a mux to select who controls the bus, but I still want the bus toact the same.
    For simplicity:

    with control select
    mdio_proc1 <= Normal operation as before when '0',
    'Z' when others;

    Now my problem is how can I force it to normal operation within the with select or another method.


    The only thing I can think of now is adding Direction and Device data into my mux select and making it like:

    with direction & mdio_device_data & control select
    mdio_proc1 <= '0' when "100",
    'Z' when others;

    mdio_proc2 would look like:

    with direction & mdio_device_data & control select
    mdio_proc2 <= '0' when "101",
    'Z' when others;
    Cory Shol, May 16, 2013
    #5
  6. Cory Shol

    Andy Guest

    If you are willing to live with the warning, it looks like synthesis built HW that behaves like you want, but without any internal tristate, using equivalent logic (assuming pullup). Simulate the gate level (post-synthesis) netlist to verify.

    If you don't want the warning, you will have to describe the behavior you want without using internal tri-state signals.

    Andy
    Andy, May 16, 2013
    #6
  7. Cory Shol

    rickman Guest

    On 5/15/2013 3:23 PM, Cory Shol wrote:
    >
    > Could you give me an example of what you mean by Break up the assignments into a seperate with-select assignment for the data, followed by a when-else assignment for the tri-state buffer.


    He means something like this...

    A <= 'z' when (foo = 1) else B;

    B <= stuff when (other stuff);

    BTW, separate has "a rat". I was taught that in elementary school and I
    never forgot it.

    --

    Rick
    rickman, May 17, 2013
    #7
    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. Devin Panchal

    if and else statements.

    Devin Panchal, Dec 9, 2003, in forum: Java
    Replies:
    2
    Views:
    442
    Devin Panchal
    Dec 9, 2003
  2. raver
    Replies:
    6
    Views:
    375
    Joona I Palaste
    Apr 28, 2005
  3. Harry George
    Replies:
    6
    Views:
    375
    Bart Nessux
    Feb 23, 2004
  4. tobiah
    Replies:
    22
    Views:
    572
    Ben Finney
    Sep 1, 2006
  5. John Crichton
    Replies:
    6
    Views:
    264
    John Crichton
    Jul 12, 2010
Loading...

Share This Page