mirror of
https://github.com/sxpert/hp-saturn
synced 2024-11-16 19:50:19 +01:00
start implementing jump instructions
This commit is contained in:
parent
d17a4eb533
commit
631b7f9153
4 changed files with 108 additions and 7 deletions
|
@ -125,6 +125,8 @@ saturn_inst_decoder instruction_decoder(
|
|||
.o_alu_imm_value (dec_alu_imm_value),
|
||||
.o_alu_opcode (dec_alu_opcode),
|
||||
|
||||
.o_jump_length (dec_jump_length),
|
||||
|
||||
.o_instr_type (dec_instr_type),
|
||||
.o_instr_decoded (dec_instr_decoded),
|
||||
.o_instr_execute (dec_instr_execute)
|
||||
|
@ -136,6 +138,8 @@ wire [4:0] dec_alu_reg_src_2;
|
|||
wire [3:0] dec_alu_imm_value;
|
||||
wire [4:0] dec_alu_opcode;
|
||||
|
||||
wire [2:0] dec_jump_length;
|
||||
|
||||
wire [3:0] dec_instr_type;
|
||||
wire [0:0] dec_instr_decoded;
|
||||
wire [0:0] dec_instr_execute;
|
||||
|
@ -151,6 +155,8 @@ wire [0:0] aluop_copy = (dec_alu_opcode == `ALU_OP_COPY);
|
|||
wire [0:0] inst_alu_p_eq_n = aluop_copy && reg_dest_p && reg_src_1_imm;
|
||||
wire [0:0] inst_alu_other = !(inst_alu_p_eq_n);
|
||||
|
||||
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* registers module (contains A, B, C, D, R0, R1, R2, R3, R4)
|
||||
|
@ -174,7 +180,9 @@ saturn_regs_pc_rstk regs_pc_rstk (
|
|||
.i_bus_busy (i_bus_busy),
|
||||
|
||||
.i_nibble (i_nibble),
|
||||
|
||||
.i_jump_instr (inst_jump),
|
||||
.i_jump_length (dec_jump_length),
|
||||
|
||||
.o_current_pc (reg_PC)
|
||||
);
|
||||
|
||||
|
@ -200,6 +208,8 @@ reg [4:0] bus_program[0:31];
|
|||
reg [4:0] bus_prog_addr;
|
||||
reg [2:0] addr_nibble_ptr;
|
||||
|
||||
reg [2:0] jump_counter;
|
||||
|
||||
wire [3:0] reg_PC_nibble = reg_PC[addr_nibble_ptr*4+:4];
|
||||
|
||||
assign o_program_data = bus_program[i_program_address];
|
||||
|
@ -213,6 +223,8 @@ initial begin
|
|||
control_unit_ready = 1'b0;
|
||||
bus_prog_addr = 5'd0;
|
||||
addr_nibble_ptr = 3'd0;
|
||||
|
||||
jump_counter = 3'd0;
|
||||
|
||||
/* registers */
|
||||
reg_P = 4'b0;
|
||||
|
@ -278,7 +290,7 @@ always @(posedge i_clk) begin
|
|||
// `ifdef SIM
|
||||
// $display("CTRL %0d: [%d] starting to do things", i_phase, i_cycle_ctr);
|
||||
// `endif
|
||||
if (i_cycle_ctr == 10) begin
|
||||
if (i_cycle_ctr == 15) begin
|
||||
control_unit_error <= 1'b1;
|
||||
$display("CTRL %0d: [%d] enough cycles for now", i_phase, i_cycle_ctr);
|
||||
end
|
||||
|
@ -307,11 +319,22 @@ always @(posedge i_clk) begin
|
|||
* the general case
|
||||
*/
|
||||
end
|
||||
`INSTR_TYPE_JUMP: begin
|
||||
$display("CTRL %0d: [%d] JUMP instruction", i_phase, i_cycle_ctr);
|
||||
jump_counter <= 1'b0;
|
||||
end
|
||||
default: begin
|
||||
$display("CTRL %0d: [%d] unsupported instruction", i_phase, i_cycle_ctr);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (i_phases[2] && ! dec_instr_execute) begin
|
||||
if (inst_jump) begin
|
||||
// $display("CTRL %0d: [%d] JUMP nibble %0d : %h", i_phase, i_cycle_ctr, jump_counter, i_nibble);
|
||||
jump_counter <= jump_counter + 3'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (i_reset) begin
|
||||
|
@ -323,6 +346,8 @@ always @(posedge i_clk) begin
|
|||
bus_prog_addr <= 5'd0;
|
||||
addr_nibble_ptr <= 3'd0;
|
||||
|
||||
jump_counter <= 3'd0;
|
||||
|
||||
/* registers */
|
||||
reg_P <= 4'b0;
|
||||
end
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
|
||||
`define INSTR_TYPE_NOP 0
|
||||
`define INSTR_TYPE_ALU 1
|
||||
`define INSTR_TYPE_JUMP 2
|
||||
|
||||
`define INSTR_TYPE_NONE 15
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ module saturn_inst_decoder (
|
|||
o_alu_imm_value,
|
||||
o_alu_opcode,
|
||||
|
||||
o_jump_length,
|
||||
|
||||
o_instr_type,
|
||||
o_instr_decoded,
|
||||
o_instr_execute,
|
||||
|
@ -73,6 +75,8 @@ output reg [4:0] o_alu_reg_src_2;
|
|||
output reg [3:0] o_alu_imm_value;
|
||||
output reg [4:0] o_alu_opcode;
|
||||
|
||||
output reg [2:0] o_jump_length;
|
||||
|
||||
output reg [3:0] o_instr_type;
|
||||
/* instruction is fully decoded */
|
||||
output reg [0:0] o_instr_decoded;
|
||||
|
@ -112,6 +116,12 @@ reg [0:0] decode_started;
|
|||
*/
|
||||
|
||||
reg [0:0] block_2x;
|
||||
reg [0:0] block_6x;
|
||||
|
||||
/*
|
||||
* temporary variables
|
||||
*/
|
||||
reg [2:0] jump_counter;
|
||||
|
||||
/*
|
||||
* initialization
|
||||
|
@ -136,6 +146,10 @@ initial begin
|
|||
decode_started = 1'b0;
|
||||
|
||||
block_2x = 1'b0;
|
||||
block_6x = 1'b0;
|
||||
|
||||
/* local variables */
|
||||
jump_counter = 3'd0;
|
||||
end
|
||||
|
||||
/****************************
|
||||
|
@ -161,7 +175,9 @@ always @(posedge i_clk) 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);
|
||||
o_instr_pc <= i_current_pc;
|
||||
o_instr_pc <= i_current_pc;
|
||||
/* set the instruction to NOP, to avoid any stray processes */
|
||||
o_instr_type <= `INSTR_TYPE_NOP;
|
||||
end
|
||||
|
||||
if (i_phases[2] && !decode_started) begin
|
||||
|
@ -170,6 +186,15 @@ always @(posedge i_clk) begin
|
|||
decode_started <= 1'b1;
|
||||
case (i_nibble)
|
||||
4'h2: block_2x <= 1'b1;
|
||||
4'h6:
|
||||
begin
|
||||
o_instr_type <= `INSTR_TYPE_JUMP;
|
||||
o_jump_length <= 3'd2;
|
||||
jump_counter <= 3'd0;
|
||||
o_instr_execute <= 1'b1;
|
||||
block_6x <= 1'b1;
|
||||
end
|
||||
default: o_instr_type <= `INSTR_TYPE_NOP;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -190,6 +215,16 @@ always @(posedge i_clk) begin
|
|||
decode_started <= 1'b0;
|
||||
end
|
||||
|
||||
if (block_6x) begin
|
||||
// $display("DECODER %0d: [%d] GOTO %h", i_phase, i_cycle_ctr, i_nibble);
|
||||
jump_counter <= jump_counter + 3'd1;
|
||||
if (jump_counter == o_jump_length) begin
|
||||
block_6x <= 1'b0;
|
||||
o_instr_decoded <= 1'b1;
|
||||
decode_started <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (i_phases[3]) begin
|
||||
|
@ -221,6 +256,10 @@ always @(posedge i_clk) begin
|
|||
decode_started <= 1'b0;
|
||||
|
||||
block_2x <= 1'b0;
|
||||
block_6x <= 1'b0;
|
||||
|
||||
/* local variables */
|
||||
jump_counter = 3'd0;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -31,6 +31,8 @@ module saturn_regs_pc_rstk (
|
|||
i_bus_busy,
|
||||
|
||||
i_nibble,
|
||||
i_jump_instr,
|
||||
i_jump_length,
|
||||
|
||||
o_current_pc
|
||||
|
||||
|
@ -46,6 +48,8 @@ input wire [31:0] i_cycle_ctr;
|
|||
input wire [0:0] i_bus_busy;
|
||||
|
||||
input wire [3:0] i_nibble;
|
||||
input wire [0:0] i_jump_instr;
|
||||
input wire [2:0] i_jump_length;
|
||||
|
||||
output wire [19:0] o_current_pc;
|
||||
|
||||
|
@ -55,19 +59,27 @@ output wire [19:0] o_current_pc;
|
|||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
wire [0:0] do_jump_instr = !just_reset && i_jump_instr;
|
||||
|
||||
/*
|
||||
* local variables
|
||||
*/
|
||||
|
||||
reg [0:0] just_reset;
|
||||
reg [0:0] jump_decode;
|
||||
reg [0:0] jump_exec;
|
||||
reg [2:0] jump_counter;
|
||||
|
||||
reg [19:0] PC;
|
||||
|
||||
assign o_current_pc = PC;
|
||||
|
||||
initial begin
|
||||
just_reset = 1'b1;
|
||||
PC = 20'h00000;
|
||||
just_reset = 1'b1;
|
||||
jump_decode = 1'b0;
|
||||
jump_exec = 1'b0;
|
||||
jump_counter = 3'd0;
|
||||
PC = 20'h00000;
|
||||
end
|
||||
|
||||
/*
|
||||
|
@ -95,11 +107,35 @@ always @(posedge i_clk) begin
|
|||
$display("PC_RSTK %0d: [%d] inc_pc %5h => %5h", i_phase, i_cycle_ctr, PC, PC + 20'h00001);
|
||||
PC <= PC + 20'h00001;
|
||||
end
|
||||
|
||||
if (i_phases[2] && do_jump_instr && jump_decode) begin
|
||||
$display("PC_RSTK %0d: [%d] decode jump %0d - %0d %h", i_phase, i_cycle_ctr, i_jump_length, jump_counter, i_nibble);
|
||||
jump_counter <= jump_counter + 3'd1;
|
||||
if (jump_counter == i_jump_length) begin
|
||||
jump_decode <= 1'b0;
|
||||
jump_exec <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_phases[3] && do_jump_instr && !jump_decode && !jump_exec) begin
|
||||
$display("PC_RSTK %0d: [%d] start decode jump %0d ", i_phase, i_cycle_ctr, i_jump_length);
|
||||
jump_counter <= 3'd0;
|
||||
jump_decode <= 1'b1;
|
||||
end
|
||||
|
||||
if (i_phases[3] && do_jump_instr && jump_exec) begin
|
||||
$display("PC_RSTK %0d: [%d] execute jump %0d ", i_phase, i_cycle_ctr, i_jump_length);
|
||||
jump_exec <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (i_reset) begin
|
||||
just_reset <= 1'b1;
|
||||
PC <= 20'h00000;
|
||||
just_reset <= 1'b1;
|
||||
jump_decode <= 1'b0;
|
||||
jump_exec <= 1'b0;
|
||||
jump_counter <= 3'd0;
|
||||
PC <= 20'h00000;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue