System verilog: if loop inside always block not executing - verilog

I wrote a piece of code to assert a signal (val_changed) synchronously when another 64-bit signal (val) changes value by more than a threshold. Later this signal need to be de-asserted based on a third signal's (adj_in_prog) negedge.
Here clk and val are inputs to the block.
logic [63:0] val_reg;
always #(posedge clk) begin
val_reg <= val;
end
always #(posedge clk) begin
if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
val_changed <= 1'b1;
#(negedge adj_in_prog);
val_changed <= 1'b0;
end
I understand that the above method is not the cleanest of ways to do it, but since this is test-bench code and so I don't need to synthesis this, thought of experimenting. But this code is not working as val_changed is not going 1. I would like to know why the if loop won't execute. As per me, val_changed should have gone high at the clock edge where marker is positioned in the waveform attached. Can someone please help? (waveform values are in hex)

in your case at the very first posedge of clk the second always block starts executing and processes the 'if' statement. Then it sticks at the #(negedge adj_in_prog) statement, waiting for the event. On the next clock edge it will continue waiting and will not re-enter and evaluate the 'if' statement, and so on. So, this explains why it is not progressing.
so, assuming that the adj_in_prog is turned on at val_changed changing to one, the following should work for you.
always #(posedge clk) begin
if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
val_changed <= 1'b1;
else if (!adj_in_prog);
val_changed <= 1'b0;
end

Related

Verilog Design Problems

How to fix multiple driver , default value and combinational loop problems in the code below?
always #(posedge clk)
myregister <= #1 myregisterNxt;
always #* begin
if(reset)
myregisterNxt = myregisterNxt +1;
else if(flag == 1)
myregister = myregister +2;
end
right there are at least 3 issues in your code:
you are driving myregister within 2 different always blocks. Synthesis will find multiple drivers there. Simulation results will be unpredictable. The rule: you must drive a signal within a single always block.
you ave a zero-delay loop over myregisterNxt = myregisterNxt +1. Since you are using a no-flop there, it is a real loop in simulation and in hardware. You need to break such loops with flops
#1 delay is not synthesizable and it is not needed here at all.
You have not described what you were trying to build and it is difficult to figure it out from our code sample. In general, reset is used to set up initial values. So, something like the following could be a template for you.
always #(posedge clk) begin
if (reset)
myregister <= 0;
else
myregister <= myregister + increment;
end
always #* begin
if (flag == 1)
increment = 1;
else
increment = 2;
end
the flop with posedge clk and nonblocking assignments will not be in a loop.

How to program a delay in Verilog?

I'm trying to make a morse code display using an led. I need a half second pulse of the light to represent a dot and a 1.5 second pulse to represent a dash.
I'm really stuck here. I have made a counter using an internal 50MHz clock on my FPGA. The machine I have to make will take as input a 3 bit number and translate that to a morse letter, A-H with A being 000, B being 001 and so on. I just need to figure out how to tell the FPGA to keep the led on for the specified time and then turn off for about a second (that would be the delay between a dot pulse and a dash pulse).
Any tips would be greatly appreciated.
Also, it has to be synthesizable.
Here is my code. It's not functioning yet. The error message it keeps giving me is:
Error (10028): Can't resolve multiple constant drivers for net "c3[0]"
at part4.v(149)
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always #(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always#(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always #(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
I have been reading your code and there are many issues:
The code is not formatted.
You did not provide a test-bench. Did you write one?
"Can't resolve multiple constant drivers for net" Search on stack exchange for the error message. It has been asked many times.
Use always #(*) not e.g. always #(STATE) you are missing signals like i, halfsecflag, ending. But see point 6: You want the STATE in a clocked section.
Where you use always #(posedge CLK) you must use non-blocking assignments: <=.
There are many places where you use always #(posedge CLK) where you want to use always #(*) (e.g. where you set length and code) Opposite you want to use a posedge CLK where you work with your STATE.
Use one clock and one clock only. Do not use CLK and CLOCK_50. Use either one or the other.
Take care of your vector sizes. This 8'd25000000 is wrong as you can no fit 25000000 in 8 bits.
Your usage of halfsecflag is excellent! I have see many times where people think they can use always #(halfsecflag) which is a recipe for disaster!
Below you find a small piece of your code which I have re-written.
All assignments are non-blocking <=
halfsecflag is essential to operate the code only every half a second, so I put that by itself in a separate if at the top. I would use that throughout the code.
All register are reset, both COUNT2 and dashflag.
dashflag was set to 1 but never set back to 0. I fixed that.
I specified the vector sizes. It makes the code "Lint proof".
Here is it:
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
Start fixing the rest of your code the same way. Write a test-bench, simulate and trace on a waveform display where things go wrong.
Normally you would build the finite state machine to produce the output. That machine would have some stages, like reading the input, mapping it to a sequence of morse code element, shifting out the elements to output buffer, waiting for conditions to move to the next morse element. You will need some timer that would produce one morse time unit intervals, and depending on the FSM stage you will wait one, three or seven time units. The FSM will spin in the waiting stage, it doesn't "magically" sleeps in some fpga-produced delay, there's no such things.
Okay a year later, I know exactly what one should do if they want to create a delay in their verilog program! Essentially, what you should do is create a timer using one of the clocks on your FPGA. For me on my Altera DE1-SoC, the timer I could use is the 50MHz clock known as CLOCK_50. What you do is make a timer module that triggers on the positive (or negative, doesn't matter) edge of the 50MHz clock. Set up a count register that holds a constant value. For example, reg [24:0] timer_limit = 25'd25000000; This is a register that can hold 25 bits. I've set this register to hold the number 25 million. The idea is to flip a bit every time the value in this register is exceeded. Here's some pseudocode to help you understand:
//Your variable declarations
reg [24:0] timer_limit = 25'd25000000; //defining our timer limit register
reg [25:0] timer_count = 0; //See note A
reg half_sec_clock;
always#(posedge of CLOCK_50) begin
if timer_count >= timer_limit then begin
reset timer_count to 0;
half_sec_clock = ~half_sec_clock; //toggle your half_sec_clock
end
Note A: Setting it to zero may or may not initialize count, it's always best to include a reset function that clears your count to zero because you don't know what the initial state is when you're dealing with hardware.
This is the basic idea of how to introduce timing into your hardware. You need to use an onboard clock on your device, trigger on the edge of that clock and create your own slower clock to measure things like seconds. The example above will give you a clock that triggers periodically every half second. For me, this allowed me to easily make a morse code light that could flash on either 1 half second count, or 3 half seconds. My best advice to you beginners is to work in a modular fashion. For example build your half second clock and then test it out to see if you can get a light on your FPGA to toggle once every half second (or whatever interval you want). :) I really hope this is the answer that helps you. I know this is what I was looking for when I originally posted this question so long ago.

how to write to common register from two always block

In my application i need to access register from two always blocks.
first block will be of xillinx axi interface.
when user will write 1 via axi i need to start working in another always block and when its done i want to clear that reg i.e make it 0.
Can you please suggest logic to achieve required functionality.
but issue is that i cant write to flag from two always blocks.
psudo code
//from axi interface always block
flag=1;
//axi interface block code end
//my custom always block
always #(posedge mainclk) //50Mhz main clokc
begin
if(flag==1)
begin
//so some task
flag=0;
end
end
You can not use signals from different clock domains as-is.
In your case the 'flag' signal must be synchronized to the mainclk:
reg flag_meta,flag_sync;
always #(posedge mainclk or negedge reset_n)
begin
if (!reset_n)
begin
flag_meta <= 1'b0;
flag_sync <= 1'b0;
end
else
begin
flag_meta <= flag;
flag_sync <= flag_meta;
end
end
In a similar way your 'done' signal must synchronized to the AXI clock:
reg done_meta,done_sync;
always #(posedge aclk or negedge reset_n)
... // etc.
In your AXI code you need to clear the 'flag'. Something like:
always #(posedge aclk or negedge reset_n)
begin
... // some code that sets the 'flag'
... // probably on an AXI write
if (done_sync)
fag <= 1'b0;
end
end
There is a caveat:
This only works if both 'flag' and 'done' change slowly. There must be at least two clock cycles on each side to pass the change on. This is most important if you transfer a signal from a fast to a slow clock.

How to compare integer values with binary in for loop for Delay Generation in Verilog Synthesis?

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.

IF with ternary operator - Verilog

I am trying to write a program in Verilog that should "move" a light LED on an array of LEDs. With a button the light should move to the left, with another one it should move to the right. This is my code:
module led_shift(UP, DOWN, RES, CLK, LED);
input UP, DOWN, RES, CLK;
output reg [7:0] LED;
reg [7:0] STATE;
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
begin
STATE <= 8'b00010000;
end
else
begin
STATE <= UP ? STATE>>1 : STATE<<1;
end
end
always # (posedge CLK)
begin
LED <= STATE;
end
endmodule
The problem is in STATE <= UP ? STATE>>1 : STATE<<1; and the error the following:
Error (10200): Verilog HDL Conditional Statement error at led_shift.v(34): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
I tried to modify the code without using that kind of if:
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
STATE <= 8'b00010000;
else
begin
if(!DOWN)
STATE <= STATE<<1;
else
begin
if(!UP)
STATE <= STATE>>1;
else
STATE <= STATE;
end
end
end
It compiles, but does not work: the LED "moves" only to the left, when I press the other button all LEDs shut down. Probably there is a problem in my code, but I cannot understand why my first code does not compile at all.
Thank you for any help!
harrym
It is not clear for the synthesizer to know how to control STATE with the 3 asynchronous control signals.
Most likely your your synthesizer is trying to map STATE to a D flip flop with asynchronous active low set and reset. For example it might be trying to synthesize to something like:
dff state_0_(.Q(STATE[0], .CLK(DOWN), .SET_N(UP), .RST_N(RES(, .D(/*...*/));
In a real flop with asynchronous set and reset, the default should be consent and would explain the error in your first code. In your second attempt, UP becomes part of the combination logic cloud along with DOWN. DOWN is also being used as a clock. Since UP is not a clock, shifting continuously happens while UP is low, completely shifting the on bit out instantly. Another error for the second case would actually be more appropriate.
For the synthesizer to do a better job, you first need to synchronize your asynchronous control signals. Use the same technique as CDC (clock domain crossing; A paper by Cliff Cummings goes into detains here). A basic example:
always #(posedge clk) begin
pre_sync_DOWN <= DOWN;
sync_DOWN <= pre_sync_DOWN;
end
Now that the controls signals are synchronized, make STATE the output of your combination logic. Example:
always #* begin
if(!sync_RES)
STATE = 8'b00010000;
else
case({sync_UP,sync_DOWN})
2'b01 : STATE = LED>>1;
2'b10 : STATE = LED<<1;
default: STATE = LED;
endcase
end
With everything running on one clock domain and explicitly defined combination logic, the synthesizer can construct equivalent logic using flops and basic gates.
FYI:
To shift only on a negedge event you need to keep the last sync value and check for the high to low transition. Remember to swap sync_ with do_ in the combination logic that drives STATE.
always #(posedge clk)
keep_DOWN <= sync_DOWN;
always #*
do_DOWN = (keep_DOWN && !sync_DOWN);

Resources