diff --git a/def-alu.v b/def-alu.v index 2216e40..2aa576f 100644 --- a/def-alu.v +++ b/def-alu.v @@ -62,7 +62,7 @@ //15 `define ALU_REG_DAT0 16 `define ALU_REG_DAT1 17 -`define ALU_REG_CST 18 +`define ALU_REG_HST 18 `define ALU_REG_ST 19 `define ALU_REG_P 20 `define ALU_REG_M 21 diff --git a/saturn_alu.v b/saturn_alu.v index 1d41544..9e42e41 100644 --- a/saturn_alu.v +++ b/saturn_alu.v @@ -287,9 +287,9 @@ always @(posedge i_clk) begin `ifdef SIM if (alu_debug) $display({"ALU_INIT 3: run %b | done %b | stall %b | op %d | s %h | l %h ", - "| ialu %b | dest %d | src1 %d | src2 %d"}, + "| ialu %b | dest %d | src1 %d | src2 %d | imm %h"}, alu_run, alu_done, o_alu_stall_dec, i_alu_op,i_field_start, i_field_last, - i_ins_alu_op, i_reg_dest, i_reg_src1, i_reg_src2); + i_ins_alu_op, i_reg_dest, i_reg_src1, i_reg_src2, i_imm_value); `endif jump_bse <= PC; @@ -346,7 +346,8 @@ always @(posedge i_clk) begin `ALU_OP_2CMPL, `ALU_OP_JMP_REL3, `ALU_OP_JMP_REL4, - `ALU_OP_JMP_ABS5: + `ALU_OP_JMP_ABS5, + `ALU_OP_CLR_MASK: case (reg_src1) `ALU_REG_A: p_src1 <= A [f_start*4+:4]; `ALU_REG_B: p_src1 <= B [f_start*4+:4]; @@ -355,10 +356,20 @@ always @(posedge i_clk) begin `ALU_REG_D0: p_src1 <= D0[f_start*4+:4]; `ALU_REG_D1: p_src1 <= D1[f_start*4+:4]; `ALU_REG_P: p_src1 <= P; + `ALU_REG_HST: p_src1 <= HST; `ALU_REG_IMM: p_src1 <= i_imm_value; - default: $display("####UNHANDLED REGISTER %0d", reg_src1); + default: $display("#### SRC_1 UNHANDLED REGISTER %0d", reg_src1); endcase - default: $display("####UNHANDLED OPERATION %0d", alu_op); + default: $display("#### SRC_1 UNHANDLED OPERATION %0d", alu_op); + endcase + + case (alu_op) + `ALU_OP_CLR_MASK: + case (reg_src2) + `ALU_REG_IMM: p_src2 <= i_imm_value; + default: $display("#### SRC_2 UNHANDLED REGISTER %0d", reg_src2); + endcase + default: $display("#### SRC_2 UNHANDLED OPERATION %0d", alu_op); endcase // setup p_carry @@ -401,6 +412,7 @@ always @(posedge i_clk) begin `ALU_OP_JMP_REL3, `ALU_OP_JMP_REL4, `ALU_OP_JMP_ABS5: jump_off[f_start*4+:4] <= p_src1; + `ALU_OP_CLR_MASK: c_res1 <= p_src1 & ~p_src2; endcase case (alu_op) @@ -436,28 +448,32 @@ always @(posedge i_clk) begin // (~p_src1) == 4'hf ); case (alu_op) - `ALU_OP_ZERO, - `ALU_OP_COPY, - `ALU_OP_2CMPL: - case (reg_dest) - `ALU_REG_A: A [f_start*4+:4] <= c_res1; - `ALU_REG_B: B [f_start*4+:4] <= c_res1; - `ALU_REG_C: C [f_start*4+:4] <= c_res1; - `ALU_REG_D: D [f_start*4+:4] <= c_res1; - `ALU_REG_D0: D0[f_start*4+:4] <= c_res1; - `ALU_REG_D1: D1[f_start*4+:4] <= c_res1; - `ALU_REG_ST: ST[f_start*4+:4] <= c_res1; - `ALU_REG_P: P <= c_res1; - endcase - `ALU_OP_RST_BIT, - `ALU_OP_SET_BIT: - case (reg_dest) - `ALU_REG_ST: ST[c_res1] <= alu_op==`ALU_OP_SET_BIT?1:0; - default: - $display("invalid register for op"); - endcase + `ALU_OP_ZERO, + `ALU_OP_COPY, + `ALU_OP_2CMPL, + `ALU_OP_CLR_MASK: + case (reg_dest) + `ALU_REG_A: A [f_start*4+:4] <= c_res1; + `ALU_REG_B: B [f_start*4+:4] <= c_res1; + `ALU_REG_C: C [f_start*4+:4] <= c_res1; + `ALU_REG_D: D [f_start*4+:4] <= c_res1; + `ALU_REG_D0: D0[f_start*4+:4] <= c_res1; + `ALU_REG_D1: D1[f_start*4+:4] <= c_res1; + `ALU_REG_ST: ST[f_start*4+:4] <= c_res1; + `ALU_REG_P: P <= c_res1; + `ALU_REG_HST: HST <= c_res1; + endcase + `ALU_OP_RST_BIT, + `ALU_OP_SET_BIT: + case (reg_dest) + `ALU_REG_ST: ST[c_res1] <= alu_op==`ALU_OP_SET_BIT?1:0; + default: $display("#### ALU_SAVE invalid register %0d for op %0d", reg_dest, alu_op); + endcase + default: $display("#### ALU_SAVE UNHANDLED OP %0d", alu_op); endcase + + case (alu_op) `ALU_OP_2CMPL: CARRY <= !is_zero; endcase diff --git a/saturn_decoder.v b/saturn_decoder.v index b4e325f..c2ddba0 100644 --- a/saturn_decoder.v +++ b/saturn_decoder.v @@ -214,31 +214,46 @@ always @(posedge i_clk) begin if (o_ins_alu_op) begin case (o_alu_op) - `ALU_OP_JMP_REL3: $write("GOTO"); - `ALU_OP_JMP_REL4: $write("%s", o_push?"GOSUBL":"GOLONG"); - `ALU_OP_JMP_ABS5: $write("%s", o_push?"GOSBVL":"GOVLNG"); - default: - case (o_reg_dest) - `ALU_REG_A: $write("A"); - `ALU_REG_B: $write("B"); - `ALU_REG_C: - if (is_lc_hex) $write("LCHEX"); - else $write("C"); - `ALU_REG_D: $write("D"); - `ALU_REG_D0: $write("D0"); - `ALU_REG_D1: $write("D1"); - `ALU_REG_RSTK: $write("RSTK"); - `ALU_REG_R0: $write("R0"); - `ALU_REG_R1: $write("R1"); - `ALU_REG_R2: $write("R2"); - `ALU_REG_R3: $write("R3"); - `ALU_REG_R4: $write("R4"); - `ALU_REG_DAT0: $write("DAT0"); - `ALU_REG_DAT1: $write("DAT1"); - `ALU_REG_ST: if (o_alu_op!=`ALU_OP_ZERO) $write("ST"); - `ALU_REG_P: $write("P"); - default: $write("[dest:%0d]", o_reg_dest); - endcase + `ALU_OP_JMP_REL3: $write("GOTO"); + `ALU_OP_JMP_REL4: $write("%s", o_push?"GOSUBL":"GOLONG"); + `ALU_OP_JMP_ABS5: $write("%s", o_push?"GOSBVL":"GOVLNG"); + `ALU_OP_CLR_MASK: + case (o_reg_dest) + `ALU_REG_HST: + case (o_imm_value) + 4'h1: $write("XM=0"); + 4'h2: $write("SB=0"); + 4'h4: $write("SR=0"); + 4'h8: $write("MP=0"); + default: begin + $write("CLRHST"); + if (o_imm_value != 4'hF) $write("\t%1h", o_imm_value); + end + endcase + default: $write("[VLR_MASK dest:%0d]", o_reg_dest); + endcase + default: + case (o_reg_dest) + `ALU_REG_A: $write("A"); + `ALU_REG_B: $write("B"); + `ALU_REG_C: + if (is_lc_hex) $write("LCHEX"); + else $write("C"); + `ALU_REG_D: $write("D"); + `ALU_REG_D0: $write("D0"); + `ALU_REG_D1: $write("D1"); + `ALU_REG_RSTK: $write("RSTK"); + `ALU_REG_R0: $write("R0"); + `ALU_REG_R1: $write("R1"); + `ALU_REG_R2: $write("R2"); + `ALU_REG_R3: $write("R3"); + `ALU_REG_R4: $write("R4"); + `ALU_REG_DAT0: $write("DAT0"); + `ALU_REG_DAT1: $write("DAT1"); + `ALU_REG_ST: if (o_alu_op!=`ALU_OP_ZERO) $write("ST"); + `ALU_REG_P: $write("P"); + default: $write("[dest:%0d]", o_reg_dest); + endcase endcase case (o_alu_op) @@ -259,7 +274,8 @@ always @(posedge i_clk) begin `ALU_OP_EXCH, `ALU_OP_JMP_REL3, `ALU_OP_JMP_REL4, - `ALU_OP_JMP_ABS5: begin end + `ALU_OP_JMP_ABS5, + `ALU_OP_CLR_MASK: begin end default: $write("[op:%0d]", o_alu_op); endcase @@ -365,7 +381,8 @@ always @(posedge i_clk) begin else case (o_reg_dest) `ALU_REG_P, - `ALU_REG_ST: begin end + `ALU_REG_ST, + `ALU_REG_HST: begin end `ALU_REG_C: if (o_reg_src1 == `ALU_REG_P) $write("%0d", o_field_start); @@ -898,6 +915,7 @@ always @(posedge i_clk) begin if (do_block_82x) begin o_ins_alu_op <= 1; o_alu_op <= `ALU_OP_CLR_MASK; + o_imm_value <= i_nibble; next_nibble <= 0; o_ins_decoded <= 1; end @@ -1127,6 +1145,12 @@ always @(posedge i_clk) begin o_reg_src2 <= 0; end + if (do_block_82x) begin + o_reg_dest <= `ALU_REG_HST; + o_reg_src1 <= `ALU_REG_HST; + o_reg_src2 <= `ALU_REG_IMM; + end + if (do_block_Fx) begin case (i_nibble) 4'h8, 4'h9, 4'hA, 4'hB: begin