module data_path( input clk, input jump,mem_read, mem_write, alu_src, reg_dst, mem_to_reg, reg_write, bne, beq, input [1:0]alu_op, output [3:0]opcode ); reg [15:0]pc_current; wire [15:0]pc_next; wire [15:0]pc_2; wire [15:0]instr; wire [2:0]reg_write_dest; wire [15:0]reg_write_data; wire [2:0]reg_read_addr_1; wire [15:0]reg_read_data_1; wire [2:0]reg_read_addr_2; wire [15:0]reg_read_data_2; wire [15:0]ext_im; wire [15:0]read_data2; wire [2:0]alu_control; wire [15:0]alu_out; wire zero_flag; wire [15:0]pc_j; wire [15:0]pc_beq; wire [15:0]pc_beq2; wire [15:0]pc_bne; wire [15:0]pc_bne2; wire beq_control; wire bne_control; wire [12:0]jump_shift; wire [15:0]mem_read_data; //set start position counter to 0 initial begin pc_current <= 16'd0; end //on pos edge set poisition counter to next value always @(posedge clk) begin pc_current <= pc_next; end //set value of next instruction position assign pc_2 = pc_current + 16'd2; //read current instruction from pc_current and write to instr instr_memory im( .pc(pc_current), .instruction(instr) ); //jump shift 2 assign jump_shift = {instr[11:0],1'b0}; //register where to write data assign reg_write_dest = (reg_dst==1'b1) ? instr[5:3] : instr[8:6]; //2 read register addresses assign reg_read_addr_1 = instr[11:9]; assign reg_read_addr_2 = instr[8:6]; //General purpose register,process values according to settings gpr_register gpr( .clk(clk), .reg_write_en(reg_write), .reg_write_dest(reg_write_dest), .reg_write_data(reg_write_data), .reg_read_addr_1(reg_read_addr_1), .reg_read_data_1(reg_read_data_1), .reg_read_addr_2(reg_read_addr_2), .reg_read_data_2(reg_read_data_2) ); //imidiate extend, set all higher bits to value of the last bit assign ext_im = {{10{instr[5]}}, instr[5:0]}; //alu control unit alu_control ac( .alu_op(alu_op), .opcode(instr[15:12]), .alu_cnt(alu_control) ); // multiplexer read from ext or from data register //read imidiate value or one from alu assign read_data2 = (alu_src==1'b1) ? ext_im : reg_read_data_2; alu alu( .a(reg_read_data_1), .b(read_data2), .alu_sel(alu_control), .alu_out(alu_out), .carry_out(zero_flag) ); //position counter values if assign pc_beq = pc_2 + {ext_im[14:0], 1'b0}; assign pc_bne = pc_2 + {ext_im[14:0], 1'b0}; assign beq_control = beq & zero_flag; assign bne_control = bne & (~zero_flag); //if beq then jump imidiate value, else jump +2 positions assign pc_beq2 = (beq_control == 1'b1) ? pc_beq : pc_2; //if bne jusm imidiate value, else jump beq value assign pc_bne2 = (bne_control == 1'b1) ? pc_bne : pc_beq2; assign pc_j = {pc_2[15:13],jump_shift}; assign pc_next = (jump == 1'b1) ? pc_j : pc_bne2; data_memory dm( .clk(clk), .mem_access_addr(alu_out), .mem_write_data(reg_read_data_2), .mem_write_en(mem_write), .mem_read(mem_read), .mem_read_data(mem_read_data) ); //writeback assign reg_write_data = (mem_to_reg == 1'b1)? mem_read_data : alu_out; assign opcode = instr[15:12]; endmodule