**LAB 10 &11**
NAME- CH. PRANAV
ROLL- NO. CS22B014
Top Module
```verilog
module Top;
genvar genvar_i;
input [31:0] instruction_memory[0:255];
input [31:0] data_memory[0:255];
input [31:0] reg_file[0:31];
wire [31:0] PC = 32'h0;
input clk;
always @(posedge clk) begin
if (reset) begin
PC <= 32'h0;
end else begin
PC <= PC + 1;
end
end
always @(*) begin
wire [6:0] opcode;
wire [4:0] rd;
wire [4:0] rs1;
wire [4:0] rs2;
wire [6:0] fun7;
wire [11:0] immediate;
InstructionDecoder uut(instruction_memory[PC], opcode, rd, rs1, rs2, fun7, immediate);
RegisterRead uut1(reg_file, rs1, rs1_value);
RegisterRead uut2(reg_file, rs2, rs2_value);
wire [31:0] alu_output;
wire [31:0] loaded_val;
if (opcode == 7'b0001011) begin
ALU alu(rs1_value, immediate, opcode, alu_output);
MemoryRead mr(alu_output, 1'b1, data_memory, loaded_val);
RegisterWrite regwr(reg_file, rd, loaded_val, 1'b1);
end else if (opcode == 7'b0001100) begin
ALU alu(rs1_value, immediate, opcode, alu_output);
MemoryWrite memwr(rs2_value, alu_output, 1'b1, data_memory);
end else begin
RegisterWrite regwr(reg_file, rd, alu_output, 1'b1);
end
end
endmodule
```
ALU
```verilog=
module ALU(input [31:0] operand_a, input [31:0] operand_b, input [6:0] opcode, output reg [31:0] result);
wire [31:0] add_result, sub_result, xor_result, or_result, and_result, sll_result, srl_result, sra_result, slt_result, sltu_result, lw1_result, lw2_result;
add_32bit add_inst(.a(operand_a), .b(operand_b), .y(add_result));
sub_32bit sub_inst(.a(operand_a), .b(operand_b), .y(sub_result));
xor_32bit xor_inst(.a(operand_a), .b(operand_b), .y(xor_result));
or_32bit or_inst(.a(operand_a), .b(operand_b), .y(or_result));
and_32bit and_inst(.a(operand_a), .b(operand_b), .y(and_result));
sll_32bit sll_inst(.a(operand_a), .b(operand_b), .y(sll_result));
srl_32bit srl_inst(.a(operand_a), .b(operand_b), .y(srl_result));
sra_32bit sra_inst(.a(operand_a), .b(operand_b), .y(sra_result));
slt_32bit slt_inst(.a(operand_a), .b(operand_b), .y(slt_result));
sltu_32bit sltu_inst(.a(operand_a), .b(operand_b), .y(sltu_result));
lw lw1_inst(.rs(operand_a), .offset(operand_b), .y(lw1_result));
lw lw2_inst(.rs(operand_a), .offset(operand_b), .y(lw2_result));
always @(*) begin
integer i;
// Default output to all zeros
for (i = 0; i < 32; i = i + 1) begin
mux_16to1 mux_inst(
add_result[i], sub_result[i], xor_result[i], or_result[i],
sll_result[i], srl_result[i], add_result[i], sra_result[i],
slt_result[i], sltu_result[i], lw1_result[i], lw2_result[i],
opcode[3], opcode[2], opcode[1], opcode[0], result[i]
);
end
end
endmodule
```
Helper Modules
```verilog=
module not_32bit
(
input [31:0] a, ,
output [31:0] y
);
not a0(y[0], a[0]);
not a1(y[1], a[1]);
not a2(y[2], a[2]);
not a3(y[3], a[3]);
not a0(y[4], a[4]);
not a1(y[5], a[5]);
not a2(y[6], a[6]);
not a3(y[7], a[7]);
not a0(y[8], a[8]);
not a1(y[9], a[9]);
not a2(y[10], a[10]);
not a3(y[11], a[11]);
not a0(y[12], a[12]);
not a1(y[13], a[13]);
not a2(y[14], a[14]);
not a3(y[15], a[15]);
not a0(y[16], a[16]);
not a1(y[17], a[17]);
not a2(y[18], a[18]);
not a3(y[19], a[19]);
not a0(y[20], a[20]);
not a1(y[21], a[21]);
not a2(y[22], a[22]);
not a3(y[23], a[23]);
not a0(y[24], a[24]);
not a1(y[25], a[25]);
not a2(y[26], a[26]);
not a3(y[27], a[27]);
not a0(y[28], a[28]);
not a1(y[29], a[29]);
not a2(y[30], a[30]);
not a3(y[31], a[31]);
endmodule
module or_32bit
(
input [31:0] a, b,
output [31:0] y
);
or a0(y[0], a[0], b[0]);
or a1(y[1], a[1], b[1]);
or a2(y[2], a[2], b[2]);
or a3(y[3], a[3], b[3]);
or a0(y[4], a[4], b[4]);
or a1(y[5], a[5], b[5]);
or a2(y[6], a[6], b[6]);
or a3(y[7], a[7], b[7]);
or a0(y[8], a[8], b[8]);
or a1(y[9], a[9], b[9]);
or a2(y[10], a[10], b[10]);
or a3(y[11], a[11], b[11]);
or a0(y[12], a[12], b[12]);
or a1(y[13], a[13], b[13]);
or a2(y[14], a[14], b[14]);
or a3(y[15], a[15], b[15]);
or a0(y[16], a[16], b[16]);
or a1(y[17], a[17], b[17]);
or a2(y[18], a[18], b[18]);
or a3(y[19], a[19], b[19]);
or a0(y[20], a[20], b[20]);
or a1(y[21], a[21], b[21]);
or a2(y[22], a[22], b[22]);
or a3(y[23], a[23], b[23]);
or a0(y[24], a[24], b[24]);
or a1(y[25], a[25], b[25]);
or a2(y[26], a[26], b[26]);
or a3(y[27], a[27], b[27]);
or a0(y[28], a[28], b[28]);
or a1(y[29], a[29], b[29]);
or a2(y[30], a[30], b[30]);
or a3(y[31], a[31], b[31]);
endmodule
module and_32bit
(
input [31:0] a, b,
output [31:0] y
);
and a0(y[0], a[0], b[0]);
and a1(y[1], a[1], b[1]);
and a2(y[2], a[2], b[2]);
and a3(y[3], a[3], b[3]);
and a0(y[4], a[4], b[4]);
and a1(y[5], a[5], b[5]);
and a2(y[6], a[6], b[6]);
and a3(y[7], a[7], b[7]);
and a0(y[8], a[8], b[8]);
and a1(y[9], a[9], b[9]);
and a2(y[10], a[10], b[10]);
and a3(y[11], a[11], b[11]);
and a0(y[12], a[12], b[12]);
and a1(y[13], a[13], b[13]);
and a2(y[14], a[14], b[14]);
and a3(y[15], a[15], b[15]);
and a0(y[16], a[16], b[16]);
and a1(y[17], a[17], b[17]);
and a2(y[18], a[18], b[18]);
and a3(y[19], a[19], b[19]);
and a0(y[20], a[20], b[20]);
and a1(y[21], a[21], b[21]);
and a2(y[22], a[22], b[22]);
and a3(y[23], a[23], b[23]);
and a0(y[24], a[24], b[24]);
and a1(y[25], a[25], b[25]);
and a2(y[26], a[26], b[26]);
and a3(y[27], a[27], b[27]);
and a0(y[28], a[28], b[28]);
and a1(y[29], a[29], b[29]);
and a2(y[30], a[30], b[30]);
and a3(y[31], a[31], b[31]);
endmodule
module xor_32bit
(
input [31:0] a, b,
output [31:0] y
);
xor a0(y[0], a[0], b[0]);
xor a1(y[1], a[1], b[1]);
xor a2(y[2], a[2], b[2]);
xor a3(y[3], a[3], b[3]);
xor a0(y[4], a[4], b[4]);
xor a1(y[5], a[5], b[5]);
xor a2(y[6], a[6], b[6]);
xor a3(y[7], a[7], b[7]);
xor a0(y[8], a[8], b[8]);
xor a1(y[9], a[9], b[9]);
xor a2(y[10], a[10], b[10]);
xor a3(y[11], a[11], b[11]);
xor a0(y[12], a[12], b[12]);
xor a1(y[13], a[13], b[13]);
xor a2(y[14], a[14], b[14]);
xor a3(y[15], a[15], b[15]);
xor a0(y[16], a[16], b[16]);
xor a1(y[17], a[17], b[17]);
xor a2(y[18], a[18], b[18]);
xor a3(y[19], a[19], b[19]);
xor a0(y[20], a[20], b[20]);
xor a1(y[21], a[21], b[21]);
xor a2(y[22], a[22], b[22]);
xor a3(y[23], a[23], b[23]);
xor a0(y[24], a[24], b[24]);
xor a1(y[25], a[25], b[25]);
xor a2(y[26], a[26], b[26]);
xor a3(y[27], a[27], b[27]);
xor a0(y[28], a[28], b[28]);
xor a1(y[29], a[29], b[29]);
xor a2(y[30], a[30], b[30]);
xor a3(y[31], a[31], b[31]);
endmodule
module lw (
input [31:0] rs,
input [31:0] offset,
output [31:0] y
);
wire cout;
add_32bit uut(rs,offset,0,y,cout);
endmodule
//ripplecarryadder
module add_32bit(input [31:0]a,b, input cin, output [31:0]sum,output c32);
wire c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c189,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31;
full_adder fa0(a[0],b[0],cin,sum[0],c1);
full_adder fa1(a[1],b[1],c1,sum[1],c2);
full_adder fa2(a[2],b[2],c2,sum[2],c3);
full_adder fa3(a[3],b[3],c3,sum[3],c4);
full_adder fa4(a[4],b[4],c4,sum[4],c5);
full_adder fa5(a[5],b[5],c5,sum[5],c6);
full_adder fa6(a[6],b[6],c6,sum[6],c7);
full_adder fa7(a[7],b[7],c7,sum[7],c8);
full_adder fa8(a[8],b[8],c8,sum[8],c9);
full_adder fa9(a[9],b[9],c9,sum[9],c10);
full_adder fa10(a[10],b[10],c10,sum[10],c11);
full_adder fa11(a[11],b[11],c11,sum[11],c12);
full_adder fa12(a[12],b[12],c12,sum[12],c13);
full_adder fa13(a[13],b[13],c13,sum[13],c14);
full_adder fa14(a[14],b[14],c14,sum[14],c15);
full_adder fa15(a[15],b[15],c15,sum[15],c16);
full_adder fa16(a[16],b[16],c16,sum[16],c17);
full_adder fa17(a[17],b[17],c17,sum[17],c18);
full_adder fa18(a[18],b[18],c18,sum[18],c19);
full_adder fa19(a[19],b[19],c19,sum[19],c20);
full_adder fa20(a[20],b[20],c20,sum[20],c21);
full_adder fa21(a[21],b[21],c21,sum[21],c22);
full_adder fa22(a[22],b[22],c22,sum[22],c23);
full_adder fa23(a[23],b[23],c23,sum[23],c24);
full_adder fa24(a[24],b[24],c24,sum[24],c25);
full_adder fa25(a[25],b[25],c25,sum[25],c26);
full_adder fa26(a[26],b[26],c26,sum[26],c27);
full_adder fa27(a[27],b[27],c27,sum[27],c28);
full_adder fa28(a[28],b[28],c28,sum[28],c29);
full_adder fa29(a[29],b[29],c29,sum[29],c30);
full_adder fa30(a[30],b[30],c30,sum[30],c31);
full_adder fa31(a[31],b[31],c31,sum[31],c32);
endmodule
module sll_32bit (
input [31:0] a, // Input A
input [31:0] b, // Input B (shift amount)
output [31:0] y // Output Y (result of shift)
);
assign y = a << b; // Perform left logical shift
endmodule
module srl_32bit (
input [31:0] a, // Input A
input [31:0] b, // Input B (shift amount)
output [31:0] y // Output Y (result of shift)
);
assign y = a >> b; // Perform right logical shift
endmodule
module sra_32bit (
input [31:0] a, // Input A
input [31:0] b, // Input B (shift amount)
output [31:0] y // Output Y (result of shift)
);
assign y = a >>> b; // Perform right arithmetic shift
endmodule
module slt_32bit (
input [31:0] a, // Input A
input [31:0] b, // Input B
output y // Output Y (result of comparison)
);
assign y = (a < b) ? 1'b1 : 1'b0; // Perform signed less than comparison
endmodule
module slt_32bit (
input [31:0] a, // Input A
input [31:0] b, // Input B
output y // Output Y (result of comparison)
);
assign y = (a < b) ? 1'b1 : 1'b0; // Perform signed less than comparison
endmodule
module sub_32bit(
input [31:0] a,
input [31:0] b,
output [31:0] sum,
output c32
);
wire [31:0]w1;
not_32bit Notification(b,w1);
// Instantiate the ripple carry adder module
ripplecarryadder ripple_carry_adder_inst (
.a(a),
.b(w1),
.cin(1'b1),
.sum(sum),
.c32(c32)
);
endmodule
//fulladder
module FullAdder(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
wire s0,c1;
wire c2;
HalfAdder ha0(.a(a),.b(b),.sum(s0),.cout(c1));
HalfAdder ha1(.a(cin),.b(s0),.sum(sum),.cout(c2));
assign cout = c1 | c2 ;
endmodule
//halfadder
module HalfAdder(a,b,sum,cout);
input a,b;
output sum,cout;
assign sum = a^ b;
assign cout = a & b;
endmodule
```
MUX
```verilog=
module mux_16to1 (
input sum_in, diff_in, xor_in, or_in, and_in, sll_in, srl_in, sra_in, slt_in, sltu_in, lw_in, sw_in,
input select1, select2, select3, select4,
output reg data_out
);
always @(*) begin
data_out = (select1 & select2 & select3 & select4 & 0) |
(select1 & select2 & select3 & ~select4 & 0) |
(select1 & select2 & ~select3 & select4 & 0) |
(select1 & select2 & ~select3 & ~select4 & 0) |
(select1 & ~select2 & select3 & select4 & sw_in) |
(select1 & ~select2 & select3 & ~select4 & lw_in) |
(select1 & ~select2 & ~select3 & select4 & sltu_in) |
(select1 & ~select2 & ~select3 & ~select4 & slt_in) |
(~select1 & select2 & select3 & select4 & sra_in) |
(~select1 & select2 & select3 & ~select4 & srl_in) |
(~select1 & select2 & ~select3 & select4 & sll_in) |
(~select1 & select2 & ~select3 & ~select4 & and_in) |
(~select1 & ~select2 & select3 & select4 & or_in) |
(~select1 & ~select2 & select3 & ~select4 & xor_in) |
(~select1 & ~select2 & ~select3 & select4 & diff_in) |
(~select1 & ~select2 & ~select3 & ~select4 & sum_in);
end
endmodule
```
Modules in data path and control
```verilog=
module InstructionDecoder (
input wire [31:0] instruction, // Input: 32-bit instruction
output reg [6:0] opcode, // Output: Opcode field (7 bits)
output reg [4:0] rd, // Output: Destination register field (5 bits)
output reg [4:0] rs1, // Output: Source register 1 field (5 bits)
output reg [4:0] rs2, // Output: Source register 2 field (5 bits)
output reg [6:0] fun7, // Output: Fun7 field (7 bits)
output reg [11:0] immediate // Output: Immediate value (12 bits)
);
// Define opcode values
parameter OPCODE_D11 = 7'b0001011; // Opcode value for decimal 11
parameter OPCODE_12 = 7'000b1100; // Opcode value for decimal 12
// Decode instruction fields
always @(*) begin
opcode = instruction[6:0]; // Extract opcode field (bits 6-0)
rd = instruction[11:7]; // Extract rd field (bits 11-7)
rs1 = instruction[19:15]; // Extract rs1 field (bits 19-15)
rs2 = instruction[24:20]; // Extract rs2 field (bits 24-20)
fun7 = instruction[31:25]; // Extract fun7 field (bits 31-25)
// Check if opcode is 'd11'
if (opcode == OPCODE_D11) begin
// Concatenate rs2 and fun7 bits to form immediate value
immediate = {rs2, fun7};
end else if (opcode == OPCODE_12) begin
// Concatenate rd and fun7 bits to form immediate value
immediate = {rd, fun7};
end else begin
// If opcode does not match, set immediate to 0
immediate = 12'b0;
end
end
endmodule
```
```verilog=
module MemoryWrite (
input [31:0] data_in, // Data to write to memory
input [9:0] address, // Address to write to in memory
input write_enable, // Write enable signal
output reg [31:0] memory [0:255] // Memory array
);
// Write to memory if write_enable is asserted
always @* begin
if (write_enable) begin
memory[address] <= data_in;
end
end
endmodule
```
```verilog=
module RegisterWrite (
input [31:0] registers [0:31], // Array of 32 registers
input [4:0] write_address, // Write address
input [31:0] write_data, // Data to write
input write_enable // Write enable signal
);
// Write to register if write_enable is asserted
always @(posedge clk) begin
if (write_enable) begin
registers[write_address] <= write_data;
end
end
endmodule
```
```verilog=
module ProgramCounter (
input wire clk, // Clock input
input wire reset, // Reset input
output reg [31:0] pc_output // Output: Program Counter (PC)
);
// Define the Program Counter (PC) register
reg [31:0] pc;
// Increment PC on every clock cycle
always @(posedge clk or posedge reset) begin
if (reset)
pc <= 0; // Reset PC to initial value
else
pc <= pc + 1; // Increment PC
end
// Output the PC value
assign pc_output = pc;
endmodule
```
```verilog=
module MemoryRead (
input [9:0] address, // Address to read from in memory
input read_enable, // Read enable signal
input [31:0] memory [0:255], // Memory array
output reg [31:0] data_out // Data read from memory
);
// Read from memory if read_enable is asserted
always @* begin
if (read_enable) begin
data_out = memory[address];
end
end
endmodule
```
```verilog=
module RegisterRead (
input [31:0] registers [0:31], // Array of 32 registers
input [4:0] read_address, // Read address
output reg [31:0] read_data // Output data read from register
);
// Read data from register
always @* begin
read_data = registers[read_address];
end
endmodule
```