if you had a process like this for example:
process (clk)
if (var = '1') then
var2 = '1';
end if;
if (var2 = '1') then
//do something
end if;
end process;
Would the 2nd if statement get executed on the next clock cycle, or would it get executed as soon as var2 = '1' is executed?
Would the below code do exactly the same thing as the code above?
process (clk)
if (var = '1') then
var2 = '1';
end if;
end process;
process (var2)
if (var2 = '1') then
//do something
end if;
end process;
If someone could explain the timing issues that would be great.
If your vars are variables, then you can't sensibly do the second option as you can't use variables across processes (in most circumstances, see later). If they are actually signals, then yes you can.
In the first code - if they are variables, then yes, they will update immediately and the second part of the code will run.
If they are signals then the second if block will only run next time around, as signals are only updated at the end of the process that writes to them.
The second example code will run the second process in the next "delta cycle" after the first one runs, as it is sensitive to the change on var2.
You can use variables between processes, but they have to be specified as shared variables. If you do that with "straight" shaed variables, you run the risk of hideous Verilog-like race conditions as the order of reading and updates is undefined.
You should make them of a protected type which is a bit OO-like and has methods to operate on the values which allows accesses to be atomic across multiple processes.
In your first piece of code - As var2 is a variable it will get the new value immediately. Therefore the if statement will see the new value, and //do something would happen in the same time slice.
(// comments? Really? This is VHDL. We used --)
Your second piece of code wont work. Variables are scoped to a process, and can't be used to transfer values between processes. You have to use signals, and so the rules change. Consider this code:
signal sig : std_logic := 1;
signal sig2 : std_logic := 0;
process (clk)
if (sig = '1') then
sig2 <= '1';
end if;
if (sig2 = '1') then
-- do something
end if;
end process;
process (sig2)
if (sig2 = '1') then
-- do something else
end if;
end process;
Initial conditions: sig is 1 and sig2 is 0, so we're just waiting for a clk edge.
When the clock edge arrives we enter the first process we see that sig is 1 and assign 1 to sig2. All simple so far, but because sig2 is a signal the assignment wont happen until the process completes. Than means than when we compare sig2 to 1 on the next line, it will be false (sig2 is still 0 for now), and we won't -- do something. We then end the process.
Now, because at the end of the first process sig2 changed value 0 -> 1 the second process will be triggered (it's sensitive to sig2). It sees that sig2 is 1 and so it will -- do something else.
When the next clock edge comes (and it could be a negative edge with this code), sig2 is still 1 and so now we'll -- do something, and we'll do that for every clock edge.
In summary the order of events for this code would be:
Clk : 0->1
Sig2 : 0->1
-- Do Something Else
Clk : 1->0
-- Do Something
Clk : 0->1
-- Do Something
Clk : 1->0
-- Do Something
Clk : 0->1
-- Do Something
.........
When you understand that ordering, you'll understand an important part of how VHDL schedules things.
Related
If we have two tasks in Ada, and if I had a delay statement, whether that's a "delay 0.0" or "delay 1.0", does that put that process into the blocked state? Or do the process states not apply here? The following is a simple code to illustrate my question:
with Ada.Text_IO; use Ada.Text_IO;
procedure Two_Tasks is
task Task_1;
task Task_2;
task body Task_1 is
begin
for I in 1 .. 10 loop
Put_Line ("Visited task 1, iteration number" & Integer'Image (I));
delay 0.0;
end loop;
end Task_1;
task body Task_2 is
begin
for I in 1 .. 10 loop
Put_Line ("Visited task 2, iteration number" & Integer'Image (I));
end loop;
end Task_2;
begin
Put_Line ("Visited the main task");
end Two_Tasks;
In terms of the process states, I am talking about the process/thread state shown in this diagram:
According to Ada 2012 Reference Manual section 9.6:
For the execution of a delay_statement, the delay_expression is first evaluated. For a delay_until_statement, the expiration time for the delay is the value of the delay_expression, in the time base associated with the type of the expression. For a delay_relative_statement, the expiration time is defined as the current time, in the time base associated with relative delays, plus the value of the delay_expression converted to the type Duration, and then rounded up to the next clock tick. The time base associated with relative delays is as defined in D.9, “Delay Accuracy” or is implementation defined.
The task executing a delay_statement is blocked until the expiration time is reached, at which point it becomes ready again. If the expiration time has already passed, the task is not blocked.
All I want to do is to send one value to the channel and return from the main() function and exit the program right after I receive one value from the channel ch.
But this keeps running forever:
ch := make(chan int)
for {
go func() {
ch <- 1
}()
}
<-ch
How do I return with this for loop after I receive one value from the channel?
And why does this run forever?
Go playground link is here
http://play.golang.org/p/EvmT6Pw96Y
Since the for loop runs forever, your code runs forever. Receiving from ch after the for loop is never reached.
If you want your code to exit sometime, you have to end the for loop sometime, e.g. make it run only a certain number of iterations:
for i := 0; i < 5; i++ {
...
}
So if you only run 5 iterations (like in my example), after the for loop receiving from ch will be executed which may block (because ch is unbuffered) if other goroutines have not yet run, and at least one of the started goroutines will be executed which sends a value on the channel which may trigger the main goroutine to continue (because its blocking operating is no longer blocking).
Also note that the Go Memory Model only guarantees that certain events happen before other events, you have no guarantee how 2 concurrent goroutines are executed. You have no guarantee that the goroutines started in the for loop will start to execute before the main goroutine gets blocked at receiving from ch.
Usually when a goroutine gets blocked (e.g. blocking channel receive operation), the runtime may schedule another goroutine to run.
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).
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.
Well i have process a in my main component and process b in my other sub component(inmplemented in the main one).
both process a and b have only the clock in their sensitivity list:
process a control eneable signal called ready which if 1 process b can work , 0 process b will do nothing.
Problem is in process a , when process a changes value of enable signal to 0 , it has to take to the next clock cycle to change so process b ends up and run an extra clock cycle.
a:process(clk)
begin
if(rising_edge(clk)) then
if(output/=old_output) then
enable<='0';
end if;
end if;
end process;
b:process(clk)
begin
if(rising_edge(clk)) then
if(enable='1') then
--do anything
end if;
end if;
end process;
The reason is that the value is latched/sampled at the exact rising_edge of the clock. At that time, 'enable' is still equal to one. In that simulation delta, enabled will get the value zero, but it won't be available until AFTER the first delta.
This is also true for when enable BECOMES one (given that it is also generated on a rising clock edge), the process will latch the value exactly when clock rises, and in the simulator, enabled will look high for a whole clock period, even though "--do anything" will not happen.
You can think of this as real electrical circuits instead of a programming language. Consider that the evaluation of "output/=old_output" will consume time, and that you as a designer want that to be DONE before the next rising clock edge.
Hope this helps, but this is how the language works. I could give you a better answer if both the setting and resetting of the enable.