mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-22 12:30:01 +00:00
verilog: 2d array; digits; score; reset w/ no init; more warnings
This commit is contained in:
parent
e4fd886c94
commit
27a9076cb5
@ -1,4 +1,36 @@
|
||||
`include "hvsync_generator.v"
|
||||
`include "digits10.v"
|
||||
|
||||
module player_stats(reset, score, lives, incscore, declives);
|
||||
|
||||
input reset;
|
||||
output [3:0] score[2];
|
||||
input incscore;
|
||||
output [3:0] lives;
|
||||
input 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;
|
||||
end else begin
|
||||
score[0] <= score[0] + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge declives or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
lives <= 3;
|
||||
else if (lives != 0)
|
||||
lives <= lives - 1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
|
||||
@ -21,6 +53,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] lives;
|
||||
reg incscore;
|
||||
reg declives;
|
||||
|
||||
localparam BRICKS_H = 16;
|
||||
localparam BRICKS_V = 8;
|
||||
|
||||
@ -42,6 +79,32 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
.vpos(vpos)
|
||||
);
|
||||
|
||||
// scoreboard
|
||||
|
||||
player_stats stats(.reset(reset), .score(score), .lives(lives),
|
||||
.incscore(incscore), .declives(declives));
|
||||
|
||||
wire [3:0] score_digit;
|
||||
wire [4:0] score_bits;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
case (hpos[7:5])
|
||||
1: score_digit = score[1];
|
||||
2: score_digit = score[0];
|
||||
6: score_digit = lives;
|
||||
default: score_digit = 15; // no digit
|
||||
endcase
|
||||
end
|
||||
|
||||
digits10_case numbers(
|
||||
.digit(score_digit),
|
||||
.yofs(vpos[4:2]),
|
||||
.bits(score_bits)
|
||||
);
|
||||
|
||||
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)
|
||||
@ -65,16 +128,21 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
reg brick_present;
|
||||
reg [6:0] brick_index;
|
||||
|
||||
// compute main_gfx and locate bricks
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (vpos[8:6] == 1 && !lr_border) // 8 rows
|
||||
// see if we are scanning brick area
|
||||
if (vpos[8:6] == 1 && !lr_border)
|
||||
begin
|
||||
// compute brick index
|
||||
// every 16th pixel, starting at 8
|
||||
if (hpos[3:0] == 8) begin
|
||||
// compute brick index
|
||||
brick_index <= {vpos[5:3], hpos[7:4]};
|
||||
main_gfx <= 0; // 2 pixel horiz spacing between bricks
|
||||
// load brick bit from array
|
||||
end else if (hpos[3:0] == 9) begin
|
||||
end
|
||||
// every 17th pixel
|
||||
else if (hpos[3:0] == 9) begin
|
||||
// load brick bit from array
|
||||
brick_present <= brick_array[brick_index];
|
||||
end else begin
|
||||
main_gfx <= brick_present && vpos[2:0] != 0; // 1 pixel vert. spacing
|
||||
@ -82,6 +150,10 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
end else begin
|
||||
brick_present <= 0;
|
||||
case (vpos[8:3])
|
||||
0: main_gfx <= score_gfx; // scoreboard
|
||||
1: main_gfx <= score_gfx;
|
||||
2: main_gfx <= score_gfx;
|
||||
3: main_gfx <= 0;
|
||||
4: main_gfx <= 1; // top border
|
||||
//14: main_gfx <= hpos[4];
|
||||
//21: main_gfx <= hpos[5];
|
||||
@ -98,26 +170,40 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
reg [5:0] ball_collide_bits = 0;
|
||||
/* verilator lint_on MULTIDRIVEN */
|
||||
|
||||
// compute ball collisions with paddle and playfield
|
||||
always @(posedge clk)
|
||||
if (ball_pixel_collide) begin
|
||||
if (paddle_gfx) // did we collide w/ paddle?
|
||||
ball_collide_bits[4] <= 1;
|
||||
else if (brick_present)
|
||||
brick_array[brick_index] <= 0;
|
||||
// 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;
|
||||
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
|
||||
end
|
||||
|
||||
// compute ball collisions with brick
|
||||
always @(posedge clk)
|
||||
if (ball_pixel_collide && brick_present) begin
|
||||
brick_array[brick_index] <= 0;
|
||||
incscore <= 1; // increment score
|
||||
end else begin
|
||||
incscore <= 0; // reset incscore
|
||||
end
|
||||
|
||||
wire signed [8:0] ball_paddle_dx = ball_x - paddle_pos + 8;
|
||||
|
||||
// compute ball new position and velocity
|
||||
always @(posedge vsync or posedge reset)
|
||||
begin
|
||||
if (reset) begin
|
||||
ball_dir_y <= BALL_DIR_DOWN;
|
||||
end else
|
||||
if (ball_collide_bits[4]) begin // collided with paddle?
|
||||
reg signed [8:0] ball_paddle_dx = ball_x - paddle_pos + 8;
|
||||
// ball collided with paddle?
|
||||
if (ball_collide_bits[4]) begin
|
||||
// bounces upward off of paddle
|
||||
ball_dir_y <= BALL_DIR_UP;
|
||||
// which side of paddle, left/right?
|
||||
@ -127,6 +213,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
end else begin
|
||||
// collided with playfield
|
||||
// TODO: can still slip through corners
|
||||
// compute left/right bounce
|
||||
casez (ball_collide_bits[3:0])
|
||||
4'b01?1: ball_dir_x <= BALL_DIR_RIGHT; // left edge/corner
|
||||
4'b1101: ball_dir_x <= BALL_DIR_RIGHT; // left corner
|
||||
@ -134,6 +221,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
4'b1110: ball_dir_x <= BALL_DIR_LEFT; // right corner
|
||||
default: ;
|
||||
endcase
|
||||
// compute top/bottom bounce
|
||||
casez (ball_collide_bits[3:0])
|
||||
4'b1011: ball_dir_y <= BALL_DIR_DOWN;
|
||||
4'b0111: ball_dir_y <= BALL_DIR_DOWN;
|
||||
@ -146,7 +234,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
ball_collide_bits <= 0;
|
||||
ball_collide_bits <= 0; // clear all collide bits for frame
|
||||
end
|
||||
|
||||
always @(negedge vsync or posedge reset)
|
||||
@ -165,9 +253,9 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
|
||||
wire grid_gfx = (((hpos&7)==0) || ((vpos&7)==0));
|
||||
|
||||
wire r = display_on && (grid_gfx | ball_gfx);
|
||||
wire r = display_on && (ball_gfx | paddle_gfx);
|
||||
wire g = display_on && (main_gfx | ball_gfx);
|
||||
wire b = display_on && (ball_gfx | brick_present);
|
||||
wire b = display_on && (grid_gfx | ball_gfx | brick_present);
|
||||
assign rgb = {b,g,r};
|
||||
|
||||
endmodule
|
||||
|
184
presets/verilog/digits10.v
Normal file
184
presets/verilog/digits10.v
Normal file
@ -0,0 +1,184 @@
|
||||
`include "hvsync_generator.v"
|
||||
|
||||
module digits10_case(digit, yofs, bits);
|
||||
|
||||
input [3:0] digit;
|
||||
input [2:0] yofs;
|
||||
output [4:0] bits;
|
||||
|
||||
wire [6:0] caseexpr = {digit,yofs};
|
||||
always @(*)
|
||||
case (caseexpr)
|
||||
7'o00: bits = 5'b11111;
|
||||
7'o01: bits = 5'b10001;
|
||||
7'o02: bits = 5'b10001;
|
||||
7'o03: bits = 5'b10001;
|
||||
7'o04: bits = 5'b11111;
|
||||
|
||||
7'o10: bits = 5'b01100;
|
||||
7'o11: bits = 5'b00100;
|
||||
7'o12: bits = 5'b00100;
|
||||
7'o13: bits = 5'b00100;
|
||||
7'o14: bits = 5'b11111;
|
||||
|
||||
7'o20: bits = 5'b11111;
|
||||
7'o21: bits = 5'b00001;
|
||||
7'o22: bits = 5'b11111;
|
||||
7'o23: bits = 5'b10000;
|
||||
7'o24: bits = 5'b11111;
|
||||
|
||||
7'o30: bits = 5'b11111;
|
||||
7'o31: bits = 5'b00001;
|
||||
7'o32: bits = 5'b11111;
|
||||
7'o33: bits = 5'b00001;
|
||||
7'o34: bits = 5'b11111;
|
||||
|
||||
7'o40: bits = 5'b10001;
|
||||
7'o41: bits = 5'b10001;
|
||||
7'o42: bits = 5'b11111;
|
||||
7'o43: bits = 5'b00001;
|
||||
7'o44: bits = 5'b00001;
|
||||
|
||||
7'o50: bits = 5'b11111;
|
||||
7'o51: bits = 5'b10000;
|
||||
7'o52: bits = 5'b11111;
|
||||
7'o53: bits = 5'b00001;
|
||||
7'o54: bits = 5'b11111;
|
||||
|
||||
7'o60: bits = 5'b11111;
|
||||
7'o61: bits = 5'b10000;
|
||||
7'o62: bits = 5'b11111;
|
||||
7'o63: bits = 5'b10001;
|
||||
7'o64: bits = 5'b11111;
|
||||
|
||||
7'o70: bits = 5'b11111;
|
||||
7'o71: bits = 5'b00001;
|
||||
7'o72: bits = 5'b00001;
|
||||
7'o73: bits = 5'b00001;
|
||||
7'o74: bits = 5'b00001;
|
||||
|
||||
7'o100: bits = 5'b11111;
|
||||
7'o101: bits = 5'b10001;
|
||||
7'o102: bits = 5'b11111;
|
||||
7'o103: bits = 5'b10001;
|
||||
7'o104: bits = 5'b11111;
|
||||
|
||||
7'o110: bits = 5'b11111;
|
||||
7'o111: bits = 5'b10001;
|
||||
7'o112: bits = 5'b11111;
|
||||
7'o113: bits = 5'b00001;
|
||||
7'o114: bits = 5'b11111;
|
||||
|
||||
default: bits = 0;
|
||||
endcase
|
||||
endmodule
|
||||
|
||||
module digits10_array(digit, yofs, bits);
|
||||
|
||||
input [3:0] digit;
|
||||
input [2:0] yofs;
|
||||
output [4:0] bits;
|
||||
|
||||
reg [4:0] bitarray[10][5];
|
||||
|
||||
always @(*)
|
||||
bits = bitarray[digit][yofs];
|
||||
|
||||
initial
|
||||
begin
|
||||
bitarray[0][0] = 5'b11111;
|
||||
bitarray[0][1] = 5'b10001;
|
||||
bitarray[0][2] = 5'b10001;
|
||||
bitarray[0][3] = 5'b10001;
|
||||
bitarray[0][4] = 5'b11111;
|
||||
|
||||
bitarray[1][0] = 5'b01100;
|
||||
bitarray[1][1] = 5'b00100;
|
||||
bitarray[1][2] = 5'b00100;
|
||||
bitarray[1][3] = 5'b00100;
|
||||
bitarray[1][4] = 5'b11111;
|
||||
|
||||
bitarray[2][0] = 5'b11111;
|
||||
bitarray[2][1] = 5'b00001;
|
||||
bitarray[2][2] = 5'b11111;
|
||||
bitarray[2][3] = 5'b10000;
|
||||
bitarray[2][4] = 5'b11111;
|
||||
|
||||
bitarray[3][0] = 5'b11111;
|
||||
bitarray[3][1] = 5'b00001;
|
||||
bitarray[3][2] = 5'b11111;
|
||||
bitarray[3][3] = 5'b00001;
|
||||
bitarray[3][4] = 5'b11111;
|
||||
|
||||
bitarray[4][0] = 5'b10001;
|
||||
bitarray[4][1] = 5'b10001;
|
||||
bitarray[4][2] = 5'b11111;
|
||||
bitarray[4][3] = 5'b00001;
|
||||
bitarray[4][4] = 5'b00001;
|
||||
|
||||
bitarray[5][0] = 5'b11111;
|
||||
bitarray[5][1] = 5'b10000;
|
||||
bitarray[5][2] = 5'b11111;
|
||||
bitarray[5][3] = 5'b00001;
|
||||
bitarray[5][4] = 5'b11111;
|
||||
|
||||
bitarray[6][0] = 5'b11111;
|
||||
bitarray[6][1] = 5'b10000;
|
||||
bitarray[6][2] = 5'b11111;
|
||||
bitarray[6][3] = 5'b10001;
|
||||
bitarray[6][4] = 5'b11111;
|
||||
|
||||
bitarray[7][0] = 5'b11111;
|
||||
bitarray[7][1] = 5'b00001;
|
||||
bitarray[7][2] = 5'b00001;
|
||||
bitarray[7][3] = 5'b00001;
|
||||
bitarray[7][4] = 5'b00001;
|
||||
|
||||
bitarray[8][0] = 5'b11111;
|
||||
bitarray[8][1] = 5'b10001;
|
||||
bitarray[8][2] = 5'b11111;
|
||||
bitarray[8][3] = 5'b10001;
|
||||
bitarray[8][4] = 5'b11111;
|
||||
|
||||
bitarray[9][0] = 5'b11111;
|
||||
bitarray[9][1] = 5'b10001;
|
||||
bitarray[9][2] = 5'b11111;
|
||||
bitarray[9][3] = 5'b00001;
|
||||
bitarray[9][4] = 5'b11111;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module test_numbers_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 [3:0] digit = hpos[6:3];
|
||||
wire [2:0] yofs = vpos[2:0];
|
||||
wire [4:0] bits;
|
||||
|
||||
digits10_array numbers(
|
||||
.digit(digit),
|
||||
.yofs(yofs),
|
||||
.bits(bits)
|
||||
);
|
||||
|
||||
wire r = display_on && 0;
|
||||
wire g = display_on && bits[hpos[2:0] ^ 3'b111];
|
||||
wire b = display_on && 0;
|
||||
assign rgb = {b,g,r};
|
||||
|
||||
endmodule
|
@ -1,3 +1,5 @@
|
||||
`ifndef HVSYNC_GENERATOR_H
|
||||
`define HVSYNC_GENERATOR_H
|
||||
|
||||
module hvsync_generator(
|
||||
clk, hsync, vsync, display_on, hpos, vpos);
|
||||
@ -57,3 +59,5 @@ module hvsync_generator(
|
||||
assign vsync = ~vga_VS;
|
||||
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
@ -5,6 +5,7 @@ var VERILOG_PRESETS = [
|
||||
{id:'hvsync_generator.v', name:'Video Sync Generator'},
|
||||
{id:'test_hvsync.v', name:'Test Pattern'},
|
||||
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
|
||||
{id:'digits10.v', name:'Digits'},
|
||||
{id:'ball_slip_counter.v', name:'Ball Motion (slipping counter)'},
|
||||
{id:'ball_paddle.v', name:'Brick Smash Game'},
|
||||
//{id:'pong.v', name:'Pong'},
|
||||
@ -69,6 +70,8 @@ function VerilatorBase() {
|
||||
|
||||
this.reset2 = function() {
|
||||
if (this.reset !== undefined) {
|
||||
this.reset = 0;
|
||||
this.tick2();
|
||||
this.reset = 1;
|
||||
for (var i=0; i<RESET_TICKS; i++)
|
||||
this.tick2();
|
||||
|
@ -18,11 +18,22 @@ function parseDecls(text, arr, name, bin, bout) {
|
||||
arr.push({
|
||||
wordlen:parseInt(m[1]),
|
||||
name:m[2],
|
||||
arrlen:parseInt(m[3]),
|
||||
arrdim:[parseInt(m[3])],
|
||||
len:parseInt(m[4]),
|
||||
ofs:parseInt(m[5]),
|
||||
});
|
||||
}
|
||||
re = new RegExp(name + "(\\d+)[(](\\w+)\\[(\\d+)\\]\\[(\\d+)\\],(\\d+),(\\d+)[)]", 'gm');
|
||||
var m;
|
||||
while ((m = re.exec(text))) {
|
||||
arr.push({
|
||||
wordlen:parseInt(m[1]),
|
||||
name:m[2],
|
||||
arrdim:[parseInt(m[3]), parseInt(m[4])],
|
||||
len:parseInt(m[5]),
|
||||
ofs:parseInt(m[6]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buildModule(o) {
|
||||
@ -33,10 +44,17 @@ function buildModule(o) {
|
||||
m += "\tself." + o.ports[i].name + ";\n";
|
||||
}
|
||||
for (var i=0; i<o.signals.length; i++) {
|
||||
if (o.signals[i].arrlen)
|
||||
m += "\tvar " + o.signals[i].name + " = self." + o.signals[i].name + " = [];\n";
|
||||
else
|
||||
m += "\tself." + o.signals[i].name + ";\n";
|
||||
var sig = o.signals[i];
|
||||
if (sig.arrdim) {
|
||||
if (sig.arrdim.length == 1) {
|
||||
m += "\tvar " + sig.name + " = self." + sig.name + " = [];\n";
|
||||
} else if (sig.arrdim.length == 2) {
|
||||
m += "\tvar " + sig.name + " = self." + sig.name + " = [];\n";
|
||||
m += "\tfor(var i=0; i<" + sig.arrdim[0] + "; i++) { " + sig.name + "[i] = []; }\n";
|
||||
}
|
||||
} else {
|
||||
m += "\tself." + sig.name + ";\n";
|
||||
}
|
||||
}
|
||||
for (var i=0; i<o.funcs.length; i++) {
|
||||
m += o.funcs[i];
|
||||
@ -56,9 +74,9 @@ function translateFunction(text) {
|
||||
text = text.replace(/[(]IData[)]/g, '');
|
||||
text = text.replace(/\b(0x[0-9a-f]+)U/gi, '$1');
|
||||
text = text.replace(/\b([0-9]+)U/gi, '$1');
|
||||
text = text.replace(/\bQData /, 'var ');
|
||||
text = text.replace(/\bbool /, '');
|
||||
text = text.replace(/\bint /, 'var ');
|
||||
text = text.replace(/\bQData /g, 'var ');
|
||||
text = text.replace(/\bbool /g, '');
|
||||
text = text.replace(/\bint /g, 'var ');
|
||||
text = text.replace(/(\w+ = VL_RAND_RESET_I)/g, 'self.$1');
|
||||
//text = text.replace(/(\w+\[\w+\] = VL_RAND_RESET_I)/g, 'self.$1');
|
||||
text = text.replace(/^#/gm, '//#');
|
||||
|
@ -1058,7 +1058,9 @@ function compileVerilator(code, platform, options) {
|
||||
FS.writeFile(topmod+".v", code);
|
||||
writeDependencies(options.dependencies, FS, errors);
|
||||
starttime();
|
||||
verilator_mod.callMain(["--cc", "-O3", "--x-assign", "fast", "--noassert", "--pins-bv", "33",
|
||||
verilator_mod.callMain(["--cc", "-O3",
|
||||
"-Wall", "-Wno-DECLFILENAME", "-Wno-UNUSED",
|
||||
"--x-assign", "fast", "--noassert", "--pins-bv", "33",
|
||||
"--top-module", topmod, topmod+".v"]);
|
||||
endtime("compile");
|
||||
if (errors.length) return {errors:errors};
|
||||
|
Loading…
Reference in New Issue
Block a user