Implementing Sequential Circuit in Verilog - 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

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.

I2S Transmitter Verilog Implementation not working

I am trying to implement the I2S Transmitter in verilog. The datasheet for it is at: https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf
I wrote the code, but my SD line is delayed 1 clock cycle when i test it.
Can someone check my implementation?
module Transmiter(
input signed [23:0] DLeft, input signed [23:0] DRight, input WS, input CLK,
output reg SD
);
wire PL;
reg Q1,Q2;
reg [23:0] shift_reg;
reg [23:0] Tdata;
assign PL = Q1^Q2;
always #(posedge CLK)
begin
Q1 <= WS;
Q2 <= Q1;
end
always #( Q1) begin
if (Q1)
begin
Tdata <= DRight;
end
else
begin
Tdata <= DLeft;
end
end
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else begin
SD <= shift_reg[23];
shift_reg <= {shift_reg[22:0],1'b0};
end
end
endmodule
EDIT: here is a image of waveform image
TEST BENCH CODE:
module Transmitter_tb(
);
reg CLK, WS;
reg [23:0] dataL;
reg [23:0] dataR;
wire SDout;
Transmiter UT(dataL, dataR, WS, CLK, SDout);
initial begin
dataL = 24'hF0F0FF; #2;
dataR = 24'h0000F0; #2;
end
always begin
CLK=0; #20;
CLK=1; #20;
end;
always begin
WS=0; #1000;
WS=1; #1000;
end;
endmodule
Your negedge block contains an if-else construct and will only ever compute one or the other on a single clock edge. SD will therefore not change value when PL is high.
Furthermore you are using non-blocking assignments(<=) in your code. This roughly means that changes won't be evaluated until the end of the always block. So even if SD <= shift_reg[23] after shift_reg <= Tdata it will not take on the new value in shift_reg[23] but use the previous value. If you want SD to change immediately when shift_reg[23] changes you need to do this combinatorically.
This should work:
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else
shift_reg <= {shift_reg[22:0],1'b0};
end
assign SD = shift_reg[23];
Working example: https://www.edaplayground.com/x/4bPv
On a side note I am still not convinced that DRight and DLeft are in fact constants, I can see that they are in your TB but it doesn't make sense that the data for your I2S is constant. Your current construct will probably generate a latch(instead of a MUX), and we generally don't want those in our design.
You should clean up your use of blocking versus non-blocking statements:
Always use non-blocking assigments, meaning "<=", in clocked statements.
Always use blocking assigments, meaning "=", in combinational (non-clocked) statements.
This is a industry-wide recommendation, not a personal opinion. You can find this recommendation many places, see for instance:
http://web.mit.edu/6.111/www/f2007/handouts/L06.pdf
The sensitivtity list being incomplete (as pointed out by #Hida) may also cause issues.
Try to correct these two things, and see if it starts working more as expected.
Also note that you are using Q1 (among other signals) to generate your PL signal. If the WS input is not synchronous to your local clock (as I assume it is not), you need to put one more flop (i.e. two in series) before starting to use the output, to avoid metastability-issues. But you won't see this in an RTL simulation.

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

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.

Always Statements in 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.

Resources