Assignment under multiple single edges is not supported for synthesis - verilog

I have written this code:
module Key_Schedule(
subkey_tupple1,
subkey_tupple2,
generate_key_final_step,
rst,clk
);
reg [0:31] a1,b1,a2,b2;
input [0:31] subkey_tupple1;
input [0:31] subkey_tupple2;
//input [31:0] subkey_A_swap;
//input [31:0] subkey_B_swap;
input clk,rst;
output reg [0:63] generate_key_final_step;
reg [0:63] temp;
reg [0:63] round_sub_key_left;
always #(posedge clk or negedge rst)
begin
if (!rst)
begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else
temp<={subkey_tupple1[0:31],subkey_tupple2[0:31]};
//The error is below... line 49
round_sub_key_left<={temp[8:15],temp[16:23],temp[24:31],temp[0:7],temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end
endmodule
When I click Synthesize -XST I get this error:
ERROR:HDLCompiler:1128 - "D:\Embedded_Project\Key_Schedule.v" Line 49: Assignment under multiple single edges is not supported for synthesis

There is a missing begin-end around the else condition. Therefore the assignment to temp is the only assignment in the else condition. When in active reset round_sub_key_left is still derived from temp. There error is likey do to the fact that during asynchronous reset round_sub_key_left is not being assigned to a constant.
Also, at toolic mentioned: It is generally a bad practice to put your combinational logic and synchronous logic in the same always block (ie mix blocking and non-blocking assignments). The best practice is to put combinational logic in an always #* block with blocking assignments (=). Synchronous logic (ie flip-flop) should go in an always #(posedge clk /*+ async-set/set*/) and only use non-blocking assignment (<=).
always #(posedge clk or negedge rst) begin
if (!rst) begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else begin
temp <= {subkey_tupple1[0:31],subkey_tupple2[0:31]};
round_sub_key_left <= temp[8:31],temp[0:7],temp[40:63],temp[32:39]};
end
end
always #* begin : output_comb_logic
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end

else at line 47 affects only one line, and it is not right.
Under reset condition round_sub_key_left has two conflicting drivers.
Place code after else in begin-end parentheses.

Related

How to understand the blocking and non blocking statements in verilog?

I understood the basic difference between blocking and non-blocking statements in Verilog. But still it is not possible for me to understand what's happening & when and where to use blocking and non-blocking statements. For example, consider simple d ff code:
module dff (clk, reset,d, q, qb);
input clk;
input reset;
input d;
output q;
output qb;
reg q;
assign qb = ~q;
always #(posedge clk or posedge reset)
begin
if (reset) begin
// Asynchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule
But if I write the very same logic using two-segment coding technique:
module dff(input wire d,
clk,
reset,
en,
output wire q);
reg q;
reg r_reg, r_next;
always #(posedge clk, posedge reset)
if(reset)
r_reg<=1'b0;
else
r_reg<=r_next;
always #*
if(en)
r_reg=d;
else
r_reg=r_next;
assign q<=r_reg;
endmodule
Now, in this code, I just didn't understand why are using <= in the first always block and why they are using = in 2nd always block. I also know that in combinational logic circuit = is advised to use & in sequential <= this is advised to use. But still, I couldn't be able to find out the answer to the usage of blocking and non-blocking statements. Can you please help me!?
Blocking/non-blocking assignments is a simulation artifact only. Contrary to the believe, verilog does not describe hardware. Verilog describes desired behavior of the hardware trying to fit it into an event-driven simulation scheme.
Here is a simple example of a shift register which employs 2 flops:
always #(posedge clk)
out1 = in;
always #(posedge clk)
out2 = out1;
Now, what would the output of the out2 be? Since we are dealing with simulation, then it depends on the order in which these 2 statements are executed. Either it will be the old value of out1, or the new one (actually the value of in);.
In hardware there is no such mess. It will flop the value which existed at the posedge time, the old value of out1 (well, unless there are unusual delays in clocks).
In order to match this behavior, the non-blocking assignment was introduced. Verilog simulation is done in simulation ticks. Every tick is as long as there are events which could cause re-evaluation of other blocks. The non-blocking assignments are scheduled to be executed at the end of such a tick with current rhs values ( in reality there are several scheduling zones). So, consider the following:
always #(posedge clk)
out1 <= in;
always #(posedge clk)
out2 <= out1;
In the above example the all assignments will happen at the end of the tick. 'out2` will be assigned a value which existed at the time of the <=, so, it will be the old value of out1. Now, it does not matter in which order they are executed.
So, the top-level recommendation is to use blocking assignments (=) for combinational logic and use non-blocking assignments (<=) for all outputs of state devices, flops and latches. Note that some temporary variables inside state devices, which are only used there internally should also be assigned with blocking. Also, never use non-blocking assignments in clock trees.

Asynchronous reset D flipflop code syntax error

I'm writing a code to implement an asynchronous reset D flipfip, but the always# line is showing a syntax error:
`timescale 1ns / 1ps
module Dflipflop(
input D,
input reset,
input clk,
output Q
);
reg Q;
initial
begin
if(reset==1) //clear the output (Q=0)
begin
Q <= 0;
end
else if(reset==0)
begin
always#(posedge clk) //syntax error here...
begin
Q <= D;
end
end
end
endmodule
What could be the possible error, and is there a better logic for implementing the same ?
First of all I would not encourage you to use the initial statement except in testbench. This is not synthetizable so it should not appear in RTL.
Then I think you are confusing Verilog with a standard programming language which it is not.
In Verilog, there is two classes of statements:
processes, like always or initial
assignment, with assign that allows you to directly assign a 'value' to a wire
In processes there can be distinguished two classes :
Synchronous processes, //do something statements begin end will be evaluated only when an edge, specified in the #, occurs
always # (posedge clock) begin
//do something
end
Combinatorial processes, //do something statements will be evaluated every time the value of a wire or reg used in the //do something block changes
always #* begin
//do something
end
Here you have instantiated a process inside a process something that has no physical reality.
Another point, as described you want to activate the process only when reset==0 so you put a condition to enter the process. Once more, that does not make any sense in terms of synthesis. The process should be activated and that is in the process that the conditions should be evaluated.
A classical solution for implementing a D flip-flop with asynchronous reset is the following:
module Dflipflop(
input D,
input reset,
input clk,
output reg Q
);
always # (posedge clk or negedge reset) begin
if (!reset)
Q <= 1'b0; // Clear Q when reset negative edge occurs
else
Q <= D; // Capture D in Q when clk positive edge occurs and reset is high
end
endmodule
You cannot have always block inside initial. It should be written like this:
`timescale 1ns / 1ps
module Dflipflop(
input D,
input reset,
input clk,
output Q
);
reg Q;
always #(posedge clk, posedge reset)
begin
if(reset==1) //clear the output (Q=0)
begin
Q <= 0;
end
else
begin
Q <= D;
end
end
endmodule
You should either use initial(not recommended for synthesis) or always. One procedural block cannot come inside another. If you are really interested in designing a non-synthesizable logic and want to try out with initial, you can do something like this mentioned below. Both initial and always are procedural blocks.
....
else if(reset==0)
begin
repeat(100000) #(posedge clk)
begin
Q <= D;
end
end
end

8-bit Adder Error: The logic does not match a known FF or Latch template

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.

Monitor statement verilog

Removing #2 reset after monitor statement makes the code not to work.The output just stands at 0 x. Whereas including it works fine. Why?
module counter(out,clock,reset);
input clock,reset;
wire clock,reset;
output [3:0]out;
reg [3:0]out;
always #(posedge clock or negedge clock)
begin
if(reset)
out<=1'b0;
else
out<=out+1;
end
endmodule
module tb();
reg clock,reset;
output [3:0]out;
counter c(out,clock,reset);
initial
begin
clock=0;
reset=1;
end
initial
begin
$monitor("%d %d",$time,out);
#2 reset=0;
end
always
#1 clock=~clock;
initial
#100 $finish;
endmodule
By removing the #2 you create a race condition on reset:
initial reset = 1;
initial reset = 0;
Simulators will often have the the final value of reset the last assignment read in the compiling order. Try merging you initial blocks:
initial
begin
$monitor("%d %d",$time,out);
clock=0;
reset=1;
#2 // <-- optional (and still recommened) if you make the below change
// #(clk) //<-- if you truely want a dual edge triggered flip-flop with synchronous reset
reset=0;
end
Dual edge triggered flip-flop are very uncommon and many synthesizers and FPGAs do not support them. I'm guessing you are intending to have an negative edge triggered flip-flop with an active high asynchronous reset. In this case replace:
always #(posedge clock or negedge clock)
with:
always #(negedge clock or posedge reset)

Shift Registers Verilog

I am very new to HDL language. I have a question about how to program a shift register. (i know i shift to the other direction). Why does the book use wire[N-1:0] r_next? what's drawback of my implementation?
thanks
my first try is as following
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg[0]=data;
r_reg = r_reg<<1;
end
assign out =r_reg[N-1];
endmodule
but the book gives:
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
wire[N-1:0] r_next;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg <= r_next;
end
assign r_next= {data, r_reg[N-1:1]};
assign out =r_reg[N-1];
endmodule
First of all, don't forget your begin-ends around sections of code:
else begin
r_reg[0]=data;
r_reg = r_reg<<1;
end
Without this, only r_reg[0]=data will be in the else clause of the if statement. This will work, but is considered bad style due to the blocking statements in a sequential logic description...
Second, for modeling sequential blocks, use nonblocking assignments (<=) or your calculations may 'fall through' (google nonblocking vs blocking for more info). Your example may very well work (did you try it in a simulator?) but if things get more complicated and more variables are added things can break.
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg <= 0;
else begin // This is horrible! Don't write code like this!
r_reg[0] = data; // blocking
r_reg <= r_reg<<1; // non-blocking
end
end
For the above reason, it is sometimes recommended that combo logic is separated from sequential logic so that you can write nonblocking assignments to registers in sequential blocks, and blocking in combo blocks and never have to worry about the scheduling.
To code in this way, you need to calculate what the next output should be using the current state, hence the r_next bus in the answer. I think it tends to help the synthesis tool out too if all the flip-flops are separated from surrounding combo logic in this way.
Also, if your reset is active low (ie LOW resets ) it should be named as such, eg resetb or reset_n.
Your implementation produces quite a different output from the book's. You should prove this to yourself by constructing a simple testbench to drive your inputs and run a simulation. You will see that the book's output shifts the input data by a single clock cycle, whereas your output shifts the input data by eight clock cycles.
By the way you have indented your always block, I am led to believe that it is not what you wanted. This is how your block really behaves:
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r_reg =0;
end else begin
r_reg[0]=data;
end
r_reg = r_reg<<1;
end
I always explicitly use the begin/end keywords in if/else statements to avoid this confusion.
The way it simulates, r_reg is always 0 because you clobber the 1st assignment (r_reg[0]=data;) with the 2nd (r_reg = r_reg<<1;). Another difference is that the book assigns data to the MSB of the shift register, but you assign it to the LSB.
If you are using decent linting and synthesis tools, you would probably get a bunch of warnings for your code. This would alert you to make some changes.

Resources