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)
);