SystemVerilog Assertion does not fail when it should - fpga

I have a simple assertion as follows:
$rose(req) |=> !req[*1:10] until ack ##1 !ack;
As I understand, on detection of $rose(req), the assertion should check for !req to be low consecutively for max 10 clocks OR -until- ack arrives (ack=1). Once ack is true, it should de-assert the very next clock.
My test starts with $rose(req); then keep !req asserted for a few clocks (less than 10) and then drives ack=1. Then, I keep ack=1 for 4 clocks. It does not go low the very next clock, as the assertion requires. Still, the assertion does not fail. The thread "!req[*1:10] until ack" seems to keep firing, even after ack has arrived and the 'until' condition is satisfied.
Any ideas why the assertion does not fail?
Here's the EDA playground link that simulates the scenario.
EXAMPLE

You assertion is totally valid!
You are giving no information about ack signal during the !req[*1:10] phase.
The simulator finds a sequence where req=0 for some clock cycles (max 10), then find ack=1 followed by ack=0;
What you want can be obtained with:
$rose(req) |=> (!ack throughout !req[*1:10]) ##1 ack ##1 !ack;
I would not use until ack here, just ##1 ack

G.C.'s solution works.
I found another solution as well.
#(posedge clk) $rose(req) |=> first_match(!req[*1:10] ##1 ack) ##1 !ack;

Related

VHDL: Help understanding time steps/states and concurrency

I'm normally a C#/Java programmer and I'm still having trouble fully wrapping my head around hardware description.
I have a register that loads in a value. Afterwards, a comparator compares the output of the register with the value '16'. If the value is less than or equal, I go to State_0, if it's greater than, I go to State_3.
I have a 'controlsignals' process running concurrently to my statetable process. For my control signals, I know that I have to set the enable for the register to high when I'm in State_2, so:
controlsignals: PROCESS (Tstep_Q)
BEGIN
.... initialisation ...
CASE Tstep_Q IS
.... other states ....
WHEN T2 => --define signals in time step T2
enRegister = '1';
For my state table:
statetable: PROCESS (Tstep_Q, regOutput)
BEGIN
CASE Tstep_Q IS
.... other states ....
WHEN T2 =>
IF ((regOutput - 16) > 0)
THEN Tstep_D <= T3;
ELSE Tstep_D <= T0;
END IF;
And near the end of my code I have:
fsmflipflops: PROCESS (Clock)
BEGIN
IF Clock'EVENT AND Clock = '1' THEN
Tstep_Q <= Tstep_D;
END IF;
END PROCESS;
reg: regn PORT MAP (somevalue, enReg, Clock, regOutput);
Since my state table and my control signals are concurrent blocks, my confusion is... will I first enable the register and then run the comparator to determine my next state, like I want my circuit to run (since the statetable is sensitive to regOutput)? Or would it be safer to create a new state after T2 where I have my comparator? Thank you in advance.
Concurrency of the comparator
Imagine that right after the clock edge, the state signal has been updated. You've got one clock period to do a comparison and set the next state.
Your 'statetable' is being evaluated at all times.
Timing of enRegister
Doing the comparison in T2 only makes sense if you can read the output of the register in the same clock cycle as you are setting the enable. This may be a problem, but your question does not contain the information to check that.
Sensitivity list of statetable
You want this process to run concurrently, so all its inputs need to go in the sensitivity list.
It looks like you are working from a decent reference and structuring your code well. I suspect that the sensitivity list is really the problem you are having - causing odd behaviour in simulation, so I'll keep this answer short and let you try to fix that.

event and transaction in vhdl(timing diagram)

I tried to solve the problem, but I got a different table than the table that xilinx shows. I attatched both my answer and real answer. Xilinx shows that "out" is 'U' until 36ns, after 36ns, it is '1'. Can anyone help me about why the "out" graphics is not assigned any value before 36ns?(I think it should be assigned first at 20 ns).
my answer
question
This turned out to be a really good question. I initially thought you had done something wrong when simulating, but then I ran my own simulation and got the same result.
It turns out that the a <= b after x assignment uses something called the "inertial time model" by default. In this mode scheduled events will be cancelled if b changes again before x time has passed. The purpose is to filter pulses shorter than the specified delay. In your case this is what the simulator will do:
At t=0, out is scheduled to change to 1 at t=20.
At t=12, tem1 or tem2 changes to 0. The scheduled change at t=20 is cancelled and a new change to 0 is scheduled at t=32.
At t=16, tem1 or tem2 changes back to 1. Again the scheduled change is cancelled and a new change is scheduled at t=36.
After this tem1 or tem2 remains at 1, so the change at t=36 is executed and out finally changes from U.
You can change to the "transport delay model" using out <= transport tem1 or tem2 after 20 ns; In this case your drawn waveform will match with simulation.

Can we use two wait statements in a single process in VHDL?

I have to create a delay of say 20 ms in a process waiting in an input button.
I wrote the following code and it gives an error
wait until clk'EVENT and clk='1';
wait for 20 ms;
Or, can I use a construct like:
wait for 20 ms until clk'EVENT and clk='1';
Any help is highly appreciated.
You can wait for an event, for time, or for both (or neither--but that is a unique case).
Now, I'm not quite sure why your first example gives an error since it is a valid sequential statement. But you have not provided a complete example nor the error code. So, my answer here will be pretty basic.
First, a wait statement can only occur as a sequential statement, essentially meaning only in a process (or called from a process). So, if you are trying to use it concurrently, it is a problem.
Now, if you are using it from a process, it must be in a process without a sensitivity list. That is, the following is illegal:
process(clk)
begin
wait until clk'EVENT and clk='1';
end process;
It must be a bare process, such as:
process
begin
wait until clk'EVENT and clk='1';
end process;
A bit more on your first example (properly placed in a sequential context and does compile):
process
begin
wait until clk'EVENT and clk='1';
wait for 20 ms;
end process;
This code waits for a rising edge on clk, and then waits for 20ms. These are sequentially executed (hence the sequential context in a process).
Your second statement needs to be tweaked to compile. Generally, a wait statement has the form wait until <event> for <time>, where both event and time are optional. For example:
process
begin
wait; -- No event, no time. Wait forever.
wait until clk'event and clk='1'; -- Wait forever for a rising edge on 'clk'
wait for 20 ms; -- Wait for 20 ms
wait until clk'event and clk='1' for 20 ms; --Wait for up to 20 ms for a rising edge on 'clk'
end process;
So, your second example has the order backward for event and time.
Finally, your introductory text indicates you are waiting for 20ms for a push button. This hints that you are trying to create real logic. The wait statement is synthesizable only in very limited use cases. And one of the cases specifically excluded is waiting for a period of time. If you need to wait for 20 ms, you'll need to do it some other way (such as counting clocks). And if you are trying to wait up to 20 ms for the button, it'll have to be a combination of detecting the change on the pushbutton and counting clocks.

Failed TWI transaction after sleep on Xmega

we've had some troubles with TWI/I2C after waking up from sleep with the Atmel Xmega256A3. Instead of digging into the details of TWI/I2C we've decided to use the supplied twi_master_driver from Atmel attached to AVR1308 application note.
The problem is one or a few failed TWI transactions just after waking up from sleep. On the I2C-bus connected to the XMega we have a few potentiometers, a thermometer and an RTC. The XMega acts as the only master on the bus.
We use the sleep functions found in AVRLIBC:
{code for turning of VCC to all I2C connected devices}
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
{code for turning on VCC to all I2C connected devices}
The XMega as woken from sleep by the RTC which sets a pin high. After the XMega is woken from sleep, we want to set a value on one of the potentiometers, but this fails. For some reason, the TWI-transaction result is TWIM_RESULT_NACK_RECEIVED instead of TWIM_RESULT_OK in the first transaction. After that everything seems to work again.
Have we missed anything here? Is there any known issues with the XMega, sleep and TWI? Do we need to reset the TWI of clear any flags after waking from sleep?
Best regards
Fredrik
There is a common problem on I2C/TWI where the internal state machine gets stuck in an intermediate state if a transaction is not completed fully. The slave then does not respond correctly when addressed on the next transaction. This commonly happens when the master is reset or stops outputting the SCK signal part way through the read or write. A solution is to toggle the SCK line manually 8 or 9 times before starting any data transactions so the that the internal state machines in the slaves are all reset to the start of transfer point and they are all then looking for their address byte.

Chain of packets in MathLink: are the packets always strictly ordered?

The Documentation does not state clear the order of packets returned
by slave kernel via MathLink. It is natural to suppose that (when
sending an input expression with head EnterExpressionPacket and working in standard mode):
1) the last packet before the next InputNamePacket is always
ReturnExpressionPacket
2) there may be always only one ReturnExpressionPacket and one
OutputNamePacket for one EnterExpressionPacket
3) ReturnExpressionPacket is always the next after OutputNamePacket
4) after MessagePacket the next packet is always TextPacket with
all contents of that message
5) there are only 7 types of returned packets in the standard mode: InputNamePacket, OutputNamePacket, ReturnExpressionPacket, DisplayPacket, DisplayEndPacket,
MessagePacket, TextPacket.
Which of these statements are true?
1 is probably not guaranteed.
2 is definitely not true (evaluate: "2+2\n2+3").
3 is probably true but probably not guaranteed.
I believe 4 is true.
5 is not guaranteed.
In general you should write your code to not rely on the order of packets coming from the kernel. The evaluation should be considered "active" until you receive a new InputNamePacket. OutputNamePacket should update some variable. ReturnExpressionPacket should use the current output name from that variable. If you receive an unknown packet simply ignore it and move on to the next packet.

Resources