Always Statements in Verilog - verilog

I am writing code for an 8-bit synchronous counter using t_flipflops with asynchronous clear. Here is my code:
module T_ff(CLK,E,CLEAR,T,Q);
input CLK,E,CLEAR,D;
output reg Q;
always#(posedge CLK, negedge CLEAR,E,T)
begin:
if(~CLEAR)
Q<=1b'0;
else if (E == 1)
Q<=Q^T;
end:
endmodule
However, I get an error at the if statement:
Error (10170): Verilog HDL syntax error at lab5.v(25) near text "if"; expecting an identifier ("if" is a reserved keyword )
Any help? Also, can I put E and T in the sensitivity list along with the posedge and negedge functions?

You don't need the colons after the begin and end.
You shouldn't put E and T into the sensitivity list.
A flipflop does something when the clock changes, or when reset. You don't want the block to be triggered when E or T change.
module T_ff(CLK,E,CLEAR,T,Q);
input CLK,E,CLEAR,D;
output reg Q;
always#(posedge CLK or negedge CLEAR)
begin
if(~CLEAR)
Q<=1b'0;
else if (E == 1)
Q<=Q^T;
end
endmodule

If you use colons after begin/end keywords, you need to follow them with an identifier. Keep in mind that this is a SystemVerilog feature (refer to IEEE Std 1800-2012, Section 9.3.4 "Block Names"). For example, you could name your block dff:
module T_ff(CLK,E,CLEAR,T,Q);
input CLK,E,CLEAR,T; // D should be T
output reg Q;
always#(posedge CLK, negedge CLEAR)
begin: dff
if(~CLEAR)
Q<=1b'0;
else if (E == 1)
Q<=Q^T;
end: dff
endmodule
Naming your blocks is optional. Using a name after the end keyword is also optional.
Also, I think you should change D to T in your port declaration. As the other Answer said, you should not use E or T in your sensitivity list.

Related

Verilog : error Reference to scalar wire 'VALUE' is not a legal reg or variable lvalue

I'm stuck with this code. I don't understand why my VALUE cannot be inverted.
module PREDIV(
input wire QUARTZ,
output wire VALUE);
always # (posedge QUARTZ)
assign VALUE= ~VALUE;
endmodule
There are a few problems.
You should not use the assign keyword inside an always block.
When making a procedural assignment (those inside an always block), you should declare the signal as a reg type, not a wire. This is what your error message is referring to.
For sequential logic, you should use nonblocking assignments: <=.
Finally, a reg is initialized as unknown (X). You need a way to initialize VALUE, otherwise it will remain X. One way is to add a RESET signal.
module PREDIV(
input wire QUARTZ, input RESET,
output reg VALUE);
always # (posedge QUARTZ or posedge RESET)
if (RESET) begin
VALUE <= 0;
end else begin
VALUE <= ~VALUE;
end
endmodule
It looks like the code is using blocking assignment in the always block.
The always blocks should be using only non-blocking assignments.
The code should be something like:
always #(posedge QUARTS)
Value <= ~Value;

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

How to modify the Verilog code to avoid multiple drivers?

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

Implementing Sequential Circuit in Verilog

I'm trying to implement the following Sequential Circuit in Verilog (Modelsim 10.4a)
Here's the code I'm using
seq_circuit1.v
module seq_circuit1(x, clk, Q0, Q1);
input x, clk;
output Q0, Q1;
reg J0,K0,J1,K1;
always #(negedge clk)
begin
//Blocking and Non Blocking both will work
J0 = Q1 & ~x;
K0 = Q1 & x;
J1 = x;
K1 = (Q0 & x) || (~Q0 & ~x);
jkfflop JKff0 (J0,K0,Q0);
jkfflop JKff1 (J1,K1,Q1);
end
endmodule
jkfflop.v
module jkfflop(J,K,clk,Q);
input J,K,clk;
output Q;
if(J==0 & K==1)
begin
assign Q = 0;
end
else if(J==1 & K==0)
begin
assign Q = 1;
end
else if(J==1 & K==1)
begin
assign Q = ~Q;
end
endmodule
I'm getting some errors and I'm unable to figure out why. Can anybody tell me where did I do it wrong..
seq_circuit1
You can't instantiate submodules (your FFs) inside an always block.
Move them outside, either before or after.
Your instantiations for jkfflop are missing the clk input signal.
based on your diagram, your inputs to the FFs should be combinational logic, not sequential, and should therefore use an always #(*) block, not a clocked one.
jkfflop
if statements in verilog are only valid inside a generate, always or inital block. Since this is a FF, you'll want an always #(posedge clk) or always #(negedge clk)
If using an always block, replace the assign statements with non-blocking assignments (<=). We use NBA's here instead of a blocking assignments (=), as it's an edge-triggered block.
If assigning a value to Q inside an always block, change output Q to output reg Q

Assignment under multiple single edges is not supported for synthesis

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.

Resources