677adcef63409CA Lab12 Fall2024
677adcef63409CA Lab12 Fall2024
Project Report
Marks Obtained
1|Page
Fall 2024 CA Lab-Project
2|Page
Fall 2024 CA Lab-Project
Introduction
Single Cycle Processor
A RISC-V single cycle processor is a fundamental implementation of the RISC-V instruction
set architecture (ISA), designed to execute one instruction per clock cycle. It serves as a
simple yet effective model to understand the principles of computer architecture and processor
design. The processor executes instructions such as arithmetic operations, memory access, and
control flow in a single clock cycle by coordinating various components, including the
instruction memory, data memory, registers, and an arithmetic logic unit (ALU).
Key features of a single-cycle RISC-V processor include a straightforward control unit, which
manages instruction decoding and execution, and a data path that efficiently handles data
movement and computations. While this design is easy to implement and comprehend, it is
not optimized for performance, as the cycle time is determined by the slowest instruction.
Despite this limitation, the RISC-V single cycle processor remains an essential building block
for learning about more advanced pipelined or multicycle processor designs.
3|Page
Fall 2024 CA Lab-Project
4|Page
Fall 2024 CA Lab-Project
1. Program Counter:
The Program Counter (PC) is a key component of a processor that
holds the address of the next instruction to be executed. In a single
cycle processor, the PC is updated once every clock cycle to fetch the
next instruction from instruction memory.This ensures that instructions
are executed sequentially unless altered by control instructions like
branches or jumps.
Working:
Instruction Fetch: At the start of each cycle, the PC provides the
address to fetch the current instruction from the instruction memory.
Increment or Branch: After the instruction is fetched, the PC is
updated when incremented by 4 for sequential execution or updated
with a branch or jump address if a control instruction requires a
change in program flow.
Diagram:
Verilog Code:
// PC_Counter
module pc(clk, reset, PC_inp, PC_out);
input clk, reset;
input [31:0] PC_inp;
output reg [31:0] PC_out;
5|Page
Fall 2024 CA Lab-Project
Waveform:
2. Instruction Memory
The Instruction Memory is a component that stores the program's instructions, which the
processor executes. It is typically read-only during execution and contains the machine code
of the program.
Working:
6|Page
Fall 2024 CA Lab-Project
Diagram:
Verilog Code:
// Instruction Memory
module ins_mem(clk, reset, ReadPC, Instruction_out);
input clk, reset;
input [31:0] ReadPC;
output [31:0] Instruction_out;
reg [31:0] mem [127:0];
integer i;
assign Instruction_out = mem[ReadPC];
always @(posedge clk or posedge reset) begin
if (reset) begin
for (i = 0; i < 64; i = i + 1) begin
mem[i] = 32'b00;end
end else begin
// r-type
mem[0] =
32'b00000000000000000000000000000000; // no
operations
mem[4] =
32'b0000000_11001_10000_000_01101_0110011; //
add x13, x16, x25
7|Page
Fall 2024 CA Lab-Project
mem[8] =
32'b0100000_00011_01000_000_00101_0110011; //
sub x5, x8, x3
mem[12] =
32'b0000000_00011_00010_111_00001_0110011; //
and x1, x2, x3
mem[16] =
32'b0000000_00101_00011_110_00100_0110011; // or
x4, x3, x5
mem[20] =
32'b0000000_00011_00010_100_00001_0110011; //
xor x1, x2, x3
mem[24] =
32'b0000000_00101_00010_001_00001_0110011; //sll
x1, x2, x5
mem[28] =
32'b0000000_01000_00101_010_00011_0110011; //stl
x3, x5, x8
mem[32] =
32'b0000000_00101_01000_011_00011_0110011; //stlu
x3, x8, x4
mem[36] =
32'b0000000_00111_00110_101_00101_0110011; // srl
x5, x6, x7
// i_type
mem[36] =
32'b000000000011_10101_000_10110_0010011; //
addi x22, x21, 3
mem[40] =
32'b000000000001_01000_110_01001_0010011; // ori
x9, x8, 1
8|Page
Fall 2024 CA Lab-Project
mem[44] =
32'b000000001001_01000_111_01001_0010011; //
andi x7, x6, 7
mem[48] =
32'b000000000101_00011_100_01001_0010011; // xori
x8,x7,5
mem[52] =
32'b000000000111_00101_001_01001_0010011; // slli
x8,x7,7
mem[56] =
32'b000000000001_00111_010_01001_0010011; // stli
x8,x7,1
mem[60] =
32'b000000000001_00111_011_01001_0010011; // stli
x8,x7,1 signed
mem[64] =
32'b000000000001_00111_101_01001_0010011; // srl
x8,x7,1
mem[68] =
32'b010000000001_00111_101_01001_0010011; //srai
x8,x7,1 arithmetic
// l_type
mem[72] =
32'b000000001111_00101_010_01000_0000011; // lw
x8, 15(x5)
mem[76] =
32'b000000000011_00011_010_01001_0000011; // lw
x9, 3(x3)
// s-type
9|Page
Fall 2024 CA Lab-Project
mem[80] =
32'b0000000_01111_00101_010_01100_0100011; // sw
x15, 12(x5)
mem[84] =
32'b0000000_01110_00110_010_01010_0100011; // sw
x14, 10(x6)
//Branch
mem[88] =
32'b0000010_00101_00111_000_01100_1100011; //beq
// SB-type
// mem[92] = 32'h00948663; // beq x9, x9, 12
end
end
endmodule
Waveform
· Read Register 1: Specifies the address of the first source register to read.
· Read Register 2: Specifies the address of the second source register to
read.
· Write Register: Specifies the address of the destination register to write
data to.
· Read Data 1: Outputs the data stored in the first source register.
· Read Data 2: Outputs the data stored in the second source register.
10 | P a g e
Fall 2024 CA Lab-Project
· Write Data: Receives the data to be written into the destination register.
· Register Write Signal: A control signal that enables writing data to a
register.
Diagram:
Verilog Code:
// Register File
module reg_file(clk, reset, Reg_write, Rs1, Rs2, Rd,
Write_data, Read_data1, Read_data2);
input clk, reset, Reg_write;
input [19:15] Rs1;
input [24:20] Rs2;
input [11:7] Rd;
input [31:0] Write_data;
output [31:0] Read_data1, Read_data2;
Register[1] = 4;
Register[2] = 2;
Register[3] = 24;
Register[4] = 4;
Register[5] = 1;
Register[6] = 44;
Register[7] = 4;
Register[8] = 2;
Register[9] = 1;
Register[10] = 23;
Register[11] = 4;
Register[12] = 90;
Register[13] = 10;
Register[14] = 20;
Register[15] = 30;
Register[16] = 40;
Register[17] = 50;
Register[18] = 60;
Register[19] = 70;
Register[20] = 80;
Register[21] = 80;
Register[22] = 90;
Register[23] = 70;
Register[24] = 60;
Register[25] = 65;
Register[26] = 4;
Register[27] = 32;
Register[28] = 12;
Register[29] = 34;
Register[30] = 5;
Register[31] = 10;
if (reset) begin
12 | P a g e
Fall 2024 CA Lab-Project
Waveform
4. Immediate Generator
The Immediate Generator is a component that extracts and extends immediate values from
instruction fields in RISC-V.
Working:
1. Extraction: It takes specific bits from an instruction (e.g.,
immediate fields) based on the instruction type (I-type, S-type, B-
type, etc.).
2. Sign Extension: The extracted bits are sign-extended to 32 bits,
ensuring compatibility with the 32-bit data path.
Diagram:
13 | P a g e
Fall 2024 CA Lab-Project
Verilog Code:
// Immediate Generator
module imm_gen(opcode, instruction, immext);
input [6:0] opcode;
input [31:0] instruction;
output reg [31:0] immext;
always @(*) begin
case (opcode)
7'b0010011:immext<={{20{instruction[31]}},instruction[3
1:20]};//i type
7'b0000011:immext<= {{20{instruction[31]}},
instruction[31:20]};// l type
7'b0100011:immext <= {{20{instruction[31]}},
instruction[31:25], instruction[11:7]};//store type
7'b1100011: immext <= {{19{instruction[31]}},
instruction[31], instruction[30:25], instruction[11:8],
1'b0};//Branch
7'b0110111: immext <= {instruction[31:12], 12'b0};//U
type
7'b0010111: immext <= {instruction[31:12], 12'b0};//U
type
7'b1101111: immext <= {{11{instruction[31]}},
instruction[19:12], instruction[20], instruction[30:21],
1'b0};
default : immext = 32'b0;
endcase
end
14 | P a g e
Fall 2024 CA Lab-Project
endmodule
Waveform
5.ALU
An arithmetic Logic Unit (ALU) is a combinational logic digital circuit
that performs arithmetic operations (Addition, Subtraction,
Multiplication, Division) and logical operations (AND, OR, NAND,
NOR, XOR, XNOR, and many more). ALU is also referred as the
brain of a processor.
Diagram:
ALU
Functions Name
controls lines
0000 and AND
0001 or OR
Verilog Code:
// ALU
16 | P a g e
Fall 2024 CA Lab-Project
zero = 0;
end
endmodule
Waveform:
I- ALU Control
The ALU Control module is a crucial component in the design of an Arithmetic Logic Unit
(ALU) within a processor architecture. The ALU Control interprets control signals from the
instruction decoder to determine which arithmetic or logical operation the ALU should
perform. This allows the ALU to execute a wide range of instructions, from basic arithmetic
(like addition and subtraction) to bitwise operations (like AND, OR, and XOR). By processing
inputs such as aluOP, funct3 and funct7, the ALU Control can dynamically configure the
ALU to handle different operations based on the instruction set architecture (ISA). This
adaptability is essential for executing various types of instructions in a processor.
ALUop
ALU Operation func7[30] func3[14:12] Control Output
(2 bits)
AND 00 0 000 0000
OR 00 0 001 0001
Diagram:
Verilog Code:
module AluControl (
input [1:0] AlUOp, // ALU operation from
Control Unit
input func7, // Bit 30 of instruction
(funct7[5])
input [2:0] func3, // Bits [14:12] of instruction
(funct3)
output reg [3:0] Control_out // ALU control signal
);
always @(*) begin
case (AlUOp)
2'b00: Control_out = 4'b0010; // Load/Store:
ADD
2'b01: Control_out = 4'b0110; // Branch: SUB
2'b10: begin // R-type instructions
case ({func7, func3})
4'b0000: Control_out = 4'b0010; // ADD....
4'b1000: Control_out = 4'b0110; // SUB....
4'b0111: Control_out = 4'b0000; // AND....
18 | P a g e
Fall 2024 CA Lab-Project
Waveform:
6.Control Unit
A control unit is responsible for generating signals that guide the operation of
various components in a processor. In a single-cycle processor, each instruction
is executed in one clock cycle, so the control signals must be generated correctly
for each instruction type (e.g., R-type, I-type, Load, Store, Branch, etc.) in
RISC-V. Following are components of control unit:
The input to the control unit is the 7-bit opcode field from the
instruction.
The outputs of the control unit consist of two 1-bit signals that are
used to control multiplexors (ALUSrc and MemtoReg).
Three signals for controlling reads and writes in the register file and
data memory (RegWrite, MemRead, and MemWrite).
19 | P a g e
Fall 2024 CA Lab-Project
Diagram:
20 | P a g e
Fall 2024 CA Lab-Project
Verilog Code:
// Control Unit
module Control_Unit(reset, instruction, Branch,
MemRead, MemtoReg, ALUOp, MemWrite, ALUSrc,
RegWrite);
input reset;
input [6:0] instruction;
output reg Branch, MemRead, MemtoReg,
MemWrite, ALUSrc, RegWrite;
output reg [1:0] ALUOp;
always @(*) begin
if (reset) begin
ALUSrc <= 0; MemtoReg <= 0; RegWrite <= 0;
MemRead <= 0; MemWrite <= 0; Branch <= 0; ALUOp
<= 2'b00;
end
else begin
case (instruction)
7'b0110011: {ALUSrc, MemtoReg, RegWrite,
MemRead, MemWrite, Branch, ALUOp} <=
8'b001000_10; // R-Type
21 | P a g e
Fall 2024 CA Lab-Project
Waveform:
7.Data Memory
Data Memory on the other hand, is a read-write memory that stores variable data
manipulated during program execution. It allows for both storage and retrieval operations,
essential for tasks such as storing intermediate results and processing data.
Diagram:
22 | P a g e
Fall 2024 CA Lab-Project
Verilog Code:
// Data Memory
module data_mem(clk, reset, MemRead, MemWrite,
read_Address, Write_data, mem_data);
input clk, reset, MemRead, MemWrite;
input [31:0] read_Address, Write_data;
output [31:0] mem_data;
reg [31:0] mem [127:0];
integer i;
always @ (posedge clk or posedge reset) begin
mem[0] = 0;
mem[1] = 4;
mem[2] = 2;
mem[3] = 24;
mem[4] = 4;
mem[5] = 1;
mem[6] = 44;
mem[7] = 4;
mem[8] = 2;
mem[9] = 1;
mem[10] = 23;
23 | P a g e
Fall 2024 CA Lab-Project
mem[11] = 4;
mem[12] = 90;
mem[13] = 10;
mem[14] = 20;
mem[15] = 30;
mem[16] = 40;
mem[17] = 50;
mem[18] = 60;
mem[19] = 70;
mem[20] = 80;
mem[21] = 80;
mem[22] = 90;
mem[23] = 70;
mem[24] = 60;
mem[25] = 65;
mem[26] = 4;
mem[27] = 32;
mem[28] = 12;
mem[29] = 34;
mem[30] = 5;
mem[31] = 10;
if (reset) begin
for (i = 0; i < 128; i = i + 1) begin
mem[i] <= 32'b00;
end
end
else if (MemWrite) begin
mem[read_Address] <= Write_data;
end
end
assign mem_data = (MemRead) ?
mem[read_Address] : 32'b00;
24 | P a g e
Fall 2024 CA Lab-Project
endmodule
Waveform:
25 | P a g e
Fall 2024 CA Lab-Project
Diagram:
Verilog Code:
// Multiplexers
// mux1
module mux1(sel1, A1, B1, mux1_out);
input [31:0] A1, B1;
input sel1;
26 | P a g e
Fall 2024 CA Lab-Project
27 | P a g e
Fall 2024 CA Lab-Project
28 | P a g e
Fall 2024 CA Lab-Project
immediate(.opcode(inst_top[6:0]), .instruction(inst_top)
, .immext(immgext_top));
// Control Unit
Control_Unit
control_Unit(.reset(reset), .instruction(inst_top[6:0]), .B
ranch(branch_top), .MemRead(memread_top), .Memto
Reg(memtoreg_top), .ALUOp(aluop_top), .MemWrite(m
emwrite_top), .ALUSrc(alusrc_top), .RegWrite(regwrite
_top));
// ALU Control
AluControl
alu_control(.func7(inst_top[30]), .func3(inst_top[14:12]
), .AlUOp(aluop_top), .Control_out(control_top));
// ALU
Alu_unit
ALU_UNIT(.a(Rd1_top), .b(mux1_top), .Control_in(contr
ol_top), .zero(zero_top), .AluResult(address_top));
// ALU Multiplexer
mux1
alumux1(.sel1(alusrc_top), .A1(Rd2_top), .B1(immgext_
top), .mux1_out(mux1_top));
// Adder
simple_adder
adder(.in_1(nextopc_top), .in_2(address_top), .sum_out(
sum_out_top));
// Branch Logic
and_logic
branch_logic(.branch(branch_top), .zero(zero_top), .and
_out(andout_top));
// Data Memory
data_mem
29 | P a g e
Fall 2024 CA Lab-Project
// Multiplexers for PC
mux2
mux2_PC(.sel2(andout_top), .A2(nextopc_top), .B2(sum
_out_top), .mux2_out(mux2out_top));
// Writeback
mux3
mux3_Writeback(.sel3(memtoreg_top), .A3(address_top
), .B3(memdata_top), .mux3_out(writeback_top));
endmodule
Waveform
RISCV Instructions
Instruction Format
30 | P a g e
Fall 2024 CA Lab-Project
i. R -type
R-type instructions are computational instructions in the RISC-V ISA
that perform operations between two registers (e.g., addition,
subtraction, or logical operations). They use three register fields: two
for source operands and one for the destination, and rely on the ALU
for execution.
31 | P a g e
Fall 2024 CA Lab-Project
Waveform:
I. I.Add
II. Sub
III. And
IV. Or
V. Xor
VI. Sll
VII. Stl
VIII. Stlu
IX. Srl
ii. I -type
I-Addi
II-Ori
III-Andi
IV-Xori
V-Slli
32 | P a g e
Fall 2024 CA Lab-Project
VI-Stli
VII-Srli
VIII-Srl
IX-Srai
iii. l -type
In RISC-V, L-type instructions are typically load instructions used to transfer data from
memory to a register. They specify a base address in a register and an immediate offset to
calculate the memory address for the load operation.
Lw
iv. S -type
S-type instructions in RISC-V are used for store operations, where data from a
register is written to memory. They include fields for a base address register, a
source register containing the data, and an immediate offset to calculate the
memory address.
Results of S-type isntruction
Sw
v. B -type
B-type instructions in RISC-V are branch instructions used for
conditional jumps based on comparisons. They specify two registers
for comparison and a signed immediate value to calculate the target
address if the branch condition is true.
33 | P a g e
Fall 2024 CA Lab-Project
Beq
Conclusion:
34 | P a g e
Fall 2024 CA Lab-Project
35 | P a g e
Fall 2024 CA Lab-Project
36 | P a g e
Fall 2024 CA Lab-Project
37 | P a g e