# Lab 10-11 Name: G Jaswanth Roll No.: CS22B020 --- ## TopModule ```verilog= module Top; 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]a,input [31:0]b,input [6:0]opcode,output reg [31:0]out); //assuming inputs-7 bit size wire [31:0]w1,w2,w3,w4,w5,w6,w8,w9,w10,w11,w12,w7; add_32bit a1(.a(a),.b(b),.y(w1)); sub_32bit a2(.a(a),.b(b),.y(w2)); xor_32bit a3(.a(a),.b(b),.y(w3)); or_32bit a4(.a(a),.b(b),.y(w4)); and_32bit a5(.a(a),.b(b),.y(w5)); sll_32bit a6(.a(a),.b(b),.y(w6)); srl_32bit a7(.a(a),.b(b),.y(w7)); sra_32bit a8(.a(a),.b(b),.y(w8)); slt_32bit a9(.a(a),.b(b),.y(w9)); sltu_32bit a10(.a(a),.b(b),.y(w10)); lw a11(.rs(a),.offset(b),.y(w11)); lw a12(.rs(a),.offset(b),.y(w12)); always @(*) begin integer i; // Default output to all zeros for (i = 0; i < 32; i = i + 1) begin mux_16to1 ma(w1[i],w2[i],w3[i],w4[i],w6[i],w7[i],w1[i],w8[i],w9[i],w10[i],w11[i],w12[i],opcode[3],opcode[2],opcode[1],opcode[0],out[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, diff, xor, or , and , sll , srl , sra , slt, sltu , lw ,sw , input s1, s2, s3, s4, output reg data_out); always @(*) begin data_out = (s1 & s2 & s3 & s4 & 0) | (s1 & s2 & s3 & ~s4 & 0) | (s1 & s2 & ~s3 & s4 & 0) | (s1 & s2 & ~s3 & ~s4 & 0) | (s1 & ~s2 & s3 & s4 & sw) | (s1 & ~s2 & s3 & ~s4 & lw) | (s1 & ~s2 & ~s3 & s4 & sltu) | (s1 & ~s2 & ~s3 & ~s4 & slt) | (~s1 & s2 & s3 & s4 & sra) | (~s1 & s2 & s3 & ~s4 & srl) | (~s1 & s2 & ~s3 & s4 & sll) | (~s1 & s2 & ~s3 & ~s4 & and) | (~s1 & ~s2 & s3 & s4 & or) | (~s1 & ~s2 & s3 & ~s4 & xor) | (~s1 & ~s2 & ~s3 & s4 & diff) | (~s1 & ~s2 & ~s3 & ~s4 & sum); end endmodule ``` --- ## Modules in datapath & 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 ``` ---