"use strict"; var VERILOG_PRESETS = [ {id:'clock_divider.v', name:'Clock Divider'}, {id:'hvsync_generator.v', name:'Video Sync Generator'}, {id:'test_hvsync.v', name:'Test Pattern'}, {id:'lfsr.v', name:'Linear Feedback Shift Register'}, {id:'pong.v', name:'Pong'}, ]; var VERILOG_KEYCODE_MAP = makeKeycodeMap([ [Keys.VK_LEFT, 0, 0x1], [Keys.VK_RIGHT, 0, 0x2], [Keys.VK_UP, 0, 0x4], [Keys.VK_DOWN, 0, 0x8], [Keys.VK_SPACE, 0, 0x10], [Keys.VK_SHIFT, 0, 0x20], [Keys.VK_1, 0, 0x40], [Keys.VK_2, 0, 0x80], [Keys.VK_5, 0, 0x100], [Keys.VK_6, 0, 0x200], [Keys.VK_7, 0, 0x400], ]); function VerilatorBase() { this.VL_RAND_RESET_I = function(bits) { return Math.floor(Math.random() * (1< 100) { vl_fatal("Verilated model didn't converge"); } } if (__VclockLoop > maxVclockLoop) { maxVclockLoop = __VclockLoop; console.log("Graph took " + maxVclockLoop + " iterations to stabilize"); } } this._eval_initial_loop = function(vlSymsp) { vlSymsp.__Vm_didInit = true; this._eval_initial(vlSymsp); vlSymsp.__Vm_activity = true; var __VclockLoop = 0; var __Vchange=1; while (__Vchange) { this._eval_settle(vlSymsp); this._eval(vlSymsp); __Vchange = this._change_request(vlSymsp); if (++__VclockLoop > 100) { vl_fatal("Verilated model didn't DC converge"); } } } } var VerilogPlatform = function(mainElement, options) { var self = this; var video, audio; var videoWidth = 288; var videoHeight = 248; var idata, timer; var gen; var frameRate = 60; var AUDIO_FREQ = 15750; var current_output; var paddle_x = 0; var paddle_y = 0; var switches = [0]; this.getPresets = function() { return VERILOG_PRESETS; } var RGBLOOKUP = [ 0xff111111, 0xff1111ff, 0xff11ff11, 0xff11ffff, 0xffff1111, 0xffff11ff, 0xffffff11, 0xffffffff, ]; function vidtick() { gen.tick2(); audio.addSingleSample(0+gen.spkr); // TODO: sync with audio freq } function updateVideoFrame() { var i=0; for (var y=0; y paddle_x ? 1 : 0; gen.vpaddle = y > paddle_y ? 1 : 0; for (var x=0; x1 ? v.len*2+8 : 8; var y2 = y1+ys; var z = gen[v.name]; var y = Math.round(y2 - ys*((z-lo)/hi)); yposlist[i] = y2; var ly = lasty[i]; if (x > 0 && ly != y) { var dir = ly < y ? 1 : -1; while ((ly += dir) != y && ly >= y1 && ly <= y2) { idata[x + ly*videoWidth] = COLOR_TRANS_SIGNAL; } } lasty[i] = y; //idata[x + y1*videoWidth] = COLOR_BORDER; //idata[x + y2*videoWidth] = COLOR_BORDER; idata[x + y*videoWidth] = COLOR_SIGNAL; y1 += ys+yb; } } video.updateFrame(); // draw labels var ctx = video.getContext(); ctx.font = "8px TinyFont"; ctx.fillStyle = "white"; for (var i=0; i e.lineNumber-5 && i < e.lineNumber+5) { s += lines[i] + '\n'; } } console.log(s); } } this.loadROM = function(title, output) { var mod; try { mod = new Function('base', output.code); } catch (e) { printErrorCodeContext(e, output.code); throw e; } var base = new VerilatorBase(); gen = new mod(base); gen.__proto__ = base; output.code = null; output.ports_signals = output.ports.concat(output.signals); current_output = output; this.reset(); } this.isRunning = function() { return timer && timer.isRunning(); } this.pause = function() { timer.stop(); audio.stop(); } this.resume = function() { timer.start(); audio.start(); } this.reset = function() { gen._ctor_var_reset(); gen.reset2(); } this.getToolForFilename = function(fn) { return "verilator"; } this.getDefaultExtension = function() { return ".v"; }; }; //////////////// PLATFORMS['verilog'] = VerilogPlatform;