diff options
Diffstat (limited to 'datapath')
-rw-r--r-- | datapath/v0.1/Makefile | 17 | ||||
-rw-r--r-- | datapath/v0.1/data_path.v | 129 | ||||
-rw-r--r-- | datapath/v0.1/test_data_path.v | 158 |
3 files changed, 304 insertions, 0 deletions
diff --git a/datapath/v0.1/Makefile b/datapath/v0.1/Makefile new file mode 100644 index 0000000..b4aa522 --- /dev/null +++ b/datapath/v0.1/Makefile @@ -0,0 +1,17 @@ + +I_INSTRMEM=-I../../instrmem/v0.1 ../../instrmem/v0.1/instr_memory.v +I_GPR=-I../../gpr/v0.1 ../../gpr/v0.1/gpr_register.v +I_ALUCONTROL=-I../../alu_control/v0.1 ../../alu_control/v0.1/alu_control.v +I_ALU8=-I../../alu/v0.1 ../../alu/v0.1/alu.v +I_DATAMEM=-I../../datamem/v0.1 ../../datamem/v0.1/data_memory.v + +make: + iverilog -g2005-sv -o data_path data_path.v $(I_INSTRMEM) $(I_GPR) $(I_ALUCONTROL) $(I_ALU8) $(I_DATAMEM) + iverilog -g2005-sv -o test_data_path data_path.v test_data_path.v $(I_INSTRMEM) $(I_GPR) $(I_ALUCONTROL) $(I_ALU8) $(I_DATAMEM) + +test: + ./test_data_path + + +wave: + gtkwave test_data_path.vcd
\ No newline at end of file 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 diff --git a/datapath/v0.1/test_data_path.v b/datapath/v0.1/test_data_path.v new file mode 100644 index 0000000..9625087 --- /dev/null +++ b/datapath/v0.1/test_data_path.v @@ -0,0 +1,158 @@ +`timescale 1ns/1ps + +module test_data_path; + +reg clk; +reg jump; +reg mem_read; +reg mem_write; +reg alu_src; +reg reg_dst; +reg mem_to_reg; +reg reg_write; +reg bne; +reg beq; +reg [1:0]alu_op; +reg [3:0]opcode; + +data_path uut( + .clk(clk), + .jump(jump), + .mem_read(mem_read), + .mem_write(mem_write), + .alu_src(alu_src), + .reg_dst(reg_dst), + .mem_to_reg(mem_to_reg), + .reg_write(reg_write), + .bne(bne), + .beq(beq), + .alu_op(alu_op), + .opcode(opcode) +); + +initial begin + $display("Start testing data path"); + $dumpfile("test_data_path.vcd"); + $dumpvars(0,test_data_path); + + clk=0; + jump=0; + mem_read=0; + mem_write=0; + alu_src=0; + reg_dst=0; + mem_to_reg=0; + reg_write=0; + bne=0; + beq=0; + alu_op=2'b00; + + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; + + #10 + clk=1; + + #10 + clk=0; +end + +initial begin + $monitor("At time=%t",$time); +end + +endmodule
\ No newline at end of file |