In this project, we are going to design a serial adder. A serial adder is a circuit that performs binary addition bit by bit (i.e., instead of presenting both operands at the inputs of an adder at the same time, the operands are fed into the serial adder bit by bit and it generates the answer on the fly). To design such a circuit, we are going to use the state diagram as the mode of describing the behavior of the circuit, and then translate the state diagram into Verilog code.
Qty | Description |
---|---|
1 | Digilent Nexys™4, Nexys™3, Nexys™2, or Basys™2 FPGA Board |
1 | Xilinx ISE Design Suite: WebPACK (14.6 Recommended) |
1 | Digilent Adept |
If you did this correctly, you will notice that when you are in S2, and both A and B are asserted, you need to add the carry generated by the previous bit together with current A and B together, resulting in $F = 1$ and $Cout = 1$. This is a state that is different from S0, S1, and S2. So we have the fourth state in the state machine and we will label it S4.
A state machine is composed of three parts: next state decoding logic, state registers, and output logic, as shown in Fig. 8 below.
The next state logic is a combinational block that implements the state transition logic. In other words, it generates the state code for the next state based on the present state and inputs. The state register updates the current state with the next state logic, calculated by the next state logic at every rising edge of the clock. The output logic is another combinational logic block that asserts the output based on the present state. So we can code the state machine in sections—a combinational block for next state logic, a sequential block for state register, and finally another combinational block for output logic.
`timescale 1ns / 1ps
module SA(
input A,
input B,
output F,
output Cout,
input clk,
input rst
);
// Define State Codes
localparam S0 = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;
reg [1:0] pState, nState;
always @
. The block will drive
the next state signal (nState) based on the present state (pState)
signals and inputs (A and B). In state diagrams, we describe state
transitions by an arrow starting from present state
and pointing to the next state with a label showing input conditions
for state transition. It is pretty straightforward
to use case statement to describe the state transitions.
// Combinational Logic: Next State Logic
always @ (pState, A, B)
begin
case (pState)
S0:begin
if (A == 1'b0 && B == 1'b0)
nState = S0;
else if (A == 1'b1 && B == 1'b1)
nState = S2;
else
nState = S1;
end
S1:
if (A == 1'b0 && B == 1'b0)
nState = S0;
else if (A == 1'b1 && B == 1'b1)
nState = S2;
else
nState = S1;
S2:
if (A == 1'b0 && B == 1'b0)
nState = S1;
else if (A == 1'b1 && B == 1'b1)
nState = S3;
else
nState = S2;
S3:
if (A == 1'b0 && B == 1'b0)
nState = S1 ;
else if (A == 1'b1 && B == 1'b1)
nState = S3;
else
nState = S2;
default:
nState = S0;
endcase
end
// State Registers
always @ (posedge(clk), posedge(rst))
begin
if (rst == 1'b1)
pState <= S0;
else
pState <= nState;
end
// Output Logic
assign F = (pState == S1 || pState == S3) ? 1'b1 : 1'b0;
assign Cout = (pState == S2 || pState == S3) ? 1'b1 : 1'b0;
`timescale 1ns / 1ps
module SA(
input A,
input B,
output F,
output Cout,
input clk,
input rst
);
// Define State Codes
localparam S0 = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;
reg [1:0] pState, nState;
// Combinational Logic: Next State Logic
always @ (pState, A, B)
begin
case (pState)
S0:begin
if (A == 1'b0 && B == 1'b0)
nState = S0;
else if (A == 1'b1 && B == 1'b1)
nState = S2;
else
nState = S1;
end
S1:
if (A == 1'b0 && B == 1'b0)
nState = S0;
else if (A == 1'b1 && B == 1'b1)
nState = S2;
else
nState = S1;
S2:
if (A == 1'b0 && B == 1'b0)
nState = S1;
else if (A == 1'b1 && B == 1'b1)
nState = S3;
else
nState = S2;
S3:
if (A == 1'b0 && B == 1'b0)
nState = S1 ;
else if (A == 1'b1 && B == 1'b1)
nState = S3;
else
nState = S2;
default:
nState = S0;
endcase
end
// State Registers
always @ (posedge(clk), posedge(rst))
begin
if (rst == 1'b1)
pState <= S0;
else
pState <= nState;
end
// Output Logic
assign F = (pState == S1 || pState == S3) ? 1'b1 : 1'b0;
assign Cout = (pState == S2 || pState == S3) ? 1'b1 : 1'b0;
endmodule