mirror of
https://github.com/sxpert/hp-saturn
synced 2024-11-16 19:50:19 +01:00
decode our first instruction
execute said instruction start implementing the debugging engine to see what we are doing
This commit is contained in:
parent
c75b33a64a
commit
2fcd9f7b23
5 changed files with 389 additions and 21 deletions
|
@ -70,7 +70,17 @@ saturn_control_unit control_unit (
|
|||
.o_no_read (ctrl_unit_no_read),
|
||||
.i_nibble (i_bus_nibble_in),
|
||||
|
||||
.o_error (ctrl_unit_error)
|
||||
.o_error (ctrl_unit_error),
|
||||
|
||||
/* debugger interface */
|
||||
.o_alu_reg_dest (dec_alu_reg_dest),
|
||||
.o_alu_reg_src_1 (dec_alu_reg_src_1),
|
||||
.o_alu_reg_src_2 (dec_alu_reg_src_2),
|
||||
.o_alu_imm_value (dec_alu_imm_value),
|
||||
.o_alu_opcode (dec_alu_opcode),
|
||||
|
||||
.o_instr_type (dec_instr_type),
|
||||
.o_instr_decoded (dec_instr_decoded)
|
||||
);
|
||||
|
||||
wire [0:0] ctrl_unit_error;
|
||||
|
@ -78,6 +88,17 @@ wire [4:0] ctrl_unit_prog_addr;
|
|||
wire [4:0] ctrl_unit_prog_data;
|
||||
wire [0:0] ctrl_unit_no_read;
|
||||
|
||||
/* debugger insterface */
|
||||
|
||||
wire [4:0] dec_alu_reg_dest;
|
||||
wire [4:0] dec_alu_reg_src_1;
|
||||
wire [4:0] dec_alu_reg_src_2;
|
||||
wire [3:0] dec_alu_imm_value;
|
||||
wire [4:0] dec_alu_opcode;
|
||||
|
||||
wire [3:0] dec_instr_type;
|
||||
wire [0:0] dec_instr_decoded;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* debugger module
|
||||
|
@ -90,7 +111,18 @@ saturn_debugger debugger (
|
|||
.i_phases (i_phases),
|
||||
.i_phase (i_phase),
|
||||
.i_cycle_ctr (i_cycle_ctr),
|
||||
.o_debug_cycle (dbg_debug_cycle)
|
||||
|
||||
.o_debug_cycle (dbg_debug_cycle),
|
||||
|
||||
/* debugger interface */
|
||||
.i_alu_reg_dest (dec_alu_reg_dest),
|
||||
.i_alu_reg_src_1 (dec_alu_reg_src_1),
|
||||
.i_alu_reg_src_2 (dec_alu_reg_src_2),
|
||||
.i_alu_imm_value (dec_alu_imm_value),
|
||||
.i_alu_opcode (dec_alu_opcode),
|
||||
|
||||
.i_instr_type (dec_instr_type),
|
||||
.i_instr_decoded (dec_instr_decoded)
|
||||
);
|
||||
|
||||
wire [0:0] dbg_debug_cycle;
|
||||
|
@ -153,6 +185,7 @@ always @(posedge i_clk) begin
|
|||
/*
|
||||
* in this phase, we can send a command or data from the processor
|
||||
*/
|
||||
// $display("BUSCTRL %0d: [%d] cycle start", i_phase, i_cycle_ctr);
|
||||
if (more_to_write) begin
|
||||
$write("BUSCTRL %0d: [%d] %0d : %5b ", i_phase, i_cycle_ctr, next_bus_prog_addr, bus_program[next_bus_prog_addr]);
|
||||
if (bus_program[next_bus_prog_addr][4]) $write("CMD : ");
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
`default_nettype none
|
||||
|
||||
`include "saturn_def_buscmd.v"
|
||||
`include "saturn_def_alu.v"
|
||||
|
||||
module saturn_control_unit (
|
||||
i_clk,
|
||||
|
@ -38,7 +39,16 @@ module saturn_control_unit (
|
|||
o_no_read,
|
||||
i_nibble,
|
||||
|
||||
o_error
|
||||
o_error,
|
||||
|
||||
o_alu_reg_dest,
|
||||
o_alu_reg_src_1,
|
||||
o_alu_reg_src_2,
|
||||
o_alu_imm_value,
|
||||
o_alu_opcode,
|
||||
|
||||
o_instr_type,
|
||||
o_instr_decoded
|
||||
);
|
||||
|
||||
input wire [0:0] i_clk;
|
||||
|
@ -59,9 +69,27 @@ input wire [3:0] i_nibble;
|
|||
output wire [0:0] o_error;
|
||||
assign o_error = control_unit_error;
|
||||
|
||||
output wire [4:0] o_alu_reg_dest;
|
||||
output wire [4:0] o_alu_reg_src_1;
|
||||
output wire [4:0] o_alu_reg_src_2;
|
||||
output wire [3:0] o_alu_imm_value;
|
||||
output wire [4:0] o_alu_opcode;
|
||||
|
||||
output wire [3:0] o_instr_type;
|
||||
output wire [0:0] o_instr_decoded;
|
||||
|
||||
assign o_alu_reg_dest = dec_alu_reg_dest;
|
||||
assign o_alu_reg_src_1 = dec_alu_reg_src_1;
|
||||
assign o_alu_reg_src_2 = dec_alu_reg_src_2;
|
||||
assign o_alu_imm_value = dec_alu_imm_value;
|
||||
assign o_alu_opcode = dec_alu_opcode;
|
||||
|
||||
assign o_instr_type = dec_instr_type;
|
||||
assign o_instr_decoded = dec_instr_decoded;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* cpu modules go here
|
||||
* decoder module
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
|
@ -75,9 +103,53 @@ saturn_inst_decoder instruction_decoder(
|
|||
|
||||
.i_bus_busy (i_bus_busy),
|
||||
|
||||
.i_nibble (i_nibble)
|
||||
.i_nibble (i_nibble),
|
||||
|
||||
.o_alu_reg_dest (dec_alu_reg_dest),
|
||||
.o_alu_reg_src_1 (dec_alu_reg_src_1),
|
||||
.o_alu_reg_src_2 (dec_alu_reg_src_2),
|
||||
.o_alu_imm_value (dec_alu_imm_value),
|
||||
.o_alu_opcode (dec_alu_opcode),
|
||||
|
||||
.o_instr_type (dec_instr_type),
|
||||
.o_instr_decoded (dec_instr_decoded)
|
||||
);
|
||||
|
||||
wire [4:0] dec_alu_reg_dest;
|
||||
wire [4:0] dec_alu_reg_src_1;
|
||||
wire [4:0] dec_alu_reg_src_2;
|
||||
wire [3:0] dec_alu_imm_value;
|
||||
wire [4:0] dec_alu_opcode;
|
||||
|
||||
wire [3:0] dec_instr_type;
|
||||
wire [0:0] dec_instr_decoded;
|
||||
|
||||
/*
|
||||
* wires for decode shortcuts
|
||||
*/
|
||||
|
||||
wire [0:0] reg_dest_p;
|
||||
wire [0:0] reg_src_1_imm;
|
||||
wire [0:0] aluop_copy;
|
||||
|
||||
assign reg_dest_p = (dec_alu_reg_dest == `ALU_REG_P);
|
||||
assign reg_src_1_imm = (dec_alu_reg_src_1 == `ALU_REG_IMM);
|
||||
assign aluop_copy = (dec_alu_opcode == `ALU_OP_COPY);
|
||||
|
||||
wire [0:0] inst_alu_p_eq_n;
|
||||
wire [0:0] inst_alu_other;
|
||||
|
||||
assign inst_alu_p_eq_n = aluop_copy && reg_dest_p && reg_src_1_imm;
|
||||
assign inst_alu_other = !(inst_alu_p_eq_n);
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* processor registers
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
reg [3:0] reg_P;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* the control unit
|
||||
|
@ -90,6 +162,7 @@ reg [0:0] control_unit_ready;
|
|||
reg [4:0] bus_prog_addr;
|
||||
|
||||
initial begin
|
||||
/* control variables */
|
||||
o_program_address = 5'd31;
|
||||
o_program_data = 5'd0;
|
||||
o_no_read = 1'b0;
|
||||
|
@ -97,6 +170,9 @@ initial begin
|
|||
just_reset = 1'b1;
|
||||
control_unit_ready = 1'b0;
|
||||
bus_prog_addr = 5'd0;
|
||||
|
||||
/* registers */
|
||||
reg_P = 4'b0;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
|
@ -168,12 +244,35 @@ always @(posedge i_clk) begin
|
|||
$display("CTRL %0d: [%d] interpreting %h", i_phase, i_cycle_ctr, i_nibble);
|
||||
end
|
||||
|
||||
if (i_phases[3]) begin
|
||||
$display("CTRL %0d: [%d] start instruction execution", i_phase, i_cycle_ctr);
|
||||
if (i_phases[3] && dec_instr_decoded) begin
|
||||
case (dec_instr_type)
|
||||
`INSTR_TYPE_NOP: begin
|
||||
$display("CTRL %0d: [%d] NOP instruction", i_phase, i_cycle_ctr);
|
||||
end
|
||||
`INSTR_TYPE_ALU: begin
|
||||
$display("CTRL %0d: [%d] ALU instruction", i_phase, i_cycle_ctr);
|
||||
|
||||
/*
|
||||
* treat special cases
|
||||
*/
|
||||
if (inst_alu_p_eq_n) begin
|
||||
$display("CTRL %0d: [%d] exec : P= %h", i_phase, i_cycle_ctr, dec_alu_imm_value);
|
||||
reg_P <= dec_alu_imm_value;
|
||||
end
|
||||
|
||||
/*
|
||||
* the general case
|
||||
*/
|
||||
end
|
||||
default: begin
|
||||
$display("CTRL %0d: [%d] unsupported instruction", i_phase, i_cycle_ctr);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
if (i_reset) begin
|
||||
/* control variables */
|
||||
o_program_address <= 5'd31;
|
||||
o_program_data <= 5'd0;
|
||||
o_no_read <= 1'b0;
|
||||
|
@ -181,6 +280,9 @@ always @(posedge i_clk) begin
|
|||
just_reset <= 1'b1;
|
||||
control_unit_ready <= 1'b0;
|
||||
bus_prog_addr <= 5'd0;
|
||||
|
||||
/* registers */
|
||||
reg_P <= 4'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -27,7 +27,17 @@ module saturn_debugger (
|
|||
i_phase,
|
||||
i_cycle_ctr,
|
||||
|
||||
o_debug_cycle
|
||||
o_debug_cycle,
|
||||
|
||||
/* interface from the control unit */
|
||||
i_alu_reg_dest,
|
||||
i_alu_reg_src_1,
|
||||
i_alu_reg_src_2,
|
||||
i_alu_imm_value,
|
||||
i_alu_opcode,
|
||||
|
||||
i_instr_type,
|
||||
i_instr_decoded
|
||||
);
|
||||
|
||||
input wire [0:0] i_clk;
|
||||
|
@ -38,13 +48,50 @@ input wire [31:0] i_cycle_ctr;
|
|||
|
||||
output reg [0:0] o_debug_cycle;
|
||||
|
||||
/* inteface from the control unit */
|
||||
input wire [4:0] i_alu_reg_dest;
|
||||
input wire [4:0] i_alu_reg_src_1;
|
||||
input wire [4:0] i_alu_reg_src_2;
|
||||
input wire [3:0] i_alu_imm_value;
|
||||
input wire [4:0] i_alu_opcode;
|
||||
|
||||
input wire [3:0] i_instr_type;
|
||||
input wire [0:0] i_instr_decoded;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* debugger process registers
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
reg [3:0] counter;
|
||||
|
||||
initial begin
|
||||
o_debug_cycle = 1'b0;
|
||||
end
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* debugger process
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
|
||||
if (i_phases[3] && i_instr_decoded) begin
|
||||
$display("DEBUGGER %0d: [%d] start debugger cycle", i_phase, i_cycle_ctr);
|
||||
o_debug_cycle <= 1'b1;
|
||||
counter <= 3'b0;
|
||||
end
|
||||
|
||||
if (o_debug_cycle) begin
|
||||
$display("DEBUGGER %0d: [%d] debugger %0d", i_phase, i_cycle_ctr, counter);
|
||||
counter <= counter + 1;
|
||||
if (counter == 15) begin
|
||||
$display("DEBUGGER %0d: [%d] end debugger cycle", i_phase, i_cycle_ctr);
|
||||
o_debug_cycle <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_reset) begin
|
||||
o_debug_cycle <= 1'b0;
|
||||
|
|
102
saturn_def_alu.v
Normal file
102
saturn_def_alu.v
Normal file
|
@ -0,0 +1,102 @@
|
|||
`ifndef _DEF_ALU
|
||||
`define _DEF_ALU
|
||||
|
||||
// stuff (where should that go ?)
|
||||
`define T_SET 0
|
||||
`define T_TEST 1
|
||||
|
||||
`define T_DIR_OUT 0
|
||||
`define T_DIR_IN 1
|
||||
|
||||
`define T_PTR_0 0
|
||||
`define T_PTR_1 1
|
||||
|
||||
/*
|
||||
*
|
||||
* Opcodes for the ALU
|
||||
*
|
||||
*/
|
||||
|
||||
// copy / exchange
|
||||
`define ALU_OP_ZERO 0
|
||||
`define ALU_OP_COPY 1
|
||||
`define ALU_OP_EXCH 2
|
||||
// shifts
|
||||
`define ALU_OP_SHL 3
|
||||
`define ALU_OP_SHR 4
|
||||
// logic
|
||||
`define ALU_OP_AND 5
|
||||
`define ALU_OP_OR 6
|
||||
// bit set/reset
|
||||
`define ALU_OP_RST_BIT 7
|
||||
`define ALU_OP_SET_BIT 8
|
||||
// arithmetic
|
||||
`define ALU_OP_2CMPL 9
|
||||
`define ALU_OP_1CMPL 10
|
||||
`define ALU_OP_INC 11
|
||||
`define ALU_OP_DEC 12
|
||||
`define ALU_OP_ADD 13
|
||||
`define ALU_OP_SUB 14
|
||||
// tests
|
||||
`define ALU_OP_TEST_EQ 15
|
||||
`define ALU_OP_TEST_NEQ 16
|
||||
// relative jump
|
||||
`define ALU_OP_JMP_REL2 17
|
||||
`define ALU_OP_JMP_REL3 18
|
||||
`define ALU_OP_JMP_REL4 19
|
||||
`define ALU_OP_JMP_ABS5 20
|
||||
`define ALU_OP_CLR_MASK 21
|
||||
|
||||
`define ALU_OP_TEST_GO 30
|
||||
`define ALU_OP_NOP 31
|
||||
|
||||
/*
|
||||
*
|
||||
* Registers
|
||||
*
|
||||
*/
|
||||
|
||||
`define ALU_REG_A 0
|
||||
`define ALU_REG_B 1
|
||||
`define ALU_REG_C 2
|
||||
`define ALU_REG_D 3
|
||||
`define ALU_REG_D0 4
|
||||
`define ALU_REG_D1 5
|
||||
`define ALU_REG_PC 6
|
||||
`define ALU_REG_RSTK 7
|
||||
`define ALU_REG_R0 8
|
||||
`define ALU_REG_R1 9
|
||||
`define ALU_REG_R2 10
|
||||
`define ALU_REG_R3 11
|
||||
`define ALU_REG_R4 12
|
||||
//13
|
||||
//14
|
||||
//15
|
||||
`define ALU_REG_DAT0 16
|
||||
`define ALU_REG_DAT1 17
|
||||
`define ALU_REG_HST 18
|
||||
`define ALU_REG_ST 19
|
||||
`define ALU_REG_P 20
|
||||
`define ALU_REG_M 21
|
||||
`define ALU_REG_IMM 22
|
||||
`define ALU_REG_ADDR 23
|
||||
|
||||
`define ALU_REG_ZERO 30
|
||||
`define ALU_REG_NONE 31
|
||||
|
||||
// specific bits
|
||||
`define ALU_HST_XM 0
|
||||
`define ALU_HST_SB 1
|
||||
`define ALU_HST_SR 2
|
||||
`define ALU_HST_MP 3
|
||||
|
||||
/*
|
||||
*
|
||||
* instruction types
|
||||
*
|
||||
*/
|
||||
|
||||
`define INSTR_TYPE_NOP 0
|
||||
`define INSTR_TYPE_ALU 1
|
||||
|
||||
`endif
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
`default_nettype none
|
||||
|
||||
`include "saturn_def_alu.v"
|
||||
|
||||
module saturn_inst_decoder (
|
||||
i_clk,
|
||||
i_reset,
|
||||
|
@ -30,7 +32,16 @@ module saturn_inst_decoder (
|
|||
|
||||
i_bus_busy,
|
||||
|
||||
i_nibble
|
||||
i_nibble,
|
||||
|
||||
o_alu_reg_dest,
|
||||
o_alu_reg_src_1,
|
||||
o_alu_reg_src_2,
|
||||
o_alu_imm_value,
|
||||
o_alu_opcode,
|
||||
|
||||
o_instr_type,
|
||||
o_instr_decoded
|
||||
);
|
||||
|
||||
input wire [0:0] i_clk;
|
||||
|
@ -44,6 +55,15 @@ input wire [0:0] i_bus_busy;
|
|||
|
||||
input wire [3:0] i_nibble;
|
||||
|
||||
output reg [4:0] o_alu_reg_dest;
|
||||
output reg [4:0] o_alu_reg_src_1;
|
||||
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 [3:0] o_instr_type;
|
||||
output reg [0:0] o_instr_decoded;
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* sub-modules go here
|
||||
|
@ -59,14 +79,44 @@ input wire [3:0] i_nibble;
|
|||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
/*
|
||||
* process state variables
|
||||
*/
|
||||
|
||||
reg [0:0] decode_started;
|
||||
|
||||
/*
|
||||
* decoder block variables
|
||||
*/
|
||||
|
||||
reg [0:0] block_2x;
|
||||
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
|
||||
initial begin
|
||||
o_alu_reg_dest = `ALU_REG_NONE;
|
||||
o_alu_reg_src_1 = `ALU_REG_NONE;
|
||||
o_alu_reg_src_2 = `ALU_REG_NONE;
|
||||
o_alu_imm_value = 4'b0;
|
||||
o_alu_opcode = `ALU_OP_NOP;
|
||||
|
||||
o_instr_decoded = 1'b0;
|
||||
|
||||
decode_started = 1'b0;
|
||||
|
||||
block_2x = 1'b0;
|
||||
end
|
||||
|
||||
/****************************
|
||||
*
|
||||
* main process
|
||||
*
|
||||
*/
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
|
||||
|
||||
/*
|
||||
* only do something when nothing is busy doing some other tasks
|
||||
* either talking to the bus, or debugging something
|
||||
|
@ -74,13 +124,36 @@ always @(posedge i_clk) begin
|
|||
|
||||
if (!i_debug_cycle && !i_bus_busy) begin
|
||||
|
||||
if (i_phases[2]) begin
|
||||
$display("DECODER %0d: [%d] decoding", i_phase, i_cycle_ctr);
|
||||
if (i_phases[2] && !decode_started) begin
|
||||
$display("DECODER %0d: [%d] start instruction decoding %h", i_phase, i_cycle_ctr, i_nibble);
|
||||
|
||||
decode_started <= 1'b1;
|
||||
case (i_nibble)
|
||||
4'h2: block_2x <= 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
if (i_phases[2] && decode_started) begin
|
||||
$display("DECODER %0d: [%d] decoding %h", i_phase, i_cycle_ctr, i_nibble);
|
||||
|
||||
if (block_2x) begin
|
||||
$display("DECODER %0d: [%d] P= %h", i_phase, i_cycle_ctr, i_nibble);
|
||||
o_alu_reg_dest <= `ALU_REG_P;
|
||||
o_alu_reg_src_1 <= `ALU_REG_IMM;
|
||||
o_alu_reg_src_2 <= `ALU_REG_NONE;
|
||||
o_alu_imm_value <= i_nibble;
|
||||
o_alu_opcode <= `ALU_OP_COPY;
|
||||
o_instr_type <= `INSTR_TYPE_ALU;
|
||||
o_instr_decoded <= 1'b1;
|
||||
block_2x <= 1'b0;
|
||||
decode_started <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (i_phases[3]) begin
|
||||
$display("DECODER %0d: [%d] decoder cleanup", i_phase, i_cycle_ctr);
|
||||
o_instr_decoded <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -88,6 +161,17 @@ always @(posedge i_clk) begin
|
|||
|
||||
if (i_reset) begin
|
||||
/* stuff that needs reset */
|
||||
o_alu_reg_dest <= `ALU_REG_NONE;
|
||||
o_alu_reg_src_1 <= `ALU_REG_NONE;
|
||||
o_alu_reg_src_2 <= `ALU_REG_NONE;
|
||||
o_alu_imm_value <= 4'b0;
|
||||
o_alu_opcode <= `ALU_OP_NOP;
|
||||
|
||||
o_instr_decoded <= 1'b0;
|
||||
|
||||
decode_started <= 1'b0;
|
||||
|
||||
block_2x <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue