Verilog: functionality like always & synthesizable - verilog

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

Related

Blocked and non-blocking assignment error in verilator

I'm testing SystemVerilog code using verilator, and it looks like below.
output [31:0] data_out1;
reg [31:0] data_out1;
always #(rst_b or addr1 or data_in1 or write_mask1)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ....
end
always #(posedge clk)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ..
end
It has two always blocks, and in each block, data_out1 is assigned in non-blocking. But, it shows a "Blocked and non-blocking assignments to same variable" error.
I do not use blocking assignment, and I can't understand why such an error occurs. I would appreciate if anyone can help.
When I run verilator on your code snippet, I get messages like the following:
%Warning-COMBDLY: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).
%Warning-COMBDLY: *** See the manual before disabling this,
%Warning-COMBDLY: else you may end up with different sim results.
%Error-BLKANDNBLK: Unsupported: Blocked and non-blocking assignments to same variable: data_out1
The 1st warning message indicates that verilator interprets your 1st always block as combinational logic, not sequential logic, and it treats the nonblocking assignment operator (=>) as a blocking assignment.
Since your 1st block does not use #(posedge clk), it is treated as combinational logic.
Also, you should not make assignments to the same signal from multiple blocks.
Lastly, you should not use nonblocking assignment to infer combinational logic.
There are two issues:
The code in the post is assigning the same signal from two always blocks. This can't be done, data_out1 must be driven from a single always block.
The always block without the clock infers combinational logic. The correct way to model combinational logic is by using blocking assignments (=).
The 2nd always block is ok (but not clean, because the rst_b is not at the first condition alone, it might cause problem for some simulator), working as a FF with sync low-active reset. The problem is the 1st always block.
Based on your modeling with <= in the 1st block, if write_mask1 changes to trigger the sensitivity list, you want to assign data_out1 depending on the old value of write_mask1 at the time point that write_mask1 has been updated with the new value. This behavior is inferred latch, because it needs the memory to hold the old value before the event, but it is also not a valid behavior of a FF. It seems that Verilator interprets this inferred latch still as "blocking assignment". (By the way, latch itself won't cause error, because it is indeed a right way to model if you have latches for purposes like clock gating)
If it is SystemVerilog (instead of Verilog), i would try to use always_comb for combinational logic, and always_ff for sequential. (and always_latch for latch). In your case, the simplest clean way to model is to be aware of which part is combitional and which sequential. I'd model it as:
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b)
begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else if(write_mask1 != 32'b0)
begin
data_out1 <= 32'hxxxxxxxx; // the value you want to update
end
end
// if there is no other condition, it will keep the old value based on the FF behavior
... do something ..
end
If you really mean to have 2 blocks, one doing combinational, one sequential, here we are:
always_comb begin
if(write_mask1 != 32'b0) begin
data_out1_next = 32'hxxxxxxxx;
end
else begin
// now it's necessary to write else-clause because it's not a FF -- it has no memory
data_out1_next = data_out1;
end
end
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b) begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else begin
data_out1 <= data_out1_next;
end
end

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.

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!

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);

verilog always #(posedge) failing in uart

I'm learning verilog and I think there is something that I must not understand about always #* and always (#posedge clk, ...)
Here is a piece of code supposed to send bits via uart. It fails at synthesization.
The error is
" The logic for 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."
(and 3 other errors for , and )
If I change the always #(...) by always #*, things fail in the next step ("implement design") because things are not connected.
In the book that I have, they implement an fsmd with an always (posedge clk) for the state, and always #* for the other logic, but I don't understand why this doesn't work.
On another forum, I read that the error could come from too complicated conditions. But I have simplified things too (not code the code here but basically I removed the case(state) and the ifs to have single line assignments with ? : or binary conditions, but it didn't work either)
I have seen this error before in other pieces of code that I wrote but I didn't get to the bottom of it, so if you could help me understand the general problem (with this uart thing as a support for a concrete example), I would be very happy.
Thanks
Thomas
P.S : Im using xilinx spartan 3e starter kit and xilinx ise 14.4
module UART_out #(parameter [3:0] NUM_BITS = 8)
(
input wire baud_clk,
input wire send_tick,
input wire[NUM_BITS-1:0] data_in,
output wire tx,
output wire debug_done
);
localparam
IDLE = 0,
TRANSMIT = 1;
reg[NUM_BITS:0] bits_to_send;
reg state;
reg out_bit;
reg[4:0] cnt;
always #(posedge baud_clk, posedge send_tick)
begin
case (state)
IDLE:
if (send_tick)
begin
bits_to_send <= {data_in, 0};
state <= TRANSMIT;
cnt <= 0;
end
TRANSMIT:
begin
if (cnt < NUM_BITS)
cnt <= cnt + 1;
else
state <= IDLE;
bits_to_send <= {1, bits_to_send[NUM_BITS:1]};
out_bit <= bits_to_send[0];
end
endcase
end
assign tx = (state == IDLE ? 1 : out_bit);
assign debug_done = (state == IDLE);
endmodule
The error:
The logic for 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.
Is referring to the fact that the synthesis tool does not have any hardware cells to use which match your description.
What hardware do you want from :
always #(posedge baud_clk, posedge send_tick)
This looks like you want a flip-flop with an enable signal. The enable signal (send_tick) should be 1 clock period wide. This is then used to select the path of logic on a clock edge. not as an alternative trigger.
I think that this is all you really need:
always #(posedge baud_clk) begin
case (state)
IDLE:
if (send_tick) begin
//...
end
//...
endcase
end
If send_tick is from another clock domain then you will need to do some clock domain crossing to turn it it to a clock wide pulse on the baud_clk.
You may be getting confused with blocks which have multiple triggers, they are normally a clk and reset. A negedge reset_n or posedge reset are often added for reset (initialisation) conditions.
If adding a reset :
always #(posedge baud_clk or negedge reset_n) begin
if (~reset_n) begin
//reset conditions
state <= IDLE;
//...
end
else begin
// Standard logic
end
end
You will notice that there is a very definite structure here, if reset else ... The synthesis tools recognise this as a flip-flop with an asynchronous reset. The data in the reset condition is also static, typically setting everything to zero.

Resources