# Lab 11
Name: SHIVADHARSHAN S
Roll No.: CS22B057
---
## Question 1
**Processor Design:**
Generated schematic in Vivado

**Code**
ALU: Same as previous lab
PC:
```verilog=
module program_counter(pc,clk);
output [31:0] pc;
reg [31:0] pc_i;
input clk;
initial begin
pc_i <= 0;
end
always @(posedge clk ) begin
pc_i <= pc_i + 1;
$display("pc=%d",pc_i);
end
assign pc = pc_i;
endmodule
```
Instruction Memory:
```verilog=
module instruction_memory(read_address,out,clk);
input [31:0] read_address;
input clk;
reg [31:0] output_buffer;
reg [31:0] memory [1023:0];
output [31:0] out;
initial begin
/*
add x1 x2 x3
sub x1 x2 x4
and x4 x1 x5
sll x6 x1 x2
slt x9 x0 x1
sw x6 1(x0)
lw x15 1(x0)
or x8 x1 x15
*/
memory[0] = 32'b00000000001100010000000010110011;
memory[1] = 32'b01000000010000010000000010110011;
memory[2] = 32'b00000000010100001000001000110011;
memory[3] = 32'b00000000001000001001001100110011;
memory[4] = 32'b00000000000100000010010010110011;
memory[5] = 32'b00000000011000000010000010100011;
memory[6] = 32'b00000000000100000010011110000011;
memory[7] = 32'b00000000111100001110010000110011;
//smemory[3] = 32'b10000000001100010000000010110011;
end
always @(*) begin
output_buffer <= memory[read_address];
$display("instruction_fetched = %b",output_buffer);
end
assign out = output_buffer;
endmodule
```
Data Memory:
```verilog=
module data_memory(rw,location,out,data,clk);
input rw;
input clk;
input [31:0] data;
input [31:0] location;
output [31:0] out;
reg [31:0] output_buffer;
reg [31:0] memory [1023:0];
always @(*) begin
if (rw==1'b0) begin
output_buffer = memory[location];
end
else if (rw==1'b1) begin
memory[location] = data;
end
end
assign out = output_buffer;
endmodule
```
register file:
```verilog=
module register_file(data,rs1,rs2,rsd,rw,out1,out2,clk);
reg [31:0] reg_file [31:0];
input clk;
input [4:0]rsd;
input [4:0]rs1;
input [4:0]rs2;
input [31:0] data;
input rw;
output [31:0]out1;
output [31:0]out2;
reg [31:0]outbuffer1;
reg [31:0]outbuffer2;
initial begin
reg_file[0] = 32'b0;
reg_file[1] = 32'b0;
reg_file[2] = 32'b1;
reg_file[3] = 32'b1;
reg_file[4] = 32'b0;
reg_file[5] = 32'b0;
reg_file[6] = 32'b0;
reg_file[7] = 32'b0;
reg_file[8] = 32'b0;
reg_file[9] = 32'b0;
reg_file[10] = 32'b0;
reg_file[11] = 32'b0;
reg_file[12] = 32'b0;
reg_file[13] = 32'b0;
reg_file[14] = 32'b0;
reg_file[15] = 32'b0;
reg_file[16] = 32'b0;
reg_file[17] = 32'b0;
reg_file[18] = 32'b0;
reg_file[19] = 32'b0;
reg_file[20] = 32'b0;
reg_file[21] = 32'b0;
reg_file[22] = 32'b0;
reg_file[23] = 32'b0;
reg_file[24] = 32'b0;
reg_file[25] = 32'b0;
reg_file[26] = 32'b0;
reg_file[27] = 32'b0;
reg_file[28] = 32'b0;
reg_file[29] = 32'b0;
reg_file[30] = 32'b0;
reg_file[31] = 32'b0;
end
always @(*) begin
if (rw==1'b1 && rsd!=1'b0) begin
reg_file[rsd] <= data;
$display("wrote %d to %d reg",data,rsd);
end
outbuffer1 <= reg_file[rs1];
outbuffer2 <= reg_file[rs2];
$display("read %d from %d reg",outbuffer1,rs1);
end
assign out1 = outbuffer1;
assign out2 = outbuffer2;
endmodule
```
alu control:
```verilog=
module alu_control(instruction,control);
input [31:0] instruction;
output [6:0] control;
// reg control_state;
// always @(instruction) begin
// control_state <= (instruction[6:0] == 7'b0110011) ? (instruction[14:12] == 3'b000) ?(instruction[31:25] == 7'b0000000) ? 7'b0 : 7'b1 : (instruction[14:12] == 3'b100) ? 7'b10 : (instruction[14:12] == 3'b110) ? 7'b11 : (instruction[14:12] == 3'b111) ? 7'b100 :(instruction[14:12] == 3'b001) ? 7'b101 : (instruction[14:12] == 3'b101) ? (instruction[31:25] == 7'b0000000) ? 7'b110 :7'b111: (instruction[14:12] == 3'b010) ? 7'b1000 :7'b1001: 7'b1;
// end
assign control= (instruction[6:0] == 7'b0110011) ? (instruction[14:12] == 3'b000) ?(instruction[31:25] == 7'b0000000) ? 7'b0 : 7'b1 : (instruction[14:12] == 3'b100) ? 7'b10 : (instruction[14:12] == 3'b110) ? 7'b11 : (instruction[14:12] == 3'b111) ? 7'b100 :(instruction[14:12] == 3'b001) ? 7'b101 : (instruction[14:12] == 3'b101) ? (instruction[31:25] == 7'b0000000) ? 7'b110 :7'b111: (instruction[14:12] == 3'b010) ? 7'b1000 :7'b1001: 7'b0;
endmodule
```
control:
```verilog=
module control_path(opcode,mem_read,mem_to_reg,reg_write,mem_write,alu_src,clk);
input [6:0] opcode;
input clk;
output mem_read,mem_to_reg,reg_write,mem_write,alu_src;
reg mem_read_state,mem_to_reg_state,reg_write_state,mem_write_state,alu_src_state;
initial begin
mem_read_state = 0;
mem_to_reg_state = 0;
reg_write_state = 0;
mem_write_state = 0;
alu_src_state = 0;
end
// lw 0000011
// sw 0100011
always @(*) begin
case(opcode)
7'b0000011: begin //load
mem_read_state = 1;
mem_to_reg_state = 1;
reg_write_state = 1;
mem_write_state = 0;
alu_src_state = 1;
end
7'b0100011: begin //store
mem_read_state = 0;
mem_to_reg_state = 0;
reg_write_state = 0;
mem_write_state = 1;
alu_src_state = 1;
end
7'b0110011: begin // add sub or and etc..
mem_read_state = 0;
mem_to_reg_state = 0;
reg_write_state = 1;
mem_write_state = 0;
alu_src_state = 0;
end
endcase
end
assign mem_read = mem_read_state;
assign mem_to_reg = mem_to_reg_state;
assign mem_write = mem_write_state;
assign reg_write = reg_write_state;
assign alu_src = alu_src_state;
endmodule
```
datapath: (Top Level)
```verilog=
module datapath(clk);
input clk;
wire [31:0] pc_wire, instruction,write_data,read_data1,read_data2,alu_output,memory_out,alu_2_input,immediate;
wire mem_read,mem_to_reg,reg_write,mem_write,alu_src;
wire [6:0] alu_control_s;
program_counter pc(pc_wire,clk);
instruction_memory instructionMemory(pc_wire,instruction,clk);
data_memory dataMemory(mem_write,alu_output,memory_out,read_data2,clk);
alu_control alucontrol(instruction,alu_control_s);
ALU alu(alu_control_s,read_data1,alu_2_input,alu_output);
assign immediate = (instruction[6:0] == 7'b0000011) ? instruction[31:20] : {instruction[31:25],instruction[11:7]};
control_path control(instruction[6:0],mem_read,mem_to_reg,reg_write,mem_write,alu_src,clk);
assign alu_2_input = alu_src ? immediate : read_data2;
assign write_data = mem_to_reg ? memory_out : alu_output;
register_file reg_file(write_data,instruction[19:15],instruction[24:20],instruction[11:7],reg_write,read_data1,read_data2,clk);
endmodule
```
TestBench:
```verilog=
module datapath_tb();
reg clk;
datapath dp(clk);
initial begin
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
#100 clk = 0;
#100 clk = 1;
end
endmodule
```
**Output:** (ModelSim)
[Model Sim output pdf](https://drive.google.com/file/d/19BAvPsEH6hRHkWob9lIDgAXndBG10X44/view?usp=sharing)
___