From 2fcd9f7b236fa470d36d755654fcf5cff4a1d475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Jacquot?= Date: Sat, 2 Mar 2019 19:40:31 +0100 Subject: [PATCH] decode our first instruction execute said instruction start implementing the debugging engine to see what we are doing --- saturn_bus_controller.v | 37 +++++++++++- saturn_control_unit.v | 126 ++++++++++++++++++++++++++++++++++++---- saturn_debugger.v | 49 +++++++++++++++- saturn_def_alu.v | 102 ++++++++++++++++++++++++++++++++ saturn_inst_decoder.v | 96 ++++++++++++++++++++++++++++-- 5 files changed, 389 insertions(+), 21 deletions(-) create mode 100644 saturn_def_alu.v diff --git a/saturn_bus_controller.v b/saturn_bus_controller.v index 72dfd07..d811615 100644 --- a/saturn_bus_controller.v +++ b/saturn_bus_controller.v @@ -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 : "); diff --git a/saturn_control_unit.v b/saturn_control_unit.v index 00d74ff..6559b3c 100644 --- a/saturn_control_unit.v +++ b/saturn_control_unit.v @@ -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,25 +69,87 @@ 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 * *************************************************************************************************/ saturn_inst_decoder instruction_decoder( - .i_clk (i_clk), - .i_reset (i_reset), - .i_phases (i_phases), - .i_phase (i_phase), - .i_cycle_ctr (i_cycle_ctr), - .i_debug_cycle (i_debug_cycle), + .i_clk (i_clk), + .i_reset (i_reset), + .i_phases (i_phases), + .i_phase (i_phase), + .i_cycle_ctr (i_cycle_ctr), + .i_debug_cycle (i_debug_cycle), - .i_bus_busy (i_bus_busy), + .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 diff --git a/saturn_debugger.v b/saturn_debugger.v index 326b74f..879b8ef 100644 --- a/saturn_debugger.v +++ b/saturn_debugger.v @@ -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; diff --git a/saturn_def_alu.v b/saturn_def_alu.v new file mode 100644 index 0000000..94964c5 --- /dev/null +++ b/saturn_def_alu.v @@ -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 \ No newline at end of file diff --git a/saturn_inst_decoder.v b/saturn_inst_decoder.v index b8d0e27..e9ec58c 100644 --- a/saturn_inst_decoder.v +++ b/saturn_inst_decoder.v @@ -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