mirror of
https://github.com/sxpert/hp-saturn
synced 2024-12-26 09:58:09 +01:00
make it so that execution of bus programs happen
in the same cycle as the instruction modify the way jump and rtn are handled add some registers to the debugger
This commit is contained in:
parent
e97ec2243f
commit
c62d562008
5 changed files with 186 additions and 47 deletions
|
@ -89,6 +89,7 @@ saturn_control_unit control_unit (
|
|||
.o_error (ctrl_unit_error),
|
||||
|
||||
.o_alu_busy (alu_busy),
|
||||
.o_exec_unit_busy (exec_unit_busy),
|
||||
|
||||
/* debugger interface */
|
||||
.o_current_pc (ctrl_current_pc),
|
||||
|
@ -122,6 +123,7 @@ wire [4:0] ctrl_unit_prog_data;
|
|||
wire [0:0] ctrl_unit_no_read;
|
||||
|
||||
wire [0:0] alu_busy;
|
||||
wire [0:0] exec_unit_busy;
|
||||
|
||||
/* debugger insterface */
|
||||
wire [19:0] ctrl_current_pc;
|
||||
|
@ -161,6 +163,7 @@ saturn_debugger debugger (
|
|||
|
||||
.o_debug_cycle (dbg_debug_cycle),
|
||||
.i_alu_busy (alu_busy),
|
||||
.i_exec_unit_busy (exec_unit_busy),
|
||||
|
||||
/* debugger interface */
|
||||
.i_current_pc (ctrl_current_pc),
|
||||
|
|
|
@ -44,6 +44,7 @@ module saturn_control_unit (
|
|||
|
||||
/* alu is busy doing something */
|
||||
o_alu_busy,
|
||||
o_exec_unit_busy,
|
||||
|
||||
/* debugger interface */
|
||||
|
||||
|
@ -92,7 +93,14 @@ output wire [0:0] o_error;
|
|||
assign o_error = control_unit_error || dec_error;
|
||||
|
||||
output wire [0:0] o_alu_busy;
|
||||
assign o_alu_busy = inst_alu_other || alu_start;
|
||||
output wire [0:0] o_exec_unit_busy;
|
||||
assign o_alu_busy = inst_alu_other || alu_start;
|
||||
assign o_exec_unit_busy = i_bus_busy ||
|
||||
alu_busy ||
|
||||
jump_busy ||
|
||||
rtn_busy ||
|
||||
reset_busy ||
|
||||
config_busy;
|
||||
|
||||
/* debugger interface */
|
||||
|
||||
|
@ -153,6 +161,7 @@ saturn_inst_decoder instruction_decoder(
|
|||
|
||||
.i_bus_busy (i_bus_busy),
|
||||
.i_alu_busy (o_alu_busy),
|
||||
.i_exec_unit_busy (o_exec_unit_busy),
|
||||
|
||||
.i_nibble (i_nibble),
|
||||
.i_reg_p (reg_P),
|
||||
|
@ -203,6 +212,8 @@ wire [0:0] dec_error;
|
|||
wire [0:0] inst_alu = (dec_instr_type == `INSTR_TYPE_ALU);
|
||||
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
|
||||
wire [0:0] inst_rtn = (dec_instr_type == `INSTR_TYPE_RTN);
|
||||
wire [0:0] inst_reset = (dec_instr_type == `INSTR_TYPE_RESET);
|
||||
wire [0:0] inst_config = (dec_instr_type == `INSTR_TYPE_CONFIG);
|
||||
|
||||
wire [0:0] reg_dest_c = (dec_alu_reg_dest == `ALU_REG_C);
|
||||
wire [0:0] reg_dest_hst = (dec_alu_reg_dest == `ALU_REG_HST);
|
||||
|
@ -228,6 +239,12 @@ wire [0:0] inst_alu_other = inst_alu &&
|
|||
inst_alu_st_eq_01_n
|
||||
);
|
||||
|
||||
wire [0:0] alu_busy = inst_alu_other || alu_start;
|
||||
wire [0:0] jump_busy = (inst_jump && dec_instr_decoded) || send_reg_PC;
|
||||
wire [0:0] rtn_busy = (inst_rtn && dec_instr_decoded) || send_reg_PC;
|
||||
wire [0:0] reset_busy = inst_reset;
|
||||
wire [0:0] config_busy = inst_config;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* PC and RSTK module
|
||||
|
@ -244,6 +261,7 @@ saturn_regs_pc_rstk regs_pc_rstk (
|
|||
|
||||
.i_bus_busy (i_bus_busy),
|
||||
.i_alu_busy (o_alu_busy),
|
||||
.i_exec_unit_busy (o_exec_unit_busy),
|
||||
|
||||
.i_nibble (i_nibble),
|
||||
.i_jump_instr (inst_jump),
|
||||
|
@ -379,6 +397,8 @@ reg [4:0] bus_program[0:31];
|
|||
reg [4:0] bus_prog_addr;
|
||||
reg [2:0] addr_nibble_ptr;
|
||||
reg [0:0] load_pc_loop;
|
||||
|
||||
reg [0:0] send_reg_PC;
|
||||
reg [0:0] send_reg_C_A;
|
||||
reg [0:0] send_pc_read;
|
||||
|
||||
|
@ -398,6 +418,8 @@ initial begin
|
|||
bus_prog_addr = 5'd0;
|
||||
addr_nibble_ptr = 3'd0;
|
||||
load_pc_loop = 1'b0;
|
||||
|
||||
send_reg_PC = 1'b0;
|
||||
send_reg_C_A = 1'b0;
|
||||
send_pc_read = 1'b0;
|
||||
|
||||
|
@ -432,18 +454,12 @@ always @(posedge i_clk) begin
|
|||
*
|
||||
*/
|
||||
|
||||
if (i_clk_en && (just_reset || reload_PC) && i_phases[3]) begin
|
||||
if (i_clk_en && just_reset && i_phases[3]) begin
|
||||
/* this happend right after reset */
|
||||
if (just_reset) begin
|
||||
`ifdef SIM
|
||||
$display("CTRL %0d: [%d] we were just reset, loading PC", i_phase, i_cycle_ctr);
|
||||
$display("CTRL %0d: [%d] we were just reset, loading PC", i_phase, i_cycle_ctr);
|
||||
`endif
|
||||
just_reset <= 1'b0;
|
||||
end else begin
|
||||
`ifdef SIM
|
||||
$display("CTRL %0d: [%d] reloading PC", i_phase, i_cycle_ctr);
|
||||
`endif
|
||||
end
|
||||
just_reset <= 1'b0;
|
||||
/* this loads the PC to the modules */
|
||||
bus_program[bus_prog_addr] <= {1'b1, `BUSCMD_LOAD_PC };
|
||||
`ifdef SIM
|
||||
|
@ -576,23 +592,38 @@ always @(posedge i_clk) begin
|
|||
`endif
|
||||
reg_alu_mode <= dec_alu_imm_value[0];
|
||||
end
|
||||
`INSTR_TYPE_JUMP: begin end
|
||||
`INSTR_TYPE_JUMP,
|
||||
`INSTR_TYPE_RTN:
|
||||
begin
|
||||
case (dec_alu_opcode)
|
||||
`ALU_OP_SET_CRY: reg_CARRY <= o_alu_imm_value[0];
|
||||
default:
|
||||
begin
|
||||
$display("CTRL %0d: [%d] alu_opcode for RTN %0d", i_phase, i_cycle_ctr, dec_alu_opcode);
|
||||
control_unit_error <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
if (inst_jump) begin
|
||||
$display("CTRL %0d: [%d] JUMP", i_phase, i_cycle_ctr);
|
||||
end
|
||||
if (inst_rtn) begin
|
||||
$display("CTRL %0d: [%d] RTN", i_phase, i_cycle_ctr);
|
||||
case (dec_alu_opcode)
|
||||
`ALU_OP_SET_CRY: reg_CARRY <= o_alu_imm_value[0];
|
||||
default:
|
||||
begin
|
||||
$display("CTRL %0d: [%d] alu_opcode for RTN %0d", i_phase, i_cycle_ctr, dec_alu_opcode);
|
||||
control_unit_error <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (dec_instr_decoded) begin
|
||||
$display("CTRL %0d: [%d] exec : JUMP/RTN reload pc to %5h", i_phase, i_cycle_ctr, reg_PC);
|
||||
bus_program[bus_prog_addr] <= {1'b1, `BUSCMD_LOAD_PC };
|
||||
bus_prog_addr <= bus_prog_addr + 5'd1;
|
||||
addr_nibble_ptr <= 3'b0;
|
||||
send_reg_PC <= 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
`INSTR_TYPE_LOAD:
|
||||
begin
|
||||
case (dec_alu_reg_dest)
|
||||
`ALU_REG_C: reg_C[dec_alu_ptr_begin] <= dec_alu_imm_value;
|
||||
`ALU_REG_D0: reg_D0[dec_alu_ptr_begin] <= dec_alu_imm_value;
|
||||
`ALU_REG_D0: reg_D0[dec_alu_ptr_begin[2:0]] <= dec_alu_imm_value;
|
||||
default:
|
||||
begin
|
||||
$display("CTRL %0d: [%d] unsupported register for load %0d", i_phase, i_cycle_ctr, dec_alu_reg_dest);
|
||||
|
@ -624,6 +655,27 @@ always @(posedge i_clk) begin
|
|||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* sending bus programs
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
if (i_clk_en && control_unit_ready) begin
|
||||
|
||||
if (send_reg_PC) begin
|
||||
$display("CTRL %0d: [%d] exec: send_reg_PC[%0d] %h", i_phase, i_cycle_ctr, addr_nibble_ptr, reg_PC[addr_nibble_ptr*4+:4] );
|
||||
bus_program[bus_prog_addr] <= { 1'b0, reg_PC[addr_nibble_ptr*4+:4] };
|
||||
addr_nibble_ptr <= addr_nibble_ptr + 3'd1;
|
||||
bus_prog_addr <= bus_prog_addr + 5'd1;
|
||||
if (addr_nibble_ptr == 3'd4) begin
|
||||
addr_nibble_ptr <= 3'd0;
|
||||
send_reg_PC <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* send C(A)
|
||||
* used for CONFIG and UNCNFG
|
||||
|
@ -650,11 +702,16 @@ always @(posedge i_clk) begin
|
|||
end
|
||||
|
||||
|
||||
/******************************************************************************************
|
||||
*
|
||||
* ALU control
|
||||
*
|
||||
*****************************************************************************************/
|
||||
end
|
||||
|
||||
|
||||
/******************************************************************************************
|
||||
*
|
||||
* ALU control
|
||||
*
|
||||
*****************************************************************************************/
|
||||
|
||||
if (i_clk_en && control_unit_ready) begin
|
||||
|
||||
if (alu_start && alu_prep_run && !alu_prep_done) begin
|
||||
$display("ALU_PREP %0d: [%d] b %h | p %h | e %h", i_phase, i_cycle_ctr, alu_ptr_begin, alu_prep_pos, alu_ptr_end);
|
||||
|
@ -714,6 +771,8 @@ always @(posedge i_clk) begin
|
|||
bus_prog_addr <= 5'd0;
|
||||
addr_nibble_ptr <= 3'd0;
|
||||
load_pc_loop <= 1'b0;
|
||||
|
||||
send_reg_PC <= 1'b0;
|
||||
send_reg_C_A <= 1'b0;
|
||||
send_pc_read <= 1'b0;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ module saturn_debugger (
|
|||
|
||||
o_debug_cycle,
|
||||
i_alu_busy,
|
||||
i_exec_unit_busy,
|
||||
|
||||
/* interface from the control unit */
|
||||
i_current_pc,
|
||||
|
@ -81,6 +82,7 @@ input wire [31:0] i_cycle_ctr;
|
|||
|
||||
output reg [0:0] o_debug_cycle;
|
||||
input wire [0:0] i_alu_busy;
|
||||
input wire [0:0] i_exec_unit_busy;
|
||||
|
||||
/* inteface from the control unit */
|
||||
input wire [19:0] i_current_pc;
|
||||
|
@ -187,7 +189,7 @@ end
|
|||
|
||||
always @(posedge i_clk) begin
|
||||
|
||||
if (i_clk_en && i_phases[3] && i_instr_decoded && !debug_done && !i_alu_busy) begin
|
||||
if (i_clk_en && i_phases[3] && i_instr_decoded && !debug_done && !i_exec_unit_busy) begin
|
||||
$display("DEBUGGER %0d: [%d] start debugger cycle (alu_busy %b)", i_phase, i_cycle_ctr, i_alu_busy);
|
||||
o_debug_cycle <= 1'b1;
|
||||
registers_ctr <= 9'd0;
|
||||
|
@ -586,6 +588,65 @@ always @(posedge i_clk) begin
|
|||
if (registers_reg_ptr == 6'd0) begin
|
||||
registers_reg_ptr <= 6'd0;
|
||||
o_dbg_register <= `ALU_REG_NONE;
|
||||
registers_state <= `DBG_REG_R4_STR;
|
||||
end
|
||||
end
|
||||
`DBG_REG_R4_STR:
|
||||
begin
|
||||
case (registers_reg_ptr)
|
||||
6'd0: registers_str[registers_ctr] <= " ";
|
||||
6'd1: registers_str[registers_ctr] <= " ";
|
||||
6'd2: registers_str[registers_ctr] <= "R";
|
||||
6'd3: registers_str[registers_ctr] <= "4";
|
||||
6'd4: registers_str[registers_ctr] <= ":";
|
||||
6'd5: registers_str[registers_ctr] <= " ";
|
||||
6'd6: registers_str[registers_ctr] <= " ";
|
||||
default: begin end
|
||||
endcase
|
||||
registers_reg_ptr <= registers_reg_ptr + 6'd1;
|
||||
if (registers_reg_ptr == 6'd6) begin
|
||||
registers_reg_ptr <= 6'd15;
|
||||
o_dbg_register <= `ALU_REG_R4;
|
||||
registers_state <= `DBG_REG_R4_VALUE;
|
||||
end
|
||||
end
|
||||
`DBG_REG_R4_VALUE:
|
||||
begin
|
||||
registers_str[registers_ctr] <= hex[i_dbg_reg_nibble];
|
||||
registers_reg_ptr <= registers_reg_ptr - 6'd1;
|
||||
if (registers_reg_ptr == 6'd0) begin
|
||||
registers_reg_ptr <= 6'd0;
|
||||
o_dbg_register <= `ALU_REG_NONE;
|
||||
registers_state <= `DBG_REG_RSTK1_STR;
|
||||
end
|
||||
end
|
||||
`DBG_REG_RSTK1_STR:
|
||||
begin
|
||||
case (registers_reg_ptr)
|
||||
6'd0: registers_str[registers_ctr] <= " ";
|
||||
6'd1: registers_str[registers_ctr] <= " ";
|
||||
6'd2: registers_str[registers_ctr] <= "R";
|
||||
6'd3: registers_str[registers_ctr] <= "S";
|
||||
6'd4: registers_str[registers_ctr] <= "T";
|
||||
6'd5: registers_str[registers_ctr] <= "K";
|
||||
6'd6: registers_str[registers_ctr] <= "1";
|
||||
6'd7: registers_str[registers_ctr] <= ":";
|
||||
6'd8: registers_str[registers_ctr] <= " ";
|
||||
default: begin end
|
||||
endcase
|
||||
registers_reg_ptr <= registers_reg_ptr + 6'd1;
|
||||
if (registers_reg_ptr == 6'd8) begin
|
||||
registers_reg_ptr <= 6'd4;
|
||||
o_dbg_rstk_ptr <= 3'd1;
|
||||
registers_state <= `DBG_REG_RSTK1_VALUE;
|
||||
end
|
||||
end
|
||||
`DBG_REG_RSTK1_VALUE:
|
||||
begin
|
||||
registers_str[registers_ctr] <= hex[i_dbg_rstk_val[(registers_reg_ptr)*4+:4]];
|
||||
registers_reg_ptr <= registers_reg_ptr - 6'd1;
|
||||
if (registers_reg_ptr == 6'd0) begin
|
||||
registers_reg_ptr <= 6'd0;
|
||||
registers_state <= `DBG_REG_SPACES_7;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,6 +32,7 @@ module saturn_inst_decoder (
|
|||
|
||||
i_bus_busy,
|
||||
i_alu_busy,
|
||||
i_exec_unit_busy,
|
||||
|
||||
i_nibble,
|
||||
i_reg_p,
|
||||
|
@ -70,6 +71,7 @@ input wire [31:0] i_cycle_ctr;
|
|||
|
||||
input wire [0:0] i_bus_busy;
|
||||
input wire [0:0] i_alu_busy;
|
||||
input wire [0:0] i_exec_unit_busy;
|
||||
|
||||
input wire [3:0] i_nibble;
|
||||
input wire [3:0] i_reg_p;
|
||||
|
@ -235,7 +237,7 @@ always @(posedge i_clk) begin
|
|||
o_instr_decoded <= 1'b1;
|
||||
end
|
||||
|
||||
if (i_clk_en && !i_bus_busy && !i_alu_busy) begin
|
||||
if (i_clk_en && !i_bus_busy && !i_exec_unit_busy) begin
|
||||
|
||||
if (i_phases[1] && !decode_started) begin
|
||||
// $display("DECODER %0d: [%d] store current PC as instruction start %5h", i_phase, i_cycle_ctr, i_current_pc);
|
||||
|
|
|
@ -30,6 +30,7 @@ module saturn_regs_pc_rstk (
|
|||
|
||||
i_bus_busy,
|
||||
i_alu_busy,
|
||||
i_exec_unit_busy,
|
||||
|
||||
i_nibble,
|
||||
i_jump_instr,
|
||||
|
@ -56,6 +57,7 @@ input wire [31:0] i_cycle_ctr;
|
|||
|
||||
input wire [0:0] i_bus_busy;
|
||||
input wire [0:0] i_alu_busy;
|
||||
input wire [0:0] i_exec_unit_busy;
|
||||
|
||||
input wire [3:0] i_nibble;
|
||||
input wire [0:0] i_jump_instr;
|
||||
|
@ -152,7 +154,7 @@ always @(posedge i_clk) begin
|
|||
// if (!i_debug_cycle)
|
||||
// $display("PC_RSTK %0d: [%d] !i_bus_busy %b", i_phase, i_cycle_ctr, !i_bus_busy);
|
||||
|
||||
if (i_clk_en && !i_bus_busy && !i_alu_busy) begin
|
||||
if (i_clk_en && !i_bus_busy && !i_exec_unit_busy) begin
|
||||
|
||||
if (i_phases[3] && just_reset) begin
|
||||
$display("PC_RSTK %0d: [%d] exit from reset mode", i_phase, i_cycle_ctr);
|
||||
|
@ -168,8 +170,12 @@ always @(posedge i_clk) begin
|
|||
* jump instruction calculations
|
||||
*/
|
||||
|
||||
/* start the jump instruction */
|
||||
if (i_phases[3] && do_jump_instr && !jump_decode && !jump_exec) begin
|
||||
/* start the jump instruction
|
||||
* the jump base is:
|
||||
* address of first nibble of the offset when goto
|
||||
* address of nibble after the offset when gosub
|
||||
*/
|
||||
if (i_phases[3] && do_jump_instr && !jump_decode) begin
|
||||
$display("PC_RSTK %0d: [%d] start decode jump %0d | jump_base %5h", i_phase, i_cycle_ctr, i_jump_length, reg_PC);
|
||||
jump_counter <= 3'd0;
|
||||
jump_base <= reg_PC;
|
||||
|
@ -182,25 +188,33 @@ always @(posedge i_clk) begin
|
|||
jump_offset <= jump_next_offset;
|
||||
jump_counter <= jump_counter + 3'd1;
|
||||
if (jump_counter == i_jump_length) begin
|
||||
$write("PC_RSTK %0d: [%d] execute jump(%0d) jump_base %h jump_next_offset %h", i_phase, i_cycle_ctr, i_jump_length, jump_base, jump_next_offset);
|
||||
jump_decode <= 1'b0;
|
||||
jump_exec <= 1'b1;
|
||||
o_reload_pc <= 1'b1;
|
||||
// jump_exec <= 1'b1;
|
||||
// o_reload_pc <= 1'b1;
|
||||
reg_PC <= jump_relative ? jump_next_offset + jump_base : jump_next_offset;
|
||||
if (i_push_pc) begin
|
||||
$write(" ( push %5h => RSTK[%0d] )", reg_PC, reg_rstk_ptr + 3'd1);
|
||||
reg_RSTK[(reg_rstk_ptr + 3'o1)&3'o7] <= reg_PC;
|
||||
reg_rstk_ptr <= reg_rstk_ptr + 3'd1;
|
||||
end
|
||||
$write("\n");
|
||||
end
|
||||
end
|
||||
|
||||
/* all done, apply to PC and RSTK */
|
||||
if (i_phases[3] && do_jump_instr && jump_exec) begin
|
||||
$write("PC_RSTK %0d: [%d] execute jump %0d", i_phase, i_cycle_ctr, i_jump_length);
|
||||
if (i_push_pc) begin
|
||||
$write(" ( push %5h => RSTK[%0d])", reg_PC, reg_rstk_ptr + 3'd1);
|
||||
reg_RSTK[(reg_rstk_ptr + 3'o1)&3'o7] <= reg_PC;
|
||||
reg_rstk_ptr <= reg_rstk_ptr + 3'd1;
|
||||
end
|
||||
$display("");
|
||||
reg_PC <= jump_relative ? jump_offset + jump_base : jump_offset;
|
||||
jump_exec <= 1'b0;
|
||||
o_reload_pc <= 1'b0;
|
||||
end
|
||||
// /* all done, apply to PC and RSTK */
|
||||
// if (i_phases[3] && do_jump_instr && jump_exec) begin
|
||||
// $write("PC_RSTK %0d: [%d] execute jump %0d", i_phase, i_cycle_ctr, i_jump_length);
|
||||
// if (i_push_pc) begin
|
||||
// $write(" ( push %5h => RSTK[%0d])", reg_PC, reg_rstk_ptr + 3'd1);
|
||||
// reg_RSTK[(reg_rstk_ptr + 3'o1)&3'o7] <= reg_PC;
|
||||
// reg_rstk_ptr <= reg_rstk_ptr + 3'd1;
|
||||
// end
|
||||
// $display("");
|
||||
// reg_PC <= jump_relative ? jump_offset + jump_base : jump_offset;
|
||||
// jump_exec <= 1'b0;
|
||||
// o_reload_pc <= 1'b0;
|
||||
// end
|
||||
|
||||
/*
|
||||
* RTN instruction
|
||||
|
@ -216,7 +230,7 @@ always @(posedge i_clk) begin
|
|||
4'h3: $display("CC");
|
||||
default: begin end
|
||||
endcase
|
||||
o_reload_pc <= 1'b1;
|
||||
// o_reload_pc <= 1'b1;
|
||||
end
|
||||
|
||||
if (i_phases[3] && i_rtn_instr) begin
|
||||
|
@ -225,7 +239,7 @@ always @(posedge i_clk) begin
|
|||
reg_RSTK[reg_rstk_ptr] <= 20'h00000;
|
||||
reg_rstk_ptr <= (reg_rstk_ptr - 3'd1) & 3'd7;
|
||||
/* o_reload_pc was set in advance above */
|
||||
o_reload_pc <= 1'b0;
|
||||
// o_reload_pc <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue