# Lab 11 Name: SHIVADHARSHAN S Roll No.: CS22B057 --- ## Question 1 **Processor Design:** Generated schematic in Vivado ![Vivado schematic](https://hackmd.io/_uploads/Ski8pK3G0.jpg) **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) ___