mirror of
https://github.com/sxpert/hp-saturn
synced 2024-12-27 09:58:16 +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_error (ctrl_unit_error),
|
||||||
|
|
||||||
.o_alu_busy (alu_busy),
|
.o_alu_busy (alu_busy),
|
||||||
|
.o_exec_unit_busy (exec_unit_busy),
|
||||||
|
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
.o_current_pc (ctrl_current_pc),
|
.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] ctrl_unit_no_read;
|
||||||
|
|
||||||
wire [0:0] alu_busy;
|
wire [0:0] alu_busy;
|
||||||
|
wire [0:0] exec_unit_busy;
|
||||||
|
|
||||||
/* debugger insterface */
|
/* debugger insterface */
|
||||||
wire [19:0] ctrl_current_pc;
|
wire [19:0] ctrl_current_pc;
|
||||||
|
@ -161,6 +163,7 @@ saturn_debugger debugger (
|
||||||
|
|
||||||
.o_debug_cycle (dbg_debug_cycle),
|
.o_debug_cycle (dbg_debug_cycle),
|
||||||
.i_alu_busy (alu_busy),
|
.i_alu_busy (alu_busy),
|
||||||
|
.i_exec_unit_busy (exec_unit_busy),
|
||||||
|
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
.i_current_pc (ctrl_current_pc),
|
.i_current_pc (ctrl_current_pc),
|
||||||
|
|
|
@ -44,6 +44,7 @@ module saturn_control_unit (
|
||||||
|
|
||||||
/* alu is busy doing something */
|
/* alu is busy doing something */
|
||||||
o_alu_busy,
|
o_alu_busy,
|
||||||
|
o_exec_unit_busy,
|
||||||
|
|
||||||
/* debugger interface */
|
/* debugger interface */
|
||||||
|
|
||||||
|
@ -92,7 +93,14 @@ output wire [0:0] o_error;
|
||||||
assign o_error = control_unit_error || dec_error;
|
assign o_error = control_unit_error || dec_error;
|
||||||
|
|
||||||
output wire [0:0] o_alu_busy;
|
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 */
|
/* debugger interface */
|
||||||
|
|
||||||
|
@ -153,6 +161,7 @@ saturn_inst_decoder instruction_decoder(
|
||||||
|
|
||||||
.i_bus_busy (i_bus_busy),
|
.i_bus_busy (i_bus_busy),
|
||||||
.i_alu_busy (o_alu_busy),
|
.i_alu_busy (o_alu_busy),
|
||||||
|
.i_exec_unit_busy (o_exec_unit_busy),
|
||||||
|
|
||||||
.i_nibble (i_nibble),
|
.i_nibble (i_nibble),
|
||||||
.i_reg_p (reg_P),
|
.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_alu = (dec_instr_type == `INSTR_TYPE_ALU);
|
||||||
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
|
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_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_c = (dec_alu_reg_dest == `ALU_REG_C);
|
||||||
wire [0:0] reg_dest_hst = (dec_alu_reg_dest == `ALU_REG_HST);
|
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
|
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
|
* PC and RSTK module
|
||||||
|
@ -244,6 +261,7 @@ saturn_regs_pc_rstk regs_pc_rstk (
|
||||||
|
|
||||||
.i_bus_busy (i_bus_busy),
|
.i_bus_busy (i_bus_busy),
|
||||||
.i_alu_busy (o_alu_busy),
|
.i_alu_busy (o_alu_busy),
|
||||||
|
.i_exec_unit_busy (o_exec_unit_busy),
|
||||||
|
|
||||||
.i_nibble (i_nibble),
|
.i_nibble (i_nibble),
|
||||||
.i_jump_instr (inst_jump),
|
.i_jump_instr (inst_jump),
|
||||||
|
@ -379,6 +397,8 @@ reg [4:0] bus_program[0:31];
|
||||||
reg [4:0] bus_prog_addr;
|
reg [4:0] bus_prog_addr;
|
||||||
reg [2:0] addr_nibble_ptr;
|
reg [2:0] addr_nibble_ptr;
|
||||||
reg [0:0] load_pc_loop;
|
reg [0:0] load_pc_loop;
|
||||||
|
|
||||||
|
reg [0:0] send_reg_PC;
|
||||||
reg [0:0] send_reg_C_A;
|
reg [0:0] send_reg_C_A;
|
||||||
reg [0:0] send_pc_read;
|
reg [0:0] send_pc_read;
|
||||||
|
|
||||||
|
@ -398,6 +418,8 @@ initial begin
|
||||||
bus_prog_addr = 5'd0;
|
bus_prog_addr = 5'd0;
|
||||||
addr_nibble_ptr = 3'd0;
|
addr_nibble_ptr = 3'd0;
|
||||||
load_pc_loop = 1'b0;
|
load_pc_loop = 1'b0;
|
||||||
|
|
||||||
|
send_reg_PC = 1'b0;
|
||||||
send_reg_C_A = 1'b0;
|
send_reg_C_A = 1'b0;
|
||||||
send_pc_read = 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 */
|
/* this happend right after reset */
|
||||||
if (just_reset) begin
|
|
||||||
`ifdef SIM
|
`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
|
`endif
|
||||||
just_reset <= 1'b0;
|
just_reset <= 1'b0;
|
||||||
end else begin
|
|
||||||
`ifdef SIM
|
|
||||||
$display("CTRL %0d: [%d] reloading PC", i_phase, i_cycle_ctr);
|
|
||||||
`endif
|
|
||||||
end
|
|
||||||
/* this loads the PC to the modules */
|
/* this loads the PC to the modules */
|
||||||
bus_program[bus_prog_addr] <= {1'b1, `BUSCMD_LOAD_PC };
|
bus_program[bus_prog_addr] <= {1'b1, `BUSCMD_LOAD_PC };
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
@ -576,23 +592,38 @@ always @(posedge i_clk) begin
|
||||||
`endif
|
`endif
|
||||||
reg_alu_mode <= dec_alu_imm_value[0];
|
reg_alu_mode <= dec_alu_imm_value[0];
|
||||||
end
|
end
|
||||||
`INSTR_TYPE_JUMP: begin end
|
`INSTR_TYPE_JUMP,
|
||||||
`INSTR_TYPE_RTN:
|
`INSTR_TYPE_RTN:
|
||||||
begin
|
begin
|
||||||
case (dec_alu_opcode)
|
if (inst_jump) begin
|
||||||
`ALU_OP_SET_CRY: reg_CARRY <= o_alu_imm_value[0];
|
$display("CTRL %0d: [%d] JUMP", i_phase, i_cycle_ctr);
|
||||||
default:
|
end
|
||||||
begin
|
if (inst_rtn) begin
|
||||||
$display("CTRL %0d: [%d] alu_opcode for RTN %0d", i_phase, i_cycle_ctr, dec_alu_opcode);
|
$display("CTRL %0d: [%d] RTN", i_phase, i_cycle_ctr);
|
||||||
control_unit_error <= 1'b1;
|
case (dec_alu_opcode)
|
||||||
end
|
`ALU_OP_SET_CRY: reg_CARRY <= o_alu_imm_value[0];
|
||||||
endcase
|
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
|
end
|
||||||
`INSTR_TYPE_LOAD:
|
`INSTR_TYPE_LOAD:
|
||||||
begin
|
begin
|
||||||
case (dec_alu_reg_dest)
|
case (dec_alu_reg_dest)
|
||||||
`ALU_REG_C: reg_C[dec_alu_ptr_begin] <= dec_alu_imm_value;
|
`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:
|
default:
|
||||||
begin
|
begin
|
||||||
$display("CTRL %0d: [%d] unsupported register for load %0d", i_phase, i_cycle_ctr, dec_alu_reg_dest);
|
$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
|
endcase
|
||||||
end
|
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)
|
* send C(A)
|
||||||
* used for CONFIG and UNCNFG
|
* used for CONFIG and UNCNFG
|
||||||
|
@ -650,11 +702,16 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************************
|
end
|
||||||
*
|
|
||||||
* ALU control
|
|
||||||
*
|
/******************************************************************************************
|
||||||
*****************************************************************************************/
|
*
|
||||||
|
* ALU control
|
||||||
|
*
|
||||||
|
*****************************************************************************************/
|
||||||
|
|
||||||
|
if (i_clk_en && control_unit_ready) begin
|
||||||
|
|
||||||
if (alu_start && alu_prep_run && !alu_prep_done) 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);
|
$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;
|
bus_prog_addr <= 5'd0;
|
||||||
addr_nibble_ptr <= 3'd0;
|
addr_nibble_ptr <= 3'd0;
|
||||||
load_pc_loop <= 1'b0;
|
load_pc_loop <= 1'b0;
|
||||||
|
|
||||||
|
send_reg_PC <= 1'b0;
|
||||||
send_reg_C_A <= 1'b0;
|
send_reg_C_A <= 1'b0;
|
||||||
send_pc_read <= 1'b0;
|
send_pc_read <= 1'b0;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ module saturn_debugger (
|
||||||
|
|
||||||
o_debug_cycle,
|
o_debug_cycle,
|
||||||
i_alu_busy,
|
i_alu_busy,
|
||||||
|
i_exec_unit_busy,
|
||||||
|
|
||||||
/* interface from the control unit */
|
/* interface from the control unit */
|
||||||
i_current_pc,
|
i_current_pc,
|
||||||
|
@ -81,6 +82,7 @@ input wire [31:0] i_cycle_ctr;
|
||||||
|
|
||||||
output reg [0:0] o_debug_cycle;
|
output reg [0:0] o_debug_cycle;
|
||||||
input wire [0:0] i_alu_busy;
|
input wire [0:0] i_alu_busy;
|
||||||
|
input wire [0:0] i_exec_unit_busy;
|
||||||
|
|
||||||
/* inteface from the control unit */
|
/* inteface from the control unit */
|
||||||
input wire [19:0] i_current_pc;
|
input wire [19:0] i_current_pc;
|
||||||
|
@ -187,7 +189,7 @@ end
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
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);
|
$display("DEBUGGER %0d: [%d] start debugger cycle (alu_busy %b)", i_phase, i_cycle_ctr, i_alu_busy);
|
||||||
o_debug_cycle <= 1'b1;
|
o_debug_cycle <= 1'b1;
|
||||||
registers_ctr <= 9'd0;
|
registers_ctr <= 9'd0;
|
||||||
|
@ -586,6 +588,65 @@ always @(posedge i_clk) begin
|
||||||
if (registers_reg_ptr == 6'd0) begin
|
if (registers_reg_ptr == 6'd0) begin
|
||||||
registers_reg_ptr <= 6'd0;
|
registers_reg_ptr <= 6'd0;
|
||||||
o_dbg_register <= `ALU_REG_NONE;
|
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;
|
registers_state <= `DBG_REG_SPACES_7;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,7 @@ module saturn_inst_decoder (
|
||||||
|
|
||||||
i_bus_busy,
|
i_bus_busy,
|
||||||
i_alu_busy,
|
i_alu_busy,
|
||||||
|
i_exec_unit_busy,
|
||||||
|
|
||||||
i_nibble,
|
i_nibble,
|
||||||
i_reg_p,
|
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_bus_busy;
|
||||||
input wire [0:0] i_alu_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_nibble;
|
||||||
input wire [3:0] i_reg_p;
|
input wire [3:0] i_reg_p;
|
||||||
|
@ -235,7 +237,7 @@ always @(posedge i_clk) begin
|
||||||
o_instr_decoded <= 1'b1;
|
o_instr_decoded <= 1'b1;
|
||||||
end
|
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
|
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);
|
// $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_bus_busy,
|
||||||
i_alu_busy,
|
i_alu_busy,
|
||||||
|
i_exec_unit_busy,
|
||||||
|
|
||||||
i_nibble,
|
i_nibble,
|
||||||
i_jump_instr,
|
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_bus_busy;
|
||||||
input wire [0:0] i_alu_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_nibble;
|
||||||
input wire [0:0] i_jump_instr;
|
input wire [0:0] i_jump_instr;
|
||||||
|
@ -152,7 +154,7 @@ always @(posedge i_clk) begin
|
||||||
// if (!i_debug_cycle)
|
// if (!i_debug_cycle)
|
||||||
// $display("PC_RSTK %0d: [%d] !i_bus_busy %b", i_phase, i_cycle_ctr, !i_bus_busy);
|
// $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
|
if (i_phases[3] && just_reset) begin
|
||||||
$display("PC_RSTK %0d: [%d] exit from reset mode", i_phase, i_cycle_ctr);
|
$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
|
* jump instruction calculations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* start the jump instruction */
|
/* start the jump instruction
|
||||||
if (i_phases[3] && do_jump_instr && !jump_decode && !jump_exec) begin
|
* 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);
|
$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_counter <= 3'd0;
|
||||||
jump_base <= reg_PC;
|
jump_base <= reg_PC;
|
||||||
|
@ -182,25 +188,33 @@ always @(posedge i_clk) begin
|
||||||
jump_offset <= jump_next_offset;
|
jump_offset <= jump_next_offset;
|
||||||
jump_counter <= jump_counter + 3'd1;
|
jump_counter <= jump_counter + 3'd1;
|
||||||
if (jump_counter == i_jump_length) begin
|
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_decode <= 1'b0;
|
||||||
jump_exec <= 1'b1;
|
// jump_exec <= 1'b1;
|
||||||
o_reload_pc <= 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
|
||||||
end
|
end
|
||||||
|
|
||||||
/* all done, apply to PC and RSTK */
|
// /* all done, apply to PC and RSTK */
|
||||||
if (i_phases[3] && do_jump_instr && jump_exec) begin
|
// 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);
|
// $write("PC_RSTK %0d: [%d] execute jump %0d", i_phase, i_cycle_ctr, i_jump_length);
|
||||||
if (i_push_pc) begin
|
// if (i_push_pc) begin
|
||||||
$write(" ( push %5h => RSTK[%0d])", reg_PC, reg_rstk_ptr + 3'd1);
|
// $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[(reg_rstk_ptr + 3'o1)&3'o7] <= reg_PC;
|
||||||
reg_rstk_ptr <= reg_rstk_ptr + 3'd1;
|
// reg_rstk_ptr <= reg_rstk_ptr + 3'd1;
|
||||||
end
|
// end
|
||||||
$display("");
|
// $display("");
|
||||||
reg_PC <= jump_relative ? jump_offset + jump_base : jump_offset;
|
// reg_PC <= jump_relative ? jump_offset + jump_base : jump_offset;
|
||||||
jump_exec <= 1'b0;
|
// jump_exec <= 1'b0;
|
||||||
o_reload_pc <= 1'b0;
|
// o_reload_pc <= 1'b0;
|
||||||
end
|
// end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RTN instruction
|
* RTN instruction
|
||||||
|
@ -216,7 +230,7 @@ always @(posedge i_clk) begin
|
||||||
4'h3: $display("CC");
|
4'h3: $display("CC");
|
||||||
default: begin end
|
default: begin end
|
||||||
endcase
|
endcase
|
||||||
o_reload_pc <= 1'b1;
|
// o_reload_pc <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (i_phases[3] && i_rtn_instr) begin
|
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[reg_rstk_ptr] <= 20'h00000;
|
||||||
reg_rstk_ptr <= (reg_rstk_ptr - 3'd1) & 3'd7;
|
reg_rstk_ptr <= (reg_rstk_ptr - 3'd1) & 3'd7;
|
||||||
/* o_reload_pc was set in advance above */
|
/* o_reload_pc was set in advance above */
|
||||||
o_reload_pc <= 1'b0;
|
// o_reload_pc <= 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue