summaryrefslogtreecommitdiff
path: root/datapath/v0.1/data_path.v
diff options
context:
space:
mode:
Diffstat (limited to 'datapath/v0.1/data_path.v')
-rw-r--r--datapath/v0.1/data_path.v129
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