Ex No:1 Design of Registers by Verilog HDL
(i) Verilog Code for a Single D-Flip Flop:
module d_flip_flop(
input clk, // Clock signal
input reset, // Reset signal (active high)
input d, // Data input
output reg q // Data output
);
always @(posedge clk or posedge reset) begin
if (reset)
q <= 0; // Reset the output to 0
else
q <= d; // Store the input data on the rising edge of the clock
end
endmodule
(ii) Verilog Code for a 4-bit Parallel Load Register:
module parallel_load_register(
input clk, // Clock signal
input reset, // Reset signal
input load, // Load control signal (active high)
input [3:0] data_in, // 4-bit data input
output reg [3:0] data_out // 4-bit data output
);
always @(posedge clk or posedge reset) begin
if (reset)
data_out <= 4'b0000; // Reset to 0
else if (load)
data_out <= data_in; // Load the data when 'load' is high
end
endmodule
(iii) Verilog Code for a 4-bit Serial-In Parallel-Out Shift Register:
module serial_in_parallel_out_shift_register(
input clk, // Clock signal
input reset, // Reset signal
input serial_in, // Serial input data
output reg [3:0] parallel_out // 4-bit parallel output
);
always @(posedge clk or posedge reset) begin
if (reset)
parallel_out <= 4'b0000; // Reset to 0
else
parallel_out <= {parallel_out[2:0], serial_in}; // Shift left and input new bit
end
endmodule
(iv) Verilog Code for a 4-bit Parallel-In Serial-Out Shift Register:
module parallel_in_serial_out_shift_register(
input clk, // Clock signal
input reset, // Reset signal
input [3:0] parallel_in, // 4-bit parallel input data
output reg serial_out // Serial output data
);
reg [3:0] shift_reg; // Internal shift register
always @(posedge clk or posedge reset) begin
if (reset)
shift_reg <= 4'b0000; // Reset the register to 0
else
shift_reg <= parallel_in; // Load the parallel input data
end
// Serial output shifts out the data on each clock pulse
always @(posedge clk or posedge reset) begin
if (reset)
serial_out <= 0; // Reset serial output to 0
else
serial_out <= shift_reg[3]; // Output the MSB as serial output
end
endmodule
EX no.2 Design of counters by Verilog HDL
(i) Verilog Code for a 4-bit Synchronous Up Counter:
module up_counter(
input clk, // Clock signal
input reset, // Reset signal
output reg [3:0] count // 4-bit counter output
);
// Counter behavior
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b0000; // Reset to 0
else
count <= count + 1; // Increment the counter on each clock edge
end
endmodule
(ii) Verilog Code for a 4-bit Synchronous Down Counter:
module down_counter(
input clk, // Clock signal
input reset, // Reset signal
output reg [3:0] count // 4-bit counter output
);
// Counter behavior
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b1111; // Reset to 15
else
count <= count - 1; // Decrement the counter on each clock edge
end
endmodule
(iii) Verilog Code for a 4-bit Up/Down Counter:
module up_down_counter(
input clk, // Clock signal
input reset, // Reset signal
input up_down, // Control signal (1 for up, 0 for down)
output reg [3:0] count // 4-bit counter output
);
// Counter behavior
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b0000; // Reset to 0
else if (up_down)
count <= count + 1; // Increment the counter
else
count <= count - 1; // Decrement the counter
end
endmodule
(iv) Verilog Code for a 4-bit Asynchronous Up Counter:
module async_up_counter(
input clk, // Clock signal
input reset, // Reset signal
output reg [3:0] count // 4-bit counter output
);
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b0000; // Reset to 0
else
count[0] <= count[0] + 1; // LSB toggles on every clock pulse
end
always @(posedge count[0] or posedge reset) begin
if (reset)
count[1] <= 0;
else
count[1] <= count[1] + 1; // Flip-flop 1 toggles on count[0] transition
end
always @(posedge count[1] or posedge reset) begin
if (reset)
count[2] <= 0;
else
count[2] <= count[2] + 1; // Flip-flop 2 toggles on count[1] transition
end
always @(posedge count[2] or posedge reset) begin
if (reset)
count[3] <= 0;
else
count[3] <= count[3] + 1; // Flip-flop 3 toggles on count[2] transition
end
endmodule
(v) Verilog Code for 4-bit Up/Down Asynchronous Counter:
module async_up_down_counter(
input clk, // Clock signal
input reset, // Reset signal
input up_down, // Control signal (1 for up, 0 for down)
output reg [3:0] count // 4-bit counter output
);
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b0000; // Reset to 0
else if (up_down)
count[0] <= count[0] + 1; // LSB toggles on every clock pulse (up)
else
count[0] <= count[0] - 1; // LSB toggles on every clock pulse (down)
end
always @(posedge count[0] or posedge reset) begin
if (reset)
count[1] <= 0;
else if (up_down)
count[1] <= count[1] + 1;
else
count[1] <= count[1] - 1;
end
always @(posedge count[1] or posedge reset) begin
if (reset)
count[2] <= 0;
else if (up_down)
count[2] <= count[2] + 1;
else
count[2] <= count[2] - 1;
end
always @(posedge count[2] or posedge reset) begin
if (reset)
count[3] <= 0;
else if (up_down)
count[3] <= count[3] + 1;
else
count[3] <= count[3] - 1;
end
endmodule
Ex no : 3 Design of sequential Machines by Verilog HDL
(i) Verilog Code for Moore Machine (2-bit Counter):
module moore_counter(
input clk, // Clock signal
input reset, // Reset signal
output reg [1:0] count // 2-bit counter output
);
// State encoding
typedef enum reg [1:0] {
S0 = 2'b00, // State 0
S1 = 2'b01, // State 1
S2 = 2'b10, // State 2
S3 = 2'b11 // State 3
} state_t;
state_t current_state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if 3(reset)
current_state <= S0; // Reset to initial state
else
current_state <= next_state; // Transition to next state
end
// Next state logic
always @(current_state) begin
case (current_state)
S0: next_state = S1;
S1: next_state = S2;
S2: next_state = S3;
S3: next_state = S0;
default: next_state = S0;
endcase
end
// Output logic (depends only on current state)
always @(current_state) begin
case (current_state)
S0: count = 2'b00;
S1: count = 2'b01;
S2: count = 2'b10;
S3: count = 2'b11;
default: count = 2'b00;
endcase
end
endmodule
(ii) Verilog Code for Mealy Machine (2-bit Sequence Detector):
module mealy_detector(
input clk, // Clock signal
input reset, // Reset signal
input bit_in, // Input bit stream
output reg detected // Output: 1 if sequence "10" is detected
);
// State encoding
typedef enum reg [1:0] {
S0 = 2'b00, // Initial state (No "10" detected)
S1 = 2'b01, // State 1: detected "1"
S2 = 2'b10 // State 2: detected "10"
} state_t;
state_t current_state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
current_state <= S0; // Reset to initial state
else
current_state <= next_state; // Transition to next state
end
// Next state logic
always @(current_state or bit_in) begin
case (current_state)
S0: next_state = (bit_in == 1) ? S1 : S0; // If input is 1, move to state S1
S1: next_state = (bit_in == 0) ? S2 : S1; // If input is 0, move to state S2
S2: next_state = (bit_in == 1) ? S1 : S0; // If input is 1, move to state S1
default: next_state = S0;
endcase
end
// Output logic (depends on state and input)
always @(current_state or bit_in) begin
case (current_state)
S0: detected = 0;
S1: detected = 0;
S2: detected = 1; // Output 1 if "10" is detected
default: detected = 0;
endcase
end
endmodule
EX no.4 Design of serial adders, multipliers and divider by Verilog HDL
(i) Serial Adder:
module serial_adder(
input clk, // Clock signal
input reset, // Reset signal
input start, // Start signal for addition
input A, // Input A (1 bit)
input B, // Input B (1 bit)
output reg sum, // Sum output (1 bit)
output reg carry, // Carry output (1 bit)
output reg done // Done flag
);
reg [1:0] state, next_state;
reg [1:0] sum_reg, carry_reg;
reg start_reg;
// State encoding
parameter IDLE = 2'b00, ADD = 2'b01, DONE = 2'b10;
// Sequential process for state transition
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next state logic
always @(state or start) begin
case (state)
IDLE:
if (start)
next_state = ADD;
else
next_state = IDLE;
ADD:
next_state = DONE;
DONE:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
// Output logic and sum calculation
always @(posedge clk) begin
if (state == ADD) begin
{carry, sum} = A + B + carry_reg;
sum_reg = sum;
carry_reg = carry;
end
else if (state == DONE) begin
done <= 1;
end
else begin
done <= 0;
end
end
endmodule
(ii) Serial Multiplier :
module serial_multiplier(
input clk, // Clock signal
input reset, // Reset signal
input start, // Start signal
input A, // Input A (1 bit)
input B, // Input B (1 bit)
output reg product, // Product output (1 bit)
output reg done // Done flag
);
reg [3:0] state, next_state;
reg [7:0] shift_reg_A, shift_reg_B, product_reg;
// State encoding
parameter IDLE = 4'b0000, MULT = 4'b0001, DONE = 4'b0010;
// Sequential process for state transition
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next state logic
always @(state or start) begin
case (state)
IDLE:
if (start)
next_state = MULT;
else
next_state = IDLE;
MULT:
next_state = MULT;
DONE:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
// Multiplication logic and shift operation
always @(posedge clk) begin
if (state == MULT) begin
product_reg = product_reg + (shift_reg_A & shift_reg_B); // Adding partial product
shift_reg_A = shift_reg_A << 1; // Shift A
shift_reg_B = shift_reg_B << 1; // Shift B
end
else if (state == DONE) begin
product = product_reg;
done = 1;
end
else begin
done = 0;
end
end
endmodule
(iii) Serial Divider:
module serial_divider(
input clk, // Clock signal
input reset, // Reset signal
input start, // Start signal
input A, // Dividend bit (1 bit)
input B, // Divisor bit (1 bit)
output reg quotient, // Quotient output (1 bit)
output reg remainder, // Remainder output (1 bit)
output reg done // Done flag
);
reg [3:0] state, next_state;
reg [7:0] dividend_reg, divisor_reg, quotient_reg, remainder_reg;
// State encoding
parameter IDLE = 4'b0000, DIV = 4'b0001, DONE = 4'b0010;
// Sequential process for state transition
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next state logic
always @(state or start) begin
case (state)
IDLE:
if (start)
next_state = DIV;
else
next_state = IDLE;
DIV:
next_state = DIV;
DONE:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
// Division logic and shift operation
always @(posedge clk) begin
if (state == DIV) begin
remainder_reg = remainder_reg - divisor_reg; // Subtract divisor from remainder
quotient_reg = quotient_reg << 1; // Shift quotient
if (remainder_reg >= 0)
quotient_reg[0] = 1;
else
quotient_reg[0] = 0;
end
else if (state == DONE) begin
quotient = quotient_reg;
remainder = remainder_reg;
done = 1;
end
else begin
done = 0;
end
end
endmodule
Ex no: 5 DESIGN OF THE SIMPLE MICROPROCESSOR BY VERILOG HDL
The microprocessor design can be broken down into the following components:
1. Registers: A set of registers for holding data and instructions.
2. ALU: The Arithmetic and Logic Unit for performing operations.
3. Control Unit: Decodes the instructions and generates control signals.
4. Program Counter (PC): Keeps track of the current instruction.
5. Instruction Fetch/Decode Unit: Fetches instructions from memory.
2. ALU Design
The ALU performs basic arithmetic and logical operations.
module ALU (
input [3:0] A, // Operand A
input [3:0] B, // Operand B
input [2:0] ALU_Control, // Control signal to select the operation
output reg [3:0] ALU_Result, // Result of the ALU operation
output reg Zero // Zero flag, set if result is zero
);
always @(*) begin
case (ALU_Control)
3'b000: ALU_Result = A + B; // Addition
3'b001: ALU_Result = A - B; // Subtraction
3'b010: ALU_Result = A & B; // AND
3'b011: ALU_Result = A | B; // OR
3'b100: ALU_Result = A ^ B; // XOR
3'b101: ALU_Result = ~(A | B); // NOR
3'b110: ALU_Result = A << 1; // Shift left
3'b111: ALU_Result = A >> 1; // Shift right
default: ALU_Result = 4'b0000;
endcase
// Zero flag
Zero = (ALU_Result == 4'b0000);
end
endmodule
3. Registers Design
We need registers to hold values, including a program counter (PC), instruction register (IR),
and general-purpose registers.
verilog
Copy code
module RegisterFile (
input clk,
input reset,
input [1:0] read_addr, // Address of register to read from
input [1:0] write_addr, // Address of register to write to
input [3:0] write_data, // Data to write to the register
input write_enable, // Control signal to enable writing
output reg [3:0] read_data // Data read from register
);
reg [3:0] registers [3:0]; // 4 registers, each 4 bits wide
always @(posedge clk or posedge reset) begin
if (reset)
registers[0] <= 4'b0000; // Reset all registers
registers[1] <= 4'b0000;
registers[2] <= 4'b0000;
registers[3] <= 4'b0000;
else if (write_enable)
registers[write_addr] <= write_data; // Write data to register
end
always @(*) begin
read_data = registers[read_addr]; // Read data from register
end
endmodule
4. Control Unit Design
The control unit decodes instructions and generates control signals for the ALU, memory,
and other components.
verilog
Copy code
module ControlUnit (
input [3:0] opcode, // Instruction opcode
output reg ALU_src, // ALU source control signal
output reg RegWrite, // Register write control signal
output reg [2:0] ALU_Control, // ALU control signal
output reg PC_src, // Program counter control signal
output reg MemWrite // Memory write control signal
);
always @(*) begin
case (opcode)
4'b0000: begin // LOAD
ALU_src = 0;
RegWrite = 1;
ALU_Control = 3'b000; // Addition
PC_src = 0;
MemWrite = 0;
end
4'b0001: begin // STORE
ALU_src = 0;
RegWrite = 0;
ALU_Control = 3'b000; // Addition
PC_src = 0;
MemWrite = 1;
end
4'b0010: begin // ADD
ALU_src = 0;
RegWrite = 1;
ALU_Control = 3'b000; // Addition
PC_src = 0;
MemWrite = 0;
end
4'b0011: begin // SUB
ALU_src = 0;
RegWrite = 1;
ALU_Control = 3'b001; // Subtraction
PC_src = 0;
MemWrite = 0;
end
4'b0100: begin // AND
ALU_src = 0;
RegWrite = 1;
ALU_Control = 3'b010; // AND
PC_src = 0;
MemWrite = 0;
end
4'b0101: begin // OR
ALU_src = 0;
RegWrite = 1;
ALU_Control = 3'b011; // OR
PC_src = 0;
MemWrite = 0;
end
4'b0110: begin // JUMP
ALU_src = 0;
RegWrite = 0;
ALU_Control = 3'b000; // No operation
PC_src = 1; // Jump to address in the instruction
MemWrite = 0;
end
default: begin
ALU_src = 0;
RegWrite = 0;
ALU_Control = 3'b000; // No operation
PC_src = 0;
MemWrite = 0;
end
endcase
end
endmodule
5. Program Counter (PC) and Instruction Fetch
The program counter holds the address of the next instruction to fetch. The instruction fetch
module fetches instructions from memory.
verilog
Copy code
module ProgramCounter (
input clk, // Clock signal
input reset, // Reset signal
input PC_src, // Control signal to change the PC
input [3:0] jump_addr, // Address to jump to
output reg [3:0] PC // Program Counter output
);
always @(posedge clk or posedge reset) begin
if (reset)
PC <= 4'b0000; // Reset PC to 0
else if (PC_src)
PC <= jump_addr; // Jump to specified address
else
PC <= PC + 1; // Increment PC
end
endmodule
6. Microprocessor Top Module
Finally, we combine all the components to form a simple microprocessor.
verilog
Copy code
module SimpleMicroprocessor (
input clk, // Clock signal
input reset, // Reset signal
output [3:0] result // ALU result
);
wire [3:0] opcode;
wire [3:0] instruction;
wire [3:0] ALU_result;
wire [3:0] read_data;
wire Zero;
wire ALU_src;
wire RegWrite;
wire [2:0] ALU_Control;
wire PC_src;
wire MemWrite;
wire [3:0] PC;
wire [3:0] jump_addr;
// Instantiate components
ProgramCounter PC_unit (
.clk(clk),
.reset(reset),
.PC_src(PC_src),
.jump_addr(jump_addr),
.PC(PC)
);
// Instruction Fetch (for simplicity, assume memory is a small ROM)
assign instruction = memory[PC]; // Fetch instruction from memory (simplified)
ControlUnit CU (
.opcode(instruction[3:0]),
.ALU_src(ALU_src),
.RegWrite(RegWrite),
.ALU_Control(ALU_Control),
.PC_src(PC_src),
.MemWrite(MemWrite)
);
ALU ALU_unit (
.A(read_data),
.B(instruction[3:0]), // Use instruction as operand for simplicity
.ALU_Control(ALU_Control),
.ALU_Result(ALU_result),
.Zero(Zero)
);