Hello Dear Readers, Texas Instruments Bangalore has a vacancy for the Physical Design Engineer role. We need an Physical Design Methodology Engineer to join our ATD team. The candidate should have a strong background in back-end design of ASIC/SoC chips. The ideal candidate will have a bachelor’s or master’s degree in Electrical Engineering or a related field. Requirements: 1 - 2 Years of experience in physical design Bachelor’s or master’s degree in Electrical/Electronics Engineering or a related field Strong understanding of physical design principles Must know the basics of floorplan, placement, CTS, routing, ECO, Physical Verification Proficiency in back-end design tools, such as Cadence Genus/Innovus/Tempus/Voltus Excellent problem-solving skills and attention to detail Effective communication and collaboration skills Responsibilities: Synthesis to GDSII Perform full Physical design flow and its verification Work closely with Digital Design and DFT engineers Ensure...
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
Wow great post keep it up
ReplyDeleteIt is Hazards free code such WAW,RAW hazards etc...
ReplyDeleteYes I have solved RAW hazards which is most important and WAW hazards solve because it is inline pipeline.
DeleteWow 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?
ReplyDeleteYes basically pipeline means always block is key block and in hardware wise it is register in between two pipeline.
DeleteWhen you put RISC-V processor verilog code please bro I have try lots but not understand.
ReplyDeletei have used the code but i am not getting proper waveform i am getting clk and rst as z
ReplyDelete