Skip to main content

Product Engineer II at Cadence Design Systems

Hello Dear Readers, Cadence Design Systems has a vacancy for a Product Engineer II role. Cadence is a pivotal leader in electronic design, building upon more than 30 years of computational software expertise. The company applies its underlying Intelligent System Design strategy to deliver software, hardware and IP that turn design concepts into reality.  Cadence customers are the world’s most innovative companies, delivering extraordinary electronic products from chips to boards to systems for the most dynamic market applications including consumer, hyperscale computing, 5G communications, automotive, aerospace industrial and health. The Cadence Advantage: The opportunity to work on cutting-edge technology in an environment that encourages you to be creative, innovative, and to make an impact. Cadence’s employee-friendly policies focus on the physical and mental well-being of employees, career development, providing opportunities for learning, and celebrating success in recog...

Design of the 3 Stage Pipeline Microprocessor Using Verilog

 Hello Dear Readers,

First of all thanks for giving motivation on my first of designing microprocessor. DESIGN OF THE SINGLE CYCLE MICROPROCESSOR USING VERILOG HDL. So now in this post, i will explain the 3 stages of the pipeline microprocessors namely the Fetch Unit, Decode Unit, and Execute Unit. So Let's start designing based on the specification given below.

Stage-1: Fetch Unit

Fetch Unit comprises half-word addressable instruction memory. It takes PC as input and gives the instruction as an output. PC is also incremented by PC=PC+1.

Stage-2: Decode Unit

Decode Unit reads the fetched instruction and decodes the address of two source operands and destination register. Also, it generates the immediate data. Register Bank reads the value of source operands (Rs1 and Rs2) at negative level of the clock, and writes the data in the destination register (Rd) at positive level of clock. Control Unit uses 4-bit opcode bits to determine the type of instruction. 

Stage-3: Execute Unit

ALU Control Unit uses the type of instruction generated by control unit, and generates a 2-bit ALUOP (ALU Operation) signal. ALU Module uses the ALUOP generated by ALU Control Unit to perform the operation on source operands. Write Back Unit using the type of instruction from control unit write the output data from ALU module in the destination register of the register bank.

Instruction Format:



OPCODE 

R-type = 4’d1 
I-type = 4’d2 

Func3 

ADD and ADDI=3’d0
SUB and SUBI=3’d1 
AND and ANDI=3’d2 
OR and ORI=3’d3

So now Start coding,

Verilog Code:

FETCH  UNIT:

module fetchInstruction(
input clk,
input rst,

output reg [15:0] prog_ctr,

output reg [15:0] curr_instr
);
   reg [7:0] instr [255:0];

initial begin
  prog_ctr = 16'b0;
  curr_instr = 16'b0;
    $readmemh("instruction_memory.txt",instr);
end


  always @(posedge rst) begin
  prog_ctr = 16'b0;
  curr_instr = 16'b0;
  end

  always @(posedge clk) begin
curr_instr[7:0] = instr[prog_ctr[15:0]];
     prog_ctr = prog_ctr+1;
curr_instr[15:8] = instr[prog_ctr[15:0]];
   prog_ctr = prog_ctr+1;
  end
endmodule 

The next instruction is fetched from the memory address that is currently stored in the program counter and stored in the instruction register. At the end of the fetch operation, the PC points to the next instruction that will be read at the next cycle. 

DECODE AND CONTROL UNIT:

module decode_control_unit(
                  input clk,rst,inuse1,inuse2,
  // input from the fetch unit
  input [15:0] curr_instr,
  
  // input provided from the register bank
  input[15:0] srcRegVal1,srcRegVal2,
  output reg [2:0] srcReg1,
  output reg [2:0] srcReg2,
  output reg [2:0] nextDestReg,
  output reg [3:0] opcode,
  output reg[2:0] destReg,
  output reg[15:0] srcVal1,srcVal2,
  output reg used1,used2,
  output reg [1:0] alu_control,
  output reg [1:0] control_op
  );
initial begin
  srcReg1 = 3'b0;
  srcReg2 = 3'b0;
  nextDestReg = 3'b0;
  opcode = 4'b0;
  destReg =3'b0;
  srcVal1 =16'b0;
  srcVal2 =16'b0;
  used1 =0;
  used2 =0;
    alu_control=2'b0;
  control_op=2'b0;
end
always @(posedge rst) begin
#2
      srcReg1 = 3'b0;
srcReg2 = 3'b0;
nextDestReg = 3'b0;
opcode = 4'b0;
destReg = 3'b0;
srcVal1 = 16'b0;
srcVal2 = 16'b0;
used1 = 0;
used2 = 0;
alu_control = 2'b0;
control_op =2'b0;
end
  
always @(posedge clk) begin
     opcode = curr_instr[3:0];  
     nextDestReg = curr_instr[6:4];
  destReg = curr_instr[6:4];
  srcReg1 = curr_instr[12:10];
  srcReg2 = curr_instr[9:7];
  alu_control = curr_instr[14:13];
 end

always @(srcRegVal1 or srcRegVal2 or inuse1 or inuse2) begin
srcVal1 = srcRegVal1;
srcVal2 = srcRegVal2;
used1   = inuse1;
used2   = inuse2;
control_op =alu_control[1:0];
end
endmodule

During this stage, the encoded instruction presented in the instruction register is interpreted by the decoder. In the case of a memory instruction, the execution phase will be during the next clock pulse. If the instruction has an indirect address, the effective address is read from the main memory, and any required data is fetched from main memory to be processed and then placed into data registers. If the instruction is direct, nothing is done during this clock pulse. If this is an I/O instruction or a register instruction, the operation is performed during the clock pulse.

REGISTER UNIT:

module Register_bank(
input clk,
input rst,

input[2:0] srcReg1,
input[2:0] srcReg2,
input[2:0] nextDestReg,
input [3:0] opcode,
input[2:0] destReg,
input[15:0] destVal,
input storeNow,
output reg storeDone,
output reg [15:0] srcRegVal1,srcRegVal2,
output reg inuse1,inuse2
);
reg [15:0] ime_data[7:0];
// Array of Registers 
reg[15:0] r[7:0];
reg inuse[7:0];

/*
For loop initialization
*/
integer i;

/*
Initialize all registers and inuse bits to 0.
*/
initial begin
for(i=0; i<8; i=i+1) begin
r[i] = 16'b0;
inuse[i]=1'b0;
end
      r[2]=16'd1;
r[1]=16'd10;
r[0]=16'd4;
r[5]=16'd5;
r[6]=16'd8;
srcRegVal1 = 16'b0;
srcRegVal2 = 16'b0;
inuse1 = 0;
inuse2 = 0;
storeDone = 0;
#2
   $display(" a=0x%0h b=0x%0h",r[2],r[3]);
end

/*
Initialize all registers and inuse bits to 0 on reset.
*/
always @(posedge rst) begin
for(i=0; i<8; i=i+1) begin
r[i] = 16'b0;
inuse[i] = 1'b0;
end

srcRegVal1 = 16'b0;
srcRegVal2 = 16'b0;
inuse1 = 0;
inuse2 = 0;
storeDone = 0;
end

/*
When any input changes, recompute outputs for 'Decode & Fetch Operand' stage
*/
always @(clk or srcReg1 or srcReg2 or nextDestReg or opcode) begin
  if(opcode == 4'b0001) begin
srcRegVal1 = r[srcReg1];
srcRegVal2 = r[srcReg2];
inuse1    = inuse[srcReg1];
inuse2    = inuse[srcReg2];
end
if(opcode == 4'b0010) begin
srcRegVal1 = ime_data[srcReg1];
srcRegVal2 = r[srcReg2];
inuse2   = inuse[srcReg2];
end
end

/*
Set inuse at posedge
*/
always @(posedge clk) begin
for(i=0;i<8;i=i+1)
inuse[i] = 1'b0;
inuse[nextDestReg] = 1'b1;
end

   always @(posedge storeNow) begin
storeDone = 0;
    r[destReg] = destVal;
storeDone = 1;
end

endmodule

The register file is a register bank that holds the data required for performing operations and also stores their result after execution.

EXECUTE AND WRITE BACK STAGE:


module execute_store( 
         input clk,rst,used1,used2,storeDone,
   input [1:0] control_op,
   input [2:0] destReg,
   input [15:0] srcVal1,
   input [15:0] srcVal2,
   output reg [2:0] destRegStore,
   output reg [15:0] destVal,
   output reg storeNow,
   output reg powerdown
);
         reg [15:0] LastComputedValue,val1,val2;
 initial begin
destRegStore =3'b0;
destVal =16'b0;
LastComputedValue =16'b0;
storeNow =0;
val1 =16'b0;
val2 =16'b0;
powerdown =0;
end

always @(posedge rst) begin
destRegStore = 3'b0;
destVal = 16'b0;
LastComputedValue = 16'b0;
storeNow = 0;
val1 = 16'b0;
val2 = 16'b0;
end
always @(posedge clk) begin
       storeNow = 0;
 
#1 if(used1)
val1 = LastComputedValue;
else
val1 = srcVal1;
                if(used2)
val2 = LastComputedValue;
else
val2 = srcVal2;
       #1 case(control_op)
      2'b00:begin 
            destVal = val1 + val2;
     end
      2'b01:begin
                            destVal = val1 - val2; 
                            end
                      2'b10:begin
                            destVal = val1 & val2; 
                            end
                      2'b11:begin
    destVal = val1 | val2; 
    end
      default: begin
              powerdown = 1;
                                end
           endcase
     
           destRegStore = destReg;
           storeNow = 1;
         #1 LastComputedValue = destVal;
end
endmodule

The control unit of the CPU passes the decoded information as a sequence of control signals to the relevant function units of the CPU to perform the actions required by the instruction, such as reading values from registers, passing them to the ALU to perform mathematical or logic functions on them, and writing the result back to a register. If the ALU is involved, it sends a condition signal back to the CU. The result generated by the operation is stored in the main memory or sent to an output device. Based on the feedback from the ALU, the PC may be updated to a different address from which the next instruction will be fetched.

MAIN MODULE:

module verilog_code(
            input clk,rest,
    output powerdown,
    output [15:0] prog_ctr
    );
reg [7:0] instr [255:0];
reg [15:0] ime_data[7:0];
wire[15:0]curr_instr,srcRegVal1,srcRegVal2,srcVal1,srcVal2,destVal;
wire[2:0] srcReg1,srcReg2,destReg,nextDestReg;
wire [3:0] opcode;
wire [1:0] alu_control,control_op;
 
initial begin
$readmemh("data_memory.txt",ime_data);
$readmemh("instruction_memory.txt",instr);
 
end
 
// Fetch stage 
   fetchInstruction I(clk,rst,prog_ctr,curr_instr);

   // Decode stage
decode_control_unit
 D(clk,rst,inuse1,inuse2,curr_instr,srcRegVal1,srcRegVal2,
srcReg1,srcReg2,nextDestReg,opcode,destReg,srcVal1,srcVal2,used1,used2,alu_control,control_op);
// Register File
   Register_bank R(clk,rst,
srcReg1,srcReg2,nextDestReg,opcode,
destReg,destVal,storeNow,storeDone,
srcRegVal1,srcRegVal2,inuse1,inuse2);
// Execute Stage
execute_store   E(clk,rst,used1,used2,storeDone,alu_control,destReg,srcVal1,srcVal2,destRegStore,destVal,storeNow,powerdown);
 
endmodule 


Simulational Results:
















Comments

  1. Wow great post keep it up

    ReplyDelete
  2. It is Hazards free code such WAW,RAW hazards etc...

    ReplyDelete
    Replies
    1. Yes I have solved RAW hazards which is most important and WAW hazards solve because it is inline pipeline.

      Delete
  3. Wow bro I have used it for my project of 5 stage pipeline actually pipeline means logic of always block only or any other for whole thing?

    ReplyDelete
    Replies
    1. Yes basically pipeline means always block is key block and in hardware wise it is register in between two pipeline.

      Delete
  4. When you put RISC-V processor verilog code please bro I have try lots but not understand.

    ReplyDelete
  5. i have used the code but i am not getting proper waveform i am getting clk and rst as z

    ReplyDelete

Post a Comment

Popular posts from this blog

SDC (Synopsys Design Constraints) contents part 4

Today, we will be discussing the remaining constraints mentioned in the SDC, which pertain to timing exceptions and design rules. This is the final part of the SDC contents. This is going to be interesting, especially with multicycle paths. Take time to read and try to comprehend. 10. set_max_transition     By setting max transition value, our design checks that all ports and pins are meeting the specified limits mentioned in SDC. If these are not satisfied then timing report will give DRVs (design rule violations) in terms of slack. This is specified as               set_max_transition 0.5  UBUF1/A setting maximum limit of 500ps on pin A of Buffer1. 11. set_max_capacitance     This is same as max transition, setting the maximum capacitance value. if our design not meeting this value then violation will occur. This will also reports under design rule violations in terms of slack.     set_max_capacitance 0.7 [all_...

Apprenticeship CAI at MediaTek Bangalore

Hello Dear Readers,   Currently at MediaTek Bangalore vacancy for an Apprenticeship CAI role. Job Description: B.Tech degree in Electrical/Electronics Engineering with a strong educational background in Digital circuit design Experience in physical design of high performance design with frequencies > 2 Ghz. Experienced in hierarchical design, budgeting, multiple voltage domains and multiple clock domains. Strong skills with Cadence Encounter. Solid understanding of STA and timing constraints. Experienced in working on advanced process nodes (16nm). Strong expertise in Physical Verification to debug LVS/DRC issues at the block level. Requirement: B.Tech degree in Electrical/Electronics Engineering with strong educational background in Digital circuit design Experience in physical design of high performance design with frequencies > 2 Ghz. Experienced in hierarchical design, budgeting, multiple voltage domains and multiple clock domains. Strong skills with Cadence Enc...

IC Physical Design (PnR) at Ulkasemi

Hello Dear Readers,   Ulkasemi  has a vacancy for an IC Physical Design (PnR) role. Job Overview: As a full-time Trainee Engineer, the individual will be working on IC Physical Design implementation from RTL to GDSII to create design databases ready for manufacturing with a special focus on power, performance & area optimization with next-generation state-of-the-art process technologies. Job Responsibilities: Perform physical design implementation which includes Floor planning, Power Planning, Clock Tree Synthesis, Place and Route, ECO, Logic Equivalence checks Timing analysis, physical & electrical verification, driving the sign-off closure meeting schedule, and design goals Develop flow, methodologies, and automation scripts for various implementation steps Follow the instructions, compile documents, prepare deliverables, and report to the team lead Should remain up to date with the latest technology trends Educational Qualification:   B.Sc/M.Sc   in EEE or...