diff options
Diffstat (limited to 'datapath/v0.1/data_path.v')
-rw-r--r-- | datapath/v0.1/data_path.v | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/datapath/v0.1/data_path.v b/datapath/v0.1/data_path.v new file mode 100644 index 0000000..aee5739 --- /dev/null +++ b/datapath/v0.1/data_path.v @@ -0,0 +1,129 @@ +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
\ No newline at end of file |