mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-30 08:34:36 +01:00
implement calculations for # test
modify calculations for the unconditional jump and reload PC condition
This commit is contained in:
parent
06f79dca88
commit
ea3f53f70d
4 changed files with 61 additions and 29 deletions
|
@ -31,4 +31,4 @@ second delay is posedge $glbnet$clk -> <async>
|
|||
2019-02-15 07:14 535 97.16MHz 26.57ns 9.16ns 3073 96.10MHz 13.38ns 3.13ns
|
||||
2019-02-15 11:07 577 102.13MHz 28.63ns 11.09ns 3270 101.77MHz 13.65ns 3.67ns
|
||||
2019-02-15 17:12 1544 70.76MHz 33.39ns 12.77ns 10374 75.73MHz 16.74ns 3.99ns
|
||||
|
||||
2019-02-16 11:18 1552 72.00MHz 34.10ns 10.85ns 10072 75.65MHz 17.35ns 3.46ns
|
68
saturn_alu.v
68
saturn_alu.v
|
@ -10,7 +10,7 @@
|
|||
|
||||
`define ALU_DEBUG 1'b0
|
||||
`define ALU_DEBUG_DUMP 1'b1
|
||||
`define ALU_DEBUG_JUMP 1'b1
|
||||
`define ALU_DEBUG_JUMP 1'b0
|
||||
`define ALU_DEBUG_PC 1'b0
|
||||
|
||||
module saturn_alu (
|
||||
|
@ -419,6 +419,9 @@ always @(posedge i_clk) begin
|
|||
`endif
|
||||
end
|
||||
|
||||
/*
|
||||
* source 1
|
||||
*/
|
||||
case (alu_op)
|
||||
`ALU_OP_ZERO: begin end // no source required
|
||||
`ALU_OP_COPY,
|
||||
|
@ -427,6 +430,8 @@ always @(posedge i_clk) begin
|
|||
`ALU_OP_SET_BIT,
|
||||
`ALU_OP_2CMPL,
|
||||
`ALU_OP_ADD,
|
||||
`ALU_OP_TEST_EQ,
|
||||
`ALU_OP_TEST_NEQ,
|
||||
`ALU_OP_JMP_REL3,
|
||||
`ALU_OP_JMP_REL4,
|
||||
`ALU_OP_JMP_ABS5,
|
||||
|
@ -447,6 +452,10 @@ always @(posedge i_clk) begin
|
|||
default: $display("#### SRC_1 UNHANDLED OPERATION %0d", alu_op);
|
||||
endcase
|
||||
|
||||
|
||||
/*
|
||||
* source 2
|
||||
*/
|
||||
case (alu_op)
|
||||
`ALU_OP_ZERO,
|
||||
`ALU_OP_COPY,
|
||||
|
@ -458,6 +467,8 @@ always @(posedge i_clk) begin
|
|||
`ALU_OP_JMP_ABS5: begin end // no need for a 2nd operand
|
||||
`ALU_OP_EXCH,
|
||||
`ALU_OP_ADD,
|
||||
`ALU_OP_TEST_EQ,
|
||||
`ALU_OP_TEST_NEQ,
|
||||
`ALU_OP_CLR_MASK: begin
|
||||
case (reg_src2)
|
||||
`ALU_REG_A: p_src2 <= A [f_cur*4+:4];
|
||||
|
@ -481,6 +492,7 @@ always @(posedge i_clk) begin
|
|||
case (alu_op)
|
||||
`ALU_OP_2CMPL: p_carry <= alu_start?1'b1:c_carry;
|
||||
`ALU_OP_ADD: p_carry <= alu_start?0:c_carry;
|
||||
`ALU_OP_TEST_NEQ: p_carry <= alu_start?0:c_carry;
|
||||
endcase
|
||||
|
||||
// prepare jump base
|
||||
|
@ -501,6 +513,12 @@ always @(posedge i_clk) begin
|
|||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
|
||||
if (i_reset) begin
|
||||
$display("initializing c_carry to 0");
|
||||
c_carry <= 0;
|
||||
end
|
||||
|
||||
if (do_alu_calc) begin
|
||||
`ifdef SIM
|
||||
if (alu_debug)
|
||||
|
@ -536,9 +554,10 @@ always @(posedge i_clk) begin
|
|||
c_res1 <= ~p_src1 + p_carry;
|
||||
is_zero <= ((~p_src1 + p_carry) == 0) && alu_start?1:is_zero;
|
||||
end
|
||||
`ALU_OP_ADD: begin
|
||||
`ALU_OP_ADD:
|
||||
{c_carry, c_res1} <= p_src1 + p_src2 + p_carry;
|
||||
end
|
||||
`ALU_OP_TEST_NEQ:
|
||||
c_carry <= !(p_src1 == p_src2) || p_carry;
|
||||
`ALU_OP_JMP_REL3,
|
||||
`ALU_OP_JMP_REL4,
|
||||
`ALU_OP_JMP_ABS5: jump_off[f_cur*4+:4] <= p_src1;
|
||||
|
@ -560,7 +579,7 @@ always @(posedge i_clk) begin
|
|||
end
|
||||
|
||||
if (do_go_init) begin
|
||||
$display("GO_INIT 3: imm %h", i_imm_value);
|
||||
// $display("GO_INIT 3: imm %h", i_imm_value);
|
||||
jump_off <= { {16{1'b0}}, i_imm_value};
|
||||
end
|
||||
end
|
||||
|
@ -581,10 +600,10 @@ always @(posedge i_clk) begin
|
|||
if (do_alu_save) begin
|
||||
`ifdef SIM
|
||||
if (alu_debug) begin
|
||||
// $display({"ALU_SAVE 3: run %b | done %b | stall %b | op %d | f %h | c %h | l %h |",
|
||||
// " dest %d | cres1 %h | cres2 %h | psrc1 %h | psrc2 %h | c_carry %b"},
|
||||
// alu_run, alu_done, o_alu_stall_dec, alu_op,
|
||||
// f_first, f_cur, f_last, reg_dest, c_res1, c_res2, p_src1, p_src2, c_carry);
|
||||
$display({"ALU_SAVE 3: run %b | done %b | stall %b | op %d | f %h | c %h | l %h |",
|
||||
" dest %d | cres1 %h | cres2 %h | psrc1 %h | psrc2 %h | c_carry %b"},
|
||||
alu_run, alu_done, o_alu_stall_dec, alu_op,
|
||||
f_first, f_cur, f_last, reg_dest, c_res1, c_res2, p_src1, p_src2, c_carry);
|
||||
|
||||
// $display("-------S- SRC1 %b %h | ~SRC1 %b %h | PC %b | RES1 %b %h | CC %b",
|
||||
// p_src1, p_src1, ~p_src1, ~p_src1, p_carry,
|
||||
|
@ -617,12 +636,17 @@ always @(posedge i_clk) begin
|
|||
`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
|
||||
`ALU_OP_TEST_EQ,
|
||||
`ALU_OP_TEST_NEQ,
|
||||
`ALU_OP_JMP_REL3,
|
||||
`ALU_OP_JMP_REL4,
|
||||
`ALU_OP_JMP_ABS5: begin end // nothing to save, handled by PC management below
|
||||
default: $display("#### ALU_SAVE UNHANDLED OP %0d", alu_op);
|
||||
endcase
|
||||
|
||||
/*
|
||||
* in case of exch, we need to update src2 to finish the exchange
|
||||
*/
|
||||
case (alu_op)
|
||||
`ALU_OP_EXCH: // 2nd assign, with src2
|
||||
case (reg_src2)
|
||||
|
@ -639,11 +663,14 @@ always @(posedge i_clk) begin
|
|||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* update carry
|
||||
*/
|
||||
if (do_alu_save) begin
|
||||
case (alu_op)
|
||||
`ALU_OP_2CMPL: CARRY <= !is_zero;
|
||||
`ALU_OP_TEST_EQ,
|
||||
`ALU_OP_TEST_NEQ: CARRY <= c_carry;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -670,18 +697,22 @@ wire [19:0] next_pc;
|
|||
wire [19:0] goyes_off;
|
||||
wire [19:0] goyes_pc;
|
||||
wire [0:0] update_pc;
|
||||
wire [0:0] uncond_jmp;
|
||||
wire [0:0] pop_pc;
|
||||
wire [0:0] reload_pc;
|
||||
wire [0:0] push_pc;
|
||||
|
||||
assign next_pc = (is_alu_op_jump && alu_finish)?jump_pc:PC + 1;
|
||||
assign goyes_off = {{12{i_imm_value[3]}}, i_imm_value, jump_off[3:0]};
|
||||
assign goyes_pc = jump_bse + goyes_off;
|
||||
|
||||
assign update_pc = !o_alu_stall_dec || is_alu_op_jump;
|
||||
assign pop_pc = i_pop && i_ins_rtn &&
|
||||
((!i_ins_test_go) ||
|
||||
(i_ins_test_go && CARRY));
|
||||
assign push_pc = update_pc && i_push && alu_finish;
|
||||
assign update_pc = !o_alu_stall_dec || is_alu_op_jump;
|
||||
assign uncond_jmp = is_alu_op_jump && alu_done;
|
||||
assign pop_pc = i_pop && i_ins_rtn &&
|
||||
((!i_ins_test_go) ||
|
||||
(i_ins_test_go && c_carry));
|
||||
assign reload_pc = uncond_jmp || pop_pc;
|
||||
assign push_pc = update_pc && i_push && alu_finish;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset)
|
||||
|
@ -712,7 +743,7 @@ always @(posedge i_clk) begin
|
|||
!o_alu_stall_dec, next_pc, alu_done, alu_finish,
|
||||
is_alu_op_jump, i_ins_rtn, i_push,
|
||||
i_imm_value, jump_bse, goyes_off, goyes_pc);
|
||||
if (is_alu_op_jump && alu_done) begin
|
||||
if (reload_pc) begin
|
||||
$display(".---------------------------------.");
|
||||
$display("| SHOULD TELL THE BUS CONTROLLER |");
|
||||
$display("| TO LOAD PC INTO MODULES' PC REG |");
|
||||
|
@ -724,8 +755,9 @@ always @(posedge i_clk) begin
|
|||
PC <= pop_pc ? RSTK[rstk_ptr-1] : next_pc;
|
||||
end
|
||||
|
||||
$display("pop %b && rtn %b && ((!go %b) || (go %b && c %b))",
|
||||
i_pop, i_ins_rtn, !i_ins_test_go, i_ins_test_go, CARRY);
|
||||
|
||||
// $display("pop %b && rtn %b && ((!go %b) || (go %b && c %b))",
|
||||
// i_pop, i_ins_rtn, !i_ins_test_go, i_ins_test_go, c_carry);
|
||||
if (pop_pc) begin
|
||||
$display("POP RSTK[%0d] to PC %5h", rstk_ptr-1, RSTK[rstk_ptr - 1]);
|
||||
RSTK[rstk_ptr - 1] <= 0;
|
||||
|
|
|
@ -286,14 +286,14 @@ always @(posedge i_clk) begin
|
|||
* x first nibble
|
||||
*/
|
||||
if (block_jump_test) begin
|
||||
$display("BLOCK JUMP_TEST ON %h", i_nibble);
|
||||
o_pop <= i_nibble == 0;
|
||||
o_alu_no_stall <= 1;
|
||||
o_alu_debug <= 1;
|
||||
o_ins_test_go <= 1;
|
||||
o_imm_value <= i_nibble;
|
||||
block_jump_test2 <= 1;
|
||||
block_jump_test <= 0;
|
||||
// $display("BLOCK JUMP_TEST ON %h", i_nibble);
|
||||
o_pop <= i_nibble == 0;
|
||||
o_alu_no_stall <= 1;
|
||||
// o_alu_debug <= 1;
|
||||
o_ins_test_go <= 1;
|
||||
o_imm_value <= i_nibble;
|
||||
block_jump_test2 <= 1;
|
||||
block_jump_test <= 0;
|
||||
end else begin
|
||||
// assign block regs
|
||||
case (i_nibble)
|
||||
|
@ -350,7 +350,7 @@ always @(posedge i_clk) begin
|
|||
end
|
||||
|
||||
if (do_block_jump_test2) begin
|
||||
$display("BLOCK_JUMP_TEST_2 %h | pop %b | pop-nxt %b", i_nibble, o_pop, (i_nibble == 0) && o_pop);
|
||||
// $display("BLOCK_JUMP_TEST_2 %h | pop %b | pop-nxt %b", i_nibble, o_pop, (i_nibble == 0) && o_pop);
|
||||
o_alu_op <= `ALU_OP_TEST_GO;
|
||||
o_imm_value <= i_nibble;
|
||||
o_ins_rtn <= (i_nibble == 0) && o_pop;
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
o_fields_table <= `FT_TABLE_f;
|
||||
o_ins_alu_op <= 1;
|
||||
o_alu_op <= i_nibble[2]?`ALU_OP_TEST_NEQ:`ALU_OP_TEST_EQ;
|
||||
o_alu_debug <= 1;
|
||||
// o_alu_debug <= 1;
|
||||
o_mem_pos <= 0;
|
||||
mem_load_max <= 1;
|
||||
o_ins_decoded <= 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue