# 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-**

---
## 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
```