Rising edge detection sysverilog - verilog

module syncrisedgedetect(input logic sig_a, rst,clk,output logic sig_a_risedge);
logic sig_a_d1;
always #(posedge clk or negedge rst)
begin
if(!rst)
sig_a_d1<=1'b0;
else
sig_a_d1<=sig_a;
end
assign sig_a_risedge=sig_a & !sig_a_d1;
endmodule
Hi, I came across this code in a book regarding rising edge detection for sig_a.
Can anybody explain me its working?
Thanks

This is a basic synchronous edge detection circuit.
The input, sig_a, is sampled on each rising edge of the clock, clk. The sampled value is registered; that is, sig_a_d1 is the value of sig_a delayed by one clock cycle.
The output will go to a 1 when there is a rising edge on the input. The assignment to sig_a_risedge is responsible for this. It says that "there was a rising edge on sig_a if the current value is 1 and the value on the previous clock cycle was 0".
Note that this will only work properly if the frequency of the input signal is lower than that of clock. If the input goes 0 -> 1 -> 0 all within a single clock period of the sampling clock, the edge may be missed.

Related

verilog flop RTL simulation

Assume we have a D-flip-flop.
in RTL simulation (No t_hold and t_setup here), If its data input and clk changes at the same time, what the output should be ? The value before clk rise or the value after it ?
To make it even harder,
If a data_in and clock are connected to same wire. what should be the flop's output be ? zero all time ? or one all time ?
I tried the last case in ModelSim, and I get that the output is 1 all the time, while I expect it to be 0.
I expect that the flop in RTL-simulation should simulate the value before the clock edge.
When you use a simulation you will see results depend on how this case interpreted in the simulator what you use.
As you wrote in simulation t_setup = 0, it means that you don't need to keep signal in that level (what should be caught by flip flop) some time before rising (or falling) edge of clock signal, but can be applied exactly in the same time with the rising (or falling) edge of clock.
Because you see all time of the simulation '1' on the output of flip flop

How does clock gating in RTL design work?

I'm trying to understand how clock gating works in RTL design.
I've an example wave here:
Description:
1st signal is gated_clock
2nd signal is clock_enable
3rd signal is ungated_clock
So there are 3 cycles in this wave (let's say cycle 0,1,2). In cycle 0, clock_enable was low and gated_clock was turned off. In cycle 1 clock_enable goes high and in next cycle (cycle 2) gated_clock turns on.
Now, during simulation I see some cases where an incoming data received at cycle 1 is properly being registered into the module that is gated by the clock (using gated_clock). It's kinda odd to me and I don't quite understand how it's possible.
The logic is like this:
always_ff #(posedge gated_clock, negedge reset) begin
if (~reset) begin
some_val <= 1'b0;
end else begin
if (in_valid==1'b1 && in_ready==1'b1) begin
some_val <= in_val;
end else begin
some_val <= 1'b0;
end
end
end
So I'm seeing that if in_valid and in_ready was high in cycle 1 then some_val will register the incoming in_val data and it'll be available in cycle 2. However in cycle 1, gated_clock was zero. So how did the in_val get sampled here? From what I understand, posedge gated_clock must be 1 if we want to flop in_val in cycle 1 .
I might be missing some core circuit level digital design concept. I'll really appreicate any help.
Updated wave:
1st signal is gated_clock
2nd signal is clock_enable
3rd signal is ungated_clock
4th signal is in_valid
5th signal is in_ready
6th signal is in_val
7th signal is some_val
So here you will see at cycle 0, gated_clock is off but in_val and in_ready is high. The input data in_val is also high. In next cycle some_val goes high. So it looks like in_val captured in cycle 0 even though gated_clock was off.
It's possible there is a glitch on the gated clock that's not showing up on the waveform. You'll need to look at the User Manual of the tool you're using to find out how to record and display glitches. It might also help to see the logic for gating the clock. Is clock_enable assigned using an NBA (<=)?
Your understand of what is clocked seemed off. in_val isn't clocked here (actually, from the snippet, I can't see where it is coming from). It is free to change at will (again, from the point of view of this snippet). At the point that gated_clock goes high then whatever the value of in_val at that time will now be captured in some_val and this will be available until such time as gated_clock goes high again (at which point we will sample a new value).
Based on the new waveform some_val is generated correctly to the posted RTL. On the very first edge of gated_clock signals in_valid and in_ready are both high, thus some_val is going high too in that cycle. On the next edge it toggles back to low because in_valid goes low (and btw in_val too)

Why does this code work only partially?

This code is supposed to increment a counter (outputting to LEDs) when one button is pushed and decrement it when the other one is pushed. It works OK with decrementing but on incrementing it changes LEDs to random configuration instead.
module LED_COUNTER( CLK_50M, LED, Positive, Negative );
input wire CLK_50M;
input wire Positive;
input wire Negative;
output reg[7:0] LED;
always#( posedge Positive or posedge Negative )
begin
if(Positive == 1)
LED <= LED + 1;
else
LED <= LED - 1;
end
endmodule
I am using this board: http://www.ebay.com/itm/111621868286. The pin assignment is:
The connections:
After swapping pin assignments for buttons the behavior stays the same.
As others have already pointed out, you should be clocking with the CLK_50M and you should de-bounce your inputs (some FPGAs do it for you automatically, check your manual).
The reason you see partial functionality is from the way the synthesizer interprets the RTL. If the sensitivity list is edge triggered and that signal is referenced in the body of the always block, then the synthesizer will think it is an asynchronous level sensitive signal. This is intend for asynchronous reset & set (sometimes named clear & preset). ASIC design typically use flops with asynchronous reset in most the design. FPGAs tend to have a limited number of flops with asynchronous set or rest, so check your manual and use sparingly.
With your code, Negative is the clock and Positive is treated as an active high asynchronous input.
Modify the code to a functional behavioral equivalent (in simulation) seen below, then Positive will be the clock and Negative will be the active high asynchronous input.
always#( posedge Positive or posedge Negative )
begin
if(Negative == 1)
LED <= LED - 1;
else
LED <= LED + 1;
end
There are several resource for learning Verilog available online (use your favorite search engine), and I have some resources posted on my profile though more aimed at SystemVerilog.
Here is some pseudo code to point you in the correct direction for your project:
always #(posedge CLK_50M)
begin
past_Positive <= Positive;
// ...
case({/* ... , */ past_Positive,Positive})
4'b0001 : LED <= LED + 1;
4'b0100 : LED <= LED - 1;
// ...
endcase
end
First, update the design to a synchronous design where state only changes at rising edge of the CLK_50M, like
always#( posedge CLK_50M)
begin
...
end
Then add de-bounce logic logic for the two switch inputs; see contact bounce. This can be done with a small module you write yourself; that is a good exercise.
Output from the contact de-bounce logic can then be used for change detection, to make a single cycle indication each time a contact is pressed, and this indication can then be used to update the counter.
You have no debounce circuitry or logic. A mechanical switch will physically bounce a lot, so your 50MHz clock is going to see many, many transitions on the input signal, leading to erratic behavior.
I forgot to mention that you're not even using that 50MHz clock in a synchronous design. Rather you're asynchronously looking for transitions.
You need a low-pass filter somewhere. Either implemented with analog components on the input signal, or as a counter in hardware.

Unexpected delay in Verilog adder

I have written some Verilog code for an adder with 10 inputs. After simulation I am getting the output with one extra clock delay. Why am I getting this delay?
`timescale 1ns/1ps
module add_10(z0,z1,z2,z3,z4,z5,z6,z7,z8,z9,clk,reset,o);
input [7:0] z0,z1,z2,z3,z4,z5,z6,z7,z8,z9;
input clk,reset;
output reg[15:0] o;
always # (posedge clk or negedge reset)
begin
if (!reset)
o=16'b0000;
else
o = z0+z1+z2+z3+z4+z5+z6+z7+z8+z9;
end
endmodule
After asserting the reset, I am getting the output after one clock. But according to the code I wrote, it should come at the next posedge clk when reset=1.
It looks like it's working as it should to me.
I think you're misunderstanding how the reset signal is meant to be used. The reset signal should be kept high at all times. When it goes low, the output will be cleared immediately (it changes on the negative edge). When it goes high, the output will take on the sum of the inputs on the next clock cycle.
If you wanted to update on the positive edge of the reset signal, use the positive edge...
always # (posedge clk or posedge reset)
...
Just beware that doing so will likely affect your minimum cycle times.
I suggest you change the timing of reset with respect to clk in your testbench. The way you have it, reset and clk change simultaneously. I believe the simulator enters your always block as a result of posedge clk, while the value of reset is still 0, and therefore assigns 0 to your output.
I would shift the reset to the left or to the right of the posedge of the clock. That should give you the effect you are looking for.
Your code is probably working as expected, but it may not be. The issue is (a) that you're not showing how reset is generated, and (b) you're using blocking assignments (which you shouldn't be; use <=), so you may have a race elsewhere, in your reset generation.
Show the code that generates reset. If there are no race conditions, then your waveform is correct; edge A clears reset, but this isn't seen by your adder, which thinks that reset is still asserted; the adder sees it de-asserted on the next clock edge, so produces a result.

Verilog always block statement

i just want to know the difference between this two statement
always #(posedge CLK)
begin
state <= next_state;
end
AND:
always #(CLK)
begin
case(CLK)
1'b1:
state <= next_state;
1'b0:
state <= state;
end
Is there a difference between both ?
Thanks
Not quite. posedge detects these transitions (from the LRM):
Table 43—Detecting posedge and negedge
To 0 1 x z
From
0 No edge posedge posedge posedge
1 negedge No edge negedge negedge
x negedge posedge No edge No edge
z negedge posedge No edge No edge
So, 0->x is a posedge, for example. Your second example only detects cases where CLK ends up as 1, so misses 0->x and 0->z.
The IEEE Std. 1364.1(E):2002 (IEC 624142(E):2005), the Verilog register transfer level synthesis standard, states in Sec. 5.1 that an always block without any posedge/negedge events in the sensitivity list is combinational logic. I.e. the signals in the event list are ignored and the block is synthesized as if an implicit expression list (#(*), #*) was used. The following example is given in the standard ("Example 4" on page 14):
always # (in)
if (ena)
out = in;
else
out = 1’b1;
// Supported, but simulation mismatch might occur.
// To assure the simulation will match the synthesized logic, add ena
// to the event list so the event list reads: always # (in or ena)
(the comment is also copied from the standard document)
I.e. for a synthesis tool your second block is effectively:
always #*
begin
case(CLK)
1'b1:
state <= next_state;
1'b0:
state <= state;
end
which is just a multiplexer with CLK as select input, next_state as active-1 input and the output (state) fed back as active-0 input. A smart synthesis tool might detect that this is identical to a d-type latch with CLK as enable-input and create a d-type latch instead of a combinational loop. Note that the synthesis tool is not required to detect this latch because the code explicitly assigns state in all branches (compare Sec. 5.3. of the standard).
Either way this is different from the d-type flip-flop your first code example would synthesize to. This is one of many cases where Verilog-code has different meaning in simulation and synthesis. Therefore it is important to (1) write synthesizeable Verilog code in a way that avoids this cases and (2) always run post-synthesis simulations of your design (even if you are also using formal verification!) to make sure you have successfully avoided this pitfalls.
Functionally, those two circuits describe the same behavior in verilog, so I think there should be no difference.
However you should generally use the first style, as that is the one that is standard for writing synthesizable code, and most understandable by anyone else reading your code. The latter style, while describing the correct behavior, may confuse some synthesizers that don't expect to see clocks that are both sensitive to positive and negative edge.
The two blocks are VERY different.
The top one gives you a flip-flop while the bottom one gives you a latch with a multiplexer with the CLK as the select signal.
The critical difference between the two blocks is that the top one is a synchronous block i.e. the posedge clk part while the bottom one is asynchronous with the CLK level, not edge.
A verilog simulator could do left-hand sampling of CLK, effectively making the the case(CLK) version the same as a negedge CLK flop. Otherwise the simulator will treat it like a posedge CLK flop. It really depends how it is handled in the scheduler of specific simulator (or how a particular synthesizer will process it).
The most common codding styles all use the first condition. It is explicitly clear to the synthesizer and anyone reading the code that state is intended to be a flip-flop with a positive edge clocking trigger.
There is also a simulation performance differences. The posedge CLK performances 2 CPU operations every clock period, while the case(CLK) will perform 6 CPU operations every clock period. Granted in this example the differences is insignificance, but in large designs the poor coding used everywhere will add up to hours of simulation time wasted.

Resources