I am working with a verilog module (shown below) has two always blocks. Won't there be some sort of race condition since one block sets a register and the other uses the register. What kind of issues would this cause?
Thanks,
Stephen
module XYZ
(
input wire CLK,
input wire Reset,
input wire nReset,
input wire [15:0] X,
input wire [15:0] A,
input wire T,
input wire B,
output reg M
);
assign C = X > A;
reg P;
reg N;
always #(posedge CLK, negedge nReset)
begin
if (~nReset)
begin
P <= 1;
N <= 1;
end else begin
if (Reset)
begin
P <= 1;
N <= 1;
end else begin
P <= T? 1: ((C & ~M)? 0: P);
N <= B? 1: ((M & ~C)? 0: N);
end
end
end
always #(posedge CLK, negedge nReset)
begin
if (~nReset)
begin
M <= 0;
end else begin
if (Reset)
begin
M <= 0;
end else begin
M <= M? ~(N & ~C): (P & C);
end
end
end
endmodule
No, there is no race condition. Verilog is an event-driven simulator. Posedge (unless there is a glitch in the clock or reset) is usually executed once per the simulation tick. If you use non-blocking assignments correctly (and it looks like you did), every always block triggered by an edge will use old versions of the input variable values, the values which existed before the clock edge.
Here is a simplified example:
always #(posedge clk)
r <= in;
always #(posedge clk)
out <= r;
What happens in this situation is the following:
r will be assigned the value of in later at the simulation tick, after the always blocks have been evaluated (see the nba scheduling region).
since r has not been yet really changed, the out will be scheduled to be assigned the value of r with the value before the edge.
If r was 0 before the edge and in was 1, at the end of the simulation r will become 1 and out will become 0.
This mimics behavior for real flops in hardware.
In your case it might look as a loop dependency. In reality it it none. For the same reason as above the M value will be the one from before the the posedge and will not cause any race. Flops cannot be involved in the combinational loops due to their properties logical properties.
I completely Agree with the above answer and i would suggest some more to the above answer, when i started learning Verilog i too got the same doubt and these lines from a ref. book clarified my doubts. I am coping the statement here and
for further doubts u can comment here or u can see the
Ref. book page number 135
Book name :Verilog HDL: A Guide to Digital Design and Synthesis,
Second Edition By Samir Palnitkar
nonblocking statements used in Example 2 eliminate the race condition.
At the positive edge of clock, the values of all right-hand-side
variables are "read," and the right-hand-side expressions are
evaluated and stored in temporary variables. During the write
operation, the values stored in the temporary variables are assigned
to the left-handside variables. Separating the read and write
operations ensures that the values of registers a and b are swapped
correctly, regardless of the order in which the write operations are
performed.
On the downside, nonblocking assignments can potentially cause a
degradation in the simulator performance and increase in memory usage.
//Example 2: Two concurrent always blocks with nonblocking
//statements
always #(posedge clock)
a <= b;
always #(posedge clock)
b <= a;
And u can use this type of coding style not compulsory but for the ease of debugging and to fasten simulation u can reduce the usage of begin-end blocks where ever possible
module XYZ
(
input wire CLK,
input wire Reset,
input wire nReset,
input wire [15:0] X,
input wire [15:0] A,
input wire T,
input wire B,
output reg M
);
reg P,N;
always #(posedge CLK, negedge nReset)
if (~nReset)begin
P <= #10 1;
N <= #10 1;
end else if (Reset) begin
P <= #10 1;
N <= #10 1;
end else begin
P <= #10 T ? 1 : ((C & ~M) ? 0: P);
N <= #10 B ? 1 : ((M & ~C) ? 0: N);
end
always #(posedge CLK, negedge nReset)
if (~nReset) M <= #10 0 ;
else if ( Reset) M <= #10 0 ;
else M <= #10 M ? ~(N & ~C): (P & C);
assign C = X > A;
endmodule
Related
My code is compiling well, but it does not work when i simulate it.
It displays "error loading design".
i think that input and output port is wrong among these modules.
but i can not find them..
please help me where the error is in my code.
module tb_modulo_60_binary;
reg t_clk, reset;
wire [7:0] t_Y;
parameter sec = 30;
always #(sec) t_clk = ~t_clk;
modulo_60_binary M1 (t_Y, t_clk, reset);
initial begin
t_clk = 1; reset =1; #10;
reset = 0; #3050;
$finish;
end
endmodule
module modulo_60_binary(y, clk, reset);
output [7:0] y;
input reset, clk;
wire TA1, TA2, TA3, JA2, JA4;
reg [7:0] y;
assign TA1 = 1;
assign TA2 = (~y[6]) && y[4];
assign TA3 = (y[5] && y[4]) || (y[6] && y[4]);
assign JA2 = ~y[3];
assign JA4 = y[1]&&y[2];
jk_flip_flop JK1 (1, 1, clk, y[0]);
jk_flip_flop JK2 (JA2, 1, y[0], y[1]);
jk_flip_flop JK3 (1, 1, y[1], y[2]);
jk_flip_flop JK4 (JA4, 1, y[1], y[3]);
t_flip_flop T1 (TA1, clk, y[4]);
t_flip_flop T2 (TA2, clk, y[5]);
t_flip_flip T3 (TA3, clk, y[6]);
always #(negedge clk)
begin
if(reset)
y <= 8'b00000000;
else if(y == 8'b01110011)
y <= 8'b00000000;
end
endmodule
module t_flip_flop(t, clk, q);
input t, clk;
output q;
reg q;
initial q=0;
always #(negedge clk)
begin
if(t == 0) q <= q;
else q <= ~q;
end
endmodule
module jk_flip_flop(j, k, clk, Q);
output Q;
input j, k, clk;
reg Q;
always #(negedge clk)
if({j,k} == 2'b00) Q <= Q;
else if({j,k} == 2'b01) Q <= 1'b0;
else if({j,k} == 2'b10) Q <= 1'b1;
else if({j,k} == 2'b11) Q <= ~Q;
endmodule
Your y signal in modulo_60_binary is being driven in two places:
By bit JK# and T# instances
The reset logic that assigns all bits of y to zeros
Flops and comb-logic must have one clear driver. This is one of the fundamental differences between software and hardware languages.
The rest of my answer assuming the use of the JK and T flops are a design requirement. Therefore you need to delete the always block that assigns y to zeros and and make y a wire type.
Fixing the logic to the T flops is easy. Simply add a conditional statement. Example:
wire do_rst = reset || (y == 8'b01110011);
assign TA1 = do_rst ? y[4] : 1;
assign TA2 = do_rst ? y[5] : (~y[6]) && y[4];
assign TA3 = do_rst ? y[6] : (y[5] && y[4]) || (y[6] && y[4]);
The JK flops is harder because the output of one flop is the clock of another. I'll advice that the clock input for each JK flop should be clk, otherwise you are asking for a design headache for reset when it's y bits are non power of two minus one values (eg 1,3,7,15). This means you need to re-evaluate your JA# logic and add KA# logic (hint the do_rst from above will help). I'm not going to do the work for you beyond this.
There is the option of the asynchronous reset approach, but for this design I will advice ageist it. The reset pulse could be too short on silicon with the conditional reset for y == a particular value(s), which can result in an undependable partial reset. You could add synthesis constraints/rules to keep the push wide enough, but that is just patching a brittle design. Better to design it robust at the beginning.
FYI: y[7] does not have a driver and the module declaration of instance T3 has a typo.
I want to use the output of another module inside an always block.
Currently the only way to make this code work is by adding #1 after the pi_in assignment so that enough time has passed to allow Pi to finish.
Relevant part from module pLayer.v:
Pi pi(pi_in,pi_out);
always #(*)
begin
for(i=0; i<constants.nSBox; i++) begin
for(j=0; j<8; j++) begin
x = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1;
pi_in = 8*i+j;#1; /* wait for pi to finish */
PermutedBitNo = pi_out;
y = PermutedBitNo>>3;
tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y);
end
end
state_out = tmp;
end
Modllue Pi.v
`include "constants.v"
module Pi(in, out);
input [31:0] in;
output [31:0] out;
reg [31:0] out;
always #* begin
if (in != constants.nBits-1) begin
out = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out = constants.nBits-1;
end
end
endmodule
Delays should not be used in the final implementation, so is there another way without using #1?
In essence i want PermutedBitNo = pi_out to be evaluated only after the Pi module has finished its job with pi_in (=8*i+j) as input.
How can i block this line until Pi has finished?
Do i have to use a clock? If that's the case, please give me a hint.
update:
Based on Krouitch suggestions i modified my modules. Here is the updated version:
From pLayer.v:
Pi pi(.clk (clk),
.rst (rst),
.in (pi_in),
.out (pi_out));
counter c_i (clk, rst, stp_i, lmt_i, i);
counter c_j (clk, rst, stp_j, lmt_j, j);
always #(posedge clk)
begin
if (rst) begin
state_out = 0;
end else begin
if (c_j.count == lmt_j) begin
stp_i = 1;
end else begin
stp_i = 0;
end
// here, the logic starts
x = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1;
pi_in = 8*i+j;
PermutedBitNo = pi_out;
y = PermutedBitNo>>3;
tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y);
// at end
if (i == lmt_i-1)
if (j == lmt_j) begin
state_out = tmp;
end
end
end
endmodule
module counter(
input wire clk,
input wire rst,
input wire stp,
input wire [32:0] lmt,
output reg [32:0] count
);
always#(posedge clk or posedge rst)
if(rst)
count <= 0;
else if (count >= lmt)
count <= 0;
else if (stp)
count <= count + 1;
endmodule
From Pi.v:
always #* begin
if (rst == 1'b1) begin
out_comb = 0;
end
if (in != constants.nBits-1) begin
out_comb = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out_comb = constants.nBits-1;
end
end
always#(posedge clk) begin
if (rst)
out <= 0;
else
out <= out_comb;
end
That's a nice piece of software you have here...
The fact that this language describes hardware is not helping then.
In verilog, what you write will simulate in zero time. it means that your loop on i and j will be completely done in zero time too. That is why you see something when you force the loop to wait for 1 time unit with #1.
So yes, you have to use a clock.
For your system to work you will have to implement counters for i and j as I see things.
A counter synchronous counter with reset can be written like this:
`define SIZE 10
module counter(
input wire clk,
input wire rst_n,
output reg [`SIZE-1:0] count
);
always#(posedge clk or negedge rst_n)
if(~rst_n)
count <= `SIZE'd0;
else
count <= count + `SIZE'd1;
endmodule
You specify that you want to sample pi_out only when pi_in is processed.
In a digital design it means that you want to wait one clock cycle between the moment when you are sending pi_in and the moment when you are reading pi_out.
The best solution, in my opinion, is to make your pi module sequential and then consider pi_out as a register.
To do that I would do the following:
module Pi(in, out);
input clk;
input [31:0] in;
output [31:0] out;
reg [31:0] out;
wire clk;
wire [31:0] out_comb;
always #* begin
if (in != constants.nBits-1) begin
out_comb = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out_comb = constants.nBits-1;
end
end
always#(posedge clk)
out <= out_comb;
endmodule
Quickly if you use counters for i and j and this last pi module this is what will happen:
at a new clock cycle, i and j will change --> pi_in will change accordingly at the same time(in simulation)
at the next clock cycle out_comb will be stored in out and then you will have the new value of pi_out one clock cycle later than pi_in
EDIT
First of all, when writing (synchronous) processes, I would advise you to deal only with 1 register by process. It will make your code clearer and easier to understand/debug.
Another tip would be to separate combinatorial circuitry from sequential. It will also make you code clearer and understandable.
If I take the example of the counter I wrote previously it would look like :
`define SIZE 10
module counter(
input wire clk,
input wire rst_n,
output reg [`SIZE-1:0] count
);
//Two way to do the combinatorial function
//First one
wire [`SIZE-1:0] count_next;
assign count_next = count + `SIZE'd1;
//Second one
reg [`SIZE-1:0] count_next;
always#*
count_next = count + `SIZE'1d1;
always#(posedge clk or negedge rst_n)
if(~rst_n)
count <= `SIZE'd0;
else
count <= count_next;
endmodule
Here I see why you have one more cycle than expected, it is because you put the combinatorial circuitry that controls your pi module in you synchronous process. It means that the following will happen :
first clk positive edge i and j will be evaluated
next cycle, the pi_in is evaluated
next cycle, pi_out is captured
So it makes sense that it takes 2 cycles.
To correct that you should take out of the synchronous process the 'logic' part. As you stated in your commentaries it is logic, so it should not be in the synchronous process.
Hope it helps
Sir,
I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below
module my_upcount(
input clk,
input clr,
output [3:0] y
);
reg [26:0] temp1;
wire clk_1;
always #(posedge clk or posedge clr)
begin
temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
end
assign clk_1 = temp1[26];
reg [3:0] temp;
always #(posedge clk_1 or posedge clr)
begin
temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
end
assign y = temp;
endmodule
Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.
Apart from that, there are couple of other issues with your code:
Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.
Here's you example rewritten according to my suggestions:
module my_counter
(
input wire clk, clr,
output [3:0] y
);
reg [3:0] dvsr_reg, counter_reg;
wire [3:0] dvsr_next, counter_next;
wire dvsr_tick;
always #(posedge clk, posedge clr)
if (clr)
begin
counter_reg <= 4'b0000;
dvsr_reg <= 4'b0000;
end
else
begin
counter_reg <= counter_next;
dvsr_reg <= dvsr_next;
end
/// Combinational next-state logic
assign dvsr_next = dvsr_reg + 4'b0001;
assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;
/// Set the output signals
assign y = counter_reg;
endmodule
And here's the simple testbench to verify its operation:
module my_counter_tb;
localparam
T = 20;
reg clk, clr;
wire [3:0] y;
my_counter uut(.clk(clk), .clr(clr), .y(y));
always
begin
clk = 1'b1;
#(T/2);
clk = 1'b0;
#(T/2);
end
initial
begin
clr = 1'b1;
#(negedge clk);
clr = 1'b0;
repeat(50) #(negedge clk);
$stop;
end
endmodule
Quartus 11.0 says:
Error (10028): Can't resolve multiple constant drivers for net "n[9]"
for the following code:
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
always #(posedge h)
begin
n<=0;
end
always #(negedge clk)
begin
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
assign P=r;
endmodule
########### image is here ###########
zhe image is what i want. when flag1 start set n=0, and count clk;
when count to flag2, set P=0; when count to red arrow, set P=1;
Assuming h is synchronous to clk, simply sample h and figure out when the sample value is low and the current value is high (e.g. h rose). This way n is assigned within one always block (which is required for synthesis) and everything is is the same clocking domain.
always #(negedge clk) begin
past_h <= h;
if(!past_h && h) begin // detect 0->1
n <= 10'h000;
end
else begin
n <= n + 1'b1;
end
end
If h is asynchronous, then things get more complicated to keep the signal clean. In which case I recommend reading Clock Domain Crossing (CDC) Design & Verification Techniques by Cliff Cummings
As the warning says, there are multiple drivers for n[9], and actually all of n and r, since n and r are both driven in the initial and the always, and when synthesizing the design, there can be only one driver for a reg. And n is driven in multiple always blocks.
For synthesis, a reg should be driven from only one always block.
For the multiple always blocks where n is driven, combine these to only one, and use only one clock, e.g. clk.
If the purpose is to assign a default value for n and r, then make that in the declaration, and remove the initial, like:
reg r = 1'b1;
reg[9:0] n = 0;
However, consider adding a reset signal if possible, then then use this reset signal to assign reset values to the regs, either synchronously or asynchronously.
You can try to move the posedge h into the same always block as the negedge clock and sample h and clk based on the input logic. If h goes low before the negedge of clk then something like this may work.
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
always #(negedge clk, posedge h)
begin
if(h==1'b1)
n<=0;
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
assign P=r;
endmodule
i think it will help you out. i have compiled this one in xilinx 14.5 synthesis is done.
module make_counter(h, clk, P);
input wire h;
input wire clk;
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;
task cpu_write;
begin
# (posedge h);
n <= 0;
# (posedge clk);
if(n<600)
n<=n+1'b1;
if(n==106)
r<=1'b0;
else if(n==517)
r<=1'b1;
else;
end
endtask
assign P=r;
endmodule
I am interested to write Verilog module which simultaneously will update several outputs
Something like following code, makes 3 operations at the same time (clk 10):
module mymodule (a,b,c,d,e);
input a;
input b;
output c;
output d;
output e;
wire b;
wire a;
wire c;
wire d;
reg e;
initial begin
c <= #10 (a+b);
d <= #10 a;
e <= #10 b;
end
endmodule
Is that code legal?
How todo a one off assign of variables after 10 timeunits or clocks:
As a testbench level construct:
reg c,d,e;
initial begin
#10;
c = a+b;
d = a;
e = b;
end
For RTL (synthesis) first you need a testbench with a clock.
I would generate a clock like this in my testharness :
reg clk ; //Rising edge every 10 timesteps
initial begin
clk = 0;
#5;
forever begin
#5 ;
clk = ~clk;
end
end
Build a counter which counts to 10 and once it reaches 10 Enables the flip-flop to load new values.
wire enable = (counter == 4'b10);
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
c <= 1'b0;
d <= 1'b0;
e <= 1'b0;
end
else if (enable) begin
c <= (a+b);
d <= a;
e <= b;
end
end
endmodule
Extra Verilog Tips
Outputs are implicitly wires no need to redefine them.
Non-Blocking assignments <= are for use in an always #(posedge clk) when inferring flip-flops.
regs or logic types can be assigned inside always or initial blocks. wires are used with assign or for connectivity between ports.