If I declare 'sigio' as 'inout', as below and as I got the model, then when I simulate it, the signals in the simulation remain 'U'. So somehow the 'gentest' model drives the 'sigio' signal although the generic 'this_is_a_simulation' has been set totrue.
I then just comment out the 'rtlblk' generate, the model simulates as expected.
On Friday, December 9, 2022 at 6:20:14 AM UTC-5, Stef wrote:true.
<snip>
If I declare 'sigio' as 'inout', as below and as I got the model, then when I simulate it, the signals in the simulation remain 'U'. So somehow the 'gentest' model drives the 'sigio' signal although the generic 'this_is_a_simulation' has been set to
When you declared sigio as inout, you're saying that there will be a driver for this signal. But in your testbench you've connected sigio to the signal clk, and you have a process that drives clk. Regardless of how if this_is_a_simulation is setthere will be problems.
* if this_is_a_simulation = true then sigio will get set to '1'. But since clk is also driving the signal to either a '0' or '1', half the time the two drivers will be in conflict. When clk happens to be set to '1' is the only time that you will geta '1'. The other half of the time you'll have a '1' and a '0' being driven...resulting in unknown
* if this_is_a_simulation = false then the gentest entity will say that there is a driver for 'sigio', but since the architecture doesn't actually drive the signal, sigio will be unknown and will always override the '0' and '1' that clk is being set to.The result of that condition is an unknown, all of the time.
You could work around the problem for "if this_is_a_simulation = false" by changing the entity to give a default of 'Z' like this: "sigio : inout std_logic := 'Z'; -- Original line". Now sigio will have a driver of 'Z' at t=0 and 'clk' will always beable to override the 'Z' with a '0' or '1'.
should be of type 'in' and the "sigio <= 1'" statement should be removed OR if it really is meant to be of type 'inout', then you should only be driving sigio when nothing on the outside (i.e. the testbench signal clk) is actively driving it to '0' or '1'I then just comment out the 'rtlblk' generate, the model simulates as expected.
Not sure what you mean with "as expected". This design is fatally flawed by having two drivers both trying to drive the same signal at the same time. I have no idea what you're trying to do inside gentest with sigio in the first place. Either sigio
On 2022-12-11 KJ wrote in comp.lang.vhdl:
On Friday, December 9, 2022 at 6:20:14 AM UTC-5, Stef wrote:
In the examples I tried to reduce the problem down to a small model and
I may have simpified it too much. In the "if this_is_a_simulation =
false" situation, the sigio in gentest.vhd is connected to the clock
pin of an instantiated PLL block and according to the code I inherited,
this pin is an inout signal (you would expect an in, but it is inout).
should be of type 'in' and the "sigio <= 1'" statement should be removed OR if it really is meant to be of type 'inout', then you should only be driving sigio when nothing on the outside (i.e. the testbench signal clk) is actively driving it to '0' or '1'Not sure what you mean with "as expected". This design is fatally flawed by having two drivers both trying to drive the same signal at the same time. I have no idea what you're trying to do inside gentest with sigio in the first place. Either sigio
What I "expect" is that I can simulate the
model (this_is_a_simulation = true) with the testbench
driving the clk signal. And that by setting this_is_a_simulation
to false, I can generate the logic for the real FPGA, where clk is
connected to an IO pin and must for some reason be inout.
I now solve this by commenting in/out a block of code. This works, but
is error prone. Luckily forgetting to uncomment the PLL block is easily spotted as it results in a fast run with an empty FPGA as a result. ;-)
As I said before, I got this code with this construct and could not get
is to work and I do not know if it ever worked.
I expected the problem to be in the "if condition generate" part of the code. But of I understand you correctly, the problem already is in
declaring the signal as inout.
But what should a compiler do with a conditional generate block that is
off? Should it be completely ignored or should it still be tested for validity?
Say we have an entity with this port:
port( signal_in : in std_logic );
And then somewhere in the architecture we have this:
testblock : if false generate
signal_in <= '1';
end generate;
Should the compiler ignore driving a input signal or should it give an
error although testblock is "off"?
On Monday, December 12, 2022 at 4:26:46 AM UTC-5, Stef wrote:you don't connect inputs. Pretty simple.
On 2022-12-11 KJ wrote in comp.lang.vhdl:
On Friday, December 9, 2022 at 6:20:14 AM UTC-5, Stef wrote:
In the examples I tried to reduce the problem down to a small model and
I may have simpified it too much. In the "if this_is_a_simulation =
false" situation, the sigio in gentest.vhd is connected to the clock
pin of an instantiated PLL block and according to the code I inherited,
this pin is an inout signal (you would expect an in, but it is inout).
This doesn't make any sense. Is gentest connected to an input or an output of the PLL block? Whichever it is, gentest should be the opposite. This is pretty basic, you connect inputs to outputs and vice versa. You don't connect outputs together,
should be of type 'in' and the "sigio <= 1'" statement should be removed OR if it really is meant to be of type 'inout', then you should only be driving sigio when nothing on the outside (i.e. the testbench signal clk) is actively driving it to '0' or '1'Not sure what you mean with "as expected". This design is fatally flawed by having two drivers both trying to drive the same signal at the same time. I have no idea what you're trying to do inside gentest with sigio in the first place. Either sigio
you will then have to figure out.What I "expect" is that I can simulate the
model (this_is_a_simulation = true) with the testbench
driving the clk signal. And that by setting this_is_a_simulation
to false, I can generate the logic for the real FPGA, where clk is
connected to an IO pin and must for some reason be inout.
This doesn't make much sense either. You shouldn't be changing logic to do simulation. The whole point of simulation is to have a model of the real system. If you are making logic changes "for simulation", you are most likely making a mistake that
I now solve this by commenting in/out a block of code. This works, but
is error prone. Luckily forgetting to uncomment the PLL block is easily
spotted as it results in a fast run with an empty FPGA as a result. ;-)
Error prone is a polite way to put it. Of no value at all would be another.
As I said before, I got this code with this construct and could not get
is to work and I do not know if it ever worked.
That's why you run the simulator...to find out what's wrong. But you don't start by connecting outputs together.
I expected the problem to be in the "if condition generate" part of the
code. But of I understand you correctly, the problem already is in
declaring the signal as inout.
The problem is that you are thinking that a real design would connect two outputs together. It has nothing to do with VHDL at all.
together as you did. Instead it shows you the results of that design error which is that the resulting output is undefined.But what should a compiler do with a conditional generate block that is
off? Should it be completely ignored or should it still be tested for
validity?
The compiler already did the right thing.
Say we have an entity with this port:
port( signal_in : in std_logic );
And then somewhere in the architecture we have this:
testblock : if false generate
signal_in <= '1';
end generate;
Should the compiler ignore driving a input signal or should it give an
error although testblock is "off"?
As long as the syntax is correct (and your signal assignment to signal_in is), there is no error for the compiler to report. What error do you think should be reported? The compiler does not report on design errors such as connecting two outputs
If you want the compiler itself to help you out some more, change all your usages of 'std_logic' to 'std_ulogic' in gentest as well as the testbench. Then the compilation will fail because signals of type 'std_ulogic' can have only one driver. Youwon't even be able to start the simulation until you fix the error. Use of std_ulogic rather than std_logic finds the design errors that you are creating right at compile time and gives you all the information about where the problem is located in the
On 2022-12-14 KJ wrote in comp.lang.vhdl:
On Monday, December 12, 2022 at 4:26:46 AM UTC-5, Stef wrote:
On 2022-12-11 KJ wrote in comp.lang.vhdl:
On Friday, December 9, 2022 at 6:20:14 AM UTC-5, Stef wrote:
don't connect inputs. Pretty simple.This doesn't make any sense. Is gentest connected to an input or an output of the PLL block? Whichever it is, gentest should be the opposite. This is pretty basic, you connect inputs to outputs and vice versa. You don't connect outputs together, you
In the design I inherited the PLL pin is a package pin and declared as inout. Why this was done, I do not know. So two inouts are connected together. And yes, I am aware that you don't connect outputs or inputs together (I am and electronics engineer). I will see if it can be changed
to an input to get rid of this problem.
Aparently the PLL could not be simulated, so the clock came directly
from the test bench. So some switch between testbench and pll clock must
be made between simulation and hardware generation. Probably not the
best solution, as you say. But this is how I got it. And I try to
understand why they did this before changing everything.
The problem is that you are thinking that a real design would connect two outputs together. It has nothing to do with VHDL at all.
No I do not think that, what makes you believe I do?
The syntax in itself is correct, but assigning a value to an input is
not. So I would not expect an error on that code, as do you, I read in
the above. However when I compile this in Modelsim:
rtlblk : if this_is_a_simulation = false generate
sigio <= '1';
sigout <= '1';
end generate;
With this_is_a_simulation set to true and sigio declared as in, I get
the following error
-- Compiling architecture behav of gentest
** Error: ../gentest.vhd(19): Cannot drive signal 'sigio' of mode IN.
This is not what I expect, why is the assignment not ignored?
This is the core of my original question. What is the expected behaviour when such generate blocks are disabled and contain incorrect code?
won't even be able to start the simulation until you fix the error. Use of std_ulogic rather than std_logic finds the design errors that you are creating right at compile time and gives you all the information about where the problem is located in theIf you want the compiler itself to help you out some more, change all your usages of 'std_logic' to 'std_ulogic' in gentest as well as the testbench. Then the compilation will fail because signals of type 'std_ulogic' can have only one driver. You
No, FPGAa don't have internal tri-state signals. Changing to std_ulogic sounds like a good idea. Is this what you normally use for internal logic?
On Wednesday, December 14, 2022 at 7:08:35 AM UTC-5, Stef wrote:don't connect inputs. Pretty simple.
On 2022-12-14 KJ wrote in comp.lang.vhdl:
On Monday, December 12, 2022 at 4:26:46 AM UTC-5, Stef wrote:
On 2022-12-11 KJ wrote in comp.lang.vhdl:
On Friday, December 9, 2022 at 6:20:14 AM UTC-5, Stef wrote:
This doesn't make any sense. Is gentest connected to an input or an output of the PLL block? Whichever it is, gentest should be the opposite. This is pretty basic, you connect inputs to outputs and vice versa. You don't connect outputs together, you
inout. I doubt that to actually be the case based on what you've described so far. However, if it is truly a bi-directional signal, then that same PLL documentation will also describe the conditions under which the PLL uses the pin as an input and theIn the design I inherited the PLL pin is a package pin and declared as
inout. Why this was done, I do not know. So two inouts are connected
together. And yes, I am aware that you don't connect outputs or inputs
together (I am and electronics engineer). I will see if it can be changed
to an input to get rid of this problem.
The place to look is in the documentation for the PLL, not in the VHDL code. If the PLL documentation says that there are times when the pin is driven externally and other times that it is producing an output then it should be described in VHDL as an
If the documentation says the pin is an output, then it is. If the VHDL says it is an inout, the VHDL is not correctly describing the PLL which means the VHDL is wrong and should be corrected.
should then be doing is creating an if/generate around the PLL itself, not in some separate entity which is how it appears that you are currently doing it.Aparently the PLL could not be simulated, so the clock came directly
from the test bench. So some switch between testbench and pll clock must
be made between simulation and hardware generation. Probably not the
best solution, as you say. But this is how I got it. And I try to
understand why they did this before changing everything.
Not wanting to make changes before understanding is a good approach. But now I think we're finally getting to the nuts and bolts of the problem you're actually looking at which is that there is no simulation model for the PLL, correct? What you
So in the FPGA design there is someplace where you are instantiating a component that is the PLL. All FPGA PLLs will have an input clock and produce output clocks and will have multiple parameters to configure it. The instantiation then will looksomething like this...
MyPll : ThePll(InputClock, OutputClock, ...);originally posted had the process that generated the clock in one entity (the testbench). You don't really show where the instantiation of the PLL is located, but I'm assuming it is in gentest which I'm guessing is the FPGA design. Regardless though,
So, if you really don't have a simulation model for the PLL you would modify this single instantiation to be the following. Note that what is being switched between based on this_is_a_simulation will be in the same entity/architecture. What you
Also note that for the simulation part, I've simply copied the code you posted from the testbench just renaming the 'clk' signal to be the same name as the clock signal output from the PLL. PLLs also tend to have an output that says when the PLL haslocked on to the input and the output clock is now valid. If you're using such a signal (or other PLL output signals), you would connect them to the PLL component in the rtlblk for the MyPll but then also generate logic in the simblk to create that
simblk : if this_is_a_simulation = true generateis add the simulation model VHDL file to the simulation project. That would be the best approach since it gets you the correct simulation model as opposed to something that is cobbled together. Which software are you using to build the FPGA design? I
process
begin
OutputClock <= '0';
wait for 10ns;
OutputClock <= '1';
wait for 10ns;
end process;
-- Add code for any other PLL outputs that you're using here
Having said all that, you might want to double check your FPGA tools. Typically there is a simulation model of the PLL. In that case you wouldn't make any changes to the source code of the FPGA design as described above. Instead all you need to do
No I do not think that, what makes you believe I do?
The problem is that you are thinking that a real design would connect two outputs together. It has nothing to do with VHDL at all.
Because you added code in gentest to explicitly drive a signal that is already being driven by the testbench.
The syntax in itself is correct, but assigning a value to an input isBecause a VHDL generate statement is not like a C pre-processor where it ignores entire blocks of code. For example, in C you can have the following which will compile just fine and not produce any problems
not. So I would not expect an error on that code, as do you, I read in
the above. However when I compile this in Modelsim:
rtlblk : if this_is_a_simulation = false generate
sigio <= '1';
sigout <= '1';
end generate;
With this_is_a_simulation set to true and sigio declared as in, I get
the following error
-- Compiling architecture behav of gentest
** Error: ../gentest.vhd(19): Cannot drive signal 'sigio' of mode IN.
This is not what I expect, why is the assignment not ignored?
#if false
alkljdfljk
#endif
The equivalent in VHDL would be
MyGenerate : if false
alkljdfljk
end generate
VHDL will flag 'alkljdfljk' as an error because it analyzes all of the code, even if the conditions imply that the code will never be used. In your case, the error was that you tried to assign a value to an input.
You may choose to see this as "Why the heck are you complaining about code that will not be used?" or choose to see it as making sure that all of the code, whether it will be used or not, is valid code. In this case, it may be trivial, but consider ifyou had several if/generate statements controlled by various parameters. Would you really want to have to compile all of the possible parameter settings in order to know that every possible combination of parameters compiles correctly? What VHDL is
This is the core of my original question. What is the expected behaviour
when such generate blocks are disabled and contain incorrect code?
I think I've answered the question here. Hopefully that is the case. If not, chime back in.
won't even be able to start the simulation until you fix the error. Use of std_ulogic rather than std_logic finds the design errors that you are creating right at compile time and gives you all the information about where the problem is located in theIf you want the compiler itself to help you out some more, change all your usages of 'std_logic' to 'std_ulogic' in gentest as well as the testbench. Then the compilation will fail because signals of type 'std_ulogic' can have only one driver. You
No, FPGAa don't have internal tri-state signals. Changing to std_ulogicYes, I use std_ulogic for all signals, testbench and design, that have a single driver in 'real life'. Bi-directional interfaces, such as that to an external memory, are the only std_logic signals.
sounds like a good idea. Is this what you normally use for internal logic? >>
Kevin Jennings
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 48:24:46 |
Calls: | 6,710 |
Calls today: | 3 |
Files: | 12,243 |
Messages: | 5,354,640 |
Posted today: | 1 |