vhdl checking a range with if statements - if-statement

I am quiet new to VHDL, so i am having trouble with this issue.
A section of my program is to measure the time it takes for a capacitor to charge, and then see which range the charge time falls under.
What i want to see is if count falls under the range H43044 - H 43238 or H8c424 - H8c618
if ((count >= x"43044") and (count <= x"43238"))then
d3 <= '1'; --enable output
elsif ((count >= x"8c424") and (count <= x"8c618")) then
d4 <= '1';
end if;
i made sure the count falls under one of these statement, but i get no output at all. I wonder if this is the right way to approach this problem.

Just to close this question, turns out i was using wrong clock in my test bench, i presumed my error was in the way i presented the logic in above segment, because all other code worked just fine. now i know that is the correct method to check range. thanks every one.

Related

C++ - condition in -for loop- isn't evaluated as I think it should be

I'm quite new to C++ and I have some kind of problem. I would like to ask if someone could explain to me why the evaluation within the for condition does not work.
This is a part of a program I've written, there is a rpm value which is given by the user and gets assorted to a rpm_case to do some calculations later.
What it SHOULD do:
rpm between 800 up to 1200 ==> rpm_case = 0
rpm between 1200 up to 1800 ==> rpm_case = 1
rpm between 1800 up to 2500 ==> rpm_case = 2
rpm between 2500 to 3500 ==> rpm_case = 3
========================================================================
in the first place I had some 30-line long if-construction for that but I discarded that already and replaced it with the following much shorted and nicer way to write it (this works as expected):
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0;; rpm_case++) {
if (!(rpm > rpm_bases[rpm_case+1])) {break;}
}
but I'm still not happy because I was really trying to get rid of the if with the for loop.
But the for- loop instead always loops over the entire size of the array instead breaking at the considered point.
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0; (!(rpm > rpm_bases[rpm_case+1])); rpm_case++) {}
?? It somehow seems as it is not possible to evaluate a array with the counter-variable within the conditional part of an for-loop??? Or am I just doing something totally wrong I don't want to exclude that option either.
Big Thanks to everyone in advance.
The middle expression of a for statement is the condition that must be true for the loop to repeat. Therefore, it must be the opposite of the condition that must be true for the loop to break.
For this reason, you must negate the expression by removing the ! (NOT) operator, like this:
for (rpm_case=0; rpm > rpm_bases[rpm_case+1]; rpm_case++);
This expression will work for the cases stated in your question. However, if rpm is higher than 3500, it will cause the array rpm_bases to be accessed out of bounds, causing undefined behavior. Therefore, it would be safer to write the loop in the following way:
for ( rpm_case=0; rpm_case < known_rpm_bases; rpm_case++ )
{
if ( rpm <= rpm_bases[rpm_case] ) break;
}
That way, your program will just give you an additional increment of rpm_case if rpm is higher than the highest value, instead of accessing the array out of bounds causing undefinied behavior.
This is effectively just a typo.
The loop condition is for how long the loop does keep running, not to describe when it ends.
Invert it.

Using an if-statement for div by 0 protection in Modelica

I made a simple model of a heat pump which uses sensor data to calculate its COP.
while COP = heat / power
sometimes there is no power so the system does a (cannot divide by zero). I would like these values to just be zero. So i tried an IF-statementif-statement. if power(u) = 0 then COP(y) = 0. somehow this does not work (see time 8)COP output + data. Anyone who seems to notice the problem?
edit(still problems at time 8.1
edit(heat and power)
To make the computation a bit more generally applicable (e.g. the sign of power can change), take a look at the code below. It could also be a good idea to build a function from it (for the function the noEvent()-statements can be left out)...
model DivNoZeroExample
parameter Real eps = 1e-6 "Smallest number to be used as divisor";
Real power = 0.5-time "Some artificial value for power";
Real heat = 1 "Some artificial value for heat";
Real COP "To be computed";
equation
if noEvent(abs(power) < abs(eps)) then
COP = if noEvent(power>= 0) then heat/eps else heat/(-eps);
else
COP = heat/power;
end if;
end DivNoZeroExample;
Relational operations work a bit differently in Modelica.
If you replace if u>0 by if noEvent(u>0) it should work as you expected.
For details see section 8.5 Events and Synchronization in the Modelica specification https://modelica.org/documents/ModelicaSpec34.pdf

VHDL if statements in process driving multiple outputs per if statement

I have a weird question which sounds self explanatory in vhdl, but the code does not output to an oscilloscope even though the logic seems okay. I need to drive 0's and 1's for each bit in the vector below, and I need to do this with combinations of sliderswitches. I am using the Digilent Nexys 3.
My problem is that when I run this code or any code that has more than 3 outputs per if statement, one of the outputs does not output to logic '1' when given the right combination.
I gave my code below, which seems extremely simple. Can someone tell me why I can only output 3 things per if statement? I need to be able to output 20 or more signals per if statement.
I have tried everything I can think of, from using bit_vector, to using different syntax. Any help on why I can only get 3 outputs at most would be greatly appreciated.
Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all ;
entity pulse_gen_toVGA is port (
clk_50,sw0,sw1,sw2,sw3 : in std_logic ;
rst : in std_logic;
output : out std_logic_vector(3 downto 0));
end pulse_gen_toVGA;
architecture top of pulse_gen_toVGA is
begin
process(sw0,sw1,sw2,sw3)
begin
if (sw0='0' and sw1='0' and sw2='0' and sw3='0') then
null;
end if;
if(sw0='1') then
output<="0001";
elsif(sw1='1') then
output<="0010";
elsif(sw2='1') then
output<="0100";
elsif(sw3='1') then
output<="1000";
end if;
end process;
end top ;
Here is my ucf file of the outputs that I am using.
net "clk_50" loc="v10";
net "output<0>" loc="t12";
net "output<1>" loc="n10";
net "output<2>" loc="p11";
net "output<3>" loc="h3";
net "sw0" loc="t10";
net "sw1" loc="t9";
net "sw2" loc="v9";
net "sw3" loc="m8";
Well, your code is not exactly O.K.. Let's see:
if (sw0='0' and sw1='0' and sw2='0' and sw3='0') then
null;
end if;
This if does nothing, except waste precious bytes on your hard drive and several microseconds of cpu time everytime you synthesise or simulate. Having these lines or not changes absolutely nothing, so might as well remove them.
if(sw0='1') then
output<="0001";
elsif(sw1='1') then
output<="0010";
elsif(sw2='1') then
output<="0100";
elsif(sw3='1') then
output<="1000";
end if;
What happens if none of the switches is '1'? Implicitely, that a signal must not change its value if it is not assigned, which requires a memory element since when all switches are '0', output depends on the last switch that was active.
In that case, the synthesizer will infer a latch. Latches are known to behave erratically and should really only be used by experts. They appear every time you forget to assign a signal in one logical path of a combinational process.
You have two choices to fix your code, either you add an else to your if statement, setting output to 0 for example, or you use a proper memory element known as a register. In the first case, you will have a combinational circuit, containing only logic gates with no latch/register. In the second case, you will have the same behaviour as the latch circuit, but without the erratically of the latch. Here's how to implement a register:
process(clk_50)
begin
if rising_edge(clk_50) then
if(sw0='1') then
output<="0001";
elsif(sw1='1') then
output<="0010";
elsif(sw2='1') then
output<="0100";
elsif(sw3='1') then
output<="1000";
end if;
end if;
end process;
I have to add that the register route is not entirely fine, and encourage you to search for metastability, asynchronous input and resynchronization. Basically, using asynchronous signals (like your switches) without synchronizing it can cause problem.
Finally, it may not solve your problem, but we can look into that once you have a "clean" code.
Before you go making changes there are a couple of thing you can check.
There are not outputs labelled output in Nexys3_Master.ucf. Show us how (where) output goes that you're detecting it doesn't occur.
We can't replicate your problem with what you've provided, it isn't an Minimal, Complete, and Verifiable example.
Next, simulate your design.
Here is a simple testbench:
library ieee;
use ieee.std_logic_1164.all;
entity pgtv_tb is
end entity;
architecture foo of pgtv_tb is
signal clk_50: std_logic;
signal sw0, sw1, sw2, sw3: std_logic;
signal rst: std_logic;
signal output: std_logic_vector (3 downto 0);
begin
DUT:
entity work.pulse_gen_toVGA
port map (
clk_50 => clk_50,
sw0 => sw0,
sw1 => sw1,
sw2 => sw2,
sw3 => sw3,
rst => rst,
output => output
);
STIMULUS:
process
begin
wait for 100 ms;
sw0 <= '0';
sw1 <= '0';
sw2 <= '0';
sw3 <= '0';
wait for 100 ms;
sw0 <= '1';
wait for 100 ms;
sw0 <= '0';
wait for 100 ms;
sw1 <= '1';
wait for 100 ms;
sw1 <= '0';
wait for 100 ms;
sw2 <= '1';
wait for 100 ms;
sw2 <= '0';
wait for 100 ms;
sw3 <= '1';
wait for 100 ms;
sw3 <= '0';
wait for 100 ms;
wait;
end process;
end architecture;
And it produces:
(clickable)
Now the first thing we see is the inferred latches Jonathan Drolet was concerned with from the null statement in the first if statement.
Changing all the switch inputs to '0' didn't affect output, this happens four more times in the simulation.
But you can see we actually do get four outputs, which says
... when I run this code or any code that has more than 3 outputs per if statement, one of the outputs does not output to logic '1' when given the right combination
Isn't evident in the VHDL code. And that strongly suggests there's something wrong somewhere getting output to show up, and it's not evident in your code.
(Your code doesn't reproduce the problem for which you are asking help, regardless of whether you want those latches there or not).

Where does the error stem from in the process?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;
entity reset40 is
Port ( CLOCK : in STD_LOGIC; --50MHz
CIKIS : out STD_LOGIC
);
end reset40;
architecture Behavioral of reset40 is
signal A:std_logic;
begin
process(CLOCK) --line20
variable fcounter: unsigned(24 downto 0);
variable counter_A:integer range 0 to 40:=0;
begin
if rising_edge (CLOCK) then
fcounter := fcounter+1;
end if;
A<=fcounter(6); --fa=fclock/2^6
if ((rising_edge (A)) and (counter_A/=40)) then
counter_A:= counter_A+1;
CIKIS<=A;
else
CIKIS<='0';
end if;
end process;
end Behavioral;
ERROR:Xst:827 - "C:/Users/reset40/reset40.vhd" line 20: Signal CIKIS
cannot be synthesized, bad synchronous description. The description
style you are using to describe a synchronous element (register,
memory, etc.) is not supported in the current software release.
What is the error about clock? How come is it a 'bad synchronous description'?
Your basic mistake is that all the code that is in the process needs to run only on the rising edge of the clock. This is because the target chip only has flipflops which can respond on one edge.
The process you have written is sensitive to changes in clock due to this line:
process(clock)
so it is sensitive to both clock edges.
You have then put part of the code inside an
if rising_edge(clock) then
which limits activity to just the rising edge, which is good. The rest of your code is unfortunately outside of that if clause, and so is described as operating on every edge of the clock, either rising or falling. In simulation this will be fine, but the synthesiser cannot find any flipflops which can do that, hence the error.
Other things to note - you need to reset or initialise your counter somehow. Either with a reset signal, so that any time the reset signal is high, the counter is set back to all zeros. Or using an initialisation statement.
You can get away without them for pure synthesis, as the sythesiser will (in the absence of init or reset code) automatically set the counter to all zeros when the FPGA starts up. It's poor-form though as:
it won't work in simulation and simulation is vital. You may not have realised this yet, but you will eventually!
if you port the code to another architecture which cannot magically initialise things, you wil get random 1s and 0s in the counter at startup. This may or may not matter, but it's best to avoid having to decide.
Besides the bad synchronous description there is also bad coding style :)
First off all you should not use variables in a process if you want to describe a counter. So use a signal declared in the architecture region.
2.
Decide what signal type you want to use for counters: unsigned or integer. I would advice unsigned.
3.
Signal A is not in the sensitivity list. But adding A to the sensitivity list of your process is no solution, because having two different clocks (clock and A) in one process is (a) not supported by every synthesis tool and (b) bad coding style => so use a second process for the second counter which is using a second clock.
4.
You are using A in a 'if rising_edge(...) then' statement. Synthesis tools would infer a (new) clock signal for the signal given in brackets. So your description would lead to an asynchronous description which is also bad style. A good style would be to derive a clock enable signal from fcounter(x) which enables a second counter (counter_A). counter_A is also clocked with your main clock 'clock'
5.
fcounter has no init value despite it's a register.
6.
Why has fcounter 25 bits? you are using only 7 bits.
Besides that, using bit 6 in fcounter(6) will result in a by 128 (2^7) divided clock.
Using fcounter(0) represents a toggle flip flop, which outputs f/2. fcounter(1) -> f74 and so on...
So, how should it look like?
architecture [...]
[...]
signal fcounter : unsigned(6 downto 0) := (others => '0');
signal counter_a : unsigned(5 downto 0) := (others => '0');
begin
process(clock)
bein
if rising_edge(clock) then
-- I'm using one more bits for the counter overflow, which resets the fcounter
if (fcounter(6) = '1') then
fcounter <= (others => '0');
else
fcounter <= fcounter + 1;
end if;
-- enable counter_A every 64 cycles
if (fcounter(6) = '1') then
counter_A <= counter_A + 1;
[...]
end if;
end if;
end process;
end;
But in the end there is another question: What should this module do? Do you want to create a new /64 clock or do you want to create some kind of a reset? There are other ways to generate these kinds of signals.
Reply to Mehmet's comment:
Normally a pulse train is generated by a shift register of n bits, which is reseted to all ones and the input is assigned with '0'. For short pulse trains it's a good solution, but in your case a counter is more resource efficient :)
Example for short pulse (constant) trains
input <= '0';
--input <= any_signal;
process(clock)
begin
if rising_edge(clock) then
if (reset = '1') then
pulse_train <= (others => '1');
else
pulse_train <= pulse_train(pulse_train'high - 1 downto 0) & input;
end if;
end if;
end process;
output <= pulse_train(pulse_train'high);
Ok, in the case of supplying an external low frequency IC with a derived clock, it's ok to use a counter. If the counter can't supply the recommended frequency and duty cycle, you can use a counter to produce f_out*2 and feed this signal through a toggle flip flop. The T-FF restores the duty cycle to 50/50 and divides the clock by two to f_out.

play sound while condition is true

I have two images, when the ball image touches the other image I want a sound to be played. This is my code:
while (((dstX + 31) > wallRect.x) && ((dstX + 31) < (wallRect.x+30)) && (dstY < (wallRect.y + wallRect.h)) && ((dstY + 31) > wallRect.y)) //31 = ball dimension.
{
Mix_PlayMusic(soundEffect, -1);
}
When the first image leaves the second image the sound still plays. How can I do this?
Your code can't possibly work. Why do you even have a while loop there? This is just going to call Mix_PlayMusic() over and over again, regardless of whether the music is already playing or not. As a side effect, this loop will consume all your CPU, regardless of whether its condition evaluates to true or false.
The way this is normally done, is to have a check somewhere inside your central event loop, and check there whether the images intersect, and whether they were intersecting in the previous iteration of the event loop. This is how you decide whether to start of stop the music.
Use if instead of while, or at least check if the music is playing before calling play function.