diff --git a/dbg_const.v b/dbg_const.v index 6701775..1d59698 100644 --- a/dbg_const.v +++ b/dbg_const.v @@ -13,18 +13,20 @@ `define DBG_OP_C_ST 16'h000A `define DBG_OP_ST_C 16'h000B `define DBG_OP_CSTEX 16'h000C -`define DBG_OP_INC_P 16'h000D -`define DBG_OP_DEC_P 16'h000E +`define DBG_OP_INC 16'h000D +`define DBG_OP_DEC 16'h000E `define DBG_OP_AND 16'h000F `define DBG_OP_OR 16'h0010 `define DBG_OP_RTI 16'h0011 `define DBG_OP_COPY_FULL 16'h0012 -`define DBG_OP_EXCH_FULL 16'h0013 -`define DBG_OP_MEM_IN 16'h0014 -`define DBG_OP_MEM_OUT 16'h0015 -`define DBG_OP_ADD_CONST 16'h0016 -`define DBG_OP_SUB_CONST 16'h0017 -`define DBG_OP_LOAD_IMM 16'h0018 +`define DEB_OP_COPY 16'h0013 +`define DBG_OP_EXCH_FULL 16'h0014 +`define DBG_OP_EXCH 16'h0015 +`define DBG_OP_MEM_IN 16'h0016 +`define DBG_OP_MEM_OUT 16'h0017 +`define DBG_OP_ADD_CONST 16'h0018 +`define DBG_OP_SUB_CONST 16'h0019 +`define DBG_OP_LOAD_IMM 16'h001A diff --git a/fields.v b/fields.v index e421b4b..2397828 100644 --- a/fields.v +++ b/fields.v @@ -42,8 +42,10 @@ `define ALU_OP_DEC 9 `define ALU_OP_ADD 10 `define ALU_OP_SUB 11 -`define ALU_OP_TEST_EQ 12 -`define ALU_OP_TEST_NEQ 13 +`define ALU_OP_ADD_CST 12 +`define ALU_OP_SUB_CST 13 +`define ALU_OP_TEST_EQ 14 +`define ALU_OP_TEST_NEQ 15 `define ALU_REG_A 0 @@ -59,7 +61,7 @@ `define ALU_REG_R2 10 `define ALU_REG_R3 11 `define ALU_REG_R4 12 -// 13 +`define ALU_REG_CST 13 `define ALU_REG_M 14 `define ALU_REG_0 15 diff --git a/opcodes/1[678C]n_D[01]_math_n.v b/opcodes/1[678C]n_D[01]_math_n.v index fe35e46..b6d4357 100644 --- a/opcodes/1[678C]n_D[01]_math_n.v +++ b/opcodes/1[678C]n_D[01]_math_n.v @@ -5,14 +5,18 @@ */ `DEC_PTR_MATH: begin - case ({t_ptr, t_add_sub}) - 2'b00: {Carry, D0} <= D0 + (nb_in + 1); - 2'b01: {Carry, D0} <= D0 - (nb_in + 1); - 2'b10: {Carry, D1} <= D1 + (nb_in + 1); - 2'b11: {Carry, D1} <= D1 - (nb_in + 1); - endcase - decstate <= `DEC_START; + field <= `T_FIELD_A; + alu_first <= 0; + alu_last <= 4; + alu_const <= nb_in; + + next_cycle <= `BUSCMD_NOP; + decstate <= `DEC_ALU_INIT; + alu_return <= `DEC_START; + `ifdef SIM - $display("%5h D%b=D%b%s\t%2d", inst_start_PC, t_ptr, t_ptr, t_add_sub?"-":"+", nb_in+1); + $display("%5h D%b=D%b%s\t%2d", + inst_start_PC, alu_reg_dest[0], alu_reg_src1[0], + ((alu_op==`ALU_OP_SUB_CST)?"-":"+"), nb_in+1); `endif end \ No newline at end of file diff --git a/opcodes/1[9ABDEF]nnnnn_D[01]_EQ_[245]n.v b/opcodes/1[9ABDEF]nnnnn_D[01]_EQ_[245]n.v index ec8ffe9..5fc9926 100644 --- a/opcodes/1[9ABDEF]nnnnn_D[01]_EQ_[245]n.v +++ b/opcodes/1[9ABDEF]nnnnn_D[01]_EQ_[245]n.v @@ -35,6 +35,9 @@ end if (t_ctr == t_cnt) begin decstate <= `DEC_START; + + + `ifdef SIM $write("%5h D%b=(%1d)\t%1h", inst_start_PC, (decstate == `DEC_D0_EQ_LOOP)?1'b0:1'b1, diff --git a/opcodes/1x.v b/opcodes/1x.v index b1d0a5b..7e36cc0 100644 --- a/opcodes/1x.v +++ b/opcodes/1x.v @@ -12,8 +12,10 @@ 4'h4: decstate <= `DEC_14X; 4'h5: decstate <= `DEC_15X; 4'h6, 4'h7, 4'h8, 4'hC: begin - t_ptr <= (nb_in[0] && nb_in[1]) || (nb_in[2] && nb_in[3]); - t_add_sub <= nb_in[3]; + alu_reg_dest <= reg_D0D1; + alu_reg_src1 <= reg_D0D1; + alu_reg_src2 <= `ALU_REG_CST; + alu_op <= nb_in[3]?`ALU_OP_SUB_CST:`ALU_OP_ADD_CST; decstate <= `DEC_PTR_MATH; end 4'h9: decstate <= `DEC_D0_EQ_2N; diff --git a/opcodes/A[ab]x.v b/opcodes/A[ab]x.v index c44ce05..5f63ee6 100644 --- a/opcodes/A[ab]x.v +++ b/opcodes/A[ab]x.v @@ -12,25 +12,60 @@ `DEC_Axx_EXEC: begin if (!field_table[0]) begin - $display("table 'a' not handled yet"); - decode_error <= 1; - end else begin - if (!nb_in[3]) begin - alu_reg_dest <= {2'b0, nb_in[1:0]}; - if (!nb_in[2]) alu_op <= `ALU_OP_ZERO; - else begin - alu_op <= `ALU_OP_COPY; - alu_reg_src1 <= {2'b00, nb_in[0], (!(nb_in[0] || nb_in[1])) && nb_in[2]}; - end; - end else begin - $display("DEC_Axx_EXEC %h", nb_in); - decode_error <= 1; + // math ops + if (nb_in[3:2] != 2'b11) + alu_op <= `ALU_OP_ADD; + else alu_op <= `ALU_OP_DEC; + case (nb_in[3:2]) + 2'b00: begin + alu_reg_dest <= reg_ABCD; + alu_reg_src1 <= reg_ABCD; + alu_reg_src2 <= reg_BCAC; end + 2'b01: begin + alu_reg_dest <= reg_ABCD; + alu_reg_src1 <= reg_ABCD; + alu_reg_src2 <= reg_ABCD; + end + 2'b10: begin + alu_reg_dest <= reg_BCAC; + alu_reg_src1 <= reg_BCAC; + alu_reg_src2 <= reg_ABCD; + end + 2'b11: begin + alu_reg_dest <= reg_ABCD; + alu_reg_src1 <= reg_ABCD; + end + endcase + end else begin + // copy and exchange ops + case (nb_in[3:2]) + 2'b00: begin + alu_reg_dest <= reg_ABCD; + alu_op <= `ALU_OP_ZERO; + end + 2'b01: begin + alu_reg_dest <= reg_ABCD; + alu_reg_src1 <= reg_BCAC; + alu_op <= `ALU_OP_COPY; + end + 2'b10: begin + alu_reg_dest <= reg_BCAC; + alu_reg_src1 <= reg_ABCD; + alu_op <= `ALU_OP_COPY; + end + 2'b11: begin + alu_reg_dest <= reg_ABAC; + alu_reg_src1 <= reg_BCCD; + alu_op <= `ALU_OP_EXCH; + end + endcase end - alu_debug <= 1; + // alu_debug <= 1; next_cycle <= `BUSCMD_NOP; decstate <= `DEC_ALU_INIT; alu_return <= `DEC_START; + `ifdef SIM $write("%5h ", inst_start_PC); if (!nb_in[3]) diff --git a/opcodes/Cx.v b/opcodes/Cx.v index 079127d..f68a8bf 100644 --- a/opcodes/Cx.v +++ b/opcodes/Cx.v @@ -14,6 +14,8 @@ {Carry, A[19:0]} = A[19:0] + C[19:0]; decstate <= `DEC_START; end + + `ifdef SIM $display("%5h A=A+C\tA%s", inst_start_PC, hex_dec?"\t\t\t <=== DEC MODE NOT IMPLEMENTED":""); `endif diff --git a/opcodes/z_alu_phase_1.v b/opcodes/z_alu_phase_1.v index daa6229..9aaafef 100644 --- a/opcodes/z_alu_phase_1.v +++ b/opcodes/z_alu_phase_1.v @@ -15,12 +15,14 @@ case (decstate) `ALU_OP_2CMPL: $write("2CMPL "); `ALU_OP_1CMPL: $write("1CMPL "); `ALU_OP_INC: $write("INC "); + `ALU_OP_ADD_CST: $write("ADD_CST "); + `ALU_OP_SUB_CST: $write("SUB_CST "); `ALU_OP_TEST_EQ: $write("TEST_EQ "); `ALU_OP_TEST_NEQ: $write("TEST_NEQ"); endcase $display(" | FRST %h | LAST %h | SRC1 %h | SRC2 %h | DEST %h", - alu_first, alu_last, alu_reg_src1, alu_reg_src2,alu_reg_dest); - $display("CARRY %b | STICKY-BIT %b", Carry, HST[1]); + alu_first, alu_last, alu_reg_src1, alu_reg_src2, alu_reg_dest); + $display("AC %b | CARRY %b | STICKY-BIT %b", alu_carry, Carry, HST[1]); case (alu_op) `ALU_OP_COPY, @@ -28,6 +30,8 @@ case (decstate) `ALU_OP_2CMPL, `ALU_OP_1CMPL, `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, `ALU_OP_TEST_NEQ: begin $write("SRC1 "); @@ -90,13 +94,17 @@ case (decstate) `ALU_OP_2CMPL, `ALU_OP_1CMPL, `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, `ALU_OP_TEST_NEQ: begin case (alu_reg_src1) - `ALU_REG_A: alu_src1 <= A[alu_first*4+:4]; - `ALU_REG_B: alu_src1 <= B[alu_first*4+:4]; - `ALU_REG_C: alu_src1 <= C[alu_first*4+:4]; - `ALU_REG_D: alu_src1 <= D[alu_first*4+:4]; + `ALU_REG_A: alu_src1 <= A[alu_first*4+:4]; + `ALU_REG_B: alu_src1 <= B[alu_first*4+:4]; + `ALU_REG_C: alu_src1 <= C[alu_first*4+:4]; + `ALU_REG_D: alu_src1 <= D[alu_first*4+:4]; + `ALU_REG_D0: alu_src1 <= D0[alu_first*4+:4]; + `ALU_REG_D1: alu_src1 <= D1[alu_first*4+:4]; `ALU_REG_M: begin end // handled in phase 2 default: begin `ifdef SIM @@ -121,6 +129,8 @@ case (decstate) case (alu_op) `ALU_OP_EXCH, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, `ALU_OP_TEST_NEQ: begin case ((alu_op==`ALU_OP_EXCH)?alu_reg_dest:alu_reg_src2) @@ -128,6 +138,7 @@ case (decstate) `ALU_REG_B: alu_src2 <= B[alu_first*4+:4]; `ALU_REG_C: alu_src2 <= C[alu_first*4+:4]; `ALU_REG_D: alu_src2 <= D[alu_first*4+:4]; + `ALU_REG_CST: alu_src2 <= alu_const; `ALU_REG_0: alu_src2 <= 0; default: begin `ifdef SIM @@ -161,9 +172,13 @@ case (decstate) `ALU_OP_2CMPL, `ALU_OP_1CMPL, `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, - `ALU_OP_TEST_NEQ: + `ALU_OP_TEST_NEQ: begin + // $display("SETTING alu_carry to %h %1b", decstate, ((decstate == `DEC_ALU_INIT)?1:Carry)); alu_carry <= (decstate == `DEC_ALU_INIT)?1:Carry; + end /* * option 3: carry is always cleared */ diff --git a/opcodes/z_alu_phase_2.v b/opcodes/z_alu_phase_2.v index bc57567..d1bba19 100644 --- a/opcodes/z_alu_phase_2.v +++ b/opcodes/z_alu_phase_2.v @@ -5,7 +5,7 @@ case (decstate) `ifdef SIM if (alu_debug) begin $display("----------------------- z_alu_phase_2 - Do calculations ------------------------"); - $display("data received from reading : %h", bus_nibble_out); + $display("data received from reading : %h | carry %b", bus_nibble_out, alu_carry); end `endif @@ -33,6 +33,12 @@ case (decstate) `ALU_OP_INC: begin {alu_res_carry, alu_res1} <= alu_src1 + alu_carry; end + `ALU_OP_ADD_CST: begin + {alu_res_carry, alu_res1} <= alu_src1 + (((decstate==`DEC_ALU_INIT)?alu_src2:0) + alu_carry); + end + `ALU_OP_SUB_CST: begin + {alu_res_carry, alu_res1} <= alu_src1 - (((decstate==`DEC_ALU_INIT)?alu_src2:0) + alu_carry); + end `ALU_OP_TEST_EQ: begin alu_res_carry <= (alu_src1 == alu_src2) & alu_carry; end diff --git a/opcodes/z_alu_phase_3.v b/opcodes/z_alu_phase_3.v index 667ca1f..edba026 100644 --- a/opcodes/z_alu_phase_3.v +++ b/opcodes/z_alu_phase_3.v @@ -9,8 +9,8 @@ `ifdef SIM if (alu_debug) begin $display("------------------------ z_alu_phase_3 - Store results -------------------------"); - $display("SRC1 %h | SRC2 %h | RES1 %h | RES2 %h | RC %b | DEST %h | TMP %h | CARRY %b", - alu_src1, alu_src2, alu_res1, alu_res2, alu_res_carry, + $display("SRC1 %h | SRC2 %h | RES1 %h | RES2 %h | AC %b | RC %b | DEST %h | TMP %h | CARRY %b", + alu_src1, alu_src2, alu_res1, alu_res2, alu_carry, alu_res_carry, alu_reg_dest, alu_tmp, alu_carry); end `endif @@ -25,7 +25,9 @@ `ALU_OP_EXCH, `ALU_OP_2CMPL, `ALU_OP_1CMPL, - `ALU_OP_INC: begin + `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST: begin case ((alu_op==`ALU_OP_EXCH)?alu_reg_src1:alu_reg_dest) `ALU_REG_A: A[alu_first*4+:4] <= alu_res1; `ALU_REG_B: B[alu_first*4+:4] <= alu_res1; @@ -61,6 +63,8 @@ `ALU_OP_2CMPL, `ALU_OP_1CMPL, `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, `ALU_OP_TEST_NEQ: begin end // nothing do to with alu_res2 // exchange requires res2 @@ -96,6 +100,8 @@ `ALU_OP_2CMPL, `ALU_OP_1CMPL, `ALU_OP_INC, + `ALU_OP_ADD_CST, + `ALU_OP_SUB_CST, `ALU_OP_TEST_EQ, `ALU_OP_TEST_NEQ: begin Carry <= alu_res_carry; diff --git a/saturn_core.v b/saturn_core.v index ed31750..e7ecc7b 100644 --- a/saturn_core.v +++ b/saturn_core.v @@ -130,9 +130,10 @@ reg [3:0] t_last; reg [3:0] field; reg [1:0] field_table; -reg [3:0] alu_op; +reg [4:0] alu_op; reg [3:0] alu_first; reg [3:0] alu_last; +reg [3:0] alu_const; reg [3:0] alu_reg_src1; reg [3:0] alu_reg_src2; reg [3:0] alu_reg_dest; @@ -281,7 +282,7 @@ begin case (next_cycle) `BUSCMD_NOP: begin bus_command <= `BUSCMD_NOP; - $display("BUS NOT READING, STILL CLOCKING"); + // $display("BUS NOT READING, STILL CLOCKING"); end `BUSCMD_PC_READ: begin bus_command <= `BUSCMD_PC_READ; @@ -347,20 +348,20 @@ begin en_dec_clk <= 1; end `BUSCMD_LOAD_PC: begin - $display("CYCLE %d | INSTR %d -> BUSCMD_LOAD_PC %5h", cycle_ctr, instr_ctr, new_PC); + // $display("CYCLE %d | INSTR %d -> BUSCMD_LOAD_PC %5h", cycle_ctr, instr_ctr, new_PC); en_dec_clk <= 1; end `BUSCMD_LOAD_DP: begin - $display("CYCLE %d | INSTR %d -> BUSCMD_LOAD_DP %s %5h", - cycle_ctr, instr_ctr, t_ptr?"D1":"D0", add_out); + // $display("CYCLE %d | INSTR %d -> BUSCMD_LOAD_DP %s %5h", + // cycle_ctr, instr_ctr, t_ptr?"D1":"D0", add_out); en_dec_clk <= 1; end `BUSCMD_CONFIGURE: begin - $display("CYCLE %d | INSTR %d -> BUSCMD_CONFIGURE %5h", cycle_ctr, instr_ctr, add_out); + // $display("CYCLE %d | INSTR %d -> BUSCMD_CONFIGURE %5h", cycle_ctr, instr_ctr, add_out); en_dec_clk <= 1; end `BUSCMD_RESET: begin - $display("CYCLE %d | INSTR %d -> BUSCMD_RESET", cycle_ctr, instr_ctr); + // $display("CYCLE %d | INSTR %d -> BUSCMD_RESET", cycle_ctr, instr_ctr); en_dec_clk <= 1; end default: begin @@ -398,7 +399,7 @@ always @(posedge ph2) begin end always @(posedge ph3) begin - if (cycle_ctr == 850) + if (cycle_ctr == 890) debug_stop <= 1; end @@ -417,11 +418,13 @@ wire [3:0] reg_ABCD; wire [3:0] reg_BCAC; wire [3:0] reg_ABAC; wire [3:0] reg_BCCD; +wire [3:0] reg_D0D1; assign reg_ABCD = {2'b00, nb_in[1:0]}; assign reg_BCAC = {2'b00, nb_in[0], !(nb_in[1] || nb_in[0])}; assign reg_ABAC = {2'b00, nb_in[1] && nb_in[0], (!nb_in[1]) && nb_in[0]}; assign reg_BCCD = {2'b00, nb_in[1] || nb_in[0], (!nb_in[1]) ^ nb_in[0]}; +assign reg_D0D1 = {3'b010, (nb_in[0] && nb_in[1]) || (nb_in[2] && nb_in[3])}; always @(posedge dec_strobe) begin if (alu_requested_halt) decode_error <= 1;