# Lab 10 & 11 **Name:** *M Akash* **Roll No.:** *CS22B037* --- ## Lab 10 [ALU] **Code** ```verilog= module FullAdder(input a, b, cin, output sum, cout); assign sum = a^b^cin; assign cout = (a&b) | (b&cin) | (a&cin); endmodule module RippleCarryAdder(input [31:0]a, b, input cin, output [31:0]sum, output cout); wire [31:0]carry; genvar i; generate for (i = 0; i < 32; i = i + 1) begin : adder_loop if (i == 0) begin FullAdder fa(a[i], b[i], cin, sum[i], carry[i]); end else if (i < 31) begin FullAdder fa(a[i], b[i], carry[i-1], sum[i], carry[i]); end else begin FullAdder fa(a[i], b[i], carry[i-1], sum[i], cout); end end endgenerate endmodule module Mux16to1( input [31:0] in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, input [3:0] select, output reg [31:0] out ); always @(*) begin out = (in0 & ({32{~select[3] & ~select[2] & ~select[1] & ~select[0]}})) | (in1 & ({32{~select[3] & ~select[2] & ~select[1] & select[0]}})) | (in2 & ({32{~select[3] & ~select[2] & select[1] & ~select[0]}})) | (in3 & ({32{~select[3] & ~select[2] & select[1] & select[0]}})) | (in4 & ({32{~select[3] & select[2] & ~select[1] & ~select[0]}})) | (in5 & ({32{~select[3] & select[2] & ~select[1] & select[0]}})) | (in6 & ({32{~select[3] & select[2] & select[1] & ~select[0]}})) | (in7 & ({32{~select[3] & select[2] & select[1] & select[0]}})) | (in8 & ({32{ select[3] & ~select[2] & ~select[1] & ~select[0]}})) | (in9 & ({32{ select[3] & ~select[2] & ~select[1] & select[0]}})); end endmodule module ALU(input [31:0]a,b,[3:0]select, output [31:0]y, output reg cout); wire [31:0] add_res, sub_res, and_res, or_res, xor_res, sll_res, srl_res, sra_res, slt_res, sltu_res; wire add_cout, sub_cout; RippleCarryAdder adder(.a(a), .b(b), .cin(0), .sum(add_res), .cout(add_cout)); RippleCarryAdder subtractor(.a(a), .b(~b), .cin(1), .sum(sub_res), .cout(sub_cout)); //and x1(and_res, a, b); assign and_res = a & b; assign or_res = a | b; assign xor_res = a ^ b; assign sll_res = a << b; assign srl_res = a >> b; assign sra_res = a >>> b; assign slt_res = (a < b) ? 32'd1 : 32'd0; assign sltu_res = ($unsigned(a) < $unsigned(b)) ? 32'd1 : 32'd0; Mux16to1 result_mux( .in0(add_res), .in1(sub_res), .in2(and_res), .in3(or_res), .in4(xor_res), .in5(sll_res), .in6(srl_res), .in7(sra_res), .in8(slt_res), .in9(sltu_res), // The remaining inputs need to be defined if you have other operations .select(select), .out(y) ); always @(*) begin case(select) 4'b0000: cout = add_cout; // add=0 4'b0001: cout = sub_cout; // sub=1 default: cout = 0; endcase end endmodule module ALU_testbench(); reg [31:0]a,b; reg [3:0]select; wire [31:0]out; wire cout; ALU DUT1(.a(a),.b(b),.select(select),.y(out),.cout(cout)); initial begin a=7;b=2;select=4'b0000; #100 select=4'b0001; #100 select=4'b0010; #100 select=4'b0011; #100 select=4'b0100; #100 select=4'b0101; #100 select=4'b0110; #100 select=4'b0111; #100 select=4'b1000; #100 select=4'b1001; end endmodule ``` ### Output: **ALU-** ![Screenshot 2024-05-11 010450](https://hackmd.io/_uploads/rJq-OlhM0.png) --- ## Lab 11 [Processor] **Code** ```verilog= module FullAdder(input a, b, cin, output sum, cout); assign sum = a^b^cin; assign cout = (a&b) | (b&cin) | (a&cin); endmodule module RippleCarryAdder(input [31:0]a, b, input cin, output [31:0]sum, output cout); wire [31:0]carry; genvar i; generate for (i = 0; i < 32; i = i + 1) begin : adder_loop if (i == 0) begin FullAdder fa(a[i], b[i], cin, sum[i], carry[i]); end else if (i < 31) begin FullAdder fa(a[i], b[i], carry[i-1], sum[i], carry[i]); end else begin FullAdder fa(a[i], b[i], carry[i-1], sum[i], cout); end end endgenerate endmodule module Mux16to1( input [31:0] in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, input [3:0] select, output reg [31:0] out ); always @(*) begin out = (in0 & ({32{~select[3] & ~select[2] & ~select[1] & ~select[0]}})) | (in1 & ({32{~select[3] & ~select[2] & ~select[1] & select[0]}})) | (in2 & ({32{~select[3] & ~select[2] & select[1] & ~select[0]}})) | (in3 & ({32{~select[3] & ~select[2] & select[1] & select[0]}})) | (in4 & ({32{~select[3] & select[2] & ~select[1] & ~select[0]}})) | (in5 & ({32{~select[3] & select[2] & ~select[1] & select[0]}})) | (in6 & ({32{~select[3] & select[2] & select[1] & ~select[0]}})) | (in7 & ({32{~select[3] & select[2] & select[1] & select[0]}})) | (in8 & ({32{ select[3] & ~select[2] & ~select[1] & ~select[0]}})) | (in9 & ({32{ select[3] & ~select[2] & ~select[1] & select[0]}})) | (in9 & ({32{ select[3] & ~select[2] & select[1] & ~select[0]}})); end endmodule module ALU(input [31:0]a,b,[3:0]select, input mem_read, mem_write, output [31:0]y, output reg cout, output [31:0] address); wire [31:0] add_res, sub_res, and_res, or_res, xor_res, sll_res, srl_res, sra_res, slt_res, sltu_res; wire add_cout, sub_cout; wire [31:0] mem_data_out; DataMemory data_memory(.address(address), .write_data(b), .mem_read(mem_read), .mem_write(mem_write), .read_data(mem_data_out)); assign address = a + b; // Assume b is offset for simplicity RippleCarryAdder adder(.a(a), .b(b), .cin(0), .sum(add_res), .cout(add_cout)); RippleCarryAdder subtractor(.a(a), .b(~b), .cin(1), .sum(sub_res), .cout(sub_cout)); //and x1(and_res, a, b); assign and_res = a & b; assign or_res = a | b; assign xor_res = a ^ b; assign sll_res = a << b; assign srl_res = a >> b; assign sra_res = a >>> b; assign slt_res = (a < b) ? 32'd1 : 32'd0; assign sltu_res = ($unsigned(a) < $unsigned(b)) ? 32'd1 : 32'd0; Mux16to1 result_mux( .in0(add_res), .in1(sub_res), .in2(and_res), .in3(or_res), .in4(xor_res), .in5(sll_res), .in6(srl_res), .in7(sra_res), .in8(slt_res), .in9(sltu_res), .in10(mem_data_out, // The remaining inputs need to be defined if you have other operations .select(select), .out(y) ); always @(*) begin case(select) 4'b0000: cout = add_cout; // add=0 4'b0001: cout = sub_cout; // sub=1 default: cout = 0; endcase end endmodule module InstructionMemory( input [31:0] address, output reg [31:0] data ); reg [31:0] mem [0:255]; // 1 KB memory // Initialize memory with instructions (not shown here) always @(posedge clk) begin data <= mem[address[7:0]]; end endmodule module AddressCalculation( input [31:0] base, // Base address input [31:0] offset, // Offset output [31:0] address // Calculated address ); assign address = base + offset; // Simple addition to compute address endmodule module DataMemory( input [31:0] address, input [31:0] write_data, input mem_read, mem_write, // Control signal for write operation input clk, // System clock output reg [31:0] read_data // Output port for read operation, not used here ); // Declare memory array (1 KB of memory, word-addressed) reg [31:0] memory[0:255]; always @(posedge clk) begin if (mem_write) begin memory[address[9:2]] = write_data; // Assuming word-aligned addresses else if (mem_read) read_data = memory[address[7:0]]; // Read operation with byte addressing end endmodule module RegisterFile( input [4:0] read_address_1, read_address_2, write_address, input [31:0] write_data, input read_enable, write_enable, output reg [31:0] read_data_1, read_data_2 ); reg [31:0] registers [31:0]; always @(*) begin if (read_enable) begin read_data_1 = registers[read_address_1]; read_data_2 = registers[read_address_2]; end end always @(posedge clk) begin if (write_enable) registers[write_address] <= write_data; end endmodule module Processor( input [31:0] base_address, // Base address for sw input [31:0] offset, // Offset for sw input [31:0] store_data, // Data to store input mem_write, // Signal to perform a write input clk, // Clock signal output wire [31:0] memory_out // This is not typically used in sw but shown for completeness ); wire [31:0] calculated_address; // Instantiate the address calculation module AddressCalculation addr_calc( .base(base_address), .offset(offset), .address(calculated_address) ); // Instantiate the data memory module DataMemory data_mem( .address(calculated_address), .write_data(store_data), .mem_write(mem_write), .clk(clk), .read_data(memory_out) // Not used for 'sw' ); endmodule module Testbench; reg [31:0] base_address = 32'h1000; reg [31:0] offset = 32'h4; reg [31:0] store_data = 32'hdeadbeef; reg mem_write = 1; reg clk = 0; wire [31:0] memory_out; Processor proc( .base_address(base_address), .offset(offset), .store_data(store_data), .mem_write(mem_write), .clk(clk), .memory_out(memory_out) ); always #5 clk = !clk; // Clock generator initial begin $monitor("At %t, memory_out: %h", $time, memory_out); #10; // Run simulation for a few cycles $finish; end endmodule ```