mirror of
https://github.com/sxpert/hp-saturn
synced 2025-02-07 20:46:14 +01:00
add setting HEX or DEC mode
fix some cases not covered warnings add handling of RTN instructions
This commit is contained in:
parent
e72fe301b0
commit
8b985acc8a
1 changed files with 88 additions and 14 deletions
102
saturn_alu.v
102
saturn_alu.v
|
@ -40,6 +40,13 @@ module saturn_alu (
|
||||||
i_reg_src2,
|
i_reg_src2,
|
||||||
|
|
||||||
i_ins_alu_op,
|
i_ins_alu_op,
|
||||||
|
i_ins_set_mode,
|
||||||
|
i_ins_rtn,
|
||||||
|
|
||||||
|
i_mode_dec,
|
||||||
|
i_set_xm,
|
||||||
|
i_set_carry,
|
||||||
|
i_carry_val,
|
||||||
|
|
||||||
o_reg_p,
|
o_reg_p,
|
||||||
o_pc
|
o_pc
|
||||||
|
@ -79,7 +86,14 @@ input wire [4:0] i_reg_dest;
|
||||||
input wire [4:0] i_reg_src1;
|
input wire [4:0] i_reg_src1;
|
||||||
input wire [4:0] i_reg_src2;
|
input wire [4:0] i_reg_src2;
|
||||||
|
|
||||||
input wire i_ins_alu_op;
|
input wire [0:0] i_ins_alu_op;
|
||||||
|
input wire [0:0] i_ins_set_mode;
|
||||||
|
input wire [0:0] i_ins_rtn;
|
||||||
|
|
||||||
|
input wire [0:0] i_mode_dec;
|
||||||
|
input wire [0:0] i_set_xm;
|
||||||
|
input wire [0:0] i_set_carry;
|
||||||
|
input wire [0:0] i_carry_val;
|
||||||
|
|
||||||
output wire [3:0] o_reg_p;
|
output wire [3:0] o_reg_p;
|
||||||
output wire [19:0] o_pc;
|
output wire [19:0] o_pc;
|
||||||
|
@ -215,12 +229,14 @@ wire do_alu_prep;
|
||||||
wire do_alu_calc;
|
wire do_alu_calc;
|
||||||
wire do_alu_save;
|
wire do_alu_save;
|
||||||
wire do_alu_pc;
|
wire do_alu_pc;
|
||||||
|
wire do_alu_mode;
|
||||||
|
|
||||||
assign do_alu_init = (!i_reset) && i_en_alu_init && i_ins_alu_op && !alu_run;
|
assign do_alu_init = !i_reset && i_en_alu_init && i_ins_alu_op && !alu_run;
|
||||||
assign do_alu_prep = (!i_reset) && i_en_alu_prep && alu_run;
|
assign do_alu_prep = !i_reset && i_en_alu_prep && alu_run;
|
||||||
assign do_alu_calc = (!i_reset) && i_en_alu_calc && alu_run;
|
assign do_alu_calc = !i_reset && i_en_alu_calc && alu_run;
|
||||||
assign do_alu_save = (!i_reset) && i_en_alu_save && alu_run;
|
assign do_alu_save = !i_reset && i_en_alu_save && alu_run;
|
||||||
assign do_alu_pc = (!i_reset) && i_en_alu_save;
|
assign do_alu_pc = !i_reset && i_en_alu_save;
|
||||||
|
assign do_alu_mode = !i_reset && i_en_alu_save && i_ins_set_mode;
|
||||||
|
|
||||||
// the decoder may request the ALU to not stall it
|
// the decoder may request the ALU to not stall it
|
||||||
|
|
||||||
|
@ -243,11 +259,11 @@ assign is_alu_op_jump = ((alu_op == `ALU_OP_JMP_REL3) ||
|
||||||
(alu_op == `ALU_OP_JMP_REL4) ||
|
(alu_op == `ALU_OP_JMP_REL4) ||
|
||||||
(alu_op == `ALU_OP_JMP_ABS5));
|
(alu_op == `ALU_OP_JMP_ABS5));
|
||||||
|
|
||||||
/*
|
/*****************************************************************************
|
||||||
* dump all registers
|
|
||||||
* this only reads things...
|
|
||||||
*
|
*
|
||||||
*/
|
* Dump all registers at the end of each instruction's execution cycle
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
`ifdef ALU_DEBUG_DBG
|
`ifdef ALU_DEBUG_DBG
|
||||||
|
@ -280,6 +296,12 @@ always @(posedge i_clk) begin
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Initialize the ALU, to prepare it to execute the instruction
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
// this happens in phase 3, right after the instruction decoder (in phase 2) is finished
|
// this happens in phase 3, right after the instruction decoder (in phase 2) is finished
|
||||||
if (do_alu_init) begin
|
if (do_alu_init) begin
|
||||||
|
@ -369,6 +391,14 @@ always @(posedge i_clk) begin
|
||||||
`ALU_REG_IMM: p_src2 <= i_imm_value;
|
`ALU_REG_IMM: p_src2 <= i_imm_value;
|
||||||
default: $display("#### SRC_2 UNHANDLED REGISTER %0d", reg_src2);
|
default: $display("#### SRC_2 UNHANDLED REGISTER %0d", reg_src2);
|
||||||
endcase
|
endcase
|
||||||
|
`ALU_OP_ZERO: begin end // no source required
|
||||||
|
`ALU_OP_COPY,
|
||||||
|
`ALU_OP_RST_BIT,
|
||||||
|
`ALU_OP_SET_BIT,
|
||||||
|
`ALU_OP_2CMPL,
|
||||||
|
`ALU_OP_JMP_REL3,
|
||||||
|
`ALU_OP_JMP_REL4,
|
||||||
|
`ALU_OP_JMP_ABS5: begin end // no need for a 2nd operand
|
||||||
default: $display("#### SRC_2 UNHANDLED OPERATION %0d", alu_op);
|
default: $display("#### SRC_2 UNHANDLED OPERATION %0d", alu_op);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
@ -430,6 +460,7 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
if (do_alu_save) begin
|
if (do_alu_save) begin
|
||||||
`ifdef ALU_DEBUG
|
`ifdef ALU_DEBUG
|
||||||
if (alu_debug)
|
if (alu_debug)
|
||||||
|
@ -469,18 +500,39 @@ always @(posedge i_clk) begin
|
||||||
`ALU_REG_ST: ST[c_res1] <= alu_op==`ALU_OP_SET_BIT?1:0;
|
`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);
|
default: $display("#### ALU_SAVE invalid register %0d for op %0d", reg_dest, alu_op);
|
||||||
endcase
|
endcase
|
||||||
|
`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);
|
default: $display("#### ALU_SAVE UNHANDLED OP %0d", alu_op);
|
||||||
endcase
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if (do_alu_save) begin
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
`ALU_OP_2CMPL: CARRY <= !is_zero;
|
`ALU_OP_2CMPL: CARRY <= !is_zero;
|
||||||
endcase
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// do whatever is requested by the RTN instruction
|
||||||
|
if (i_ins_rtn) begin
|
||||||
|
|
||||||
|
if (i_set_xm)
|
||||||
|
HST[`ALU_HST_XM] <= 1;
|
||||||
|
|
||||||
|
if (i_set_carry)
|
||||||
|
CARRY <= i_carry_val;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Handles all changes to PC
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
wire [19:0] next_pc;
|
wire [19:0] next_pc;
|
||||||
wire [0:0] update_pc;
|
wire [0:0] update_pc;
|
||||||
wire [0:0] push_pc;
|
wire [0:0] push_pc;
|
||||||
|
@ -493,6 +545,10 @@ always @(posedge i_clk) begin
|
||||||
if (i_reset)
|
if (i_reset)
|
||||||
PC <= ~0;
|
PC <= ~0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* some debug information
|
||||||
|
*/
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
if (do_alu_shpc && alu_debug_pc) begin
|
if (do_alu_shpc && alu_debug_pc) begin
|
||||||
if (!o_alu_stall_dec)
|
if (!o_alu_stall_dec)
|
||||||
|
@ -503,8 +559,7 @@ always @(posedge i_clk) begin
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* updates the PC on phase 3 to be ready for the next
|
* updates the PC
|
||||||
* thing to do...
|
|
||||||
*/
|
*/
|
||||||
if (do_alu_pc) begin
|
if (do_alu_pc) begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
@ -513,7 +568,12 @@ always @(posedge i_clk) begin
|
||||||
!o_alu_stall_dec, next_pc, is_alu_op_jump, i_push);
|
!o_alu_stall_dec, next_pc, is_alu_op_jump, i_push);
|
||||||
`endif
|
`endif
|
||||||
if (update_pc) begin
|
if (update_pc) begin
|
||||||
PC <= next_pc;
|
PC <= i_pop ? RSTK[rstk_ptr-1] : next_pc;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (i_pop) begin
|
||||||
|
RSTK[rstk_ptr - 1] <= 0;
|
||||||
|
rstk_ptr <= rstk_ptr - 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (push_pc) begin
|
if (push_pc) begin
|
||||||
|
@ -524,6 +584,20 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* execute SETHEX and SETDEC
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
always @(posedge i_clk)
|
||||||
|
// changing calculation modes
|
||||||
|
if (i_ins_set_mode) begin
|
||||||
|
$display("SETTING MODE TO %s", i_mode_dec?"DEC":"HEX");
|
||||||
|
DEC <= i_mode_dec;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
`endif
|
`endif
|
Loading…
Add table
Reference in a new issue