how to write to common register from two always block - verilog

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.

Related

System verilog: if loop inside always block not executing

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

having trouble with always block in verilog

I'm currently making a watch that we can set times to start and having a problem with always#()
always # (posedge clk or posedge reset or posedge sw3 or posedge sw4) begin
if(reset == 1) begin //reset signal is not a pulse therefore this could do the thing needed for keep pressing the reset button
tmp_second = 0;
tmp_minute = 0;
tmp_hour = 0;
end
the above is just a part of the full code and the rest of it is about setting the time by sw3 and sw4 but when I try to Synthesize this module
the following Error comes up
ERROR:Xst:2089 - "first_mode.v" line 69: This sensitivity list construct will match none of the supported FF or Latch templates.
if I change the always block like
always # (posedge clk or posedge reset) begin
I dont get the error message but I want posedge sw3 and sw4 to work independently from clk
would there be any way to use always block including those 4
When synthesising, it is wise to be consistent by sticking to a template. Here is one such template for sequential logic with an asynchronous reset, which all synthesis tools should understand:
always #(posedge CLOCK or posedge RESET) // or negedge
begin
// PUT NO CODE HERE
if (RESET == 1'b1) // or (RESET == 1'b0) for an active-low reset
// set the variables driven by this always block to their reset values
// MAKE SURE YOU USE NON-BLOCKING ASSIGNMENTS ( <= )
else
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
// MAKE SURE YOU USE NON-BLOCKING ASSIGNMENTS ( <= )
end
Here is the corresponding template for a sequential process without an asynchronous reset:
always #(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
// MAKE SURE YOU USE NON-BLOCKING ASSIGNMENTS ( <= )
end
And finally, here is the template for combinational logic:
always #(*)
begin
// implement your combinational logic here
// MAKE SURE YOU USE BLOCKING ASSIGNMENTS ( = )
end
Your code does not comform to any of these three templates nor any other. That is why you synthesis tool doesn't understand it.

is it good programming style to use infinite loop to scan and update output signal

my code is as follows:
module command_FSM(sys_R_Wn,sys_ADSn,cState,sys_REF_REQ,sys_REF_ACK,sys_INIT_DONE,sys_CLK);
input sys_R_Wn;
input sys_CLK;
input sys_ADSn;
output [4:0] cState;
inout sys_INIT_DONE;
input sys_REF_REQ;
output sys_REF_ACK;
wire sys_R_Wn;
wire sys_ADSn;
reg [4:0] cState;
wire sys_INIT_DONE;
wire sys_REF_REQ;
reg sys_REF_ACK;
reg mjet;
integer i;
parameter c_idle=5'b10000;
parameter c_AR=5'b10001;
parameter c_tRFC=5'b10010;
parameter c_rdata=5'b10011;
parameter c_tDAL=5'b10100;
parameter c_cl=5'b10101;
parameter c_ACTIVE=5'b10110;
parameter c_wdata=5'b10111;
parameter c_REDA=5'b11000;
parameter c_tRCD=5'b11001;
parameter c_WRITEA=5'b11010;
initial
begin
cState=c_idle;
end
initial
begin
for(i=0;;i=i+1)
begin
#2;
if (sys_INIT_DONE==1'b1)
if(~sys_REF_REQ && ~sys_ADSn)
begin
case (cState)
5'b10000: begin
cState=c_ACTIVE;
#10;
end
5'b10110:
if(sys_R_Wn)
begin
cState=c_tRCD;
#10;
cState=c_REDA;
end
else
begin
cState=c_tRCD;
#10;
cState=c_WRITEA;
end
5'b11000: begin
cState=c_cl;
end
5'b10101: begin
cState=c_rdata;
end
5'b11010: begin
cState=c_wdata;
end
5'b10111: begin
cState=c_tDAL;
end
endcase
end
end
end
always #(posedge sys_REF_REQ)
begin
sys_REF_ACK=1;
case(cState)
5'b10000: begin
cState=c_AR;
#50;
cState=c_idle;
end
endcase
end
endmodule
here i want "cState" signal to be scanned and updated continuously based on statemachines.Firstly i tried always #* but as it had only output signal cState to be updated.So that block was executed only once because it had no input signal that was being modified in that always #* block.So my doubt is is it good thing to use "infinite for loop" to serve that purpose of scanning and updating continuously
The short answer is no; it is not good style to implement FSMs using an infinite loop.
The long answer is that it very much depends. Firstly, if this FSM is purely for a functional model in simulation and never to be synthesized for an FPGA or ASIC; you might use an infinite loop to implement an FSM. However, you should use the keyword forever to implement these loops, not for (i = 0; ; i = i + 1) or while (1). Or, if they are clocked, you can use an always #(posedge clk) or the like to trigger them (or use forever begin #(posedge clk) if its a forked process or something fancy like that).
However, based on the header of this module, it appears you want to make a synthesizable FSM, it which case, theres quite a lot you need to do to fix your code. Heres a short list of suggestions to make your code synthesizable and have better style:
As a general rule, do not use initial blocks inside an module. While they have a few limited uses (in FPGA synthesis), you should fully understand those uses before using them. If you need a variable to take on an initial state, use a reset line in the element storing that variable (see the next point)
Combinational logic should be placed in an always #* block and sequential logic should be placed in an always #(posedge clk[, negedge rstL]) block (the reset is optional). When making a state machine, I recommend the following style:
reg state, next_state;
// The register that holds the state
always #(posedge clk, negedge rstL) begin
if (~rstL) begin
state <= INIT; // Your starting state here
end
else begin
state <= next_state;
end
end
// The logic that determines the next state and output values based on the inputs and current state
always #* begin
// Defaults
[ Place your outputs here with some default value ]
next_state = state; // As selfloops are common, I typically just set the next state to be the current state
case (state)
[ Your logic for what to do in each state here ]
endcase
end
This form I find to be the best to ensure no latches and makes the synthesis tools happy with simple register blocks (the always #(posedge clk) block).
Using parameters for state names is good practice, but you should use them everywhere, even in the case statement, like:
case (state)
INIT: begin
...
end
READ: begin
...
end
endcase
Do not use delays in your combinational logic like x = 1'b0; #10; x = 1'b1;. You change cState like this in your initial block but really should have different logic for each state.
You declare sys_REF_REQ as an inout when it should probably be an input.
Don't trigger logic on non-clock things, like always #(posedge sys_REF_REQ). Only use posedge and negedge on clocks and resets within synthesizable code.
Thats all I see right now, but other might add more in the comments. Best of luck!

Verilog: functionality like always & synthesizable

Is there any other functionality like always (that would only run if the sensitive signal changes and won't iterate as long as signal stays the same) which can be cascaded, separately or within the always , but is synthesizable in Verilog.
While I don't think there's a construct specifically like this in Verilog, there is an easy way to do this. If you do an edge detect on the signal you want to be sensitive to, you can just "if" on that in your always block. Like such:
reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always # (posedge clk) begin
if (sensitive_signal != sensitive_last) begin
event_detected <= 1'b1;
end else begin
event_detected <= 1'b0;
end
sensitive_last <= sensitive_signal;
end
// Then, where you want to do things:
always # (posedge clk) begin
if (event_detected ) begin
// Do things here
end
end
The issue with doing things with nested "always" statements is that it isn't immediately obvious how much logic it would synthesize to. Depending on the FPGA or ASIC architecture you would have a relatively large register and extra logic that would be instantiated implicitly, making things like waveform debugging and gate level synthesis difficult (not to mention timing analysis). In a world where every gate/LUT counts, that sort of implicitly defined logic could become a major issue.
The assign statement is the closest to always you you can get. assign can only be for continuous assignment. The left hand side assignment must be a wire; SystemVerilog also allows logic.
I prefer the always block over assign. I find simulations give better performance when signals that usually update at the same time are group together. I believe the optimizer in the synthesizer can does a better job with always, but this might depend on the synthesizer being used.
For synchronous logic you'll need an always block. There is no issue reading hardware switches within the always block. The fpga board may already de-bounce the input for you. If not, then send the input through a two phase pipe line before using it with your code. This helps with potential setup/hold problems.
always #(posedge clk) begin
pre_sync_human_in <= human_in;
sync_human_in <= pre_sync_human_in;
end
always #* begin
//...
case( sync_human_in )
0 : // do this
1 : // do that
// ...
endcase
//...
end
always #(posedge clk) begin
//...
if ( sync_human_in==0 ) begin /* do this */ end
else begin /* else do */ end
//...
end
If you want to do a hand-shake having the state machine wait for a human to enter a multi-bit value, then add to states that wait for the input. One state that waits for not ready (stale bit from previous input), and the other waiting for ready :
always #(posedge clk) begin
case(state)
// ...
PRE_HUMAN_IN :
begin
// ...
state <= WAIT_HUMAN__FOR_NOT_READY;
end
WAIT_HUMAN_FOR_NOT_READY :
begin
// ready bit is still high for the last input, wait for not ready
if (sync_human_in[READ_BIT])
state <= WAIT_HUMAN_FOR_NOT_READY;
else
state <= WAIT_HUMAN_FOR_READY;
end
WAIT_HUMAN_FOR_READY :
begin
// ready bit is low, wait for it to go high before proceeding
if (sync_human_in[READ_BIT])
state <= WORK_WITH_HUMAN_INPUT;
else
state <= WAIT_HUMAN_FOR_READY;
end
// ...
endcase
end

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