Skip to content

Commit

Permalink
SM83: Port debug interface for new CPU
Browse files Browse the repository at this point in the history
  • Loading branch information
msinger committed Feb 21, 2021
1 parent 82a62a1 commit cc10582
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 96 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ cpu/sm83_control.sv \
cpu/sm83_sequencer.sv \
cpu/sm83_decode.sv \
cpu/sm83_int.sv \
cpu/sm83_dbg_ifc.sv \
ppu/lr35902_ppu.v \
ppu/lr35902_vram.v \
ppu/lr35902_oam.v \
Expand Down
193 changes: 97 additions & 96 deletions src/cpu/sm83_dbg_ifc.sv
Original file line number Diff line number Diff line change
@@ -1,64 +1,66 @@
`default_nettype none

`define DBG_IDLE 0
`define DBG_HALT 1
`define DBG_STEP 2
`define DBG_SEND 3

`define NUM_BP 4

(* nolatches *)
module lr35902_dbg_ifc #(
module sm83_dbg_ifc #(
parameter INITIAL_ENABLE = 0,
) (
input wire clk,
input wire reset,

input wire [7:0] probe, /* content of the currently selected register */
input wire [15:0] pc,
input wire [15:0] sp,
input wire [7:4] f,
input wire ime,
output reg [7:0] data, /* data driven on the bus when drv is set */
output reg drv, /* drive debug data on the bus instead of the requested */
output reg halt, /* halts CPU in instruction fetch state */
output reg no_inc, /* prevent PC from getting incremented */

input wire [7:0] data_rx,
input wire data_rx_valid,
input wire data_rx_seq,
output reg data_rx_ack,
output reg [7:0] data_tx,
output reg data_tx_seq,
input wire data_tx_ack,
input logic clk,
input logic reset,
input logic ncyc,

input logic [7:0] probe, /* content of the currently selected register */
input logic [15:0] pc,
input logic [15:0] sp,
input logic [15:0] wz,
input logic [7:4] f,
input logic ime,
output logic [7:0] data, /* data driven on the bus when drv is set */
output logic drv, /* drive debug data on the bus instead of the requested */
output logic halt, /* halts CPU in instruction fetch state */
output logic no_inc, /* prevent PC from getting incremented */

input logic [7:0] data_rx,
input logic data_rx_valid,
input logic data_rx_seq,
output logic data_rx_ack,
output logic [7:0] data_tx,
output logic data_tx_seq,
input logic data_tx_ack,
);

reg r_ena = INITIAL_ENABLE;
reg ena;
localparam IDLE = 0;
localparam HALT = 1;
localparam STEP = 2;
localparam SEND = 3;

localparam NUM_BP = 4;

logic r_ena = INITIAL_ENABLE;
logic ena;

reg r_halt, r_no_inc;
logic r_halt, r_no_inc;

(* mem2reg *)
reg [15:0] r_bp[0:`NUM_BP-1], bp[0:`NUM_BP-1];
logic [15:0] r_bp[0:NUM_BP-1], bp[0:NUM_BP-1];

reg [7:0] r_drvdata, drvdata;
logic [7:0] r_drvdata, drvdata;

(* mem2reg *)
reg [8:0] r_drvarr[0:3], drvarr[0:3];
logic [8:0] r_drvarr[0:3], drvarr[0:3];

reg [5:0] r_cycle, cycle;
reg [3:0] ret;
reg [3:0] tx_prep;
logic [5:0] r_cycle, cycle;
logic [3:0] ret;
logic [3:0] tx_prep;

reg [1:0] r_dbg_state, dbg_state;
logic [1:0] r_dbg_state, dbg_state;

reg rx_ack, tx_seq;
logic rx_ack, tx_seq;

integer i;

reg stepping;
logic stepping;

always @* begin
always_comb begin
ena = r_ena;
halt = r_halt;
no_inc = r_no_inc;
Expand All @@ -73,46 +75,46 @@ module lr35902_dbg_ifc #(

stepping = 0;

for (i = 0; i < `NUM_BP; i = i + 1)
for (i = 0; i < NUM_BP; i = i + 1)
bp[i] = r_bp[i];

for (i = 0; i < 4; i = i + 1)
drvarr[i] = r_drvarr[i];

case (r_dbg_state)
`DBG_IDLE:
if (data_rx_seq != data_rx_ack) casez ({ ena, data_rx_valid, data_rx })
unique case (r_dbg_state)
IDLE:
if (ncyc && (data_rx_seq != data_rx_ack)) casez ({ ena, data_rx_valid, data_rx })
'b 1_?_00000000: /* halt */
begin
halt = 1;
dbg_state = `DBG_HALT;
dbg_state = HALT;
cycle = 0;
end
'b ?_1_0000??0?: /* NOP */
begin
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end
'b 1_1_0000??11: /* continue */
begin
halt = 0;
no_inc = 0;
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end
'b 1_1_0000??10: /* step */
if (r_halt) begin
stepping = 1;
halt = 0;
cycle = 0;
cycle = 2;
{ drv, data } = r_drvarr[0];
dbg_state = `DBG_STEP;
dbg_state = STEP;
end else
rx_ack = data_rx_seq;
'b ?_1_0001????: /* prep drvdata */
begin
drvdata = { data_rx[3:0], r_drvdata[7:4] };
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end
'b 1_1_001?????: /* set control bits */
Expand All @@ -121,53 +123,53 @@ module lr35902_dbg_ifc #(
no_inc = data_rx[1];
if (!r_halt && data_rx[0] && r_drvdata == 138)
ena = 0;
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end
'b ?_1_01??????: /* set drvdata */
begin
drvarr[data_rx[1:0]] = { data_rx[5], r_drvdata };
if (!data_rx[5] && data_rx[1:0] == 1 && r_drvdata == 138)
ena = 1;
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end
'b 1_1_1???????: /* set breakpoint */
if (r_halt) begin
bp[data_rx[6:4]] = { data_rx[3:0], r_bp[data_rx[6:4]][15:4] };
dbg_state = `DBG_SEND;
dbg_state = SEND;
tx_seq = !data_tx_seq;
end else
rx_ack = data_rx_seq;
default:
rx_ack = data_rx_seq;
endcase
`DBG_HALT:
if (r_cycle == 43) begin /* longest instruction is 24; interrupt entry is 20; 24+20=44 */
dbg_state = `DBG_SEND;
HALT:
if (r_cycle == 60) begin /* longest instruction is 24; interrupt entry is 20; 24+20=44 */
dbg_state = SEND;
tx_seq = !data_tx_seq;
end else
cycle = r_cycle + 1;
`DBG_STEP:
STEP:
begin
halt = 1;
if (r_cycle == 43) begin
dbg_state = `DBG_SEND;
if (r_cycle == 60) begin
dbg_state = SEND;
tx_seq = !data_tx_seq;
end else
cycle = r_cycle + 1;
{ drv, data } = cycle[5:4] ? 'h0xx : r_drvarr[cycle[3:2]];
end
`DBG_SEND:
SEND:
if (data_tx_seq == data_tx_ack) begin
rx_ack = data_rx_seq;
dbg_state = `DBG_IDLE;
dbg_state = IDLE;
ret = ret + 1;
end
endcase

if (!stepping)
for (i = 0; i < `NUM_BP; i = i + 1)
for (i = 0; i < NUM_BP; i = i + 1)
if (pc == r_bp[i])
halt = 1;

Expand All @@ -180,54 +182,53 @@ module lr35902_dbg_ifc #(
cycle = 'bx;
rx_ack = data_rx_seq;
tx_seq = data_tx_ack;
dbg_state = `DBG_IDLE;
dbg_state = IDLE;
ret = 'bx;
drvdata = 'bx;

for (i = 0; i < `NUM_BP; i = i + 1)
for (i = 0; i < NUM_BP; i = i + 1)
bp[i] = 'hffff;

for (i = 0; i < 4; i = i + 1)
drvarr[i] = 'h0xx;
end

(* fullcase *)
case (ret)
0: tx_prep = { ime, 1'b0, r_no_inc, r_halt };
1: tx_prep = f[7:4];
2: tx_prep = probe[3:0];
3: tx_prep = probe[7:4];
4: tx_prep = pc[3:0];
5: tx_prep = pc[7:4];
6: tx_prep = pc[11:8];
7: tx_prep = pc[15:12];
8: tx_prep = sp[3:0];
9: tx_prep = sp[7:4];
10: tx_prep = sp[11:8];
11: tx_prep = sp[15:12];
// 12: tx_prep = sp[3:0];
// 13: tx_prep = sp[7:4];
// 14: tx_prep = sp[11:8];
// 15: tx_prep = sp[15:12];
unique case (ret)
0: tx_prep = { ime, 1'b0, r_no_inc, r_halt };
1: tx_prep = f[7:4];
2: tx_prep = probe[3:0];
3: tx_prep = probe[7:4];
4: tx_prep = pc[3:0];
5: tx_prep = pc[7:4];
6: tx_prep = pc[11:8];
7: tx_prep = pc[15:12];
8: tx_prep = sp[3:0];
9: tx_prep = sp[7:4];
10: tx_prep = sp[11:8];
11: tx_prep = sp[15:12];
12: tx_prep = wz[3:0];
13: tx_prep = wz[7:4];
14: tx_prep = wz[11:8];
15: tx_prep = wz[15:12];
endcase
end

always @(posedge clk) begin
r_ena <= ena;
r_halt <= halt;
r_no_inc <= no_inc;
r_cycle <= cycle;
data_rx_ack <= rx_ack;
data_tx_seq <= tx_seq;
r_dbg_state <= dbg_state;
data_tx <= { ret, tx_prep };
r_drvdata <= drvdata;
always_ff @(posedge clk) begin
r_ena = ena;
r_halt = halt;
r_no_inc = no_inc;
r_cycle = cycle;
data_rx_ack = rx_ack;
data_tx_seq = tx_seq;
r_dbg_state = dbg_state;
data_tx = { ret, tx_prep };
r_drvdata = drvdata;

for (i = 0; i < `NUM_BP; i = i + 1)
r_bp[i] <= bp[i];
for (i = 0; i < NUM_BP; i = i + 1)
r_bp[i] = bp[i];

for (i = 0; i < 4; i = i + 1)
r_drvarr[i] <= drvarr[i];
r_drvarr[i] = drvarr[i];
end

endmodule

0 comments on commit cc10582

Please sign in to comment.