1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-12-22 12:30:01 +00:00

start yosys profiling

This commit is contained in:
Steven Hugg 2017-11-19 20:32:58 -05:00
parent 27a9076cb5
commit 2525d6e585
9 changed files with 130 additions and 48 deletions

View File

@ -167,7 +167,7 @@ body {
<script src="codemirror/addon/edit/matchbrackets.js"></script>
<script src="codemirror/addon/search/search.js"></script>
<script src="codemirror/addon/search/searchcursor.js"></script>
<script src="codemirror/addon/search/jumpToLine.js"></script>
<script src="codemirror/addon/search/jump-to-line.js"></script>
<script src="codemirror/addon/dialog/dialog.js"></script>
<script src="codemirror/addon/selection/active-line.js"></script>
<link rel="stylesheet" href="codemirror/addon/dialog/dialog.css">

View File

@ -1,10 +1,11 @@
`include "hvsync_generator.v"
`include "digits10.v"
module player_stats(reset, score, lives, incscore, declives);
module player_stats(reset, score0, score1, lives, incscore, declives);
input reset;
output [3:0] score[2];
output [3:0] score0;
output [3:0] score1;
input incscore;
output [3:0] lives;
input declives;
@ -12,13 +13,13 @@ module player_stats(reset, score, lives, incscore, declives);
always @(posedge incscore or posedge reset)
begin
if (reset) begin
score[0] <= 0;
score[1] <= 0;
end else if (score[0] == 9) begin
score[0] <= 0;
score[1] <= score[1] + 1;
score0 <= 0;
score1 <= 0;
end else if (score0 == 9) begin
score0 <= 0;
score1 <= score1 + 1;
end else begin
score[0] <= score[0] + 1;
score0 <= score0 + 1;
end
end
@ -53,10 +54,11 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
reg brick_array [BRICKS_H * BRICKS_V];
wire [3:0] score[2];
wire [3:0] score0;
wire [3:0] score1;
wire [3:0] lives;
reg incscore;
reg declives;
reg declives = 0; // TODO
localparam BRICKS_H = 16;
localparam BRICKS_V = 8;
@ -81,8 +83,9 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
// scoreboard
player_stats stats(.reset(reset), .score(score), .lives(lives),
.incscore(incscore), .declives(declives));
player_stats stats(.reset(reset),
.score0(score0), .score1(score1), .incscore(incscore),
.lives(lives), .declives(declives));
wire [3:0] score_digit;
wire [4:0] score_bits;
@ -90,8 +93,8 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
always @(*)
begin
case (hpos[7:5])
1: score_digit = score[1];
2: score_digit = score[0];
1: score_digit = score1;
2: score_digit = score0;
6: score_digit = lives;
default: score_digit = 15; // no digit
endcase
@ -105,11 +108,6 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
wire score_gfx = display_on && score_bits[hpos[4:2] ^ 3'b111];
// TODO: only works when paddle at bottom of screen!
always @(posedge hsync)
if (!hpaddle)
paddle_pos <= vpos;
wire [5:0] hcell = hpos[8:3];
wire [5:0] vcell = vpos[8:3];
wire lr_border = hcell==0 || hcell==31;
@ -128,9 +126,10 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
reg brick_present;
reg [6:0] brick_index;
wire visible_clk = clk & display_on;
// compute main_gfx and locate bricks
always @(posedge clk)
begin
always @(posedge visible_clk)
// see if we are scanning brick area
if (vpos[8:6] == 1 && !lr_border)
begin
@ -162,16 +161,21 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
default: main_gfx <= lr_border; // left/right borders
endcase
end
end
// only works when paddle at bottom of screen!
// (we don't want to mess w/ paddle position during visible portion)
always @(posedge hsync)
if (!hpaddle)
paddle_pos <= vpos;
wire ball_pixel_collide = main_gfx & ball_gfx;
/* verilator lint_off MULTIDRIVEN */
reg [5:0] ball_collide_bits = 0;
reg [4:0] ball_collide_bits = 0;
/* verilator lint_on MULTIDRIVEN */
// compute ball collisions with paddle and playfield
always @(posedge clk)
always @(posedge visible_clk)
if (ball_pixel_collide) begin
if (paddle_gfx) begin
// did we collide w/ paddle?
@ -186,7 +190,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
end
// compute ball collisions with brick
always @(posedge clk)
always @(posedge visible_clk)
if (ball_pixel_collide && brick_present) begin
brick_array[brick_index] <= 0;
incscore <= 1; // increment score

View File

@ -12,17 +12,17 @@ module hvsync_generator(
// constant declarations for VGA sync parameters
localparam H_DISPLAY = 256; // horizontal display area
localparam H_L_BORDER = 12; // horizontal left border
localparam H_R_BORDER = 8; // horizontal right border
localparam H_RETRACE = 24; // horizontal retrace
localparam H_L_BORDER = 16; // horizontal left border
localparam H_R_BORDER = 16; // horizontal right border
localparam H_RETRACE = 16; // horizontal retrace
localparam H_MAX = H_DISPLAY + H_L_BORDER + H_R_BORDER + H_RETRACE - 1;
localparam START_H_RETRACE = H_DISPLAY + H_R_BORDER;
localparam END_H_RETRACE = H_DISPLAY + H_R_BORDER + H_RETRACE - 1;
localparam V_DISPLAY = 240; // vertical display area
localparam V_T_BORDER = 4; // vertical top border
localparam V_B_BORDER = 16; // vertical bottom border
localparam V_RETRACE = 2; // vertical retrace
localparam V_B_BORDER = 14; // vertical bottom border
localparam V_RETRACE = 4; // vertical retrace
localparam V_MAX = V_DISPLAY + V_T_BORDER + V_B_BORDER + V_RETRACE - 1;
localparam START_V_RETRACE = V_DISPLAY + V_B_BORDER;
localparam END_V_RETRACE = V_DISPLAY + V_B_BORDER + V_RETRACE - 1;
@ -46,8 +46,8 @@ module hvsync_generator(
reg vga_HS, vga_VS;
always @(posedge clk)
begin
vga_HS <= (hpos>=280 && hpos<288); // change this value to move the display horizontally
vga_VS <= (vpos==START_V_RETRACE); // change this value to move the display vertically
vga_HS <= (hpos>=START_H_RETRACE && hpos<=END_H_RETRACE);
vga_VS <= (vpos==START_V_RETRACE);
end
always @(posedge clk)

View File

@ -0,0 +1,26 @@
`include "hvsync_generator.v"
module top(clk, hsync, vsync, rgb);
input clk;
output hsync, vsync;
output [2:0] rgb;
wire display_on;
wire [8:0] hpos;
wire [8:0] vpos;
hvsync_generator hvsync_gen(
.clk(clk),
.hsync(hsync),
.vsync(vsync),
.display_on(display_on),
.hpos(hpos),
.vpos(vpos)
);
wire r = display_on && hpos[4];
wire g = display_on && vpos[4];
wire b = display_on && hpos[0];
assign rgb = {b,g,r};
endmodule

View File

@ -396,6 +396,7 @@ var SampleAudio = function(clockfreq) {
}
this.addSingleSample = function(value) {
if (!buffer) return;
buffer[bufpos++] = value;
if (bufpos >= buffer.length) {
bufpos = 0;

View File

@ -242,8 +242,8 @@ var VerilogPlatform = function(mainElement, options) {
video.create();
setKeyboardFromMap(video, switches, VERILOG_KEYCODE_MAP);
$(video.canvas).mousemove(function(e) {
paddle_x = clamp(4,255,Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 20));
paddle_y = clamp(4,255,Math.floor(e.offsetY * video.canvas.height / $(video.canvas).height() - 20));
paddle_x = clamp(8,240,Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 20));
paddle_y = clamp(8,240,Math.floor(e.offsetY * video.canvas.height / $(video.canvas).height() - 20));
});
audio = new SampleAudio(AUDIO_FREQ);
idata = video.getFrameData();
@ -294,11 +294,11 @@ var VerilogPlatform = function(mainElement, options) {
}
this.pause = function() {
timer.stop();
audio.stop();
if (gen.spkr !== undefined) audio.stop();
}
this.resume = function() {
timer.start();
audio.start();
if (gen.spkr !== undefined) audio.start();
}
this.reset = function() {
@ -311,6 +311,17 @@ var VerilogPlatform = function(mainElement, options) {
this.getDefaultExtension = function() { return ".v"; };
};
function traceTiming() {
// TODO: merge with main setCode(text)
var text = editor.getValue();
worker.postMessage({
code:text,
dependencies:loadFileDependencies(text),
platform:platform_id,
tool:'yosys'
});
}
////////////////
PLATFORMS['verilog'] = VerilogPlatform;

View File

@ -1198,7 +1198,7 @@ function setupDebugControls(){
$("#dbg_stepout").hide();
$("#dbg_stepback").hide();
}
if (platform_id == 'vcs') {
if (window.traceTiming) {
$("#dbg_timing").click(traceTiming).show();
}
else if (platform.readAddress) {

View File

@ -1027,6 +1027,15 @@ function detectModuleName(code) {
return m ? m[1] : null;
}
function detectTopModuleName(code) {
var topmod = detectModuleName(code) || "top";
var m = /\bmodule\s+(\w+?_top)/.exec(code);
if (m && m[1]) topmod = m[1];
m = /\bmodule\s+(\w+?_top)/.exec(code);
if (m && m[1]) topmod = m[1];
return topmod;
}
function writeDependencies(depends, FS, errors) {
if (depends) {
for (var i=0; i<depends.length; i++) {
@ -1038,7 +1047,7 @@ function writeDependencies(depends, FS, errors) {
}
function compileVerilator(code, platform, options) {
loadWASM("verilator_bin");
loadNative("verilator_bin");
load("verilator2js");
var errors = [];
var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?:)?(\d+)?[:]?\s*(.+)/i, 3, 4);
@ -1048,13 +1057,8 @@ function compileVerilator(code, platform, options) {
print:print_fn,
printErr:match_fn,
});
var topmod = detectModuleName(code) || "top";
var m = /\bmodule\s+(\w+?_top)/.exec(code);
if (m && m[1]) topmod = m[1];
m = /\bmodule\s+(\w+?_top)/.exec(code);
if (m && m[1]) topmod = m[1];
var topmod = detectTopModuleName(code);
var FS = verilator_mod['FS'];
//setupFS(FS);
FS.writeFile(topmod+".v", code);
writeDependencies(options.dependencies, FS, errors);
starttime();
@ -1078,6 +1082,37 @@ function compileVerilator(code, platform, options) {
}
}
function compileYosys(code, platform, options) {
loadNative("yosys");
var errors = [];
var match_fn = makeErrorMatcher(errors, /ERROR: (.+?) in line (.+?[.]v):(\d+) (.+)/i, 3, 4);
starttime();
var yosys_mod = yosys({
wasmBinary:wasmBlob['yosys'],
noInitialRun:true,
print:print_fn,
printErr:match_fn,
});
endtime("create module");
var topmod = detectTopModuleName(code);
var FS = yosys_mod['FS'];
FS.writeFile(topmod+".v", code);
writeDependencies(options.dependencies, FS, errors);
starttime();
yosys_mod.callMain(["-q", "-o", topmod+".json", "-S", topmod+".v"]);
endtime("compile");
if (errors.length) return {errors:errors};
try {
var json_file = FS.readFile(topmod+".json", {encoding:'utf8'});
var json = JSON.parse(json_file);
console.log(json);
return {yosys_json:json, errors:errors};
} catch(e) {
console.log(e);
return {errors:errors};
}
}
var TOOLS = {
'dasm': assembleDASM,
'acme': assembleACME,
@ -1090,6 +1125,7 @@ var TOOLS = {
'xasm6809': assembleXASM6809,
'naken': assembleNAKEN,
'verilator': compileVerilator,
'yosys': compileYosys,
}
var TOOL_PRELOADFS = {

View File

@ -71,7 +71,7 @@ function compile(tool, code, platform, callback, outlen, nlines, nerrors) {
assert.equal(nerrors, msg.errors.length, "errors");
} else {
assert.equal(nerrors||0, 0, "errors");
assert.equal(msg.output.length, outlen, "output binary");
assert.equal(msg.output.code?msg.output.code.length:msg.output.length, outlen, "output binary");
assert.equal(msg.lines.length, nlines, "listing lines");
}
callback(null, msg);
@ -159,6 +159,10 @@ describe('Worker', function() {
var csource = ab2str(fs.readFileSync('presets/coleco/skeleton.sdcc'));
compile('sdcc', csource, 'coleco', done, 32768, 31, 0);
});
it('should compile verilog example', function(done) {
var csource = ab2str(fs.readFileSync('presets/verilog/lfsr.v'));
compile('verilator', csource, 'verilog', done, 3731, 0, 0);
});
it('should NOT compile SDCC', function(done) {
compile('sdcc', 'foobar', 'mw8080bw', done, 0, 0, 1);
});