From f7e9d420a79d7ffa03f5c92100a081c9312b2257 Mon Sep 17 00:00:00 2001 From: Joshua Date: Mon, 17 Nov 2014 22:18:05 -0500 Subject: [PATCH] udate to project files --- ECE745/Project/LC3_test.sv | 486 +++++++++++++++++++++++++++++ ECE745/Project/WB.sv | 77 +++++ ECE745/Project/control.sv | 327 +++++++++++++++++++ ECE745/Project/decode.sv | 209 +++++++++++++ ECE745/Project/execute.sv | 304 ++++++++++++++++++ ECE745/Project/generator.sv | 73 +++++ ECE745/Project/if.sv | 82 +++++ ECE745/Project/mem.sv | 57 ++++ ECE745/Project/project.if.sv | 82 +++++ ECE745/Project/project.test_top.sv | 129 ++++++++ 10 files changed, 1826 insertions(+) create mode 100644 ECE745/Project/LC3_test.sv create mode 100644 ECE745/Project/WB.sv create mode 100644 ECE745/Project/control.sv create mode 100644 ECE745/Project/decode.sv create mode 100644 ECE745/Project/execute.sv create mode 100644 ECE745/Project/generator.sv create mode 100644 ECE745/Project/if.sv create mode 100644 ECE745/Project/mem.sv create mode 100644 ECE745/Project/project.if.sv create mode 100644 ECE745/Project/project.test_top.sv diff --git a/ECE745/Project/LC3_test.sv b/ECE745/Project/LC3_test.sv new file mode 100644 index 0000000..bcae88b --- /dev/null +++ b/ECE745/Project/LC3_test.sv @@ -0,0 +1,486 @@ +program LC3_test( LC3_io top_io, dut_Probe_if dut_io); + + +`define ADD 4'b0001 +`define AND 4'b0101 +`define NOT 4'b1001 +`define LD 4'b0010 +`define LDR 4'b0110 +`define LDI 4'b1010 +`define LEA 4'b1110 +`define ST 4'b0011 +`define STR 4'b0111 +`define STI 4'b1011 +`define BR 4'b0000 +`define JMP 4'b1100 + +`include "generator.sv" +`include "execute.sv" +`include "WB.sv" +`include "if.sv" +`include "decode.sv" +`include "mem.sv" +`include "control.sv" +`include "const.svi" + + covergroup ALU_opr_covg; + + Cov_ALU_opcode: coverpoint dut_io.dec_IR[15:12] + { + bins ALU_opcode1 = {`ADD}; + bins ALU_opcode2 = {`AND}; + bins ALU_opcode3 = {`NOT}; + } + Cov_Imm_en: coverpoint dut_io.dec_IR[5] + { + bins immediate_en = {1}; + } + Cov_Imm_de: coverpoint dut_io.dec_IR[5] + { + bins immediate_de = {0}; + } + Cov_SR1: coverpoint dut_io.dec_IR[8:6] + { + bins zero = {0}; + bins one = {1}; + bins two = {2}; + bins three = {3}; + bins four = {4}; + bins five = {5}; + bins six = {6}; + bins seven = {7}; + } + Cov_SR2: coverpoint dut_io.dec_IR[2:0] iff (dut_io.dec_IR[5] == 0) + { + bins zero = {0}; + bins one = {1}; + bins two = {2}; + bins three = {3}; + bins four = {4}; + bins five = {5}; + bins six = {6}; + bins seven = {7}; + } + Cov_DR: coverpoint dut_io.dec_IR[11:9] + { + bins zero = {0}; + bins one = {1}; + bins two = {2}; + bins three = {3}; + bins four = {4}; + bins five = {5}; + bins six = {6}; + bins seven = {7}; + } + + Cov_Imm_value : coverpoint dut_io.dec_IR[4:0] iff(dut_io.dec_IR[5] == 1); + + Xc_opcode_Imm_en : cross Cov_ALU_opcode , Cov_Imm_en; + + Xc_opcode_sr1_dr_imm_en : cross Cov_ALU_opcode , Cov_Imm_en, Cov_SR1, Cov_DR; + + Xc_opcode_sr1_dr_sr2 : cross Cov_ALU_opcode , Cov_Imm_de, Cov_SR1, Cov_DR, Cov_SR2 + { + ignore_bins NOT = binsof(Cov_ALU_opcode.ALU_opcode3); + } + + Cov_aluin1: coverpoint EX_aluin1 + { + option.auto_bin_max=8; + } + Cov_aluin2: coverpoint EX_aluin2 + { + option.auto_bin_max=8; + } + Cov_aluin1_corner1: coverpoint EX_aluin1 + { + bins all_0 = {0}; + } + Cov_aluin1_corner2: coverpoint EX_aluin1 + { + bins all_1 = {16'hffff}; + } + Cov_aluin1_corner3: coverpoint EX_aluin1 + { + bins alt_0_1= {16'h5555}; + } + Cov_aluin1_corner4: coverpoint EX_aluin1 + { + bins alt_1_0= {16'haaaa}; + } + Cov_aluin1_corner5: coverpoint EX_aluin1 + { + wildcard bins pos = {16'b0???????????????}; + } + Cov_aluin1_corner6: coverpoint EX_aluin1 + { + wildcard bins neg = {16'b1???????????????}; + } + + Cov_aluin2_corner1: coverpoint EX_aluin2 + { + bins all_0 = {0}; + } + Cov_aluin2_corner2: coverpoint EX_aluin2 + { + bins all_1 = {16'hffff}; + } + Cov_aluin2_corner3: coverpoint EX_aluin2 + { + bins alt_0_1= {16'h5555}; + } + Cov_aluin2_corner4: coverpoint EX_aluin2 + { + bins alt_1_0= {16'haaaa}; + } + Cov_aluin2_corner5: coverpoint EX_aluin2 + { + wildcard bins pos = {16'b0???????????????}; + } + Cov_aluin2_corner6: coverpoint EX_aluin2 + { + wildcard bins neg = {16'b1???????????????}; + } + + Xc_opcode_aluin1_corn1 : cross Cov_ALU_opcode, Cov_aluin1_corner1; + Xc_opcode_aluin1_corn2 : cross Cov_ALU_opcode, Cov_aluin1_corner2; + Xc_opcode_aluin1_corn3 : cross Cov_ALU_opcode, Cov_aluin1_corner3; + Xc_opcode_aluin1_corn4 : cross Cov_ALU_opcode, Cov_aluin1_corner4; + Xc_opcode_aluin1_corn5 : cross Cov_ALU_opcode, Cov_aluin1_corner5; + Xc_opcode_aluin1_corn6 : cross Cov_ALU_opcode, Cov_aluin1_corner6; + + Xc_opcode_aluin2_corn1 : cross Cov_ALU_opcode, Cov_aluin2_corner1; + Xc_opcode_aluin2_corn2 : cross Cov_ALU_opcode, Cov_aluin2_corner2; + Xc_opcode_aluin2_corn3 : cross Cov_ALU_opcode, Cov_aluin2_corner3; + Xc_opcode_aluin2_corn4 : cross Cov_ALU_opcode, Cov_aluin2_corner4; + Xc_opcode_aluin2_corn5 : cross Cov_ALU_opcode, Cov_aluin2_corner5; + Xc_opcode_aluin2_corn6 : cross Cov_ALU_opcode, Cov_aluin2_corner6; + + Cov_opcode_aluin_allZero: cross Cov_ALU_opcode, Cov_aluin1_corner1, Cov_aluin2_corner1; + + Cov_opcode_aluin_allOne: cross Cov_ALU_opcode, Cov_aluin1_corner2, Cov_aluin2_corner2; + + Cov_opcode_aluin_Zero_One: cross Cov_ALU_opcode, Cov_aluin1_corner1, Cov_aluin2_corner2; + + Cov_opcode_aluin_One_Zero: cross Cov_ALU_opcode, Cov_aluin1_corner2, Cov_aluin2_corner1; + + Cov_opcode_aluin_alt01_alt10: cross Cov_ALU_opcode, Cov_aluin1_corner3, Cov_aluin2_corner4; + + Cov_opcode_aluin_alt10_alt01: cross Cov_ALU_opcode, Cov_aluin1_corner4, Cov_aluin2_corner3; + + Cov_opcode_aluin_alt10_alt10: cross Cov_ALU_opcode, Cov_aluin1_corner3,Cov_aluin2_corner3; + + Cov_opcode_aluin_alt01_alt01: cross Cov_ALU_opcode, Cov_aluin1_corner4, Cov_aluin2_corner4; + + Cov_opcode_aluin_pos_pos: cross Cov_ALU_opcode, Cov_aluin1_corner5, Cov_aluin2_corner5; + + Cov_opcode_aluin_pos_neg: cross Cov_ALU_opcode, Cov_aluin1_corner5, Cov_aluin2_corner6; + + Cov_opcode_aluin_neg_pos: cross Cov_ALU_opcode, Cov_aluin1_corner6, Cov_aluin2_corner5; + + Cov_opcode_aluin_neg_neg: cross Cov_ALU_opcode, Cov_aluin1_corner6, Cov_aluin2_corner6; + + endgroup + + + covergroup MEM_OPR_cg; + + Cov_mem_opcode: coverpoint top_io.Instr_dout[`OP_CODE] + { bins MEM_opcode = { `LD, `LDI, `LDR, `LEA, `ST, `STR, `STI }; } + + + Cov_BaseR: coverpoint top_io.Instr_dout[`BASER] iff ((top_io.Instr_dout[`OP_CODE] == `LDR ) || (top_io.Instr_dout[`OP_CODE] == `STR)); + + + Cov_SR: coverpoint top_io.Instr_dout[`SR] iff ( top_io.Instr_dout[13:12] == 2'b11 ); + + + Cov_DR: coverpoint top_io.Instr_dout[`DR] iff ( (top_io.Instr_dout[13:12] == 2'b10)); + + // PCOffset6 8 bins bins Only (Loads and Stores) & (!LDR || !STR) + Cov_PCoffset9: coverpoint top_io.Instr_dout[`PCOFFSET9] iff( ( (top_io.Instr_dout[13:12] == 2'b10) || + (top_io.Instr_dout[13:12] == 2'b11 )) + && + ( (top_io.Instr_dout[`OP_CODE] != `LDR) && + (top_io.Instr_dout[`OP_CODE] != `STR ))) + { option.auto_bin_max=8;} + + // PCOffset6 cornder cases bins Only (Loads and Stores) & (!LDR || !STR) + Cov_PCoffset9_c: coverpoint top_io.Instr_dout[`PCOFFSET9] iff (((top_io.Instr_dout[13:12] == 2'b10) || + (top_io.Instr_dout[13:12] == 2'b11 )) + && + ( (top_io.Instr_dout[`OP_CODE] != `LDR) && + (top_io.Instr_dout[`OP_CODE] != `STR ))) + { bins corners[] = {9'h000, 9'h100, 9'h1FF}; } + + // PCOffset6 8 bins Only LDR STR + Cov_PCoffset6: coverpoint top_io.Instr_dout[`PCOFFSET6] iff ( (top_io.Instr_dout[`OP_CODE] == `LDR) || (top_io.Instr_dout[`OP_CODE] == `STR ) ) + { option.auto_bin_max=8;} + + + + // Cross Coverage for offset6 + Xc_BaseR_DR_offset6: cross Cov_BaseR, Cov_DR, Cov_PCoffset6 iff (top_io.Instr_dout[`OP_CODE] == `LDR); + Xc_BaseR_SR_offset6: cross Cov_BaseR, Cov_SR, Cov_PCoffset6 iff (top_io.Instr_dout[`OP_CODE] == `STR); + + Xc_DR_offset9: cross Cov_DR, Cov_PCoffset9 iff ( (top_io.Instr_dout[13:12] == 2'b10) && (top_io.Instr_dout[`OP_CODE] != `LDR)); + Xc_SR_offset9: cross Cov_SR, Cov_PCoffset9 iff ( (top_io.Instr_dout[13:12] == 2'b11) && (top_io.Instr_dout[`OP_CODE] != `STR)); + + + Cov_PCoffset6_c: coverpoint top_io.Instr_dout[`PCOFFSET6] iff ( (top_io.Instr_dout[`OP_CODE] == `LDR) || (top_io.Instr_dout[`OP_CODE] == `STR ) ) + + { bins corners[] = {6'h00, 6'h20, 6'h3F, 6'h2a, 6'h15}; } + +endgroup + + + + covergroup BR_OPR_cg; + Cov_NZP: coverpoint EX_NZP + { + bins z = {3'b010}; + bins np = {3'b101}; + bins p = {3'b001}; + bins zp = {3'b011}; + bins n = {3'b100}; + bins nz = {3'b110}; + bins others = default; + } + + Cov_BaseR: coverpoint top_io.Instr_dout[`BASER] iff(top_io.Instr_dout[`OP_CODE] == `JMP); + + Cov_psr: coverpoint WB_psr + { + bins z = {3'b010}; + bins n = {3'b100}; + bins p = {3'b001}; + bins others = default; + } + + Xc_NZP_PSR: cross Cov_NZP, Cov_psr; + endgroup + + covergroup order_of_instr; + + Cov_add_o_instr: coverpoint top_io.Instr_dout[`OP_CODE] + { bins addop = {`ADD}; } + + Cov_and_o_instr: coverpoint top_io.Instr_dout[`OP_CODE] + { bins andop = {`AND}; } + + Cov_not_o_instr: coverpoint top_io.Instr_dout[`OP_CODE] + { bins notop = {`NOT}; } + + Cov_LEA_o_instr: coverpoint top_io.Instr_dout[`OP_CODE] + { bins leaop = {`LEA}; } + + + Cov_rest_instr: coverpoint dut_io.dec_IR[`OP_CODE] + { + bins addop = {`ADD}; + bins andop = {`AND}; + bins notop = {`NOT}; + bins ldop = {`LD}; + bins ldrop = {`LDR}; + bins ldiop = {`LDI}; + bins leaop = {`LEA}; + bins stoop = {`ST}; + bins strop = {`STR}; + bins stiop = {`STI}; + bins brop = {`BR}; + bins jmpop = {`JMP}; + } + + Xc_add_all: cross Cov_add_o_instr, Cov_rest_instr; + Xc_and_all: cross Cov_and_o_instr, Cov_rest_instr; + Xc_not_all: cross Cov_not_o_instr, Cov_rest_instr; + Xc_lea_all: cross Cov_LEA_o_instr, Cov_rest_instr; + endgroup + + property br_taken_jmp; + @(top_io.cb) + ((top_io.Instr_dout[`OP_CODE] == `JMP) |-> ##2(CON_br_taken == 1)); + endproperty + jump_assertion: cover property(br_taken_jmp); + + + property br_taken; + @(top_io.cb) + (((top_io.Instr_dout[`OP_CODE] == `BR) && (|(top_io.Instr_dout[11:9] ==1))) |-> ##2(CON_br_taken == 1)); + endproperty + br_assertion: cover property(br_taken); + + property reset_prop; + @(top_io.cb) + ((dut_io.reset == 1'b1) |-> ((dut_io.fetch_pc == 16'h3000) && (dut_io.fetch_npc_out == 16'h3001))); + endproperty + reset_prop_assertion: cover property(reset_prop); + + /*property enable_all_prop; + @(top_io.cb) + (((dut_io.reset == 1'b1) && (##1( dut_io.reset == 0))) |-> ((dut_io.control_enable_decode == 1) && (##1 dut_io.control_enable_execute == 1) && (##2 dut_io.control_enable_writeback == 1))) ; + endproperty + enable_allprop_assertion: cover property(enable_all_prop);*/ + + ALU_opr_covg ALUOPS= new; + MEM_OPR_cg MEMOPS = new; + BR_OPR_cg BROPS = new; + order_of_instr ORDERINST = new; +int count = 0; + + + initial + + begin + + + @top_io.cb; + top_io.reset = 1'b1; + fork + fetch(); + decode(); + execute(); + memaccess(); + WB(); + control(); + join + + ALUOPS.sample(); + MEMOPS.sample(); + BROPS.sample(); + ORDERINST.sample(); + @top_io.cb; + @top_io.cb; + top_io.cb.reset <= 1'b0; + top_io.complete_instr <= 1'b1; + top_io.complete_data <= 1'b1; + top_io.cb.Instr_dout <= 16'h5020; + top_io.cb.Data_dout <= 16'h50; + fork + fetch(); + decode(); + execute(); + memaccess(); + WB(); + control(); + join + + ALUOPS.sample(); + MEMOPS.sample(); + BROPS.sample(); + ORDERINST.sample(); + + + while (count<8) + begin + @top_io.cb; + + + if(top_io.cb.instrmem_rd != 0) + begin + case (count) + //AND R0 R0 0 + 0:top_io.cb.Instr_dout <= 16'b101000000100000; + + //AND R1 R1 0 + 1:top_io.cb.Instr_dout <= 16'b101001001100000; + + //AND R2 R2 0 + 2:top_io.cb.Instr_dout <= 16'b101010010100000; + + //AND R3 R3 0 + 3:top_io.cb.Instr_dout <= 16'b101011011100000; + + //AND R4 R4 0 + 4:top_io.cb.Instr_dout <= 16'b101100100100000; + + //AND R5 R5 0 + 5:top_io.cb.Instr_dout <= 16'b101101101100000; + + //AND R6 R6 0 + 6:top_io.cb.Instr_dout <= 16'b101110110100000; + + //AND R7 R7 0 + 7:top_io.cb.Instr_dout <= 16'b101111111100000; + + endcase + end + + if(top_io.cb.instrmem_rd != 0) + count++; + + fork + fetch(); + decode(); + execute(); + memaccess(); + WB(); + control(); + join + + + ALUOPS.sample(); + MEMOPS.sample(); + BROPS.sample(); + ORDERINST.sample(); + end + + + instr = new(); + + + while (count<4000000) + begin + if(instr.ctrl_count < 8) + begin + if(top_io.cb.instrmem_rd == 1) + instr.ctrl_count++; + instr.arithops.constraint_mode (1); + instr.controlops.constraint_mode (0); // initially + end + + if(instr.ctrl_count === 8) + begin + instr.ctrl_count = 0; + instr.arithops.constraint_mode (0); + instr.controlops.constraint_mode (1); + end + + if((count > 0) && (count < 1000)) + instr.loadval.constraint_mode (0); + + if((count > 1000) && (count < 30000)) + instr.loadval.constraint_mode (1); + + if(count > 30000) + instr.loadval.constraint_mode (0); + + + @top_io.cb; + begin + + generator(); + + + fork + fetch(); + decode(); + execute(); + memaccess(); + WB(); + control(); + join + + ALUOPS.sample(); + MEMOPS.sample(); + BROPS.sample(); + ORDERINST.sample(); + count++; + end + end + + + #100 $finish; + end +endprogram: LC3_test + diff --git a/ECE745/Project/WB.sv b/ECE745/Project/WB.sv new file mode 100644 index 0000000..f6a428c --- /dev/null +++ b/ECE745/Project/WB.sv @@ -0,0 +1,77 @@ +logic [15:0] WB_reg_file[0:7]; +logic [15:0] WB_DR_in; +logic [2:0] WB_psr; +logic [15:0] WB_VSR1, WB_VSR2; + +// buffered inputs +logic [15:0] myWB_aluout, myWB_pcout, myWB_memout; +logic [2:0] myWB_dr; +logic [1:0] myWB_W_Control_in; +logic myWB_enable_writeback; +logic myWB_reset; + + +task WB (); + + + + if(dut_io.reset) + begin + WB_psr = 3'b000; + end + else + begin + + casex (myWB_W_Control_in) + + 2'b00: WB_DR_in = myWB_aluout; + 2'b01: WB_DR_in = myWB_memout; + 2'b10: WB_DR_in = myWB_pcout; + default: $display("error in w_control_in"); + endcase + + if (myWB_enable_writeback) + begin + if(WB_DR_in[15] === 1'b1) + begin WB_psr = 3'b100; // negative value + end + else + //psr = (DR_in > 0) ? 3'b001 : 3'b010 ; + begin + if (WB_DR_in) WB_psr = 3'b001; //value is positive and non zero + else WB_psr = 3'b010; // value is zero + end + end + + if (myWB_enable_writeback) WB_reg_file[myWB_dr] = WB_DR_in; //data written in reg file + end + + WB_VSR1 = WB_reg_file[dut_io.wb_sr1]; // asynch + WB_VSR2 = WB_reg_file[dut_io.wb_sr2]; // asynch + + // CHECKING + + if (WB_VSR1 !== dut_io.wb_VSR1) + $display ($time, " Writeback block error: VSR1 mismatch"); + + if (WB_VSR2 !== dut_io.wb_VSR2) + $display ($time, " Writeback block error: VSR2 mismatch"); + + if (WB_psr !== dut_io.wb_psr) + $display ($time, " Writeback block error: PSR mismatch"); + + // Assignment + + myWB_aluout = dut_io.wb_aluout; + myWB_pcout = dut_io.wb_pcout; + myWB_memout = dut_io.wb_memout; + myWB_dr = dut_io.wb_dr; + myWB_W_Control_in = dut_io.wb_W_Control_in; + myWB_enable_writeback = dut_io.wb_enable_writeback; + myWB_reset = dut_io.reset; + + +endtask + + + diff --git a/ECE745/Project/control.sv b/ECE745/Project/control.sv new file mode 100644 index 0000000..d020bfa --- /dev/null +++ b/ECE745/Project/control.sv @@ -0,0 +1,327 @@ +`define ADD 4'b0001 +`define AND 4'b0101 +`define NOT 4'b1001 +`define LD 4'b0010 +`define LDR 4'b0110 +`define LDI 4'b1010 +`define LEA 4'b1110 +`define ST 4'b0011 +`define STR 4'b0111 +`define STI 4'b1011 +`define BR 4'b0000 +`define JMP 4'b1100 + +logic CON_bypass_alu_1, CON_bypass_alu_2, CON_bypass_mem_1, CON_bypass_mem_2; +logic CON_en_updatePC = 0, CON_en_fetch = 0, CON_en_decode = 0, CON_en_execute = 0, CON_en_mem = 0, CON_en_WB = 0; //All our outputs. +logic [1:0] CON_mem_state; +logic [1:0] CON_stall, fetch_stall; +logic [1:0] lastIR_ST = 0; +logic x = 0, CON_br_taken; +logic [2:0] CON_counter; + +task control (); + + if(dut_io.reset) + begin + CON_en_updatePC = 1; + CON_en_fetch = 1; + CON_en_decode = 0; + CON_en_execute= 0; + CON_en_mem = 0; + CON_en_WB = 0; + CON_br_taken = 0; + CON_mem_state = 3; + CON_counter = 2; + CON_stall = 0; + lastIR_ST = 0; + fetch_stall = 0; + CON_bypass_alu_1 = 1'b0; + CON_bypass_alu_2 = 1'b0; + CON_bypass_mem_1 = 1'b0; + CON_bypass_mem_2 = 1'b0; + end + + else + begin + + CON_bypass_alu_1 = 1'b0; + CON_bypass_alu_2 = 1'b0; + CON_bypass_mem_1 = 1'b0; + CON_bypass_mem_2 = 1'b0; + CON_br_taken = 0; + + if (CON_stall) + begin + CON_stall--; + + if(CON_stall == 1) + begin + CON_en_fetch = 1; + CON_en_updatePC = 1; + CON_en_decode = 1; + CON_en_execute = 1; + CON_en_mem = 1; + CON_en_WB= 1; + end + + if (lastIR_ST == 3) + begin + CON_en_WB = 0; + lastIR_ST= 2; + end + else if(lastIR_ST == 2) + begin + CON_en_WB = 0; + lastIR_ST = 1; + end + else if(lastIR_ST == 1) + begin + CON_en_WB = 1; + lastIR_ST= 0; + end + end + + else + begin + + if(!(fetch_stall)) + begin + // CON_en_fetch = 1; + CON_en_updatePC = 1; + end + else + fetch_stall--; + + // propigate enables throught pipeline + CON_en_WB = CON_en_execute ; + + CON_en_execute = CON_en_decode; + if (~CON_en_execute) CON_en_WB = 0; + CON_en_decode = CON_en_fetch; + + //CON_en_fetch = (CON_counter == 0); + if (CON_counter == 2) CON_en_fetch = 1; + if (CON_counter > 0) + CON_counter--; + end + + //Arithmetic on Arithmetic Dependencies, and Arithmetic on Load Dependencies. Bypass Computations. + //Arithmetic in Decode. Load in Exec. + + if((dut_io.control_IR[15:12]==`ADD) || (dut_io.control_IR[15:12]==`AND) || (dut_io.control_IR[15:12]==`NOT)) + begin + if((dut_io.control_IR_Exec[15:12]==`ADD) || (dut_io.control_IR_Exec[15:12]==`AND) || (dut_io.control_IR_Exec[15:12]==`NOT) || (dut_io.control_IR_Exec[15:12]==`LEA)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[8:6]) + CON_bypass_alu_1 = 1'b1; + + if(!(dut_io.control_IR[5])) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[2:0]) + CON_bypass_alu_2 = 1'b1; + end + + end + + if((dut_io.control_IR_Exec[15:12]==`LD) || (dut_io.control_IR_Exec[15:12]==`LDI) || (dut_io.control_IR_Exec[15:12]==`LDR)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[8:6]) + CON_bypass_mem_1 = 1'b1; + + if(!(dut_io.control_IR[5])) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[2:0]) + CON_bypass_mem_2 = 1'b1; + end + end + + end + + //Load(LDR) on Arithmetic Dependencies. Bypass Computations. + //LDR in Decode. Arithmetic in Exec. + + if((dut_io.control_IR[15:12]==`LDR)) + begin + if((dut_io.control_IR_Exec[15:12]==`ADD) || (dut_io.control_IR_Exec[15:12]==`AND) || (dut_io.control_IR_Exec[15:12]==`NOT) || (dut_io.control_IR_Exec[15:12]==`LEA)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[8:6]) + CON_bypass_alu_1 = 1'b1; + end + + end + + //Store(STR) on Arithmetic Dependencies. Bypass Computations. + //STR in Decode. Arithmetic in Exec. + + if((dut_io.control_IR[15:12]==`STR)) + begin + if((dut_io.control_IR_Exec[15:12]==`ADD) || (dut_io.control_IR_Exec[15:12]==`AND) || (dut_io.control_IR_Exec[15:12]==`NOT) || (dut_io.control_IR_Exec[15:12]==`LEA)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[8:6]) + CON_bypass_alu_1 = 1'b1; + + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[11:9]) + CON_bypass_alu_2 = 1'b1; + end + + end + + //Store(ST/STI) on Arithmetic Dependencies. Bypass Computations. + //ST/STI in Decode. Arithmetic in Exec. + + if((dut_io.control_IR[15:12]==`STI) || (dut_io.control_IR[15:12]==`ST)) + begin + if((dut_io.control_IR_Exec[15:12]==`ADD) || (dut_io.control_IR_Exec[15:12]==`AND) || (dut_io.control_IR_Exec[15:12]==`NOT) || (dut_io.control_IR_Exec[15:12]==`LEA)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[11:9]) + CON_bypass_alu_2 = 1'b1; + + end + end + + //JUMP on Arithmetic Dependencies. Bypass Computations. + //JUMP in Decode. Arithmetic in Exec. + + if((dut_io.control_IR[15:12]==`JMP)) + begin + if((dut_io.control_IR_Exec[15:12]==`ADD) || (dut_io.control_IR_Exec[15:12]==`AND) || (dut_io.control_IR_Exec[15:12]==`NOT) || (dut_io.control_IR_Exec[15:12]==`LEA)) + begin + if(dut_io.control_IR_Exec[11:9] == dut_io.control_IR[8:6]) + CON_bypass_alu_1 = 1'b1; + + end + end + + + ////////// MEM_STATE LOGIC HERE! ////////////////////// + + case (CON_mem_state) + 3: begin + if((dut_io.control_IR_Exec[15:12]==`LD) || (dut_io.control_IR_Exec[15:12]==`LDR)) + CON_mem_state = 0; + + if((dut_io.control_IR_Exec[15:12]==`ST) || (dut_io.control_IR_Exec[15:12]==`STR)) + CON_mem_state = 2; + + if((dut_io.control_IR_Exec[15:12]==`STI) || (dut_io.control_IR_Exec[15:12]==`LDI)) + CON_mem_state = 1; + end + + 2: CON_mem_state = 3; + + 1: begin + if((dut_io.control_IR_Exec[15:12]==`LD) || (dut_io.control_IR_Exec[15:12]==`LDR) || (dut_io.control_IR_Exec[15:12]==`LDI)) + CON_mem_state = 0; + + if((dut_io.control_IR_Exec[15:12]==`ST) || (dut_io.control_IR_Exec[15:12]==`STR) || (dut_io.control_IR_Exec[15:12]==`STI)) + CON_mem_state = 2; + + end + + 0: CON_mem_state = 3; + endcase + + + ////////// ENABLE LOGIC BEGINS HERE! ////////////////// + //////////logic CON_en_updatePC, CON_en_fetch, CON_en_decode, CON_en_execute, CON_en_WB; + + if (!CON_stall) + begin + + if((dut_io.control_IR_Exec[15:12]==`LD) || (dut_io.control_IR_Exec[15:12]==`LDR)) + begin + CON_stall = 2; + CON_en_updatePC = 0; + CON_en_fetch = 0; + CON_en_decode = 0; + CON_en_execute = 0; + CON_en_WB = 0; + end + if((dut_io.control_IR_Exec[15:12]==`ST) || (dut_io.control_IR_Exec[15:12]==`STR)) + begin + CON_stall = 2; + CON_en_updatePC = 0; + CON_en_fetch = 0; + CON_en_decode = 0; + CON_en_execute = 0; + CON_en_WB = 0; + end + + if((dut_io.control_IR_Exec[15:12]==`LDI)|| (dut_io.control_IR_Exec[15:12]==`STI)) + begin + CON_stall = 3; + CON_en_updatePC = 0; + CON_en_fetch = 0; + CON_en_decode = 0; + CON_en_execute = 0; + CON_en_WB = 0; + end + + + if(!lastIR_ST) + begin + if((dut_io.control_IR_Exec[15:12]==`ST) || (dut_io.control_IR_Exec[15:12]==`STR)) + lastIR_ST = 2; + else if((dut_io.control_IR_Exec[15:12]==`STI)) + begin + lastIR_ST = 3; + x = 1; + end + end + end + + ////////////BRANCH TAKEN//////////// + + CON_br_taken = | (dut_io.control_NZP & dut_io.control_psr); + if (CON_br_taken) CON_en_updatePC = 1; + + if (!CON_counter) + begin + #1; + if((top_io.cb.Instr_dout[15:12]==`BR) || (top_io.cb.Instr_dout[15:12]==`JMP)) + begin + CON_en_updatePC = 0; + CON_en_fetch = 0; + fetch_stall = 2; + CON_counter = 4; + end + end + + + end + + #1; + if(CON_bypass_alu_1 !== dut_io.control_bypass_alu_1) + $display($time, " Control signal error : ALU bypass 1 incorrect "); + + if(CON_bypass_alu_2 !== dut_io.control_bypass_alu_2) + $display($time, " Control signal error : ALU bypass 2 incorrect "); + + if(CON_bypass_mem_1 !== dut_io.control_bypass_mem_1) + $display($time, " Control signal error : MEM bypass 1 incorrect "); + + if(CON_bypass_mem_2 !== dut_io.control_bypass_mem_2) + $display($time, " Control signal error : MEM bypass 2 incorrect "); + + if(CON_mem_state !== dut_io.control_mem_state) + $display($time, " Control signal error : MEM STATE incorrect "); + + if(CON_en_fetch !== dut_io.control_enable_fetch) + $display($time, " Control signal error : Enable Fetch incorrect "); + + if(CON_en_decode !== dut_io.control_enable_decode) + $display($time, " Control signal error : Enable Decode incorrect "); + + if(CON_en_execute !== dut_io.control_enable_execute) + $display($time, " Control signal error : Enable Execute incorrect "); + + if(CON_en_WB !== dut_io.control_enable_writeback) + $display($time, " Control signal error : Enable Writeback incorrect "); + + if(CON_en_updatePC !== dut_io.control_enable_updatePC) + $display($time, " Control signal error : Enable UpdatePC incorrect "); + + if(CON_br_taken !== dut_io.control_br_taken) + $display($time, " Control signal error : Branch Taken incorrect "); + +endtask diff --git a/ECE745/Project/decode.sv b/ECE745/Project/decode.sv new file mode 100644 index 0000000..0018e52 --- /dev/null +++ b/ECE745/Project/decode.sv @@ -0,0 +1,209 @@ +`define ADD 4'b0001 +`define AND 4'b0101 +`define NOT 4'b1001 +`define LD 4'b0010 +`define LDR 4'b0110 +`define LDI 4'b1010 +`define LEA 4'b1110 +`define ST 4'b0011 +`define STR 4'b0111 +`define STI 4'b1011 +`define BR 4'b0000 +`define JMP 4'b1100 + +logic [15:0] proc_instr_dout; +logic [15:0] proc_npc_in; +logic proc_enable_decode, proc_reset; +logic [15:0] DEC_IR; +logic [15:0] DEC_npc_out; +logic [5:0] DEC_E_Control; +logic [1:0] DEC_W_Control; +logic DEC_Mem_Control; + +task decode (); + + if (dut_io.reset) + begin + DEC_IR = 0; + DEC_npc_out = 0; + DEC_E_Control = 0; + DEC_W_Control = 0; + DEC_Mem_Control = 0; + end + + else + begin + + if(proc_enable_decode) + begin + DEC_IR = dut_io.dec_instr_dout; + + DEC_npc_out = proc_npc_in; + + casex (dut_io.dec_instr_dout[15:12]) //W_Control computation + + 4'bxxx1: + DEC_W_Control = 0; //Arithmetic, Stores + 4'b0x10: + DEC_W_Control = 1; //LD, LDR, LDI + 4'b1010: + DEC_W_Control = 1; // LDI + 4'b1110: + DEC_W_Control = 2; //LEA + 4'bxx00: + DEC_W_Control = 0; //BR and JMP + default: + DEC_W_Control = 0; + + endcase + + casex (dut_io.dec_instr_dout[15:12]) //E_Control computation + + `BR: //BR + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for BR instruction"); + end + + `ADD: //ADD + begin + DEC_E_Control[5:4] = 0; + if(dut_io.dec_instr_dout[5]) + DEC_E_Control[0] = 0; + else + DEC_E_Control[0] = 1; + if (DEC_E_Control[5:4] !== dut_io.dec_E_Control[5:4]) + $display ($time, "Decode block error -- E_Control error for ADD instruction, [5:4] wrong"); + if (DEC_E_Control[0] !== dut_io.dec_E_Control[0]) + $display ($time, "Decode block error -- E_Control error for ADD -- last bit wrong"); + end + + `LD: //LD + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for LD instruction"); + end + + `ST: //ST + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for ST instruction"); + end + + `AND: //AND + begin + DEC_E_Control[5:4] = 1; + if(dut_io.dec_instr_dout[5]) + DEC_E_Control[0] = 0; + else + DEC_E_Control[0] = 1; + if (DEC_E_Control[5:4] !== dut_io.dec_E_Control[5:4]) + $display ($time, "Decode block error -- E_Control error for AND instruction, [5:4] wrong"); + if (DEC_E_Control[0] !== dut_io.dec_E_Control[0]) + $display ($time, "Decode block error -- E_Control error for AND -- last bit wrong"); + end + + `LDR: //LDR + begin + DEC_E_Control[3:2] = 2; + DEC_E_Control[1] = 0; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for LDR"); + end + + `STR: //STR + begin + DEC_E_Control[3:2] = 2; + DEC_E_Control[1] = 0; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for STR"); + end + + `NOT: //NOT + begin + DEC_E_Control[5:4] = 2; + if (DEC_E_Control[5:4] !== dut_io.dec_E_Control[5:4]) + $display ($time, "Decode block error -- E_Control error for NOT instruction, [5:4] wrong"); + end + + `LDI: //LDI + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for LDI"); + end + + `STI: //STI + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for STI"); + end + + `JMP: //JMP + begin + DEC_E_Control[3:2] = 3; + DEC_E_Control[1] = 0; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for JMP"); + end + + `LEA: //LEA + begin + DEC_E_Control[3:2] = 1; + DEC_E_Control[1] = 1; + if (DEC_E_Control[3:1] !== dut_io.dec_E_Control[3:1]) + $display ($time, "Decode block error -- E_Control error for LEA"); + end + endcase + + casex (dut_io.dec_instr_dout[15:12]) //Mem_Control computation + + `LD: //LD + DEC_Mem_Control = 0; + `LDR: //LDR + DEC_Mem_Control = 0; + `LDI: //LDI + DEC_Mem_Control = 1; + `ST: //ST + DEC_Mem_Control = 0; + `STR: //STR + DEC_Mem_Control = 0; + `STI: //STI + DEC_Mem_Control = 1; + default: + DEC_Mem_Control = 0; //Should be removed. + endcase + end + end + + if (DEC_Mem_Control !== dut_io.dec_Mem_Control) + $display ($time, "Decode block error -- Mem_Control error"); + +// if (DEC_E_Control !== dut_io.dec_E_Control) +// $display ($time, "Decode block error -- E_Control error"); + + if (DEC_W_Control !== dut_io.dec_W_Control) + $display ($time, "Decode block error -- W_Control error"); + + if (DEC_IR !== dut_io.dec_IR) + $display ($time, "Decode block error -- IR incorrectly passed through decode"); + + if (DEC_npc_out !== dut_io.dec_npc_out) + $display ($time, "Decode block error -- NPC incorrectly passed through"); + + + proc_npc_in = dut_io.dec_npc_in; + proc_instr_dout = dut_io.dec_instr_dout; + proc_enable_decode = dut_io.dec_enable_decode; + proc_reset = dut_io.reset; + +endtask diff --git a/ECE745/Project/execute.sv b/ECE745/Project/execute.sv new file mode 100644 index 0000000..2a1a862 --- /dev/null +++ b/ECE745/Project/execute.sv @@ -0,0 +1,304 @@ +`define ADD 4'b0001 +`define AND 4'b0101 +`define NOT 4'b1001 +`define LD 4'b0010 +`define LDR 4'b0110 +`define LDI 4'b1010 +`define LEA 4'b1110 +`define ST 4'b0011 +`define STR 4'b0111 +`define STI 4'b1011 +`define BR 4'b0000 +`define JMP 4'b1100 + +logic [15:0] EX_imm5, EX_offset6, EX_offset9, EX_offset11; +logic [15:0] EX_aluin1, EX_aluin2, EX_aluout, EX_pcout, EX_IR_exec, EX_M_Data; +logic [1:0] EX_W_Control_out; +logic [2:0] EX_sr1, EX_sr2, EX_dr, EX_NZP; //make sure that sr1 and sr2 are ASYNCH. So NEW inputs are processed, all other i/p are old. +logic EX_Mem_Control_out; +logic [15:0] EX_a, EX_b; //for pcout calculations + +//buffers for input +logic myEX_enable_execute, myEX_Mem_Control_in; +logic [1:0] myEX_W_Control_in; +logic [15:0] myEX_IR, myEX_Mem_Bypass_Val, myEX_VSR1, myEX_VSR2, myEX_npc_in; +logic myEX_bypass_alu_1, myEX_bypass_alu_2, myEX_bypass_mem_1, myEX_bypass_mem_2; +logic [5:0] myEX_E_Control; +//logic myEX_reset; + +task execute (); + + + if (dut_io.reset) + begin + EX_IR_exec = 0; + EX_W_Control_out = 0; + EX_Mem_Control_out = 0; + EX_dr = 3'b0; + EX_pcout = 16'h0; + EX_aluout = 16'h0; + EX_NZP = 0; + EX_M_Data = 0; + EX_sr1 = 0; + EX_sr2 = 0; + end + + else + begin + + // if (dut_io.ex_enable_execute) + // if (myEX_enable_execute) + + + begin + // send the sr1 and sr2 addresses + // CHECK SR1 and SR2 asynch. i.e compare the CURRENT INPUT LOGIC with the CURRENT OUTPUT. No need of buffering these signals. + + EX_sr1 = dut_io.ex_IR[8:6]; // always -- for all instructions. RESET doesn't affect. + //also, LATEST INPUTS. ASYNCH OP. + + if ((dut_io.ex_IR[15:12] === `ADD) || (dut_io.ex_IR[15:12] === `AND) || (dut_io.ex_IR[15:12] === `NOT)) + // ADD or AND or NOT + begin + EX_sr2 = dut_io.ex_IR[2:0]; + end + + else if ((dut_io.ex_IR[15:12] === `LD) || (dut_io.ex_IR[15:12] === `LDR) || (dut_io.ex_IR[15:12] === `LDI) || (dut_io.ex_IR[15:12] === `LEA)) + // All Load instr + begin + EX_sr2 = 3'b0; + end + + else if ((dut_io.ex_IR[15:12] === `ST) || (dut_io.ex_IR[15:12] === `STR) || (dut_io.ex_IR[15:12] === `STI)) + // All Store instr + begin + EX_sr2 = dut_io.ex_IR[11:9]; + end + + else if ((dut_io.ex_IR[15:12] === `BR) || (dut_io.ex_IR[15:12] === `JMP)) + // CONTROL (branch and JMP) + begin + EX_sr2 = 3'b0; + end + else + begin + //$display ($time, "Error in the generated instruction. IR[15:12] not matching anything in gr"); + end + end + + + if (myEX_enable_execute) + begin + // passing values (non changing) + EX_IR_exec = myEX_IR; + EX_W_Control_out = myEX_W_Control_in; + EX_Mem_Control_out = myEX_Mem_Control_in; + + + // DR1 + + if ((myEX_IR[15:12] === `ADD) || (myEX_IR[15:12] === `AND) || (myEX_IR[15:12] === `NOT)) + // ADD or AND or NOT + begin + EX_dr = myEX_IR[11:9]; + end + + else if ((myEX_IR[15:12] === `LD) || (myEX_IR[15:12] === `LDR) || (myEX_IR[15:12] === `LDI) || (myEX_IR[15:12] === `LEA)) + // All Load instr + begin + EX_dr = myEX_IR[11:9]; + end + + else if ((myEX_IR[15:12] === `ST) || (myEX_IR[15:12] === `STR) || (myEX_IR[15:12] === `STI)) + // All Store instr + begin + EX_dr = 3'b0; + end + + else if ((myEX_IR[15:12] === `BR) || (myEX_IR[15:12] === `JMP)) + // CONTROL (branch and JMP) + begin + EX_dr = 3'b0; + end + else + begin + $display ($time, "Error in the generated instruction. IR[15:12] not matching anything in gr"); + end + + + // Imm5 and other offset values + + EX_imm5 = {{11{myEX_IR[4]}}, myEX_IR[4:0]}; + EX_offset6 = {{10{myEX_IR[5]}}, myEX_IR[5:0]}; + EX_offset9 = {{7{myEX_IR[8]}}, myEX_IR[8:0]}; + EX_offset11 = {{5{myEX_IR[10]}}, myEX_IR[10:0]}; + + + //aluout logic + + //EX_aluin1 = (myEX_bypass_alu_1 | myEX_bypass_mem_1)? ((myEX_bypass_alu_1)? EX_aluout: + + if (myEX_bypass_alu_1 === 1'b1) + begin + EX_aluin1 = EX_aluout; //this EX_aluout is from the gr. Should it be taken from DUT? (for better bug finding?) + end + else if (myEX_bypass_mem_1 === 1'b1) + begin + EX_aluin1 = myEX_Mem_Bypass_Val; + end + else + begin + EX_aluin1 = myEX_VSR1; // use latest VSR1 and VSR2 + end + + + // EX_aluin2 logic + + if (myEX_bypass_alu_2 === 1'b1) + begin + EX_aluin2 = EX_aluout; //this EX_aluout is from the gr. Should it be taken from DUT? (for better bug finding?) + end + else if (myEX_bypass_mem_2 === 1'b1) + begin + EX_aluin2 = myEX_Mem_Bypass_Val; + end + else + begin + EX_aluin2 = (myEX_IR[5])? EX_imm5 : myEX_VSR2; + end + + // aluout + + casex (myEX_E_Control[5:4]) + + 2'h0: EX_aluout = EX_aluin1 + EX_aluin2; + 2'h1: EX_aluout = EX_aluin1 & EX_aluin2; + 2'h2: EX_aluout = ~ EX_aluin1; + default: $display("Error in E_control"); + endcase + + + + // pcout logic + + casex (myEX_E_Control[3:2]) //pcselect1 + + 2'h0: EX_a = EX_offset11; + 2'h1: EX_a = EX_offset9; + 2'h2: EX_a = EX_offset6; + 2'h3: EX_a = 16'h0; + default: $display("Error in E_control"); + + endcase + + casex (myEX_E_Control[1]) //pcselect1 + + 2'h0: EX_b = EX_aluin1; //need value of aluin 1 !! + 2'h1: EX_b = myEX_npc_in - 1; + default: $display("Error in E_Control"); + + endcase + + + // EX_pcout = (EX_a + EX_b) - 1; + + // if ((myEX_IR[15:12] === 4'b0110) || (myEX_IR[15:12] === 4'b0111)) //LDR and STR + // EX_pcout = EX_pcout + 1; + + + EX_pcout = (EX_a + EX_b); + + + if ((myEX_IR[15:12] === `ADD) || (myEX_IR[15:12] === `AND) || (myEX_IR[15:12] === `NOT)) + // ADD or AND or NOT + + EX_pcout = EX_aluout; + + else + begin + EX_aluout = EX_pcout; + end + // NZP logic + + casex (myEX_IR[15:12]) + + 4'h0: EX_NZP = myEX_IR[11:9]; + 4'hc: EX_NZP = 3'b111; + default: EX_NZP = 3'b000; + endcase + + // M_Data + + EX_M_Data = (myEX_bypass_alu_2) ? EX_aluin2 : myEX_VSR2; + + + end + + else + begin + EX_NZP = 3'b000; + end + + + + end //END OF ALL THE LOFIC CALCULATIONS FOR THE GOLDEN REF + + + // Assignment and Checking + //Check + + if (EX_W_Control_out !== dut_io.ex_W_Control_out) + $display ($time, " Execute block error: W_control mismatch"); + + if (EX_Mem_Control_out !== dut_io.ex_Mem_Control_out) + $display ($time, " Execute block error: Mem_Control mismatch"); + + if (EX_aluout !== dut_io.ex_aluout) + $display ($time, " Execute block error: aluout mismatch"); + + if (EX_aluout !== dut_io.ex_aluout) + $display ($time, " Execute block error: aluout mismatch"); + + if (EX_pcout !== dut_io.ex_pcout) + $display ($time, " Execute block error: pcout mismatch"); + + if (EX_dr !== dut_io.ex_dr) + $display ($time, " Execute block error: DR mismatch"); + + if (EX_sr1 !== dut_io.ex_sr1) + $display ($time, " Execute block error: SR1 mismatch"); + + if (EX_sr2 !== dut_io.ex_sr2) + $display ($time, " Execute block error: SR2 mismatch"); + + if (EX_IR_exec !== dut_io.ex_IR_Exec) + $display ($time, " Execute block error: IR_Exec mismatch .. IR is not being passed correctly"); + + if (EX_NZP !== dut_io.ex_NZP) + $display ($time, " Execute block error: NZP mismatch"); + + if (EX_M_Data !== dut_io.ex_M_Data) + $display ($time, " Execute block error: M_Data mismatch"); + + + + // myEX_enable_execute = dut_io.ex_enable_execute; + myEX_Mem_Control_in = dut_io.ex_Mem_Control_in; + myEX_W_Control_in = dut_io.ex_W_Control_in; + myEX_IR = dut_io.ex_IR; + myEX_Mem_Bypass_Val = dut_io.ex_Mem_Bypass_Val; + myEX_VSR1 = dut_io.ex_VSR1; + myEX_VSR2 = dut_io.ex_VSR2; + myEX_npc_in = dut_io.ex_npc_in; + myEX_bypass_alu_1 = dut_io.ex_bypass_alu_1; + myEX_bypass_alu_2 = dut_io.ex_bypass_alu_2; + myEX_bypass_mem_1 = dut_io.ex_bypass_mem_1; + myEX_bypass_mem_2 = dut_io.ex_bypass_mem_2; + myEX_E_Control = dut_io.ex_E_Control; + // myEX_reset = dut_io.reset; + + myEX_enable_execute = dut_io.ex_enable_execute; + + + +endtask diff --git a/ECE745/Project/generator.sv b/ECE745/Project/generator.sv new file mode 100644 index 0000000..0ff8b86 --- /dev/null +++ b/ECE745/Project/generator.sv @@ -0,0 +1,73 @@ +`define ADD 4'b0001 +`define AND 4'b0101 +`define NOT 4'b1001 +`define LD 4'b0010 +`define LDR 4'b0110 +`define LDI 4'b1010 +`define LEA 4'b1110 +`define ST 4'b0011 +`define STR 4'b0111 +`define STI 4'b1011 +`define BR 4'b0000 +`define JMP 4'b1100 + +class Instruction; + rand logic [3:0] opcode; + constraint controlops { opcode inside { 4'h0, 4'hc, 4'h2, 4'h6, 4'ha, 4'h3, 4'h7, 4'hb};} + constraint arithops { opcode inside { 4'h1, 4'h5, 4'h9, 4'he };} + + rand logic [2:0] gen_nzp; + constraint nzpconstraints { gen_nzp inside { 3'h1, 3'h2, 3'h3, 3'h4,3'h5, 3'h6, 3'h7};} + + rand logic [11:0] rest; + logic [15:0] finalinst; + + rand logic [15:0] loadvalue; + constraint loadval { loadvalue inside { 16'haaaa, 16'h5555};} + + static int ctrl_count = 0; + +endclass + + Instruction instr; + +task generator(); + + if(top_io.cb.instrmem_rd != 0) + begin + + if (instr.randomize() == 1) + begin + instr.finalinst[15:12] = instr.opcode; + instr.finalinst[11:0] = instr.rest; + + case (instr.opcode) + + `NOT : instr.finalinst[5:0] = 6'b111111; + + `JMP : begin + instr.finalinst[11:9] = 3'b111; + instr.finalinst[5:0] = 6'b000000; + end + + `BR : begin + instr.finalinst[11:9] = instr.gen_nzp; + end + `ADD: begin + if(instr.finalinst[5] == 0) + instr.finalinst[4:3] = 2'b0; + end + `AND: begin + if(instr.finalinst[5] == 0) + instr.finalinst[4:3] = 2'b0; + end + + endcase + + end + + top_io.cb.Instr_dout <= instr.finalinst; + top_io.cb.Data_dout <= instr.loadvalue; + end +endtask + diff --git a/ECE745/Project/if.sv b/ECE745/Project/if.sv new file mode 100644 index 0000000..ea8bbfb --- /dev/null +++ b/ECE745/Project/if.sv @@ -0,0 +1,82 @@ +logic gr_if_instrmem_rd; +logic [15:0] gr_if_pc; +logic [15:0] gr_if_npc_out; + +logic myIF_enable_updatePC, myIF_enable_fetch, myIF_br_taken; +logic [15:0] myIF_taddr; +logic [1:0] select; + +task fetch (); + + if (dut_io.reset) + begin + gr_if_pc = 16'h3000; + gr_if_npc_out = 16'h3001; + gr_if_instrmem_rd = 1'h1; + end + + else + begin + + select = {myIF_enable_updatePC, myIF_br_taken}; + + casex (select) + + 3'b10: + begin + gr_if_pc = gr_if_npc_out; + end + + 3'b11: + begin + gr_if_pc =myIF_taddr; + end + + 3'b0x: + begin + gr_if_pc = gr_if_pc; + end + + default: + begin + end + + endcase + + gr_if_npc_out = gr_if_pc + 1; + + end + #1; + casex (dut_io.fetch_enable_fetch) + 1'b0: + begin + gr_if_instrmem_rd = 1'b0; // should be z + end + + 1'b1: + begin + gr_if_instrmem_rd = 1'b1; + end + endcase + + + myIF_enable_updatePC = dut_io.fetch_enable_updatePC; + myIF_br_taken = dut_io.fetch_br_taken; + myIF_taddr = dut_io.fetch_taddr; + myIF_enable_fetch = dut_io.fetch_enable_fetch; + + + + + + if (gr_if_instrmem_rd !== dut_io.fetch_instrmem_rd) + $display ($time, "fetch error - instrmem_rd"); + + if (gr_if_pc !== dut_io.fetch_pc) + $display ($time, "fetch error - pc"); + + if (gr_if_npc_out !== dut_io.fetch_npc_out) + $display ($time, "fetch error - npc_out"); + +endtask + diff --git a/ECE745/Project/mem.sv b/ECE745/Project/mem.sv new file mode 100644 index 0000000..f4ebdbb --- /dev/null +++ b/ECE745/Project/mem.sv @@ -0,0 +1,57 @@ +logic [15:0] MEM_dmem_addr, MEM_dmem_din, MEM_memout; +logic MEM_dmem_rd; + +task memaccess (); + + MEM_memout = dut_io.mem_dmem_dout; //Check for the LD spec. + + if (dut_io.mem_mem_state === 2'b00) //Selecting all states. + begin + MEM_dmem_rd = 1; + MEM_dmem_din = 0; + if(dut_io.mem_M_Control) + MEM_dmem_addr = dut_io.mem_dmem_dout; + else + MEM_dmem_addr = dut_io.mem_M_Addr; + end + + else if(dut_io.mem_mem_state === 2'b01) + begin + MEM_dmem_rd = 1; + MEM_dmem_din = 0; + MEM_dmem_addr = dut_io.mem_M_Addr; + end + + else if(dut_io.mem_mem_state === 2'b10) + begin + MEM_dmem_rd = 0; + MEM_dmem_din = dut_io.mem_M_Data; + if(dut_io.mem_M_Control) + MEM_dmem_addr = dut_io.mem_dmem_dout; + else + MEM_dmem_addr = dut_io.mem_M_Addr; + end + + else if(dut_io.mem_mem_state === 2'b11) + begin + MEM_dmem_rd = 1'bz; + MEM_dmem_din = 16'bz; + MEM_dmem_addr = 16'bz; + end + + + if (MEM_dmem_rd !== dut_io.mem_dmem_rd) + $display ($time, "Error in mem_dmem_rd"); + + if (MEM_dmem_din !== dut_io.mem_dmem_din) + $display ($time, "Error in mem_dmem_din"); + + if (MEM_dmem_addr !== dut_io.mem_dmem_addr) + $display ($time, "Error in mem_dmem_addr"); + + if (MEM_memout !== dut_io.mem_memout) + $display ($time, "Error in mem_memout"); + + +endtask + diff --git a/ECE745/Project/project.if.sv b/ECE745/Project/project.if.sv new file mode 100644 index 0000000..99b8ce2 --- /dev/null +++ b/ECE745/Project/project.if.sv @@ -0,0 +1,82 @@ +interface LC3_io(input bit clock); + + logic reset, instrmem_rd, complete_instr, complete_data, Data_rd; + logic [15:0] pc, Instr_dout, Data_addr, Data_dout, Data_din; + + + clocking cb @(posedge clock); + default input #1 output #0; + + // instruction memory side + input pc; + input instrmem_rd; + output Instr_dout; + + // data memory side + input Data_din; + input Data_rd; + input Data_addr; + output Data_dout; + + output reset; + + + endclocking + + modport TB(clocking cb, output complete_data, output complete_instr); //modify to include reset +endinterface + + +interface dut_Probe_if( + + input logic reset, + // fetch block interface signals + input logic fetch_enable_updatePC,fetch_enable_fetch,fetch_br_taken, + input logic [15:0] fetch_taddr, + input logic fetch_instrmem_rd, + input logic [15:0] fetch_pc,fetch_npc_out, + + //decode block interface signals + input logic [15:0] dec_npc_in, dec_instr_dout, + input logic dec_enable_decode, + // input logic [2:0] dec_psr, + input logic [15:0] dec_IR, dec_npc_out, + input logic [5:0] dec_E_Control, + input logic [1:0] dec_W_Control, + input logic dec_Mem_Control, + + //execute block + input logic [5:0] ex_E_Control, + input logic [15:0] ex_IR, ex_npc_in, + input logic ex_bypass_alu_1, ex_bypass_alu_2, ex_bypass_mem_1, ex_bypass_mem_2, + input logic [15:0] ex_VSR1, ex_VSR2, ex_Mem_Bypass_Val, + input logic [1:0] ex_W_Control_in, ex_W_Control_out, + input logic ex_Mem_Control_in, ex_Mem_Control_out, ex_enable_execute, + + input logic [15:0] ex_aluout, ex_pcout, + input logic [2:0] ex_dr, ex_sr1, ex_sr2, ex_NZP, + input logic [15:0] ex_IR_Exec, ex_M_Data, + + //writeback + input logic [15:0] wb_npc, wb_aluout, wb_pcout, wb_memout, + input logic [1:0] wb_W_Control_in, + input logic wb_enable_writeback, + input logic [2:0] wb_dr, wb_sr1, wb_sr2, + input logic [15:0] wb_VSR1, wb_VSR2, + input logic [2:0] wb_psr, + + //memory if + input logic [15:0] mem_M_Data, mem_M_Addr, mem_dmem_dout, mem_dmem_addr, mem_dmem_din, mem_memout, + input logic mem_M_Control, mem_dmem_rd, + input logic [1:0] mem_mem_state, + + //control + input logic control_complete_data, control_complete_instr, + input logic [15:0] control_IR, control_IR_Exec, control_imem_dout, + input logic [2:0] control_psr, control_NZP, + input logic control_enable_updatePC, control_enable_fetch, control_enable_decode, control_enable_execute, + input logic control_enable_writeback, control_br_taken, + input logic control_bypass_alu_1, control_bypass_alu_2, control_bypass_mem_1, control_bypass_mem_2, + input logic [1:0] control_mem_state + ); +endinterface diff --git a/ECE745/Project/project.test_top.sv b/ECE745/Project/project.test_top.sv new file mode 100644 index 0000000..01c1590 --- /dev/null +++ b/ECE745/Project/project.test_top.sv @@ -0,0 +1,129 @@ + +module LC3_test_top; + parameter simulation_cycle = 20; + + reg SysClock; + LC3_io top_io(SysClock); // Instantiate the top level interface of the testbench to be used for driving the LC3 and reading the LC3 outputs. + + // Instantiating and Connecting the probe signals for the Fetch block with the DUT fetch block signals using the "dut" instantation of LC3 below. + dut_Probe_if dut_io ( + .reset (dut.Fetch.reset), + .fetch_enable_updatePC(dut.Fetch.enable_updatePC), + .fetch_enable_fetch(dut.Fetch.enable_fetch), + .fetch_pc(dut.Fetch.pc), + .fetch_npc_out(dut.Fetch.npc_out), + .fetch_instrmem_rd(dut.Fetch.instrmem_rd), + .fetch_taddr(dut.Fetch.taddr), + .fetch_br_taken(dut.Fetch.br_taken), + + .dec_enable_decode(dut.Dec.enable_decode), + .dec_instr_dout(dut.Dec.dout), + .dec_E_Control(dut.Dec.E_Control), + .dec_npc_in(dut.Dec.npc_in), +// .dec_psr(dut.Dec.psr), + .dec_Mem_Control(dut.Dec.Mem_Control), + .dec_W_Control(dut.Dec.W_Control), + .dec_IR(dut.Dec.IR), + .dec_npc_out(dut.Dec.npc_out), + +//Ex + .ex_E_Control(dut.Ex.E_Control), + .ex_bypass_alu_1(dut.Ex.bypass_alu_1), + .ex_bypass_alu_2(dut.Ex.bypass_alu_2), + .ex_IR(dut.Ex.IR), + .ex_npc_in(dut.Ex.npc), + .ex_W_Control_in(dut.Ex.W_Control_in), + .ex_Mem_Control_in(dut.Ex.Mem_Control_in), + .ex_VSR1(dut.Ex.VSR1), + .ex_VSR2(dut.Ex.VSR2), + .ex_bypass_mem_1(dut.Ex.bypass_mem_1), + .ex_bypass_mem_2(dut.Ex.bypass_mem_2), + .ex_Mem_Bypass_Val(dut.Ex.Mem_Bypass_Val), + .ex_enable_execute(dut.Ex.enable_execute), + .ex_W_Control_out(dut.Ex.W_Control_out), + .ex_Mem_Control_out(dut.Ex.Mem_Control_out), + .ex_aluout(dut.Ex.aluout), + .ex_pcout(dut.Ex.pcout), + .ex_sr1(dut.Ex.sr1), + .ex_sr2(dut.Ex.sr2), + .ex_dr(dut.Ex.dr), + .ex_M_Data(dut.Ex.M_Data), + .ex_NZP(dut.Ex.NZP), + .ex_IR_Exec(dut.Ex.IR_Exec), + +//MemAccess + .mem_mem_state(dut.MemAccess.mem_state), + .mem_M_Control(dut.MemAccess.M_Control), + .mem_M_Data(dut.MemAccess.M_Data), + .mem_M_Addr(dut.MemAccess.M_Addr), + .mem_memout(dut.MemAccess.memout), + .mem_dmem_addr(dut.MemAccess.Data_addr), + .mem_dmem_din(dut.MemAccess.Data_din), + .mem_dmem_dout(dut.MemAccess.Data_dout), + .mem_dmem_rd(dut.MemAccess.Data_rd), + +// Writeback WB + .wb_enable_writeback(dut.WB.enable_writeback), + .wb_W_Control_in(dut.WB.W_Control), + .wb_aluout(dut.WB.aluout), + .wb_memout(dut.WB.memout), + .wb_pcout(dut.WB.pcout), + .wb_npc(dut.WB.npc), + .wb_sr1(dut.WB.sr1), + .wb_sr2(dut.WB.sr2), + .wb_dr(dut.WB.dr), + .wb_VSR1(dut.WB.d1), + .wb_VSR2(dut.WB.d2), + .wb_psr(dut.WB.psr), + +//Ctrl + .control_IR(dut.Ctrl.IR), + .control_complete_data(dut.Ctrl.complete_data), + .control_complete_instr(dut.Ctrl.complete_instr), + .control_bypass_alu_1(dut.Ctrl.bypass_alu_1), + .control_bypass_alu_2(dut.Ctrl.bypass_alu_2), + .control_bypass_mem_1(dut.Ctrl.bypass_mem_1), + .control_bypass_mem_2(dut.Ctrl.bypass_mem_2), + .control_enable_fetch(dut.Ctrl.enable_fetch), + .control_enable_decode(dut.Ctrl.enable_decode), + .control_enable_execute(dut.Ctrl.enable_execute), + .control_enable_writeback(dut.Ctrl.enable_writeback), + .control_enable_updatePC(dut.Ctrl.enable_updatePC), + .control_mem_state(dut.Ctrl.mem_state), + .control_NZP(dut.Ctrl.NZP), + .control_psr(dut.Ctrl.psr), + .control_IR_Exec(dut.Ctrl.IR_Exec), + .control_imem_dout(dut.Ctrl.Instr_dout), + .control_br_taken(dut.Ctrl.br_taken) + ); + + // Passing the top level interface and probe interface to the testbench. + LC3_test test(top_io, dut_io); + + // Instantiating the top-level DUT. + LC3 dut( + .clock(top_io.clock), + .reset(top_io.reset), + .pc(top_io.pc), + .instrmem_rd(top_io.instrmem_rd), + .Instr_dout(top_io.Instr_dout), + .Data_addr(top_io.Data_addr), + .complete_instr(top_io.complete_instr), + .complete_data(top_io.complete_data), + .Data_din(top_io.Data_din), + .Data_dout(top_io.Data_dout), + .Data_rd(top_io.Data_rd) + + ); + + initial + begin + SysClock = 0; + forever + begin + #(simulation_cycle/2) + SysClock = ~SysClock; + end + end +endmodule +