This question already has answers here:
What does #`DEL mean in Verilog?
(2 answers)
Closed 7 years ago.
I understand that always #(posedge clk) in verilog is a flip flop.
input ld;
reg ld_r;
always #(posedge clk) ld_r <= #1 ld;
What does #1 do in above code? I found it in verilog code for AES. I include a snippet of it below:
always #(posedge clk)
if(!rst) dcnt <= #1 4'h0;
else
if(ld) dcnt <= #1 4'hb;
else
if(|dcnt) dcnt <= #1 dcnt - 4'h1;
always #(posedge clk) done <= #1 !(|dcnt[3:1]) & dcnt[0] & !ld;
always #(posedge clk) if(ld) text_in_r <= #1 text_in;
always #(posedge clk) ld_r <= #1 ld;
Since you mention that always #(posedge clk) infers a flip-flop I assume you are interested in knowing what #1 is synthesized as in hardware. The answer is: nothing.
These delays will get ignored in synthesis, so if you use them in design code you run the risk of your simulation not matching your hardware.
Here is a paper that describes why you would want to add delays: http://sunburst-design.com/papers/CummingsSNUG2002Boston_NBAwithDelays.pdf
#1 Delays by 1 timestep. To find what time step your using you can use:
$printtimescale;
> Time scale of (test) is 1ns / 1ns
Just using #1 can be risky because it is based on the last instance of `timescale 10ns/1fs.
Therefore as files are added or load order changes the definition of #1 can change. Newer versions of Verilog support the use of units ie #1ns. the 1ns part is a realtime and you may perform operations on them as you would any realtime variable.
//Delay 1001ns
#(1us + 1ns);
Intra-assignment
ld_r <= #1 ld;
Equates to :
temp = ld;
#1 ld_r <= temp; // Delay execution of ld_r <= temp by 1 timestep
That is take a copy ld now and assign its value back to ld_r in #1.
The usage of this is explained in 9.4.5 Intra-assignment timing controls of SystemVerilog IEEE 1800-2012 Standard:
Related
I am a beginner in Verilog designing and following is the design and test bench code I wrote for mod16 counter with load.
Design.v
module counter(
input clk,
input reset,
input load,
input [3:0] data);
always #(posedge clk)
begin
if(reset)
data<=4'b0000;
else if(load)
data<=load_input;
else
data<=data+1'b1;
end
endmodule
Testbench.v
module counter_tb ;
reg clk;
reg reset;
reg load;
reg[3:0] load_input;
reg[3:0]data;
counter ct_1(.*);
initial begin
clk = 1'b1;
load = 1'b0;
load_input = 4'b0000;
end
always begin #1 clk=~clk;end
initial begin
reset=1'b1;
#20;
reset=1'b0;
#10;
load=1'b1;
load_input=4'b0011;
#10;
load=1'b0;
load_input=4'b0000;
end
initial begin
$monitor("time=%0d,reset=%b,data=%d,load=%d,load_input=%d\n",$time,reset,data,load,load_input);
end
endmodule:counter_tb
The output I obtained with the monitor:
time=29,reset=0,data=5,load=0,load_input=0
time=30,reset=0,data=5,load=1,load_input=3
time=31,reset=0,data=3,load=1,load_input=3
..
The question is inspite of clock completing one cycle from time=29 to time=30, the data has remained constant = 5 and not incremented by 1 as per the design code.
Everything else is as expected.
What have I missed?
Can anyone help me out!
Thanks in advance.
I agree that initially there were some syntax errors but they all were minute typos while typing the question.
Answering my own question :
The logic of my design code was that at every posedge of the clock the data needs to be incremented by 1. At the time=30 the clk=0 which is negative edge and hence the data is not incremented by 1. Hence the data remained constant at time=30 and at time=31 it incremented by 1.
Thanks to everyone who tried to answer my question..
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Please see the following verilog code. Clk is a 10ns clock. Will setting TimerCounter_10ns <=0 interfere with the increment (i.e. TimerCounter_10ns = TimerCounter_10ns+1). Are there any other issues?
Thanks,
Stephen
reg [9:0] TimerCounter_10ns;
always #(posedge CLK, negedge xRST) begin
if (~xRST) begin
...
end else begin
TimerCounter_10ns = TimerCounter_10ns+1;
if (imerCounter_10ns >= SamplePeriod[9:0])
TimerCounter_10ns <= 0;
.....
end
end
end
with some modifications , usually in fpga we wont use active low resets in the design as it will create more LUT usage and its not efficient way to implement it.So i modified the code to generate the active high reset in the logic
reg [9:0] TimerCounter_10ns;
reg sys_rst;
always #(posedge CLK, negedge xRST)
if(~xRST) sys_rst <= #1 1'b1;
else sys_rst <= #1 1'b0;
always #(posedge CLK, posedge sys_rst) begin
if (sys_rst) begin
//...
end else begin
TimerCounter_10ns <= #1 (TimerCounter_10ns >= SamplePeriod[9:0]) ? 10'h0 :
TimerCounter_10ns + 1'b1;
//.....
end
end
end
Added Non-Blocking Assignments in sequential logic with intra assignment delay(represents TCQ in flipflop on hardware) instead of using mixed blocking and non-blocking assignments(which is not preferred). It takes only 1 clk cycle to increment the counter by value of 1.if counter is initialized to zero, then it would take a maximum of 1024 cycles to reach the sample period count (10 bits , 2**10 =1024).
As far as I can understand that the hardware required to implement the code below is not supported in Xilinx ISE Web Pack. I'm trying to implement only the functionality of the 8-bit adder using an always block. Here's the code:
module Addr_8bit(Clk, Rst, En, LEDOut
);
input Clk;
input Rst;
input En;
output reg [7:0] LEDOut;
always #(posedge Clk or posedge Rst) begin
if(Rst)
LEDOut <= 8'b00000000;
if(En)
LEDOut <= LEDOut + 8'b00000001;
end
endmodule
The error is on the line where the non-blocking assignment: LEDOut <= LEDOut + 8'b00000001; is located.
Particularly it says that:
ERROR:Xst:899 - "Addr_8bit.v" line 33: The logic for <LEDOut> does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release.
I am trying to make the LEDOut's 8-bit output to correspond to the each single one of 8 LEDs on the BASYS2 FPGA Board(Spartan-3E).
Thank You.
Change your behavioral description (the code inside the always block) as follows:
always#(posedge CLK or negedge RST) begin
if(!RST) begin // Reset condition goes here
LEDOut <= 0;
end
else begin // Everything else goes here
if(En)
LEDOut <= LEDOut + 1'b1;
end
end
The reason your code won't synthesize is because you generally can't assign to the same register under the same edge of two different signals. (You can't have your always block trigger on the low to high transition of CLK and RST if you're assigning to a variable in both cases.) So you can't trigger the reset condition on the positive edge of RST, but you can do it on the negative edge. This is due to the way the physical register elements (called flip-flops) are designed.
i want to shift a signal by fixed number of clock cycles. I receive the signal from adc. kindly let me know how to implement this
HINT: Not a full answer
A 8 bit flip-flop in verilog might look like:
reg [7:0] a;
always #(posedge clk, negedge rst_n) begin
if (~rst_n) begin
// Active Low Reset condition
a <= 'b0;
end
else begin
a <= input_eight_bit;
end
end
To delay for multiple clock cycles you need multiple flip-flops feeding from one to the next. This creates a pipe line or delay line.
Hello Friends I still not know how to Generate Delay in Verilog For synthesis and call it any line in Verilog for synthesis...for finding this I write a code but it not works please help me if you know how to Generate Delay and call in any line like a C's Function*......Actually Friends if you tell me why I use for Loop here then my answer is - I want to move pointer inside for loop until and unless they completes its calculation that I made for Delay Generation..
module state_delay;
reg Clk=1'b0;
reg [3:0]stmp=4'b0000;
integer i,a;
always
begin
#50 Clk=~Clk;
end
always #(posedge Clk)
begin
a=1'b1;
delay();
a=1'b0;
delay();
a=1'b1;
end
task delay();
begin
for(i=0;i==(stmp==4'b1111);i=i+1)
begin
#(posedge Clk)
begin
stmp=stmp+1;
end
end
if(stmp==4'b1111)
begin
stmp=4'b0000;
end
end
endtask
endmodule
Actually friends I want this a=1'b0; delay(); a=1'b1; please help I already tried delay Generation Using Counter previously but it not works for me.....If you know same using Counter then please tell me......Thanks
// will generate a delay of pow(2,WIDTH) clock cycles
// between each change in the value of "a"
`define WIDTH 20
reg [`WIDTH:0] counter;
wire a = counter[`WIDTH];
always #(posedge Clk)
counter <= counter + 1;
You have to choose a suitable value for WIDTH according to how much delay you want between changes in a and the rate of your Clk signal
This question is a more succinct version of How to generate delay in verilog using Counter for Synthesis and call inside Always block?.
There is one section of code that I find troublesome:
always #(posedge Clk) begin
a = 1'b1;
delay() ;
a = 1'b0;
end
NB: A good rule to stick to is to always use <= in edge triggered processes.
for now lets think of the delay(); task as #10ns; What we get with the current code would be:
time 0ns a = x;
time 1ns a = 1; //Posedge of clk
time 6ns a = 1; //Waiting on delay
time 11ns a = 0; //Delay completed
Using <= and I think you should see a similar behaviour. However when it comes to synthesis delays like #1ns can not be created and the whole thing will collapse back down to :
always #(posedge Clk) begin
a <= 1'b0;
end
With a hardware description language a good approach is to consider what hardware we want to imply and describe it in the language. The construct always #(posedge Clk) is used to imply flip-flops, that is the output changes once per clock cycle. In the question we have a changing value 3 times, from 1 clock edge I do not know what hardware you are trying to imply.
You can not provide an inline synthesizable delay. For always #(posedge clk) blocks to be synthesizable they should be able to execute in zero time. You need to introduce a state machine to keep state between clock edges. I think I have already provided a good example on how to do this in my previous answer. If the delay is to be programmable then see mcleod_ideafix's answer.