working on verilog debugger

This commit is contained in:
Steven Hugg 2017-11-24 14:14:22 -05:00
parent 32a65a74e0
commit a541b3c4e6
4 changed files with 170 additions and 28 deletions

View File

@ -68,6 +68,7 @@ body {
<button id="dbg_pause" type="button" title="Pause"><span class="glyphicon glyphicon-pause" aria-hidden="true"></span></button>
<button id="dbg_go" type="button" title="Run"><span class="glyphicon glyphicon-play" aria-hidden="true"></span></button>
<button id="dbg_step" type="submit" title="Step"><span class="glyphicon glyphicon-step-forward" aria-hidden="true"></span></button>
<button id="dbg_tovsync" type="submit" title="Single Frame"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
<button id="dbg_toline" type="submit" title="Run To Line"><span class="glyphicon glyphicon-save" aria-hidden="true"></span></button>
<button id="dbg_stepout" type="submit" title="Step Out of Subroutine"><span class="glyphicon glyphicon-hand-up" aria-hidden="true"></span></button>
<button id="dbg_stepback" type="submit" title="Step Backwards"><span class="glyphicon glyphicon-step-backward" aria-hidden="true"></span></button>

View File

@ -180,13 +180,12 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
if (paddle_gfx) begin
// did we collide w/ paddle?
ball_collide_bits[4] <= 1; // bit 4 == paddle collide
end else begin
// ball has 4 collision quadrants
if (!ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[0] <= 1;
if (ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[1] <= 1;
if (!ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[2] <= 1;
if (ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[3] <= 1;
end
// ball has 4 collision quadrants
if (!ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[0] <= 1;
if (ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[1] <= 1;
if (!ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[2] <= 1;
if (ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[3] <= 1;
end
// compute ball collisions with brick
@ -213,7 +212,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
// which side of paddle, left/right?
ball_dir_x <= (ball_paddle_dx < 16) ? BALL_DIR_LEFT : BALL_DIR_RIGHT;
// hitting with edge of paddle makes it fast
ball_speed_x <= !(ball_collide_bits[2] && ball_collide_bits[3]);
ball_speed_x <= ball_collide_bits[3:0] != 4'b1100;
end else begin
// collided with playfield
// TODO: can still slip through corners

View File

@ -83,14 +83,20 @@ function VerilatorBase() {
//
var totalTicks = 0;
function vl_fatal(msg) {
console.log(msg);
}
this.ticks = function() { return totalTicks; }
this.setTicks = function(T) { totalTicks = T|0; }
var RESET_TICKS = 1000;
this.reset2 = function() {
if (this.reset !== undefined) {
totalTicks = 0;
this.reset = 0;
this.tick2();
this.reset = 1;
@ -130,6 +136,7 @@ function VerilatorBase() {
maxVclockLoop = __VclockLoop;
console.log("Graph took " + maxVclockLoop + " iterations to stabilize");
}
totalTicks++;
}
this._eval_initial_loop = function(vlSymsp) {
@ -176,9 +183,12 @@ var VerilogPlatform = function(mainElement, options) {
0xffffffff,
];
var debugCond;
function vidtick() {
gen.tick2();
audio.addSingleSample(0+gen.spkr); // TODO: sync with audio freq
if (debugCond && debugCond()) debugCond = null;
}
function updateInspectionFrame() {
@ -209,6 +219,7 @@ var VerilogPlatform = function(mainElement, options) {
}
function updateVideoFrame() {
debugCond = self.getDebugCallback();
var i=4; // TODO, start @ 0?
var trace=inspect_obj && inspect_sym;
for (var y=0; y<videoHeight; y++) {
@ -231,6 +242,7 @@ var VerilogPlatform = function(mainElement, options) {
updateInspectionFrame();
video.updateFrame();
updateInspectionPostFrame();
self.restartDebugState();
}
var yposlist = [];
@ -391,6 +403,117 @@ var VerilogPlatform = function(mainElement, options) {
inspect_obj = inspect_sym = null;
}
}
// DEBUGGING
this.saveState = function() {
return {T:gen.ticks(), o:$.extend(true, {}, gen)};
}
this.loadState = function(state) {
gen = $.extend(true, gen, state.o);
gen.setTicks(state.T);
}
var onBreakpointHit;
var debugCondition;
var debugSavedState = null;
var debugBreakState = null;
var debugTargetClock = 0;
this.setDebugCondition = function(debugCond) {
if (debugSavedState) {
this.loadState(debugSavedState);
} else {
debugSavedState = this.saveState();
}
debugCondition = debugCond;
debugBreakState = null;
this.resume();
}
this.restartDebugState = function() {
if (debugCondition && !debugBreakState) {
debugSavedState = this.saveState();
if (debugTargetClock > 0)
debugTargetClock -= debugSavedState.T;
debugSavedState.T = 0;
this.loadState(debugSavedState);
}
}
this.getDebugCallback = function() {
return debugCondition;
}
this.setupDebug = function(callback) {
onBreakpointHit = callback;
}
this.clearDebug = function() {
debugSavedState = null;
debugBreakState = null;
debugTargetClock = 0;
onBreakpointHit = null;
debugCondition = null;
}
this.breakpointHit = function(targetClock) {
debugTargetClock = targetClock;
debugBreakState = this.saveState();
console.log("Breakpoint at clk", debugBreakState.T);
this.pause();
if (onBreakpointHit) {
onBreakpointHit(debugBreakState);
}
}
this.wasBreakpointHit = function() {
return debugBreakState != null;
}
this.step = function() {
var self = this;
this.setDebugCondition(function() {
if (gen.ticks() > debugTargetClock) {
self.breakpointHit(gen.ticks());
return true;
}
return false;
});
}
this.runToVsync = function() {
var self = this;
this.setDebugCondition(function() {
if (gen.vsync && gen.ticks() > debugTargetClock+1000) {
self.breakpointHit(gen.ticks());
return true;
}
return false;
});
}
this.stepBack = function() {
var self = this;
var prevState;
var prevClock;
this.setDebugCondition(function() {
var debugClock = gen.ticks();
if (debugClock >= debugTargetClock && prevState) {
self.loadState(prevState);
self.breakpointHit(prevClock);
return true;
} else if (debugClock >= debugTargetClock-2 && debugClock < debugTargetClock) {
prevState = self.saveState();
prevClock = debugClock;
}
return false;
});
}
this.runEval = function(evalfunc) {
var self = this;
this.setDebugCondition(function() {
if (gen.ticks() > debugTargetClock) {
if (evalfunc(gen)) {
self.breakpointHit(gen.ticks());
return true;
}
}
return false;
});
}
};
function traceTiming() {

View File

@ -576,7 +576,7 @@ var lastDebugState;
function showMemory(state) {
var s = "";
if (state) {
if (state && platform.cpuStateToLongString) {
s = platform.cpuStateToLongString(state.c);
if (platform.getRasterPosition) {
var pos = platform.getRasterPosition();
@ -598,14 +598,16 @@ function setupBreakpoint() {
// TODO
platform.setupDebug(function(state) {
lastDebugState = state;
var PC = state.c.PC;
var line = sourcefile.findLineForOffset(PC);
if (line >= 0) {
console.log("BREAKPOINT", hex(PC), line);
setCurrentLine(line);
} else {
console.log("BREAKPOINT", hex(PC));
// TODO: switch to disasm
if (state.c) {
var PC = state.c.PC;
var line = sourcefile.findLineForOffset(PC);
if (line >= 0) {
console.log("BREAKPOINT", hex(PC), line);
setCurrentLine(line);
} else {
console.log("BREAKPOINT", hex(PC));
// TODO: switch to disasm
}
}
showMemory(state);
updateDisassembly();
@ -635,7 +637,7 @@ function _resume() {
function resume() {
clearBreakpoint();
if (! platform.isRunning())
if (! platform.isRunning() )
editor.setSelection(editor.getCursor()); // TODO??
_resume();
}
@ -645,6 +647,11 @@ function singleStep() {
platform.step();
}
function singleFrameStep() {
setupBreakpoint();
platform.runToVsync();
}
function getCurrentLine() {
return editor.getCursor().line+1;
}
@ -1213,31 +1220,40 @@ function _recordVideo() {
}
function setupDebugControls(){
var hasDebug = platform.setupDebug;
$("#dbg_reset").click(resetAndDebug);
$("#dbg_pause").click(pause);
$("#dbg_go").click(resume);
if (hasDebug) {
if (platform.step)
$("#dbg_step").click(singleStep).show();
$("#dbg_toline").click(runToCursor).show();
$("#dbg_stepout").click(runUntilReturn).show();
$("#dbg_stepback").click(runStepBackwards).show();
} else {
else
$("#dbg_step").hide();
if (platform.runToVsync)
$("#dbg_tovsync").click(singleFrameStep).show();
else
$("#dbg_tovsync").hide();
if (platform.runEval && platform_id != 'verilog')
$("#dbg_toline").click(runToCursor).show();
else
$("#dbg_toline").hide();
if (platform.runUntilReturn)
$("#dbg_stepout").click(runUntilReturn).show();
else
$("#dbg_stepout").hide();
if (platform.stepBack)
$("#dbg_stepback").click(runStepBackwards).show();
else
$("#dbg_stepback").hide();
}
if (window.traceTiming) {
$("#dbg_timing").click(traceTiming).show();
}
else if (platform.readAddress) {
} else if (platform.readAddress) {
$("#dbg_memory").click(toggleMemoryWindow).show();
}
if (platform.getProbe) {
$("#dbg_profile").click(toggleProfileWindow).show();
}
if (platform.saveState) { // TODO: only show if listing or disasm available
if (platform.saveState && platform_id != 'verilog') { // TODO: only show if listing or disasm available
$("#dbg_disasm").click(toggleDisassembly).show();
}
$("#disassembly").hide();
@ -1246,7 +1262,10 @@ function setupDebugControls(){
$("#item_new_file").click(_createNewFile);
$("#item_share_file").click(_shareFile);
$("#item_reset_file").click(_resetPreset);
$("#item_debug_expr").click(_breakExpression);
if (platform.runEval)
$("#item_debug_expr").click(_breakExpression).show();
else
$("#item_debug_expr").hide();
$("#item_download_rom").click(_downloadROMImage);
$("#item_record_video").click(_recordVideo);
updateDebugWindows();