Asynchronous With Select and When Else Statements

C

Cory Shol

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??
 
A

Andy

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
 
C

Cory Shol

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.
 
A

Andy

"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
 
C

Cory Shol

"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;
 
A

Andy

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
 
R

rickman

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.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top