decode our first instruction

execute said instruction
start implementing the debugging engine to see what we are doing
This commit is contained in:
Raphaël Jacquot 2019-03-02 19:40:31 +01:00
parent c75b33a64a
commit 2fcd9f7b23
5 changed files with 389 additions and 21 deletions

View file

@ -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 : ");

View file

@ -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

View file

@ -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
View 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

View file

@ -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