mirror of
https://github.com/sxpert/hp-saturn
synced 2024-11-16 19:50:19 +01:00
cbfbe4eb3f
add add_cst and sub_cst alu opcodes port pointer math to use ALU make A[ab]x more readable
192 lines
5.6 KiB
Verilog
192 lines
5.6 KiB
Verilog
`include "decstates.v"
|
|
|
|
case (decstate)
|
|
`DEC_ALU_INIT, `DEC_ALU_CONT: begin
|
|
`ifdef SIM
|
|
if (alu_debug) begin
|
|
$display("------------------------ z_alu_phase_1 - Prepare params ------------------------");
|
|
$write("ALU OP ");
|
|
case (alu_op)
|
|
`ALU_OP_ZERO: $write("ZERO ");
|
|
`ALU_OP_COPY: $write("COPY ");
|
|
`ALU_OP_EXCH: $write("EXCH ");
|
|
`ALU_OP_SHL: $write("SHL ");
|
|
`ALU_OP_SHR: $write("SHR ");
|
|
`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("AC %b | CARRY %b | STICKY-BIT %b", alu_carry, Carry, HST[1]);
|
|
|
|
case (alu_op)
|
|
`ALU_OP_COPY,
|
|
`ALU_OP_EXCH,
|
|
`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 ");
|
|
case (alu_reg_src1)
|
|
`ALU_REG_A: $display("A: %h", A);
|
|
`ALU_REG_B: $display("B: %h", B);
|
|
`ALU_REG_C: $display("C: %h", C);
|
|
`ALU_REG_D: $display("D: %h", D);
|
|
`ALU_REG_D0: $display("D0: %h", D0);
|
|
`ALU_REG_D1: $display("D1: %h", D1);
|
|
`ALU_REG_M: $display("M: %h", dbg_data);
|
|
`ALU_REG_0: $display("0: 0000000000000000");
|
|
default: $display("%d ?", alu_reg_src1);
|
|
endcase
|
|
$write(" ");
|
|
for (display_counter = 15; display_counter != 255; display_counter = display_counter - 1)
|
|
case (display_counter[3:0])
|
|
alu_last:
|
|
if (alu_first == alu_last) $write("!");
|
|
else $write("L");
|
|
alu_first: $write("^");
|
|
default: $write(".");
|
|
endcase
|
|
$display("");
|
|
end
|
|
endcase
|
|
|
|
// dest
|
|
$write("DEST ");
|
|
case (alu_reg_dest)
|
|
`ALU_REG_A: $display("A: %h", A);
|
|
`ALU_REG_B: $display("B: %h", B);
|
|
`ALU_REG_C: $display("C: %h", C);
|
|
`ALU_REG_D: $display("D: %h", D);
|
|
`ALU_REG_D0: $display("D0: %h", D0);
|
|
`ALU_REG_D1: $display("D1: %h", D1);
|
|
endcase
|
|
$write(" ");
|
|
for (display_counter = 15; display_counter != 255; display_counter = display_counter - 1)
|
|
case (display_counter[3:0])
|
|
alu_last:
|
|
if (alu_first == alu_last) $write("!");
|
|
else $write("L");
|
|
alu_first: $write("^");
|
|
default: $write(".");
|
|
endcase
|
|
$display("");
|
|
end
|
|
`endif
|
|
|
|
/*
|
|
*
|
|
* Setting up SRC1 register for operations
|
|
*
|
|
*/
|
|
|
|
case (alu_op)
|
|
`ALU_OP_COPY,
|
|
`ALU_OP_EXCH,
|
|
`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_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
|
|
$display("ALU_P1 ERROR: ALU_OP %d SRC1 REGISTER NOT IMPLEMENTED %d", alu_op, alu_reg_src1);
|
|
alu_p1_halt <= 1;
|
|
`endif
|
|
end
|
|
endcase
|
|
end
|
|
default: begin
|
|
`ifdef SIM
|
|
// $display("no source 1 required");
|
|
`endif
|
|
end
|
|
endcase
|
|
|
|
/*
|
|
*
|
|
* Setting up SRC2 register for operations
|
|
*
|
|
*/
|
|
|
|
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)
|
|
`ALU_REG_A: alu_src2 <= A[alu_first*4+:4];
|
|
`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
|
|
$display("ALU_P1 ERROR: ALU_OP %d SRC2 REGISTER NOT IMPLEMENTED %d", alu_op, alu_reg_src1);
|
|
alu_p1_halt <= 1;
|
|
`endif
|
|
end
|
|
endcase
|
|
end
|
|
default: begin
|
|
`ifdef SIM
|
|
// $display("no source 2 required");
|
|
`endif
|
|
end
|
|
endcase
|
|
|
|
/*
|
|
*
|
|
* update internal carry
|
|
*
|
|
*/
|
|
|
|
case (alu_op)
|
|
/*
|
|
* option 1: carry starts at 0 (not used yet)
|
|
*/
|
|
// alu_carry <= (decstate == `DEC_ALU_INIT)?0:Carry;
|
|
/*
|
|
* option 2: carry starts at 1
|
|
*/
|
|
`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
|
|
// $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
|
|
*/
|
|
`ALU_OP_1CMPL:
|
|
Carry <= 0;
|
|
endcase
|
|
|
|
if (alu_last == alu_first) alu_next_cycle <= `BUSCMD_PC_READ;
|
|
else alu_next_cycle <= `BUSCMD_NOP;
|
|
end
|
|
endcase
|