mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-31 19:57:50 +01:00
convert stuff to use the ALU module instead
This commit is contained in:
parent
f21dcd8c23
commit
799fc3c327
8 changed files with 201 additions and 71 deletions
5
fields.v
5
fields.v
|
@ -36,12 +36,17 @@
|
||||||
`define ALU_OP_EXCH 2
|
`define ALU_OP_EXCH 2
|
||||||
`define ALU_OP_SHL 3
|
`define ALU_OP_SHL 3
|
||||||
`define ALU_OP_SHR 4
|
`define ALU_OP_SHR 4
|
||||||
|
`define ALU_OP_2CMPL 5
|
||||||
|
`define ALU_OP_1CMPL 6
|
||||||
`define ALU_OP_INC 8
|
`define ALU_OP_INC 8
|
||||||
|
`define ALU_OP_TEST_EQ 12
|
||||||
|
`define ALU_OP_TEST_NEQ 13
|
||||||
|
|
||||||
|
|
||||||
`define ALU_REG_A 0
|
`define ALU_REG_A 0
|
||||||
`define ALU_REG_B 1
|
`define ALU_REG_B 1
|
||||||
`define ALU_REG_C 2
|
`define ALU_REG_C 2
|
||||||
`define ALU_REG_D 3
|
`define ALU_REG_D 3
|
||||||
|
`define ALU_REG_0 15
|
||||||
|
|
||||||
`endif
|
`endif
|
|
@ -8,15 +8,44 @@
|
||||||
`include "decstates.v"
|
`include "decstates.v"
|
||||||
|
|
||||||
`DEC_8AX: begin
|
`DEC_8AX: begin
|
||||||
case (nb_in)
|
// prepare ALU for register A
|
||||||
4'h6: begin
|
field <= `T_FIELD_A;
|
||||||
Carry = !(A[19:0] == C[19:0]);
|
alu_first <= 0;
|
||||||
$display("%5h ?A#C\tA", inst_start_PC);
|
alu_last <= 4;
|
||||||
|
alu_op <= nb_in[2]?`ALU_OP_TEST_NEQ:`ALU_OP_TEST_EQ;
|
||||||
|
if (!nb_in[3]) begin
|
||||||
|
alu_reg_src1 <= {2'b00, nb_in[0], !(nb_in[1] | nb_in[0])};
|
||||||
|
alu_reg_src2 <= {2'b00, nb_in[1:0]};
|
||||||
end
|
end
|
||||||
default: begin
|
else begin
|
||||||
$display("ERROR : DEC_8AX");
|
alu_reg_src1 <= {2'b00, nb_in[1:0]};
|
||||||
decode_error <= 1;
|
alu_reg_src2 <= `ALU_REG_0;
|
||||||
end
|
end
|
||||||
|
alu_debug <= 1;
|
||||||
|
next_cycle <= `BUSCMD_NOP;
|
||||||
|
decstate <= `DEC_ALU_INIT;
|
||||||
|
alu_return <= `DEC_TEST_GO;
|
||||||
|
|
||||||
|
`ifdef SIM
|
||||||
|
$write("%5h ?", inst_start_PC);
|
||||||
|
|
||||||
|
case ({2'b00, (nb_in[3]?nb_in[1:0]:{nb_in[0], !(nb_in[1] | nb_in[0])})})
|
||||||
|
`ALU_REG_A: $write("A");
|
||||||
|
`ALU_REG_B: $write("B");
|
||||||
|
`ALU_REG_C: $write("C");
|
||||||
|
`ALU_REG_D: $write("D");
|
||||||
endcase
|
endcase
|
||||||
decstate <= `DEC_TEST_GO;
|
|
||||||
|
$write("%s", nb_in[2]?"#":"=");
|
||||||
|
|
||||||
|
case (nb_in[3]?`ALU_REG_0:{2'b00, nb_in[1:0]})
|
||||||
|
`ALU_REG_A: $write("A");
|
||||||
|
`ALU_REG_B: $write("B");
|
||||||
|
`ALU_REG_C: $write("C");
|
||||||
|
`ALU_REG_D: $write("D");
|
||||||
|
`ALU_REG_0: $write("0");
|
||||||
|
endcase
|
||||||
|
|
||||||
|
$display("\tA");
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
if (!nb_in[2]) alu_op <= `ALU_OP_ZERO;
|
if (!nb_in[2]) alu_op <= `ALU_OP_ZERO;
|
||||||
else begin
|
else begin
|
||||||
alu_op <= `ALU_OP_COPY;
|
alu_op <= `ALU_OP_COPY;
|
||||||
alu_reg_src1 <= {nb_in[0], (!(nb_in[0] | nb_in[1])) & nb_in[2]};
|
alu_reg_src1 <= {2'b00, nb_in[0], (!(nb_in[0] | nb_in[1])) & nb_in[2]};
|
||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
$display("DEC_Axx_EXEC %h", nb_in);
|
$display("DEC_Axx_EXEC %h", nb_in);
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
alu_debug <= 1;
|
alu_debug <= 1;
|
||||||
next_cycle <= `BUSCMD_NOP;
|
next_cycle <= `BUSCMD_NOP;
|
||||||
decstate <= `DEC_ALU_INIT;
|
decstate <= `DEC_ALU_INIT;
|
||||||
|
alu_return <= `DEC_START;
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
$write("%5h ", inst_start_PC);
|
$write("%5h ", inst_start_PC);
|
||||||
if (!nb_in[3])
|
if (!nb_in[3])
|
||||||
|
|
|
@ -29,4 +29,5 @@
|
||||||
alu_debug <= 1;
|
alu_debug <= 1;
|
||||||
next_cycle <= `BUSCMD_NOP;
|
next_cycle <= `BUSCMD_NOP;
|
||||||
decstate <= `DEC_ALU_INIT;
|
decstate <= `DEC_ALU_INIT;
|
||||||
|
alu_return <= `DEC_START;
|
||||||
end
|
end
|
85
opcodes/Fx.v
85
opcodes/Fx.v
|
@ -8,54 +8,45 @@
|
||||||
`include "decstates.v"
|
`include "decstates.v"
|
||||||
|
|
||||||
`DEC_FX: begin
|
`DEC_FX: begin
|
||||||
case (nb_in)
|
field <= `T_FIELD_A;
|
||||||
4'h8, 4'h9, 4'hA, 4'hB: begin
|
alu_first <= 0;
|
||||||
if (!hex_dec) begin
|
alu_last <= 4;
|
||||||
case (nb_in)
|
alu_reg_dest <= {2'b00, nb_in[1:0]};
|
||||||
4'h8: {Carry, A[19:0]} <= - A[19:0];
|
|
||||||
4'h9: {Carry, B[19:0]} <= - B[19:0];
|
if (!nb_in[3]) begin
|
||||||
4'hA: {Carry, C[19:0]} <= - C[19:0];
|
$display("F%h shifts not implemented");
|
||||||
4'hB: {Carry, D[19:0]} <= - D[19:0];
|
|
||||||
endcase
|
|
||||||
decstate <= `DEC_START;
|
|
||||||
end
|
|
||||||
`ifdef SIM
|
|
||||||
$write("%5h ", inst_start_PC);
|
|
||||||
case (nb_in)
|
|
||||||
4'h8: $write("A=-A");
|
|
||||||
4'h8: $write("B=-B");
|
|
||||||
4'h8: $write("C=-C");
|
|
||||||
4'h8: $write("D=-D");
|
|
||||||
endcase
|
|
||||||
if (!hex_dec) $display("\tA");
|
|
||||||
else $display("\tA\t\t\t <=== DEC MODE NOT IMPLEMENTED");
|
|
||||||
`endif
|
|
||||||
end
|
|
||||||
4'hC, 4'hD, 4'hE, 4'hF: begin
|
|
||||||
if (!hex_dec) begin
|
|
||||||
case (nb_in)
|
|
||||||
4'hC: {Carry, A[19:0]} <= - A[19:0] - 1;
|
|
||||||
4'hD: {Carry, B[19:0]} <= - B[19:0] - 1;
|
|
||||||
4'hE: {Carry, C[19:0]} <= - C[19:0] - 1;
|
|
||||||
4'hF: {Carry, D[19:0]} <= - D[19:0] - 1;
|
|
||||||
endcase
|
|
||||||
decstate <= `DEC_START;
|
|
||||||
end
|
|
||||||
`ifdef SIM
|
|
||||||
$write("%5h ", inst_start_PC);
|
|
||||||
case (nb_in)
|
|
||||||
4'h8: $write("A=-A-1");
|
|
||||||
4'h8: $write("B=-B-1");
|
|
||||||
4'h8: $write("C=-C-1");
|
|
||||||
4'h8: $write("D=-D-1");
|
|
||||||
endcase
|
|
||||||
if (!hex_dec) $display("\tA");
|
|
||||||
else $display("\tA\t\t\t <=== DEC MODE NOT IMPLEMENTED");
|
|
||||||
`endif
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
$display("ERROR : DEC_FX");
|
|
||||||
decode_error <= 1;
|
decode_error <= 1;
|
||||||
|
end else begin
|
||||||
|
alu_reg_src1 <= {2'b00, nb_in[1:0]};
|
||||||
|
alu_op <= nb_in[2]?`ALU_OP_1CMPL:`ALU_OP_2CMPL;
|
||||||
end
|
end
|
||||||
|
alu_debug <= 1;
|
||||||
|
next_cycle <= `BUSCMD_NOP;
|
||||||
|
decstate <= `DEC_ALU_INIT;
|
||||||
|
alu_return <= `DEC_START;
|
||||||
|
|
||||||
|
`ifdef SIM
|
||||||
|
$write("%5h ", inst_start_PC);
|
||||||
|
case ({2'b00, nb_in[1:0]})
|
||||||
|
`ALU_REG_A: $write("A");
|
||||||
|
`ALU_REG_B: $write("B");
|
||||||
|
`ALU_REG_C: $write("C");
|
||||||
|
`ALU_REG_D: $write("D");
|
||||||
endcase
|
endcase
|
||||||
|
if (!nb_in[3]) begin
|
||||||
|
$write("S");
|
||||||
|
if (!nb_in[2]) $write("L");
|
||||||
|
else $write("R");
|
||||||
|
end else begin
|
||||||
|
$write("=-");
|
||||||
|
case ({2'b00, nb_in[1:0]})
|
||||||
|
`ALU_REG_A: $write("A");
|
||||||
|
`ALU_REG_B: $write("B");
|
||||||
|
`ALU_REG_C: $write("C");
|
||||||
|
`ALU_REG_D: $write("D");
|
||||||
|
endcase
|
||||||
|
if (nb_in[2]) $write("-1");
|
||||||
|
end
|
||||||
|
$display("\tA");
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,21 @@ case (decstate)
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
if (alu_debug) begin
|
if (alu_debug) begin
|
||||||
$display("------------------------------- z_alu_phase_2 ---------------------------------");
|
$display("------------------------------- z_alu_phase_2 ---------------------------------");
|
||||||
$display("ALU OP %h | FRST %h | LAST %h | SRC1 %h | SRC2 %h | DEST %h",
|
$write("ALU OP ");
|
||||||
alu_op, alu_first, alu_last, alu_reg_src1, alu_reg_src2,alu_reg_dest);
|
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_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]);
|
$display("CARRY %b | STICKY-BIT %b", Carry, HST[1]);
|
||||||
case (alu_reg_dest)
|
case (alu_reg_dest)
|
||||||
`ALU_REG_A: $display("A: %h", A);
|
`ALU_REG_A: $display("A: %h", A);
|
||||||
|
@ -24,21 +37,88 @@ case (decstate)
|
||||||
$display("");
|
$display("");
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Setting up SRC1 register for operations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef SIM
|
||||||
|
$display("setting up source 1 registers");
|
||||||
|
`endif
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
`ALU_OP_INC: begin
|
`ALU_OP_2CMPL,
|
||||||
|
`ALU_OP_1CMPL,
|
||||||
|
`ALU_OP_INC,
|
||||||
|
`ALU_OP_TEST_EQ,
|
||||||
|
`ALU_OP_TEST_NEQ: begin
|
||||||
case (alu_reg_src1)
|
case (alu_reg_src1)
|
||||||
`ALU_REG_A: alu_src1 <= A[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_B: alu_src1 <= B[alu_first*4+:4];
|
||||||
`ALU_REG_C: alu_src1 <= C[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_D: alu_src1 <= D[alu_first*4+:4];
|
||||||
endcase
|
endcase
|
||||||
alu_carry <= (decstate == `DEC_ALU_INIT)?1:Carry;
|
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
$display("nothing to do I suppose");
|
$display("no source 1 required");
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Setting up SRC2 register for operations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
case (alu_op)
|
||||||
|
`ALU_OP_TEST_EQ,
|
||||||
|
`ALU_OP_TEST_NEQ: begin
|
||||||
|
case (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_0: alu_src2 <= 0;
|
||||||
|
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_TEST_EQ,
|
||||||
|
`ALU_OP_TEST_NEQ:
|
||||||
|
alu_carry <= (decstate == `DEC_ALU_INIT)?1:Carry;
|
||||||
|
/*
|
||||||
|
* 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
|
end
|
||||||
endcase
|
endcase
|
||||||
|
|
|
@ -26,20 +26,39 @@
|
||||||
endcase
|
endcase
|
||||||
alu_first <= (alu_first + 1) & 4'hF;
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
end
|
end
|
||||||
`ALU_OP_SHR: begin
|
`ALU_OP_2CMPL: begin
|
||||||
|
case (alu_reg_dest)
|
||||||
|
`ALU_REG_A: {Carry, A[alu_first*4+:4]} <= !alu_src1 + alu_carry;
|
||||||
|
default: $display("ALU_OP_2CMPL register not handled");
|
||||||
|
endcase
|
||||||
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
|
end
|
||||||
|
`ALU_OP_1CMPL: begin
|
||||||
|
case (alu_reg_dest)
|
||||||
|
`ALU_REG_A: A[alu_first*4+:4] <= ~alu_src1;
|
||||||
|
default: $display("ALU_OP_1CMPL register not handled");
|
||||||
|
endcase
|
||||||
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
end
|
end
|
||||||
`ALU_OP_INC: begin
|
`ALU_OP_INC: begin
|
||||||
$display("ALU_OP_INC");
|
|
||||||
case (alu_reg_dest)
|
case (alu_reg_dest)
|
||||||
`ALU_REG_D: {Carry, D[alu_first*4+:4]} <= alu_src1 + alu_carry;
|
`ALU_REG_D: {Carry, D[alu_first*4+:4]} <= alu_src1 + alu_carry;
|
||||||
default: $display("ALU_OP_INC register not handled");
|
default: $display("ALU_OP_INC register not handled");
|
||||||
endcase
|
endcase
|
||||||
alu_first <= (alu_first + 1) & 4'hF;
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
end
|
end
|
||||||
|
`ALU_OP_TEST_EQ: begin
|
||||||
|
Carry <= (alu_src1 == alu_src2) & alu_carry;
|
||||||
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
|
end
|
||||||
|
`ALU_OP_TEST_NEQ: begin
|
||||||
|
Carry <= (alu_src1 != alu_src2) & alu_carry;
|
||||||
|
alu_first <= (alu_first + 1) & 4'hF;
|
||||||
|
end
|
||||||
default: begin
|
default: begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
$display("ALU: operation not implemented");
|
||||||
|
decode_error <= 1;
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
@ -47,7 +66,8 @@
|
||||||
|
|
||||||
if (alu_last == alu_first) begin
|
if (alu_last == alu_first) begin
|
||||||
// the alu is done
|
// the alu is done
|
||||||
decstate <= `DEC_START;
|
next_cycle <= alu_next_cycle;
|
||||||
|
decstate <= alu_return;
|
||||||
alu_requested_halt <= alu_halt;
|
alu_requested_halt <= alu_halt;
|
||||||
end else decstate <= `DEC_ALU_CONT;
|
end else decstate <= `DEC_ALU_CONT;
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,8 @@ reg alu_carry;
|
||||||
reg alu_debug;
|
reg alu_debug;
|
||||||
reg alu_halt;
|
reg alu_halt;
|
||||||
reg alu_requested_halt;
|
reg alu_requested_halt;
|
||||||
|
reg [11:0] alu_return;
|
||||||
|
reg [3:0] alu_next_cycle;
|
||||||
|
|
||||||
// processor registers
|
// processor registers
|
||||||
reg [19:0] PC;
|
reg [19:0] PC;
|
||||||
|
@ -358,7 +360,7 @@ always @(posedge ph2) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge ph3) begin
|
always @(posedge ph3) begin
|
||||||
if (cycle_ctr == 630)
|
if (cycle_ctr == 260)
|
||||||
debug_stop <= 1;
|
debug_stop <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -375,7 +377,8 @@ always @(posedge dec_strobe) begin
|
||||||
if ((next_cycle == `BUSCMD_LOAD_PC)|
|
if ((next_cycle == `BUSCMD_LOAD_PC)|
|
||||||
(next_cycle == `BUSCMD_CONFIGURE)|
|
(next_cycle == `BUSCMD_CONFIGURE)|
|
||||||
(next_cycle == `BUSCMD_RESET)|
|
(next_cycle == `BUSCMD_RESET)|
|
||||||
((next_cycle == `BUSCMD_NOP)&(decstate == `DEC_START))) begin
|
((next_cycle == `BUSCMD_NOP)&
|
||||||
|
(decstate == `DEC_START))) begin
|
||||||
$display("SETTING next_cycle to BUSCMD_PC_READ");
|
$display("SETTING next_cycle to BUSCMD_PC_READ");
|
||||||
next_cycle <= `BUSCMD_PC_READ;
|
next_cycle <= `BUSCMD_PC_READ;
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -392,8 +395,8 @@ always @(posedge dec_strobe) begin
|
||||||
$display(" RSTK0: %5h", RSTK[0]);
|
$display(" RSTK0: %5h", RSTK[0]);
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
$display("CYCLE %d | INSTR %d | PC %h | DECSTATE %3h | NIBBLE %h",
|
$display("CYCLE %d | NEXTC %h | INSTR %d | PC %h | DECSTATE %3h | NIBBLE %h",
|
||||||
cycle_ctr,
|
cycle_ctr, next_cycle,
|
||||||
(decstate == `DEC_START)?instr_ctr+1:instr_ctr,
|
(decstate == `DEC_START)?instr_ctr+1:instr_ctr,
|
||||||
PC, decstate, nb_in);
|
PC, decstate, nb_in);
|
||||||
case (decstate)
|
case (decstate)
|
||||||
|
|
Loading…
Add table
Reference in a new issue