implement 8[45]x ST=[01] n

implement GOVLNG
dump 2 lines of registers in debugger now
This commit is contained in:
Raphaël Jacquot 2019-03-04 08:08:02 +01:00
parent da3cce2c07
commit 009f01f5d7
8 changed files with 332 additions and 35 deletions

View file

@ -139,6 +139,11 @@ always @(posedge i_clk) begin
cycle_ctr <= cycle_ctr + {31'b0, phases[3]};
end
if (cycle_ctr == 53) begin
bus_halt <= 1'b1;
$display("BUS %0d: [%d] enough cycles for now", phase, cycle_ctr);
end
if (i_reset) begin
phases <= 4'b1;
cycle_ctr <= 32'd0;

View file

@ -79,6 +79,9 @@ saturn_control_unit control_unit (
/* debugger interface */
.o_current_pc (ctrl_current_pc),
.o_reg_hst (ctrl_reg_hst),
.o_reg_st (ctrl_reg_st),
.o_reg_p (ctrl_reg_p),
.o_alu_reg_dest (dec_alu_reg_dest),
.o_alu_reg_src_1 (dec_alu_reg_src_1),
@ -97,6 +100,9 @@ wire [0:0] ctrl_unit_no_read;
/* debugger insterface */
wire [19:0] ctrl_current_pc;
wire [3:0] ctrl_reg_hst;
wire [15:0] ctrl_reg_st;
wire [3:0] ctrl_reg_p;
wire [4:0] dec_alu_reg_dest;
wire [4:0] dec_alu_reg_src_1;
@ -125,6 +131,9 @@ saturn_debugger debugger (
/* debugger interface */
.i_current_pc (ctrl_current_pc),
.i_reg_hst (ctrl_reg_hst),
.i_reg_st (ctrl_reg_st),
.i_reg_p (ctrl_reg_p),
.i_alu_reg_dest (dec_alu_reg_dest),
.i_alu_reg_src_1 (dec_alu_reg_src_1),

View file

@ -45,6 +45,9 @@ module saturn_control_unit (
/* debugger interface */
o_current_pc,
o_reg_p,
o_reg_hst,
o_reg_st,
o_alu_reg_dest,
o_alu_reg_src_1,
@ -78,6 +81,9 @@ assign o_error = control_unit_error || dec_error;
/* debugger interface */
output wire [19:0] o_current_pc;
output wire [3:0] o_reg_p;
output wire [3:0] o_reg_hst;
output wire [15:0] o_reg_st;
output wire [4:0] o_alu_reg_dest;
output wire [4:0] o_alu_reg_src_1;
@ -89,6 +95,9 @@ output wire [3:0] o_instr_type;
output wire [0:0] o_instr_decoded;
assign o_current_pc = reg_PC;
assign o_reg_p = reg_P;
assign o_reg_hst = reg_HST;
assign o_reg_st = reg_ST;
assign o_alu_reg_dest = dec_alu_reg_dest;
assign o_alu_reg_src_1 = dec_alu_reg_src_1;
@ -122,6 +131,8 @@ saturn_inst_decoder instruction_decoder(
.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_ptr_begin (dec_alu_ptr_begin),
.o_alu_ptr_end (dec_alu_ptr_end),
.o_alu_imm_value (dec_alu_imm_value),
.o_alu_opcode (dec_alu_opcode),
@ -137,6 +148,8 @@ saturn_inst_decoder instruction_decoder(
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_ptr_begin;
wire [3:0] dec_alu_ptr_end;
wire [3:0] dec_alu_imm_value;
wire [4:0] dec_alu_opcode;
@ -152,14 +165,19 @@ wire [0:0] dec_error;
* wires for decode shortcuts
*/
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] reg_dest_st = (dec_alu_reg_dest == `ALU_REG_ST);
wire [0:0] reg_dest_p = (dec_alu_reg_dest == `ALU_REG_P);
wire [0:0] reg_src_1_imm = (dec_alu_reg_src_1 == `ALU_REG_IMM);
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] aluop_copy = inst_alu && (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_st_eq_01_n = aluop_copy && reg_dest_st && reg_src_1_imm;
wire [0:0] inst_alu_other = !(inst_alu_p_eq_n || inst_alu_st_eq_01_n);
wire [0:0] inst_jump = (dec_instr_type == `INSTR_TYPE_JUMP);
/**************************************************************************************************
*
@ -197,6 +215,8 @@ saturn_regs_pc_rstk regs_pc_rstk (
*
*************************************************************************************************/
reg [3:0] reg_HST;
reg [15:0] reg_ST;
reg [3:0] reg_P;
wire [19:0] reg_PC;
wire [0:0] reload_PC;
@ -215,8 +235,6 @@ reg [4:0] bus_prog_addr;
reg [2:0] addr_nibble_ptr;
reg [0:0] load_pc_loop;
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];
@ -232,9 +250,9 @@ initial begin
addr_nibble_ptr = 3'd0;
load_pc_loop = 1'b0;
jump_counter = 3'd0;
/* registers */
reg_HST = 4'b0;
reg_ST = 16'b0;
reg_P = 4'b0;
end
@ -306,10 +324,6 @@ 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 == 15) begin
control_unit_error <= 1'b1;
$display("CTRL %0d: [%d] enough cycles for now", i_phase, i_cycle_ctr);
end
// if (i_phases[2]) begin
// $display("CTRL %0d: [%d] interpreting %h", i_phase, i_cycle_ctr, i_nibble);
@ -326,31 +340,29 @@ always @(posedge i_clk) begin
/*
* treat special cases
*/
/* 2n P= n */
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
/* 8[45]n ST=[01] n */
if (inst_alu_st_eq_01_n) begin
$display("CTRL %0d: [%d] exec : ST=%b %h", i_phase, i_cycle_ctr, dec_alu_imm_value[0], dec_alu_ptr_begin);
reg_ST[dec_alu_ptr_begin] <= dec_alu_imm_value[0];
end
/*
* the general case
*/
end
`INSTR_TYPE_JUMP: begin
$display("CTRL %0d: [%d] JUMP instruction", i_phase, i_cycle_ctr);
jump_counter <= 1'b0;
end
`INSTR_TYPE_JUMP: begin 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
@ -362,10 +374,10 @@ always @(posedge i_clk) begin
bus_prog_addr <= 5'd0;
addr_nibble_ptr <= 3'd0;
load_pc_loop <= 1'b0;
jump_counter <= 3'd0;
/* registers */
reg_HST <= 4'b0;
reg_ST <= 16'b0;
reg_P <= 4'b0;
end

View file

@ -34,6 +34,9 @@ module saturn_debugger (
/* interface from the control unit */
i_current_pc,
i_reg_hst,
i_reg_st,
i_reg_p,
i_alu_reg_dest,
i_alu_reg_src_1,
@ -59,6 +62,9 @@ output reg [0:0] o_debug_cycle;
/* inteface from the control unit */
input wire [19:0] i_current_pc;
input wire [3:0] i_reg_hst;
input wire [15:0] i_reg_st;
input wire [3:0] i_reg_p;
input wire [4:0] i_alu_reg_dest;
input wire [4:0] i_alu_reg_src_1;
@ -201,10 +207,186 @@ always @(posedge i_clk) begin
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd8) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_END;
registers_state <= `DBG_REG_CALC_MODE;
end
end
`DBG_REG_CALC_MODE:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "h";
5'd1: registers_str[registers_ctr] <= ":";
5'd2: registers_str[registers_ctr] <= " ";
5'd3: registers_str[registers_ctr] <= "@";
5'd4: registers_str[registers_ctr] <= "E";
5'd5: registers_str[registers_ctr] <= "@";
5'd6: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd6) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_RSTK_PTR;
end
end
`DBG_REG_RSTK_PTR:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "r";
5'd1: registers_str[registers_ctr] <= "p";
5'd2: registers_str[registers_ctr] <= ":";
5'd3: registers_str[registers_ctr] <= " ";
5'd4: registers_str[registers_ctr] <= "X";
5'd5: registers_str[registers_ctr] <= " ";
5'd6: registers_str[registers_ctr] <= " ";
5'd7: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd7) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_RSTK7_STR;
end
end
`DBG_REG_RSTK7_STR:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "R";
5'd1: registers_str[registers_ctr] <= "S";
5'd2: registers_str[registers_ctr] <= "T";
5'd3: registers_str[registers_ctr] <= "K";
5'd4: registers_str[registers_ctr] <= "7";
5'd5: registers_str[registers_ctr] <= ":";
5'd6: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd6) begin
registers_reg_ptr <= 5'd4;
registers_state <= `DBG_REG_RSTK7_VALUE;
end
end
`DBG_REG_RSTK7_VALUE:
begin
registers_str[registers_ctr] <= "X";
// registers_str[registers_ctr] <= hex[i_current_pc[(registers_reg_ptr)*4+:4]];
registers_reg_ptr <= registers_reg_ptr - 1;
if (registers_reg_ptr == 5'd0) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_NL_0;
end
end
`DBG_REG_NL_0:
begin
registers_str[registers_ctr] <= "\n";
registers_state <= `DBG_REG_P;
end
`DBG_REG_P:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "P";
5'd1: registers_str[registers_ctr] <= ":";
5'd2: registers_str[registers_ctr] <= " ";
5'd3: registers_str[registers_ctr] <= " ";
5'd4: registers_str[registers_ctr] <= hex[i_reg_p];
5'd5: registers_str[registers_ctr] <= " ";
5'd6: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd6) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_HST;
end
end
`DBG_REG_HST:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "H";
5'd1: registers_str[registers_ctr] <= "S";
5'd2: registers_str[registers_ctr] <= "T";
5'd3: registers_str[registers_ctr] <= ":";
5'd4: registers_str[registers_ctr] <= " ";
5'd5: registers_str[registers_ctr] <= hex[{3'b000, i_reg_hst[3]}];
5'd6: registers_str[registers_ctr] <= hex[{3'b000, i_reg_hst[2]}];
5'd7: registers_str[registers_ctr] <= hex[{3'b000, i_reg_hst[1]}];
5'd8: registers_str[registers_ctr] <= hex[{3'b000, i_reg_hst[0]}];
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd8) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_HST_SPACES;
end
end
`DBG_REG_HST_SPACES:
begin
registers_str[registers_ctr] <= " ";
registers_reg_ptr <= registers_reg_ptr + 1;
if (registers_reg_ptr == 5'd5) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_ST_STR;
end
end
`DBG_REG_ST_STR:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "S";
5'd1: registers_str[registers_ctr] <= "T";
5'd2: registers_str[registers_ctr] <= ":";
5'd3: registers_str[registers_ctr] <= " ";
5'd4: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd4) begin
registers_reg_ptr <= 5'd15;
registers_state <= `DBG_REG_ST_VALUE;
end
end
`DBG_REG_ST_VALUE:
begin
registers_str[registers_ctr] <= hex[{3'b000, i_reg_st[registers_reg_ptr]}];
registers_reg_ptr <= registers_reg_ptr - 1;
if (registers_reg_ptr == 5'd0) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_ST_SPACES;
end
end
`DBG_REG_ST_SPACES:
begin
registers_str[registers_ctr] <= " ";
registers_reg_ptr <= registers_reg_ptr + 1;
if (registers_reg_ptr == 5'd2) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_RSTK6_STR;
end
end
`DBG_REG_RSTK6_STR:
begin
case (registers_reg_ptr)
5'd0: registers_str[registers_ctr] <= "R";
5'd1: registers_str[registers_ctr] <= "S";
5'd2: registers_str[registers_ctr] <= "T";
5'd3: registers_str[registers_ctr] <= "K";
5'd4: registers_str[registers_ctr] <= "6";
5'd5: registers_str[registers_ctr] <= ":";
5'd6: registers_str[registers_ctr] <= " ";
endcase
registers_reg_ptr <= registers_reg_ptr + 5'd1;
if (registers_reg_ptr == 5'd6) begin
registers_reg_ptr <= 5'd4;
registers_state <= `DBG_REG_RSTK6_VALUE;
end
end
`DBG_REG_RSTK6_VALUE:
begin
registers_str[registers_ctr] <= "X";
// registers_str[registers_ctr] <= hex[i_current_pc[(registers_reg_ptr)*4+:4]];
registers_reg_ptr <= registers_reg_ptr - 1;
if (registers_reg_ptr == 5'd0) begin
registers_reg_ptr <= 5'd0;
registers_state <= `DBG_REG_NL_1;
end
end
`DBG_REG_NL_1:
begin
registers_str[registers_ctr] <= "\n";
registers_state <= `DBG_REG_END;
end
`DBG_REG_END: begin end
default: begin $display("ERROR, unknown register state %0d", registers_state); end
endcase

View file

@ -6,9 +6,24 @@
* debugger values for the register dump
*/
`define DBG_REG_PC_STR 0
`define DBG_REG_PC_VALUE 1
`define DBG_REG_PC_SPACES 2
`define DBG_REG_CARRY 3
`define DBG_REG_END 31
`define DBG_REG_PC_STR 0
`define DBG_REG_PC_VALUE 1
`define DBG_REG_PC_SPACES 2
`define DBG_REG_CARRY 3
`define DBG_REG_CALC_MODE 4
`define DBG_REG_RSTK_PTR 5
`define DBG_REG_RSTK7_STR 6
`define DBG_REG_RSTK7_VALUE 7
`define DBG_REG_NL_0 8
`define DBG_REG_P 9
`define DBG_REG_HST 10
`define DBG_REG_HST_SPACES 11
`define DBG_REG_ST_STR 12
`define DBG_REG_ST_VALUE 13
`define DBG_REG_ST_SPACES 14
`define DBG_REG_RSTK6_STR 15
`define DBG_REG_RSTK6_VALUE 16
`define DBG_REG_NL_1 17
`define DBG_REG_END 31
`endif

View file

@ -25,7 +25,7 @@
`ifdef SIM
`define ROMBITS 20
`else
`define ROMBITS 12
`define ROMBITS 13
`endif
module saturn_hp48gx_rom (

View file

@ -41,6 +41,8 @@ module saturn_inst_decoder (
o_alu_reg_dest,
o_alu_reg_src_1,
o_alu_reg_src_2,
o_alu_ptr_begin,
o_alu_ptr_end,
o_alu_imm_value,
o_alu_opcode,
@ -73,6 +75,8 @@ output reg [19:0] o_instr_pc;
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_ptr_begin;
output reg [3:0] o_alu_ptr_end;
output reg [3:0] o_alu_imm_value;
output reg [4:0] o_alu_opcode;
@ -119,6 +123,10 @@ reg [0:0] decode_started;
reg [0:0] block_2x;
reg [0:0] block_6x;
reg [0:0] block_8x;
reg [0:0] block_84x_85x;
reg [0:0] block_JUMP;
/*
* temporary variables
@ -133,6 +141,8 @@ 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_ptr_begin = 4'h0;
o_alu_ptr_end = 4'h0;
o_alu_imm_value = 4'b0;
o_alu_opcode = `ALU_OP_NOP;
@ -149,6 +159,10 @@ initial begin
block_2x = 1'b0;
block_6x = 1'b0;
block_8x = 1'b0;
block_84x_85x = 1'b0;
block_JUMP = 1'b0;
/* local variables */
jump_counter = 3'd0;
@ -199,6 +213,7 @@ always @(posedge i_clk) begin
o_instr_execute <= 1'b1;
block_6x <= 1'b1;
end
4'h8: block_8x <= 1'b1;
default:
begin
$display("invalid instruction");
@ -211,7 +226,6 @@ always @(posedge i_clk) begin
$display("DECODER %0d: [%d] nb= %h - decoding", 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;
@ -234,6 +248,55 @@ always @(posedge i_clk) begin
end
end
if (block_8x) begin
case (i_nibble)
4'h4, 4'h5:
begin
o_alu_reg_dest <= `ALU_REG_ST;
o_alu_reg_src_1 <= `ALU_REG_IMM;
o_alu_reg_src_2 <= `ALU_REG_NONE;
o_alu_imm_value <= { 3'b000, i_nibble[0]};
o_alu_opcode <= `ALU_OP_COPY;
o_instr_type <= `INSTR_TYPE_ALU;
block_84x_85x <= 1'b1;
end
4'hD:
begin
o_instr_type <= `INSTR_TYPE_JUMP;
o_jump_length <= 3'd4;
jump_counter <= 3'd0;
o_instr_execute <= 1'b1;
block_JUMP <= 1'b1;
end
default:
begin
$display("DECODER %0d: [%d] block_8x %h", i_phase, i_cycle_ctr, i_nibble);
o_decoder_error <= 1'b1;
end
endcase
block_8x <= 1'b0;
end
if (block_84x_85x) begin
o_alu_ptr_begin <= i_nibble;
o_alu_ptr_end <= i_nibble;
o_instr_decoded <= 1'b1;
o_instr_execute <= 1'b1;
decode_started <= 1'b0;
block_84x_85x <= 1'b0;
end
/* special cases */
if (block_JUMP) begin
jump_counter <= jump_counter + 3'd1;
if (jump_counter == o_jump_length) begin
block_JUMP <= 1'b0;
o_instr_decoded <= 1'b1;
decode_started <= 1'b0;
end
end
end
/* decoder cleanup only after the instruction is completely decoded and execution has started */
@ -252,6 +315,8 @@ always @(posedge i_clk) 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_ptr_begin <= 4'h0;
o_alu_ptr_end <= 4'h0;
o_alu_imm_value <= 4'b0;
o_alu_opcode <= `ALU_OP_NOP;
@ -268,6 +333,10 @@ always @(posedge i_clk) begin
block_2x <= 1'b0;
block_6x <= 1'b0;
block_8x <= 1'b0;
block_84x_85x <= 1'b0;
block_JUMP <= 1'b0;
/* local variables */
jump_counter = 3'd0;

View file

@ -110,7 +110,12 @@ reg [0:0] reset;
wire [0:0] halt;
wire [7:0] t_led;
`define DELAY_START 26'h08287C0
/* 1/8 s */
// `define DELAY_START 26'h08287C0
// `define TEST_BIT 25
/* 1/32 s */
`define DELAY_START 26'h4143E
`define TEST_BIT 20
initial begin
led = 8'h01;
@ -120,7 +125,7 @@ end
always @(posedge clk_25mhz) begin
delay <= delay + 26'b1;
if (delay[25]) begin
if (delay[`TEST_BIT]) begin
delay <= `DELAY_START;
reset <= btn[1];
clk_en <= 1'b1;