How to realize "posedge asynchronous reset logic" in verilog? - verilog

i know high level async reset can be achieved like:
always#(posedge clk or posedge rst)
begin
if (rst==1)
but how to realize posedge async reset, which means the moment reset edge coming up, the logic in always block reset immediately?
i wrote the logic below:
always#(posedge clk or posedge rst)
begin
rst_pre<=rst;
if(!rst_pre && rst) // to test if rst is posedge
//execute reset logic here...
but the question is, the always block was triggered in a unexpected high frequency, i finally figured out that although there was only 1 posedge of rst, the always block was triggered by rst signal much more than 1 time.
(tested using altera cyclone 10LP with quartus 18)
I think the method i used to achieve posedge async reset is not stable, can anyone tell me what can i do to solve this?

What you are trying to achieve is a asynchronous reset. It can be posedge or negedge.
always#(posedge clk or posedge rst)
begin
if (rst)
// do the reset
else begin
// your normal execution logic
end
end
If you want to use negedge reset then you can use:
always#(posedge clk or negedge rst)
begin
if (~rst)
// do the reset
else begin
// your normal execution logic
end
end
Other than that, there is nothing complicated on reset. Both on these occasions, on posedge/negedge of rst, block will get triggered and it will do the reset.

The very first code snippet which you call "high level async reset" logic is "posedge asynchronous reset logic".
The code snippet specified a active high asynchronous reset signal rst. "active high" + "asynchronous" means signals generated by this always block are reset immediately when rst asserts.

As soon as you include "posedge/negedge reset" in the sensitivy list, and the reset condition inside the always block has priority over the rest of the sequential logic, it is asynchronous:
always # (posedge clk_i, posedge arst_i) begin
if(arst_i) begin
...this condition has to be first
end
else begin
...normal sequential logic
end
end
Use "posedge" for active-high reset, and "negedge" for active-low reset.
Extra note: Sometimes it is also useful to have a reset synchronizer. This synchronized "soft reset" should be included in the normal sequential logic and it would help to have everything synchronized with the clock. By doing this you would have a first asynchronous reset condition, and the last synchronized reset would avoid any metastabiliy problems regarding the asynchronous condition.

Related

implementing edge triggered reset in verilog without initial block

I'm trying to add an edge_triggered reset to my module, meaning that only if a transient from 0 to 1 detected in reset, the reset operation should be perform.
and further more, I don't want to use any initial block in my module (because I think initial blocks have issues in FPGAs).
finally, I decided to following something like this:
always # (posedge clock, posedge reset) ...
but the problem I encountered, is that I need to know which element of always block sensitivity list is activated.
also I think this method isn't a proper solution:
always # (posedge clock, posedge reset) begin
if(reset) begin
//doing reset operations
end
.
.
.
end
because if reset is 1 from previous clocks (not transient from 0 to 1) in next posedge clock the reset operation will be perform! but we didn't want this.
so, is there any way to find out which element of sensitivity list activated the always block?
or even any other solution for implementing edge_triggered reset?
There almost certainly isn't a primitive in your FPGA that will do exactly what you want. And even in simulation, you wouldn't be able to tell which of the edges in the sensitivity list triggered the update.
The code you posted should synthesize, but as you noted it will behave like a standard asynchronous reset and continue to reset as long as reset is high. In order to reset only on the reset rising edge, you'll need some clock domain crossing logic to detect the edge and output a single pulse on the clock domain.
For example:
// This module can assert reset_pulse asynchronously but must output a pulse
// for at least one 'clock' cycle and deassert synchronously.
async_edge_to_pulse e2p (
.in_edge (reset),
.out_clock (clock),
.out_pulse (reset_pulse)
);
always #(posedge clock or posedge reset_pulse) begin
if (reset_pulse) begin
// reset logic
end else begin
// operational logic
end
end

How to set a signal at both posedge and negedge of a clock?

I'm trying to implement a controller with the function that sends out the same clock signal as its input clock. But the controller can also halt the output signal if needed. I'm implementing it on Xilinx ISE.
My idea is: At the negedge of the input clock, the output clock signal set to 0. At the posedge of the input clock, if I want to send out the clock I'll set the output clock to 1, but if I want to halt the output clock, I'll set the output clock to 0 so other devices (all posedge-triggered) won't detect the posedge.
Here's my design:
module controller(
input clk_in,
input reset,
output clk_out
//and other ports
);
always #(negedge clk_in)
clk_out<=0;
always #(posedge clk_in)
if(reset)
clk_out<=1;
else
begin
case(cases)
case1:
begin
//do something and halt the output clock
clk_out<=0;
end
case2:
begin
//do something and continue the output clock
clk_out<=1;
end
endcase
end
When I synthesized the design I had an error saying the signal clk_out is connected to multiple drivers. Is there any way to solve it?
You have two different always blocks which drive the same signal clk_out. This is what synthesis tells you about. All signals in a synthesizable rtl must be driven from a single block only.
It looks like you are trying to create some type of a gated clock. Instead of going through the trouble of detecting negedges of the clock, which most likely will not be synthesizable as well, you can use a simple logic to do so:
always #*
clk_out = enable & clk_in;
You just have to figure out how to generate enable.
BTW, never use NBAs (<=) in generating clock signals or you end up with clock/data race conditions.

Verilog: always#* block not getting triggered

In the test-bench code shown below, I'm observing that the clock signal clk does not toggle as expected.
The clock changes from low to high at time 5, but doesn't toggle after that.
module tb();
reg clk;
initial begin
clk = 'b0;
#100 $finish;
end
always#* #5 clk = ~clk;
endmodule
However, if I remove #* from the always#* statement, the clock toggles every 5ns as expected. My question is why doesn't the process block always#* get triggered after the first change?
Note: I've tested the code in NCSIM and VCS, I don't think this a simulator issue.
The accepted answer is wrong - the always is initially triggered by the assignment to 0 in the initial block, so you have a perfectly valid question, which is why the always block isn't triggering itself after it ran the first time (and it clearly did run, because clk is set to 1).
Run the code below - you'll see that it works as expected if you change the blocking assignment to a non-blocking one, or if you use an intra-assignment delay instead of your delay control (clk = #5 ~clk). So, this is a scheduling issue. You might intuitively expect that your process would only trigger once, because the eventual blocking assignment and the process evaluation effectively occur in the same delta, so the blocking assignment could potentially be lost. However, I can't see a specific justification in the LRM. The delay control turns into a future inactive event, and the scheduler eventually executes it, creating an update event, which updates clk (you see this happen once). This should then create an evaluation event for the process, because it's sensitive to clk, but it's not doing this. The scheduling section is (very) woolly, and doesn't really cover this. Mentor would probably give you their version of what's going on if you ask them. VHDL avoids this issue by making all signal assignments non-blocking.
module tb();
reg clk1, clk2, clk3;
initial begin
$monitor($time,, "clk1 = %b; clk2 = %b, clk3 = %b", clk1, clk2, clk3);
clk1 = 1'b0;
clk2 = 1'b0;
clk3 = 1'b0;
#100 $finish;
end
always #*
#5 clk1 = ~clk1;
always #*
#5 clk2 <= ~clk2;
always #(clk3)
clk3 <= #5 ~clk3;
endmodule
clock generators are usually implemented in one of 2 ways:
using always with no sensitivity list, as you already tried:
always #5 clk = ~clk;
the always block without sensitivity list will loop forever and would cause your simulation to hang if it has no #delays inside. Though the latter make it perfect for the clock generator.
use forever loops in your initial block:
initial begin
forever
#5 clk = ~clk;
end
the above code works the same way as the previous always.
The problem is always#(*) will not be sensitive to signals written inside it. So in your case, the implicit sensitivity of the always block doesn't have "clk" in it. Rather it is not sensitive to any signal at all.

Error when trying to synthesize verilog code

I am trying to make a module that performs the twos complement of a value if the msb is 1. It works in cadence, however when I try to synthesize it I get the following error:
Cannot test variable X_parallel because it was not in the event expression or with wrong polarity.
The code for the module is as follows:
module xTwosComp (X_parallel, Clk, Reset, X_pos);
input [13:0] X_parallel;
input Clk, Reset;
//wire X_msb; //was an attempt at fixing the problem
output [13:0] X_pos;
reg [13:0] X_pos;
//assign X_msb=X_parallel[13];//failled attempt at fixing
always # (posedge Clk or posedge Reset)
begin
if (X_parallel[13]) begin
X_pos = ~(X_parallel) +1;
end else begin
X_pos = X_parallel;
end
end
endmodule
You are missing your reset statement. Not sure if this fixes the exact error, but synthesizers expect code to determine what events are asynchronous when there is more than one edge event.
You need an if (Reset) begin X_pos <= 14'b0; else before the if (X_parallel[13]). Otherwise posedge Reset is treated as another clock and not a asynchronous reset. This will confuse the synthesizer.
FYI: flops should be assigned with non-blocking assignments (<=). It will save you from debugging false race condition and RTL to gates simulation mismatches.
After countless hours I have figured it out. It was because i was not referencing Clk or Reset in my always block.
Thanks to anyone who considered the issue.
Thanks Greg for your answer, although I figured out how to make it work I am very glad for your response since it cleared up why it works now. Thanks!

Difference between 'wait' and '#' statement

The following set of codes do the same thing.Is there any difference between them ?If not , why is wait (clk) not generally used?
always #(posedge clk)
begin
end
always wait(clk)
begin
end
#(posedge clk) is edge sensitive , hence it is used to model synchronous circuits.While, wait(clk) is level sensitive.Since most circuits are designed to be synchronous #(posedge clk) is predominantly used
wait (expression)
The "expression" is evaluated, if false, then execution is suspended until the expression becomes true. If the expression is true when the statement is reached, then the wait has no effect, and execution proceeds to the controlled statement.
#(posedge clk) - is an edge event.
posedge:0,x,z->1 negedge:1,x,z->0
Edge events are useful for modelling clocked logic elements, like flip-flops. They are also useful for synchronizing activity in a model based on a common clock. Example, in the following always block,it enters the always block on the negative edge of clock.
always #(negedge clock)
x = f(y);

Resources