From bf2250310b101bf3d85f46653c932eb17a7e6fd9 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 12 Nov 2018 14:13:17 -0500 Subject: [PATCH] moved fpga examples to https://github.com/sehugg/fpga-examples; new framebuffer.v --- doc/notes.txt | 1 + fpga/examples/.gitignore | 6 - fpga/examples/Makefile | 22 - fpga/examples/ball_paddle.v | 250 --- fpga/examples/blktest.v | 80 - fpga/examples/cp437.hex | 2048 ---------------------- fpga/examples/cpu8.v | 232 --- fpga/examples/crttest.v | 52 - fpga/examples/digits10.v | 207 --- fpga/examples/font_cp437_8x8.v | 21 - fpga/examples/hvsync_generator.v | 69 - fpga/examples/icestick.pcf | 16 - fpga/examples/lfsr.v | 31 - fpga/examples/racing.asm | 111 -- fpga/examples/racing.hex | 128 -- fpga/examples/racing_game.v | 158 -- fpga/examples/racing_game_cpu.v | 169 -- fpga/examples/ram.v | 80 - fpga/examples/scoreboard.v | 114 -- fpga/examples/sprite_bitmap.v | 44 - fpga/examples/sprite_renderer.v | 97 - fpga/examples/sprite_rotation.v | 353 ---- fpga/examples/sprite_scanline_renderer.v | 183 -- fpga/examples/spritetest.v | 77 - fpga/examples/starfield.v | 47 - fpga/examples/test.vlog | 34 - fpga/examples/test_hvsync.v | 32 - fpga/examples/tile_renderer.v | 89 - fpga/examples/tiletest.v | 68 - presets/verilog/framebuffer.v | 108 +- 30 files changed, 35 insertions(+), 4892 deletions(-) delete mode 100644 fpga/examples/.gitignore delete mode 100644 fpga/examples/Makefile delete mode 100644 fpga/examples/ball_paddle.v delete mode 100644 fpga/examples/blktest.v delete mode 100644 fpga/examples/cp437.hex delete mode 100644 fpga/examples/cpu8.v delete mode 100644 fpga/examples/crttest.v delete mode 100644 fpga/examples/digits10.v delete mode 100644 fpga/examples/font_cp437_8x8.v delete mode 100644 fpga/examples/hvsync_generator.v delete mode 100644 fpga/examples/icestick.pcf delete mode 100644 fpga/examples/lfsr.v delete mode 100644 fpga/examples/racing.asm delete mode 100644 fpga/examples/racing.hex delete mode 100644 fpga/examples/racing_game.v delete mode 100644 fpga/examples/racing_game_cpu.v delete mode 100644 fpga/examples/ram.v delete mode 100644 fpga/examples/scoreboard.v delete mode 100644 fpga/examples/sprite_bitmap.v delete mode 100644 fpga/examples/sprite_renderer.v delete mode 100644 fpga/examples/sprite_rotation.v delete mode 100644 fpga/examples/sprite_scanline_renderer.v delete mode 100644 fpga/examples/spritetest.v delete mode 100644 fpga/examples/starfield.v delete mode 100644 fpga/examples/test.vlog delete mode 100644 fpga/examples/test_hvsync.v delete mode 100644 fpga/examples/tile_renderer.v delete mode 100644 fpga/examples/tiletest.v diff --git a/doc/notes.txt b/doc/notes.txt index bce89dbe..e6298069 100644 --- a/doc/notes.txt +++ b/doc/notes.txt @@ -74,6 +74,7 @@ TODO: - update bootstrap/jquery - clean BOM from verilog - $readmemb/h +- maybe don't have grey space with line numbers until inline ASM used? WEB WORKER FORMAT diff --git a/fpga/examples/.gitignore b/fpga/examples/.gitignore deleted file mode 100644 index e48fc88a..00000000 --- a/fpga/examples/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.asc -*.bin -*.blif -*.log -*.out -*.vcd diff --git a/fpga/examples/Makefile b/fpga/examples/Makefile deleted file mode 100644 index a0c901c4..00000000 --- a/fpga/examples/Makefile +++ /dev/null @@ -1,22 +0,0 @@ - -%.asc: %.v icestick.pcf - yosys -p "synth_ice40 -blif $*.blif" $*.v | tee $*.log - arachne-pnr -d 1k -p icestick.pcf $*.blif -o $*.asc - -%.bin: %.asc - icetime -c 12 -d hx1k $*.asc - icepack $*.asc $*.bin - -%.prog: %.bin - iceprog $< - -%.hex: %.asm - node ../../src/tools/jsasm.js < $< > $@ - -%.vlog: %.asc - icebox_vlog $*.asc > $*.vlog - -%.vcd: %.vlog test.vlog - iverilog -o $*.out -v /usr/share/yosys/ice40/cells_sim.v $< test.vlog - vvp $*.out - diff --git a/fpga/examples/ball_paddle.v b/fpga/examples/ball_paddle.v deleted file mode 100644 index 5c812a50..00000000 --- a/fpga/examples/ball_paddle.v +++ /dev/null @@ -1,250 +0,0 @@ - -`include "hvsync_generator.v" -`include "digits10.v" -`include "scoreboard.v" - -/* -A brick-smashing ball-and-paddle game. -*/ - -module ball_paddle_top(clk, reset, hpaddle, out); - - input clk; - input reset; - input hpaddle; - wire hsync, vsync; - output [1:0] out; - - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - reg [8:0] paddle_pos; // paddle X position - - reg [8:0] ball_x; // ball X position - reg [8:0] ball_y; // ball Y position - reg ball_dir_x; // ball X direction (0=left, 1=right) - reg ball_speed_x; // ball speed (0=1 pixel/frame, 1=2 pixels/frame) - reg ball_dir_y; // ball Y direction (0=up, 1=down) - - reg brick_array [0:BRICKS_H*BRICKS_V-1]; // 16*8 = 128 bits - - wire [3:0] score0; // score right digit - wire [3:0] score1; // score left digit - wire [3:0] lives; // # lives remaining - reg incscore; // incscore signal - reg declives = 0; // TODO - - localparam BRICKS_H = 16; // # of bricks across - localparam BRICKS_V = 8; // # of bricks down - - localparam BALL_DIR_LEFT = 0; - localparam BALL_DIR_RIGHT = 1; - localparam BALL_DIR_DOWN = 1; - localparam BALL_DIR_UP = 0; - - localparam PADDLE_WIDTH = 31; // horizontal paddle size - localparam BALL_SIZE = 6; // square ball size - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - // scoreboard - wire score_gfx; // output from score generator - player_stats stats( - .reset(reset), - .score0(score0), - .score1(score1), - .incscore(incscore), - .lives(lives), - .declives(declives) - ); - - scoreboard_generator score_gen( - .score0(score0), - .score1(score1), - .lives(lives), - .vpos(vpos), - .hpos(hpos), - .board_gfx(score_gfx) - ); - - wire [5:0] hcell = hpos[8:3]; // horizontal brick index - wire [5:0] vcell = vpos[8:3]; // vertical brick index - wire lr_border = hcell==0 || hcell==31; // along horizontal border? - - // TODO: unsigned compare doesn't work in JS - wire [8:0] paddle_rel_x = ((hpos-paddle_pos) & 9'h1ff); - - // player paddle graphics signal - wire paddle_gfx = (vcell == 28) && (paddle_rel_x < PADDLE_WIDTH); - - // difference between ball position and video beam - wire [8:0] ball_rel_x = (hpos - ball_x); - wire [8:0] ball_rel_y = (vpos - ball_y); - - // ball graphics signal - wire ball_gfx = ball_rel_x < BALL_SIZE - && ball_rel_y < BALL_SIZE; - - reg main_gfx; // main graphics signal (bricks and borders) - reg brick_present; // 1 when we are drawing a brick - reg [6:0] brick_index;// index into array of current brick - // brick graphics signal - wire brick_gfx = lr_border || (brick_present && vpos[2:0] != 0 && hpos[3:1] != 4); - - // scan bricks: compute brick_index and brick_present flag - always @(posedge clk2) - // see if we are scanning brick area - if (vpos[8:6] == 1 && !lr_border) - begin - // every 16th pixel, starting at 8 - if (hpos[3:0] == 8) begin - // compute brick index - brick_index <= {vpos[5:3], hpos[7:4]}; - end - // every 17th pixel - else if (hpos[3:0] == 9) begin - // load brick bit from array - brick_present <= !brick_array[brick_index]; - end - end else begin - brick_present <= 0; - 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; - - // 1 when ball signal intersects main (brick + border) signal - wire ball_pixel_collide = main_gfx & ball_gfx; - - reg ball_collide_paddle = 0; - reg [3:0] ball_collide_bits = 0; - - // compute ball collisions with paddle and playfield - always @(posedge clk2) - // clear all collide bits for frame - if (vsync) begin - ball_collide_bits <= 0; - ball_collide_paddle <= 0; - end else begin - if (ball_pixel_collide) begin - // did we collide w/ paddle? - if (paddle_gfx) begin - ball_collide_paddle <= 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 - end - - // compute ball collisions with brick and increment score - always @(posedge clk2) - if (ball_pixel_collide && brick_present) begin - brick_array[brick_index] <= 1; - incscore <= 1; // increment score - end else begin - incscore <= 0; // reset incscore - end - - // computes position of ball in relation to center of paddle - wire signed [8:0] ball_paddle_dx = ball_x - paddle_pos + 8; - - // ball bounce: determine new velocity/direction - always @(posedge vsync or posedge reset) - begin - if (reset) begin - ball_dir_y <= BALL_DIR_DOWN; - end else - // ball collided with paddle? - if (ball_collide_paddle) begin - // bounces upward off of paddle - ball_dir_y <= BALL_DIR_UP; - // which side of paddle, left/right? - ball_dir_x <= (ball_paddle_dx < 20) ? BALL_DIR_LEFT : BALL_DIR_RIGHT; - // hitting with edge of paddle makes it fast - ball_speed_x <= ball_collide_bits[3:0] != 4'b1100; - 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 - 4'b101?: ball_dir_x <= BALL_DIR_LEFT; // right edge/corner - 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; - 4'b001?: ball_dir_y <= BALL_DIR_DOWN; - 4'b0001: ball_dir_y <= BALL_DIR_DOWN; - 4'b0100: ball_dir_y <= BALL_DIR_UP; - 4'b1?00: ball_dir_y <= BALL_DIR_UP; - 4'b1101: ball_dir_y <= BALL_DIR_UP; - 4'b1110: ball_dir_y <= BALL_DIR_UP; - default: ; - endcase - end - end - - // ball motion: update ball position - always @(negedge vsync or posedge reset) - begin - if (reset) begin - // reset ball position to top center - ball_x <= 128; - ball_y <= 180; - end else begin - // move ball horizontal and vertical position - if (ball_dir_x == BALL_DIR_RIGHT) - ball_x <= ball_x + (ball_speed_x?1:0) + 1; - else - ball_x <= ball_x - (ball_speed_x?1:0) - 1; - ball_y <= ball_y + (ball_dir_y==BALL_DIR_DOWN?1:-1); - end - end - - // compute main_gfx - always @(*) - begin - case (vpos[8:3]) - 0,1,2: main_gfx = score_gfx; // scoreboard - 3: main_gfx = 0; - 4: main_gfx = 1; // top border - 8,9,10,11,12,13,14,15: main_gfx = brick_gfx; // brick rows 1-8 - 28: main_gfx = paddle_gfx | lr_border; // paddle - 29: main_gfx = hpos[0] ^ vpos[0]; // bottom border - default: main_gfx = lr_border; // left/right borders - endcase - end - - // combine signals to RGB output - wire r = display_on && (ball_gfx | paddle_gfx); - wire g = display_on && (main_gfx | ball_gfx); - wire b = display_on && (ball_gfx | brick_present); - - assign out = (hsync||vsync) ? 0 : (1+g+(r|b)); - -endmodule - diff --git a/fpga/examples/blktest.v b/fpga/examples/blktest.v deleted file mode 100644 index 4b40b0bc..00000000 --- a/fpga/examples/blktest.v +++ /dev/null @@ -1,80 +0,0 @@ - -`include "hvsync_generator.v" -`include "digits10.v" -`include "ram.v" -`include "lfsr.v" - -module test_ram2_top( - input clk, reset, - output [1:0] out -); - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - reg ram_writeenable = 0; - wire [9:0] ram_addr = {row,col}; - reg [7:0] ram_write; - reg [7:0] ram_read; - reg [7:0] ram_write; - reg [7:0] rand; - - reg clk2; - - always @(posedge clk) begin - clk2 <= !clk2; - end - - RAM_sync ram( - .clk(clk2), - .din(ram_write), - .dout(ram_read), - .addr(ram_addr), - .we(ram_writeenable) - ); - - LFSR lfsr( - .clk(clk2), - .reset(reset), - .enable(!reset), - .lfsr(rand) - ); - - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - wire [4:0] row = vpos[7:3]; - wire [4:0] col = hpos[7:3]; - wire [3:0] digit = ram_read[3:0]; - wire [2:0] xofs = hpos[2:0]; - wire [2:0] yofs = vpos[2:0]; - wire [7:0] bits; // TODO? - - digits10_case numbers( - .digit(digit), - .yofs(yofs), - .bits(bits) - ); - - wire g = display_on && bits[xofs ^ 3'b111]; - - assign out = (hsync||vsync) ? 0 : (1+g+g); - - always @(posedge clk2) - if (display_on && vpos[2:0] == 7 && rand[0]) - case (hpos[2:0]) - 6: begin - ram_write <= ram_read + 1; - ram_writeenable <= 1; - end - 7: ram_writeenable <= 0; - endcase - -endmodule diff --git a/fpga/examples/cp437.hex b/fpga/examples/cp437.hex deleted file mode 100644 index 5353e78e..00000000 --- a/fpga/examples/cp437.hex +++ /dev/null @@ -1,2048 +0,0 @@ -00 -00 -00 -00 -00 -00 -00 -00 //0 -7e -81 -a5 -81 -bd -99 -81 -7e //1 -7e -ff -db -ff -c3 -e7 -ff -7e //2 -6c -fe -fe -fe -7c -38 -10 -00 //3 -10 -38 -7c -fe -7c -38 -10 -00 //4 -38 -7c -38 -fe -fe -d6 -10 -38 //5 -10 -10 -38 -7c -fe -7c -10 -38 //6 -00 -00 -18 -3c -3c -18 -00 -00 //7 -ff -ff -e7 -c3 -c3 -e7 -ff -ff //8 -00 -3c -66 -42 -42 -66 -3c -00 //9 -ff -c3 -99 -bd -bd -99 -c3 -ff //10 -0f -07 -0f -7d -cc -cc -cc -78 //11 -3c -66 -66 -66 -3c -18 -7e -18 //12 -3f -33 -3f -30 -30 -70 -f0 -e0 //13 -7f -63 -7f -63 -63 -67 -e6 -c0 //14 -99 -5a -3c -e7 -e7 -3c -5a -99 //15 -80 -e0 -f8 -fe -f8 -e0 -80 -00 //16 -02 -0e -3e -fe -3e -0e -02 -00 //17 -18 -3c -7e -18 -18 -7e -3c -18 //18 -66 -66 -66 -66 -66 -00 -66 -00 //19 -7f -db -db -7b -1b -1b -1b -00 //20 -7e -c3 -78 -cc -cc -78 -8c -f8 //21 -00 -00 -00 -00 -7e -7e -7e -00 //22 -18 -3c -7e -18 -7e -3c -18 -ff //23 -18 -3c -7e -18 -18 -18 -18 -00 //24 -18 -18 -18 -18 -7e -3c -18 -00 //25 -00 -18 -0c -fe -0c -18 -00 -00 //26 -00 -30 -60 -fe -60 -30 -00 -00 //27 -00 -00 -c0 -c0 -c0 -fe -00 -00 //28 -00 -24 -66 -ff -66 -24 -00 -00 //29 -00 -18 -3c -7e -ff -ff -00 -00 //30 -00 -ff -ff -7e -3c -18 -00 -00 //31 -00 -00 -00 -00 -00 -00 -00 -00 //32 -30 -78 -78 -30 -30 -00 -30 -00 //33 -6c -6c -6c -00 -00 -00 -00 -00 //34 -6c -6c -fe -6c -fe -6c -6c -00 //35 -30 -7c -c0 -78 -0c -f8 -30 -00 //36 -00 -c6 -cc -18 -30 -66 -c6 -00 //37 -38 -6c -38 -76 -dc -cc -76 -00 //38 -60 -60 -c0 -00 -00 -00 -00 -00 //39 -18 -30 -60 -60 -60 -30 -18 -00 //40 -60 -30 -18 -18 -18 -30 -60 -00 //41 -00 -66 -3c -ff -3c -66 -00 -00 //42 -00 -30 -30 -fc -30 -30 -00 -00 //43 -00 -00 -00 -00 -00 -70 -30 -60 //44 -00 -00 -00 -fc -00 -00 -00 -00 //45 -00 -00 -00 -00 -00 -30 -30 -00 //46 -06 -0c -18 -30 -60 -c0 -80 -00 //47 -78 -cc -dc -fc -ec -cc -78 -00 //48 -30 -f0 -30 -30 -30 -30 -fc -00 //49 -78 -cc -0c -38 -60 -cc -fc -00 //50 -78 -cc -0c -38 -0c -cc -78 -00 //51 -1c -3c -6c -cc -fe -0c -0c -00 //52 -fc -c0 -f8 -0c -0c -cc -78 -00 //53 -38 -60 -c0 -f8 -cc -cc -78 -00 //54 -fc -cc -0c -18 -30 -60 -60 -00 //55 -78 -cc -cc -78 -cc -cc -78 -00 //56 -78 -cc -cc -7c -0c -18 -70 -00 //57 -00 -00 -30 -30 -00 -30 -30 -00 //58 -00 -00 -30 -30 -00 -70 -30 -60 //59 -18 -30 -60 -c0 -60 -30 -18 -00 //60 -00 -00 -fc -00 -fc -00 -00 -00 //61 -60 -30 -18 -0c -18 -30 -60 -00 //62 -78 -cc -0c -18 -30 -00 -30 -00 //63 -7c -c6 -de -de -de -c0 -78 -00 //64 -30 -78 -cc -cc -fc -cc -cc -00 //65 -fc -66 -66 -7c -66 -66 -fc -00 //66 -3c -66 -c0 -c0 -c0 -66 -3c -00 //67 -fc -6c -66 -66 -66 -6c -fc -00 //68 -fe -62 -68 -78 -68 -62 -fe -00 //69 -fe -62 -68 -78 -68 -60 -f0 -00 //70 -3c -66 -c0 -c0 -ce -66 -3e -00 //71 -cc -cc -cc -fc -cc -cc -cc -00 //72 -78 -30 -30 -30 -30 -30 -78 -00 //73 -1e -0c -0c -0c -cc -cc -78 -00 //74 -e6 -66 -6c -78 -6c -66 -e6 -00 //75 -f0 -60 -60 -60 -62 -66 -fe -00 //76 -c6 -ee -fe -d6 -c6 -c6 -c6 -00 //77 -c6 -e6 -f6 -de -ce -c6 -c6 -00 //78 -38 -6c -c6 -c6 -c6 -6c -38 -00 //79 -fc -66 -66 -7c -60 -60 -f0 -00 //80 -78 -cc -cc -cc -dc -78 -1c -00 //81 -fc -66 -66 -7c -78 -6c -e6 -00 //82 -78 -cc -e0 -38 -1c -cc -78 -00 //83 -fc -b4 -30 -30 -30 -30 -78 -00 //84 -cc -cc -cc -cc -cc -cc -fc -00 //85 -cc -cc -cc -cc -cc -78 -30 -00 //86 -c6 -c6 -c6 -d6 -fe -ee -c6 -00 //87 -c6 -c6 -6c -38 -6c -c6 -c6 -00 //88 -cc -cc -cc -78 -30 -30 -78 -00 //89 -fe -cc -98 -30 -62 -c6 -fe -00 //90 -78 -60 -60 -60 -60 -60 -78 -00 //91 -c0 -60 -30 -18 -0c -06 -02 -00 //92 -78 -18 -18 -18 -18 -18 -78 -00 //93 -10 -38 -6c -c6 -00 -00 -00 -00 //94 -00 -00 -00 -00 -00 -00 -00 -ff //95 -30 -30 -18 -00 -00 -00 -00 -00 //96 -00 -00 -78 -0c -7c -cc -76 -00 //97 -e0 -60 -7c -66 -66 -66 -bc -00 //98 -00 -00 -78 -cc -c0 -cc -78 -00 //99 -1c -0c -0c -7c -cc -cc -76 -00 //100 -00 -00 -78 -cc -fc -c0 -78 -00 //101 -38 -6c -60 -f0 -60 -60 -f0 -00 //102 -00 -00 -76 -cc -cc -7c -0c -f8 //103 -e0 -60 -6c -76 -66 -66 -e6 -00 //104 -30 -00 -70 -30 -30 -30 -78 -00 //105 -18 -00 -78 -18 -18 -18 -d8 -70 //106 -e0 -60 -66 -6c -78 -6c -e6 -00 //107 -70 -30 -30 -30 -30 -30 -78 -00 //108 -00 -00 -ec -fe -d6 -c6 -c6 -00 //109 -00 -00 -f8 -cc -cc -cc -cc -00 //110 -00 -00 -78 -cc -cc -cc -78 -00 //111 -00 -00 -dc -66 -66 -7c -60 -f0 //112 -00 -00 -76 -cc -cc -7c -0c -1e //113 -00 -00 -d8 -6c -6c -60 -f0 -00 //114 -00 -00 -7c -c0 -78 -0c -f8 -00 //115 -10 -30 -7c -30 -30 -34 -18 -00 //116 -00 -00 -cc -cc -cc -cc -76 -00 //117 -00 -00 -cc -cc -cc -78 -30 -00 //118 -00 -00 -c6 -c6 -d6 -fe -6c -00 //119 -00 -00 -c6 -6c -38 -6c -c6 -00 //120 -00 -00 -cc -cc -cc -7c -0c -f8 //121 -00 -00 -fc -98 -30 -64 -fc -00 //122 -1c -30 -30 -e0 -30 -30 -1c -00 //123 -18 -18 -18 -00 -18 -18 -18 -00 //124 -e0 -30 -30 -1c -30 -30 -e0 -00 //125 -76 -dc -00 -00 -00 -00 -00 -00 //126 -10 -38 -6c -c6 -c6 -c6 -fe -00 //127 -78 -cc -c0 -cc -78 -18 -0c -78 //128 -00 -cc -00 -cc -cc -cc -7e -00 //129 -1c -00 -78 -cc -fc -c0 -78 -00 //130 -7e -c3 -3c -06 -3e -66 -3f -00 //131 -cc -00 -78 -0c -7c -cc -7e -00 //132 -e0 -00 -78 -0c -7c -cc -7e -00 //133 -30 -30 -78 -0c -7c -cc -7e -00 //134 -00 -00 -7c -c0 -c0 -7c -06 -3c //135 -7e -c3 -3c -66 -7e -60 -3c -00 //136 -cc -00 -78 -cc -fc -c0 -78 -00 //137 -e0 -00 -78 -cc -fc -c0 -78 -00 //138 -cc -00 -70 -30 -30 -30 -78 -00 //139 -7c -c6 -38 -18 -18 -18 -3c -00 //140 -e0 -00 -70 -30 -30 -30 -78 -00 //141 -cc -30 -78 -cc -cc -fc -cc -00 //142 -30 -30 -00 -78 -cc -fc -cc -00 //143 -1c -00 -fc -60 -78 -60 -fc -00 //144 -00 -00 -7f -0c -7f -cc -7f -00 //145 -3e -6c -cc -fe -cc -cc -ce -00 //146 -78 -cc -00 -78 -cc -cc -78 -00 //147 -00 -cc -00 -78 -cc -cc -78 -00 //148 -00 -e0 -00 -78 -cc -cc -78 -00 //149 -78 -cc -00 -cc -cc -cc -7e -00 //150 -00 -e0 -00 -cc -cc -cc -7e -00 //151 -00 -cc -00 -cc -cc -fc -0c -f8 //152 -c6 -38 -7c -c6 -c6 -7c -38 -00 //153 -cc -00 -cc -cc -cc -cc -78 -00 //154 -18 -18 -7e -c0 -c0 -7e -18 -18 //155 -38 -6c -64 -f0 -60 -e6 -fc -00 //156 -cc -cc -78 -fc -30 -fc -30 -00 //157 -f0 -d8 -d8 -f4 -cc -de -cc -0e //158 -0e -1b -18 -7e -18 -18 -d8 -70 //159 -1c -00 -78 -0c -7c -cc -7e -00 //160 -38 -00 -70 -30 -30 -30 -78 -00 //161 -00 -1c -00 -78 -cc -cc -78 -00 //162 -00 -1c -00 -cc -cc -cc -7e -00 //163 -00 -f8 -00 -f8 -cc -cc -cc -00 //164 -fc -00 -cc -ec -fc -dc -cc -00 //165 -3c -6c -6c -3e -00 -7e -00 -00 //166 -3c -66 -66 -3c -00 -7e -00 -00 //167 -30 -00 -30 -60 -c0 -cc -78 -00 //168 -00 -00 -00 -fc -c0 -c0 -00 -00 //169 -00 -00 -00 -fc -0c -0c -00 -00 //170 -c6 -cc -d8 -3e -63 -ce -98 -1f //171 -c6 -cc -d8 -f3 -67 -cf -9f -03 //172 -00 -18 -00 -18 -18 -3c -3c -18 //173 -00 -33 -66 -cc -66 -33 -00 -00 //174 -00 -cc -66 -33 -66 -cc -00 -00 //175 -22 -88 -22 -88 -22 -88 -22 -88 //176 -55 -aa -55 -aa -55 -aa -55 -aa //177 -dd -77 -dd -77 -dd -77 -dd -77 //178 -18 -18 -18 -18 -18 -18 -18 -18 //179 -18 -18 -18 -18 -f8 -18 -18 -18 //180 -18 -18 -f8 -18 -f8 -18 -18 -18 //181 -36 -36 -36 -36 -f6 -36 -36 -36 //182 -00 -00 -00 -00 -fe -36 -36 -36 //183 -00 -00 -f8 -18 -f8 -18 -18 -18 //184 -36 -36 -f6 -06 -f6 -36 -36 -36 //185 -36 -36 -36 -36 -36 -36 -36 -36 //186 -00 -00 -fe -06 -f6 -36 -36 -36 //187 -36 -36 -f6 -06 -fe -00 -00 -00 //188 -36 -36 -36 -36 -fe -00 -00 -00 //189 -18 -18 -f8 -18 -f8 -00 -00 -00 //190 -00 -00 -00 -00 -f8 -18 -18 -18 //191 -18 -18 -18 -18 -1f -00 -00 -00 //192 -18 -18 -18 -18 -ff -00 -00 -00 //193 -00 -00 -00 -00 -ff -18 -18 -18 //194 -18 -18 -18 -18 -1f -18 -18 -18 //195 -00 -00 -00 -00 -ff -00 -00 -00 //196 -18 -18 -18 -18 -ff -18 -18 -18 //197 -18 -18 -1f -18 -1f -18 -18 -18 //198 -36 -36 -36 -36 -37 -36 -36 -36 //199 -36 -36 -37 -30 -3f -00 -00 -00 //200 -00 -00 -3f -30 -37 -36 -36 -36 //201 -36 -36 -f7 -00 -ff -00 -00 -00 //202 -00 -00 -ff -00 -f7 -36 -36 -36 //203 -36 -36 -37 -30 -37 -36 -36 -36 //204 -00 -00 -ff -00 -ff -00 -00 -00 //205 -36 -36 -f7 -00 -f7 -36 -36 -36 //206 -18 -18 -ff -00 -ff -00 -00 -00 //207 -36 -36 -36 -36 -ff -00 -00 -00 //208 -00 -00 -ff -00 -ff -18 -18 -18 //209 -00 -00 -00 -00 -ff -36 -36 -36 //210 -36 -36 -36 -36 -3f -00 -00 -00 //211 -18 -18 -1f -18 -1f -00 -00 -00 //212 -00 -00 -1f -18 -1f -18 -18 -18 //213 -00 -00 -00 -00 -3f -36 -36 -36 //214 -36 -36 -36 -36 -f7 -36 -36 -36 //215 -18 -18 -ff -00 -ff -18 -18 -18 //216 -18 -18 -18 -18 -f8 -00 -00 -00 //217 -00 -00 -00 -00 -1f -18 -18 -18 //218 -ff -ff -ff -ff -ff -ff -ff -ff //219 -00 -00 -00 -00 -ff -ff -ff -ff //220 -f0 -f0 -f0 -f0 -f0 -f0 -f0 -f0 //221 -0f -0f -0f -0f -0f -0f -0f -0f //222 -ff -ff -ff -ff -00 -00 -00 -00 //223 -00 -00 -76 -dc -c8 -dc -76 -00 //224 -00 -78 -cc -f8 -cc -f8 -c0 -c0 //225 -00 -fe -c6 -c0 -c0 -c0 -c0 -00 //226 -00 -fe -6c -6c -6c -6c -6c -00 //227 -fe -66 -30 -18 -30 -66 -fe -00 //228 -00 -00 -7e -cc -cc -cc -78 -00 //229 -00 -66 -66 -66 -66 -7c -60 -c0 //230 -00 -76 -dc -18 -18 -18 -18 -00 //231 -fc -30 -78 -cc -cc -78 -30 -fc //232 -38 -6c -c6 -fe -c6 -6c -38 -00 //233 -38 -6c -c6 -c6 -6c -6c -ee -00 //234 -1c -30 -18 -7c -cc -cc -78 -00 //235 -00 -00 -7e -db -db -7e -00 -00 //236 -06 -0c -7e -db -db -7e -60 -c0 //237 -3c -60 -c0 -fc -c0 -60 -3c -00 //238 -78 -cc -cc -cc -cc -cc -cc -00 //239 -00 -fc -00 -fc -00 -fc -00 -00 //240 -30 -30 -fc -30 -30 -00 -fc -00 //241 -60 -30 -18 -30 -60 -00 -fc -00 //242 -18 -30 -60 -30 -18 -00 -fc -00 //243 -0e -1b -1b -18 -18 -18 -18 -18 //244 -18 -18 -18 -18 -18 -d8 -d8 -70 //245 -30 -30 -00 -fc -00 -30 -30 -00 //246 -00 -72 -9c -00 -72 -9c -00 -00 //247 -38 -6c -6c -38 -00 -00 -00 -00 //248 -00 -00 -00 -18 -18 -00 -00 -00 //249 -00 -00 -00 -00 -18 -00 -00 -00 //250 -0f -0c -0c -0c -ec -6c -3c -1c //251 -78 -6c -6c -6c -6c -00 -00 -00 //252 -78 -0c -38 -60 -7c -00 -00 -00 //253 -00 -00 -3c -3c -3c -3c -00 -00 //254 -00 -00 -00 -00 -00 -00 -00 -00 //255 diff --git a/fpga/examples/cpu8.v b/fpga/examples/cpu8.v deleted file mode 100644 index 27dd2d2c..00000000 --- a/fpga/examples/cpu8.v +++ /dev/null @@ -1,232 +0,0 @@ - -`ifndef ALU_H -`define ALU_H - -// ALU operations -`define OP_ZERO 4'h0 -`define OP_LOAD_A 4'h1 -`define OP_INC 4'h2 -`define OP_DEC 4'h3 -`define OP_ASL 4'h4 -`define OP_LSR 4'h5 -`define OP_ROL 4'h6 -`define OP_ROR 4'h7 -`define OP_OR 4'h8 -`define OP_AND 4'h9 -`define OP_XOR 4'ha -`define OP_LOAD_B 4'hb -`define OP_ADD 4'hc -`define OP_SUB 4'hd -`define OP_ADC 4'he -`define OP_SBB 4'hf - -// ALU module -module ALU(A, B, carry, aluop, Y); - - parameter N = 8; // default width = 8 bits - input [N-1:0] A; // A input - input [N-1:0] B; // B input - input carry; // carry input - input [3:0] aluop; // alu operation - output [N:0] Y; // Y output + carry - - always @(*) - case (aluop) - // unary operations - `OP_ZERO: Y = 0; - `OP_LOAD_A: Y = {1'b0, A}; - `OP_INC: Y = A + 1; - `OP_DEC: Y = A - 1; - // unary operations that generate and/or use carry - `OP_ASL: Y = {A, 1'b0}; - `OP_LSR: Y = {A[0], 1'b0, A[N-1:1]}; - `OP_ROL: Y = {A, carry}; - `OP_ROR: Y = {A[0], carry, A[N-1:1]}; - // binary operations - `OP_OR: Y = {1'b0, A | B}; - `OP_AND: Y = {1'b0, A & B}; - `OP_XOR: Y = {1'b0, A ^ B}; - `OP_LOAD_B: Y = {1'b0, B}; - // binary operations that generate and/or use carry - `OP_ADD: Y = A + B; - `OP_SUB: Y = A - B; - `OP_ADC: Y = A + B + (carry?1:0); - `OP_SBB: Y = A - B - (carry?1:0); - endcase - -endmodule - -/* -Bits Description - -00ddaaaa A @ B -> dest -01ddaaaa A @ immediate -> dest -11ddaaaa A @ read [B] -> dest -10000001 swap A <-> B -1001nnnn A -> write [nnnn] -1010tttt conditional branch - - dd = destination (00=A, 01=B, 10=IP, 11=none) -aaaa = ALU operation (@ operator) -nnnn = 4-bit constant -tttt = flags test for conditional branch -*/ - -// destinations for COMPUTE instructions -`define DEST_A 2'b00 -`define DEST_B 2'b01 -`define DEST_IP 2'b10 -`define DEST_NOP 2'b11 - -// instruction macros -`define I_COMPUTE(dest,op) { 2'b00, (dest), (op) } -`define I_COMPUTE_IMM(dest,op) { 2'b01, (dest), (op) } -`define I_COMPUTE_READB(dest,op) { 2'b11, (dest), (op) } -`define I_CONST_IMM_A { 2'b01, `DEST_A, `OP_LOAD_B } -`define I_CONST_IMM_B { 2'b01, `DEST_B, `OP_LOAD_B } -`define I_JUMP_IMM { 2'b01, `DEST_IP, `OP_LOAD_B } -`define I_STORE_A(addr) { 4'b1001, (addr) } -`define I_BRANCH_IF(zv,zu,cv,cu) { 4'b1010, (zv), (zu), (cv), (cu) } -`define I_CLEAR_CARRY { 8'b10001000 } -`define I_SWAP_AB { 8'b10000001 } -`define I_RESET { 8'b10111111 } -// convenience macros -`define I_ZERO_A `I_COMPUTE(`DEST_A, `OP_ZERO) -`define I_ZERO_B `I_COMPUTE(`DEST_B, `OP_ZERO) -`define I_BRANCH_IF_CARRY(carry) `I_BRANCH_IF(1'b0, 1'b0, carry, 1'b1) -`define I_BRANCH_IF_ZERO(zero) `I_BRANCH_IF(zero, 1'b1, 1'b0, 1'b0) -`define I_CLEAR_ZERO `I_COMPUTE(`DEST_NOP, `OP_ZERO) - -module CPU(clk, reset, address, data_in, data_out, write); - - input clk; - input reset; - output [7:0] address; - input [7:0] data_in; - output [7:0] data_out; - output write; - - reg [7:0] IP; - reg [7:0] A, B; - reg [8:0] Y; - reg [2:0] state; - - reg carry; - reg zero; - wire [1:0] flags = { zero, carry }; - - reg [7:0] opcode; - wire [3:0] aluop = opcode[3:0]; - wire [1:0] opdest = opcode[5:4]; - wire B_or_data = opcode[6]; - - localparam S_RESET = 0; - localparam S_SELECT = 1; - localparam S_DECODE = 2; - localparam S_COMPUTE = 3; - localparam S_READ_IP = 4; - - ALU alu( - .A(A), - .B(B_or_data ? data_in : B), - .Y(Y), - .aluop(aluop), - .carry(carry)); - - always @(posedge clk) - if (reset) begin - state <= 0; - write <= 0; - end else begin - case (state) - // state 0: reset - S_RESET: begin - IP <= 8'h80; - write <= 0; - state <= S_SELECT; - end - // state 1: select opcode address - S_SELECT: begin - address <= IP; - IP <= IP + 1; - write <= 0; - state <= S_DECODE; - end - // state 2: read/decode opcode - S_DECODE: begin - opcode <= data_in; // (only use opcode next cycle) - casez (data_in) - // ALU A + B -> dest - 8'b00??????: begin - state <= S_COMPUTE; - end - // ALU A + immediate -> dest - 8'b01??????: begin - address <= IP; - IP <= IP + 1; - state <= S_COMPUTE; - end - // ALU A + read [B] -> dest - 8'b11??????: begin - address <= B; - state <= S_COMPUTE; - end - // A -> write [nnnn] - 8'b1001????: begin - address <= {4'b0, data_in[3:0]}; - data_out <= A; - write <= 1; - state <= S_SELECT; - end - // swap A,B - 8'b10000001: begin - A <= B; - B <= A; - state <= S_SELECT; - end - // conditional branch - 8'b1010????: begin - if ( - (data_in[0] && (data_in[1] == carry)) || - (data_in[2] && (data_in[3] == zero))) - begin - address <= IP; - state <= S_READ_IP; - end else begin - state <= S_SELECT; - end - IP <= IP + 1; // skip immediate - end - // fall-through RESET - default: begin - state <= S_RESET; // reset - end - endcase - end - // state 3: compute ALU op and flags - S_COMPUTE: begin - // transfer ALU output to destination - case (opdest) - `DEST_A: A <= Y[7:0]; - `DEST_B: B <= Y[7:0]; - `DEST_IP: IP <= Y[7:0]; - `DEST_NOP: ; - endcase - // set carry for certain operations (4-7,12-15) - if (aluop[2]) carry <= Y[8]; - // set zero flag - zero <= ~|Y[7:0]; - // repeat CPU loop - state <= S_SELECT; - end - // state 4: read new IP from memory (immediate mode) - S_READ_IP: begin - IP <= data_in; - state <= S_SELECT; - end - endcase - end - -endmodule - -`endif diff --git a/fpga/examples/crttest.v b/fpga/examples/crttest.v deleted file mode 100644 index 7a328eaf..00000000 --- a/fpga/examples/crttest.v +++ /dev/null @@ -1,52 +0,0 @@ - -`include "hvsync_generator.v" - -/* -A simple test pattern using the hvsync_generator module. - -12000000/15734/2 -381.33977373840091521545 -381-256-23-7 = 95 -*/ - -module test_hvsync_top(clk, reset, out, led); - - input clk, reset; - output [1:0] out; - wire hsync; - wire vsync; - wire [8:0] hpos; - wire [8:0] vpos; - reg [5:0] frame; - output led; - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - wire r = display_on && (((hpos&7)==0) || (((vpos+frame)&7)==0)); - wire g = display_on && vpos[4]; - wire b = display_on && hpos[4]; - - assign out = (hsync||vsync) ? 0 : (1+g+(r|b)); - - always @(posedge vsync) begin - frame <= frame + 1; - end - - assign led = frame[5]; - -endmodule - -// TODO: PWM grey scales diff --git a/fpga/examples/digits10.v b/fpga/examples/digits10.v deleted file mode 100644 index 60f2bf1f..00000000 --- a/fpga/examples/digits10.v +++ /dev/null @@ -1,207 +0,0 @@ - -`ifndef DIGITS10_H -`define DIGITS10_H - -`include "hvsync_generator.v" - -/* -ROM module with 5x5 bitmaps for the digits 0-9. - -digits10_case - Uses the case statement. -digits10_array - Uses an array and initial block. - -These two modules are functionally equivalent. -*/ - -// module for 10-digit bitmap ROM -module digits10_case(digit, yofs, bits); - - input [3:0] digit; // digit 0-9 - input [2:0] yofs; // vertical offset (0-4) - output reg [4:0] bits; // output (5 bits) - - // combine {digit,yofs} into single ROM address - wire [6:0] caseexpr = {digit,yofs}; - - always @(*) - case (caseexpr)/*{w:5,h:5,count:10}*/ - 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; // digit 0-9 - input [2:0] yofs; // vertical offset (0-4) - output [4:0] bits; // output (5 bits) - - reg [4:0] bitarray[16][5]; // ROM array (16 x 5 x 5 bits) - - assign bits = bitarray[digit][yofs]; // assign module output - - integer i,j; - - initial begin/*{w:5,h:5,count:10}*/ - 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 - -// test module -module test_numbers_top(clk, reset, hsync, vsync, rgb); - - input clk, reset; - output hsync, vsync; - output [2:0] rgb; - - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - hvsync_generator hvsync_gen( - .clk(clk), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - wire [3:0] digit = hpos[7:4]; - wire [2:0] xofs = hpos[3:1]; - wire [2:0] yofs = vpos[3:1]; - wire [4:0] bits; - - digits10_array numbers( - .digit(digit), - .yofs(yofs), - .bits(bits) - ); - - wire r = display_on && 0; - wire g = display_on && bits[xofs ^ 3'b111]; - wire b = display_on && 0; - assign rgb = {b,g,r}; - -endmodule - -`endif diff --git a/fpga/examples/font_cp437_8x8.v b/fpga/examples/font_cp437_8x8.v deleted file mode 100644 index 85abd1b7..00000000 --- a/fpga/examples/font_cp437_8x8.v +++ /dev/null @@ -1,21 +0,0 @@ - -`ifndef FONT_CP437_H -`define FONT_CP437_H - -// PC font (code page 437) - -module font_cp437_8x8(addr, data); - - input [10:0] addr; - output [7:0] data; - - reg [7:0] bitarray[0:2047]; - - assign data = bitarray[addr]; - - initial begin/*{w:8,h:8,bpp:1,count:256}*/ - $readmemh("cp437.hex", bitarray); - end -endmodule - -`endif diff --git a/fpga/examples/hvsync_generator.v b/fpga/examples/hvsync_generator.v deleted file mode 100644 index 24587616..00000000 --- a/fpga/examples/hvsync_generator.v +++ /dev/null @@ -1,69 +0,0 @@ - -`ifndef HVSYNC_GENERATOR_H -`define HVSYNC_GENERATOR_H - -/* -Video sync generator, used to drive a simulated CRT. -To use: -- Wire the hsync and vsync signals to top level outputs -- Add a 3-bit (or more) "rgb" output to the top level -*/ - -module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos); - - input clk; - input reset; - output reg hsync, vsync; - output display_on; - output reg [8:0] hpos; - output reg [8:0] vpos; - - // declarations for TV-simulator sync parameters - // horizontal constants - parameter H_DISPLAY = 256; // horizontal display width - parameter H_BACK = 23; // horizontal left border (back porch) - parameter H_FRONT = 7; // horizontal right border (front porch) - parameter H_SYNC = 23; // horizontal sync width - // vertical constants - parameter V_DISPLAY = 240; // vertical display height - parameter V_TOP = 5; // vertical top border - parameter V_BOTTOM = 14; // vertical bottom border - parameter V_SYNC = 3; // vertical sync # lines - // derived constants - parameter H_SYNC_START = H_DISPLAY + H_FRONT; - parameter H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1; - parameter H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1; - parameter V_SYNC_START = V_DISPLAY + V_BOTTOM; - parameter V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1; - parameter V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1; - - wire hmaxxed = (hpos == H_MAX) || reset; // set when hpos is maximum - wire vmaxxed = (vpos == V_MAX) || reset; // set when vpos is maximum - - // horizontal position counter - always @(posedge clk) - begin - hsync <= (hpos>=H_SYNC_START && hpos<=H_SYNC_END); - if(hmaxxed) - hpos <= 0; - else - hpos <= hpos + 1; - end - - // vertical position counter - always @(posedge clk) - begin - vsync <= (vpos>=V_SYNC_START && vpos<=V_SYNC_END); - if(hmaxxed) - if (vmaxxed) - vpos <= 0; - else - vpos <= vpos + 1; - end - - // display_on is set when beam is in "safe" visible frame - assign display_on = (hpos A -; ldb #IN_FLAGS ; addr of IN_FLAGS -> B -; and none,[B] ; read B, AND with A -; bz DisplayLoop ; loop until paddle flag set - ldb #IN_VPOS - mov A,[B] ; load vertical position -> A - sta PLAYER_X ; store player x position -; wait for vsync - lda #F_VSYNC - ldb #IN_FLAGS -WaitForVsyncOn: - and none,[B] - bz WaitForVsyncOn ; wait until VSYNC on -WaitForVsyncOff: - and none,[B] - bnz WaitForVsyncOff ; wait until VSYNC off -; check collision - lda #F_COLLIDE - ldb #IN_FLAGS - and none,[B] ; collision flag set? - bz NoCollision ; skip ahead if not - lda #16 - sta SPEED ; speed = 16 -NoCollision: -; update speed - ldb #SPEED - mov A,[B] ; speed -> A - inc A ; increment speed - bz MaxSpeed ; speed wraps to 0? - sta SPEED ; no, store speed -MaxSpeed: - mov A,[B] ; reload speed -> A - lsr A - lsr A - lsr A - lsr A ; divide speed by 16 -; add to lo byte of track pos - ldb #TRACKPOS_LO - add B,[B] ; B <- speed/16 + trackpos_lo - swapab ; swap A <-> B - sta TRACKPOS_LO ; A -> trackpos_lo - swapab ; swap A <-> B again - bcc NoCarry ; carry flag from earlier add op -; add to hi byte of track pos - ldb #TRACKPOS_HI - mov B,[B] ; B <- trackpos_hi - inc b ; increment B - swapab ; swap A <-> B - sta TRACKPOS_HI ; A -> trackpos_hi - swapab ; swap A <-> B again -NoCarry: -; update enemy vert pos - ldb #ENEMY_Y - add A,[B] - sta ENEMY_Y ; enemy_y = enemy_y + speed/16 -; update enemy horiz pos - ldb #ENEMY_X - mov A,[B] - ldb #ENEMY_DIR - add A,[B] - sta ENEMY_X ; enemy_x = enemy_x + enemy_dir - sub A,#64 - and A,#127 ; A <- (enemy_x-64) & 127 - bnz SkipXReverse ; skip if enemy_x is in range -; load ENEMY_DIR and negate - zero A - sub A,[B] - sta ENEMY_DIR ; enemy_dir = -enemy_dir -SkipXReverse: -; back to display loop - jmp DisplayLoop diff --git a/fpga/examples/racing.hex b/fpga/examples/racing.hex deleted file mode 100644 index a49f3f7d..00000000 --- a/fpga/examples/racing.hex +++ /dev/null @@ -1,128 +0,0 @@ -4b -80 -92 -94 -95 -4b -b4 -93 -0 -97 -2 -96 -5b -41 -cb -92 -4b -10 -5b -42 -f9 -ac -94 -f9 -a4 -97 -4b -20 -5b -42 -f9 -ac -a4 -4b -10 -97 -5b -7 -cb -2 -ac -ab -97 -cb -5 -5 -5 -5 -5b -8 -dc -81 -98 -81 -a1 -bf -5b -9 -db -12 -81 -99 -81 -5b -5 -cc -95 -5b -4 -cb -5b -6 -cc -94 -4d -40 -49 -7f -a4 -d3 -0 -cd -96 -6b -8c -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 diff --git a/fpga/examples/racing_game.v b/fpga/examples/racing_game.v deleted file mode 100644 index 7bc6fc88..00000000 --- a/fpga/examples/racing_game.v +++ /dev/null @@ -1,158 +0,0 @@ - -`include "hvsync_generator.v" -`include "sprite_bitmap.v" -`include "sprite_renderer.v" - -/* -A simple racing game with two sprites and a scrolling playfield. -This version does not use a CPU; all logic is straight Verilog. -*/ - -module racing_game_top(clk, reset, out, hpaddle, vpaddle); - - input clk, reset; - input hpaddle, vpaddle; - output [1:0] out; - wire hsync, vsync; - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - // player car position (set at VSYNC) - reg [7:0] player_x; - reg [7:0] player_y; - // paddle position (set continuously during frame) - reg [7:0] paddle_x; - reg [7:0] paddle_y; - // enemy car position - reg [7:0] enemy_x = 128; - reg [7:0] enemy_y = 128; - // enemy car direction, 1=right, 0=left - reg enemy_dir = 0; - - reg [15:0] track_pos = 0; // player position along track (16 bits) - reg [7:0] speed = 31; // player velocity along track (8 bits) - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - // video sync generator - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - // set paddle registers - always @(posedge hsync) - begin - if (!hpaddle) paddle_x <= vpos[7:0]; - if (!vpaddle) paddle_y <= vpos[7:0]; - end - - - // select player or enemy access to ROM - wire player_load = (hpos >= 256) && (hpos < 260); - wire enemy_load = (hpos >= 260); - // wire up car sprite ROM - // multiplex between player and enemy ROM address - wire [3:0] player_sprite_yofs; - wire [3:0] enemy_sprite_yofs; - wire [3:0] car_sprite_yofs = player_load ? player_sprite_yofs : enemy_sprite_yofs; - wire [7:0] car_sprite_bits; - car_bitmap car( - .yofs(car_sprite_yofs), - .bits(car_sprite_bits)); - - // signals for player sprite generator - wire player_vstart = {1'b0,player_y} == vpos; - wire player_hstart = {1'b0,player_x} == hpos; - wire player_gfx; - wire player_is_drawing; - - // signals for enemy sprite generator - wire enemy_vstart = {1'b0,enemy_y} == vpos; - wire enemy_hstart = {1'b0,enemy_x} == hpos; - wire enemy_gfx; - wire enemy_is_drawing; - - // player sprite generator - sprite_renderer player_renderer( - .clk(clk2), - .reset(reset), - .vstart(player_vstart), - .load(player_load), - .hstart(player_hstart), - .rom_addr(player_sprite_yofs), - .rom_bits(car_sprite_bits), - .gfx(player_gfx), - .in_progress(player_is_drawing)); - - // enemy sprite generator - sprite_renderer enemy_renderer( - .clk(clk2), - .reset(reset), - .vstart(enemy_vstart), - .load(enemy_load), - .hstart(enemy_hstart), - .rom_addr(enemy_sprite_yofs), - .rom_bits(car_sprite_bits), - .gfx(enemy_gfx), - .in_progress(enemy_is_drawing)); - - // signals for enemy bouncing off left/right borders - wire enemy_hit_left = (enemy_x == 64); - wire enemy_hit_right = (enemy_x == 192); - wire enemy_hit_edge = enemy_hit_left || enemy_hit_right; - - // update player, enemy, track counters - // runs once per frame - always @(posedge vsync) - begin - player_x <= 64; //paddle_x; - player_y <= 180; - track_pos <= track_pos + {11'b0,speed[7:4]}; - enemy_y <= enemy_y + {3'b0, speed[7:4]}; - if (enemy_hit_edge) - enemy_dir <= !enemy_dir; - if (enemy_dir ^ enemy_hit_edge) - enemy_x <= enemy_x + 1; - else - enemy_x <= enemy_x - 1; - // collision check? - if (frame_collision) - speed <= 16; - else if (speed < ~paddle_y) - speed <= speed + 1; - else if (speed > 16) - speed <= speed - 1; - end - - // set to 1 when player collides with enemy or track - reg frame_collision; - - always @(posedge clk2) - if (player_gfx && (enemy_gfx || track_gfx)) - frame_collision <= 1; - else if (vsync) - frame_collision <= 0; - - // track graphics signals - wire track_offside = (hpos[7:5]==0) || (hpos[7:5]==7); - wire track_shoulder = (hpos[7:3]==3) || (hpos[7:3]==28); - wire track_gfx = (vpos[5:1]!=track_pos[5:1]) && track_offside; - - // combine signals for RGB output - wire r = display_on && (enemy_gfx || track_shoulder); - wire g = display_on && (player_gfx || track_gfx); - wire b = display_on && (player_gfx || track_shoulder); - - assign out = (hsync||vsync) ? 0 : (1+g+(r|b)); - -endmodule diff --git a/fpga/examples/racing_game_cpu.v b/fpga/examples/racing_game_cpu.v deleted file mode 100644 index a98fb196..00000000 --- a/fpga/examples/racing_game_cpu.v +++ /dev/null @@ -1,169 +0,0 @@ - -`include "hvsync_generator.v" -`include "sprite_bitmap.v" -`include "sprite_renderer.v" -`include "cpu8.v" - -/* -A simple racing game with two sprites and a scrolling playfield. -This version uses the 8-bit CPU. -*/ - -// uncomment to see scope view -//`define DEBUG - -module racing_game_top(clk, reset, out, hpaddle, vpaddle); - - input clk, reset; - input hpaddle, vpaddle; - output [1:0] out; - wire hsync, vsync; - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - parameter PADDLE_X = 0; // paddle X coordinate - parameter PADDLE_Y = 1; // paddle Y coordinate - parameter PLAYER_X = 2; // player X coordinate - parameter PLAYER_Y = 3; // player Y coordinate - parameter ENEMY_X = 4; // enemy X coordinate - parameter ENEMY_Y = 5; // enemy Y coordinate - parameter ENEMY_DIR = 6; // enemy direction (1, -1) - parameter SPEED = 7; // player speed - parameter TRACKPOS_LO = 8; // track position (lo byte) - parameter TRACKPOS_HI = 9; // track position (hi byte) - - parameter IN_HPOS = 8'h40; // CRT horizontal position - parameter IN_VPOS = 8'h41; // CRT vertical position - // flags: [0, 0, collision, vsync, hsync, vpaddle, hpaddle, display_on] - parameter IN_FLAGS = 8'h42; - - reg [7:0] ram[0:15]; // 16 bytes of RAM - reg [7:0] rom[0:127]; // 128 bytes of ROM - - wire [7:0] address_bus; // CPU address bus - reg [7:0] to_cpu; // data bus to CPU - wire [7:0] from_cpu; // data bus from CPU - wire write_enable; // write enable bit from CPU - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - // 8-bit CPU module - CPU cpu(.clk(clk2), - .reset(reset), - .address(address_bus), - .data_in(to_cpu), - .data_out(from_cpu), - .write(write_enable)); - - // RAM write from CPU - always @(posedge clk2) - if (write_enable) - ram[address_bus[5:0]] <= from_cpu; - - // RAM read from CPU - always @(*) - casez (address_bus) - // RAM - 8'b00??????: to_cpu = ram[address_bus[5:0]]; - // special read registers - IN_HPOS: to_cpu = hpos[7:0]; - IN_VPOS: to_cpu = vpos[7:0]; - IN_FLAGS: to_cpu = {2'b0, frame_collision, - vsync, hsync, vpaddle, hpaddle, display_on}; - // ROM - 8'b1???????: to_cpu = rom[address_bus[6:0]]; - default: to_cpu = 8'bxxxxxxxx; - endcase - - // video sync generator - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - // flags for player sprite renderer module - wire player_vstart = {1'b0,ram[PLAYER_Y]} == vpos; - wire player_hstart = {1'b0,ram[PLAYER_X]} == hpos; - wire player_gfx; - wire player_is_drawing; - - // flags for enemy sprite renderer module - wire enemy_vstart = {1'b0,ram[ENEMY_Y]} == vpos; - wire enemy_hstart = {1'b0,ram[ENEMY_X]} == hpos; - wire enemy_gfx; - wire enemy_is_drawing; - - // select player or enemy access to ROM - wire player_load = (hpos >= 256) && (hpos < 260); - wire enemy_load = (hpos >= 260); - // wire up car sprite ROM - // multiplex between player and enemy ROM address - wire [3:0] player_sprite_yofs; - wire [3:0] enemy_sprite_yofs; - wire [3:0] car_sprite_yofs = player_load ? player_sprite_yofs : enemy_sprite_yofs; - wire [7:0] car_sprite_bits; - car_bitmap car( - .yofs(car_sprite_yofs), - .bits(car_sprite_bits)); - - // player sprite renderer - sprite_renderer player_renderer( - .clk(clk2), - .reset(reset), - .vstart(player_vstart), - .hstart(player_hstart), - .load(player_load), - .rom_addr(player_sprite_yofs), - .rom_bits(car_sprite_bits), - .gfx(player_gfx), - .in_progress(player_is_drawing)); - - // enemy sprite renderer - sprite_renderer enemy_renderer( - .clk(clk2), - .reset(reset), - .vstart(enemy_vstart), - .hstart(enemy_hstart), - .load(enemy_load), - .rom_addr(enemy_sprite_yofs), - .rom_bits(car_sprite_bits), - .gfx(enemy_gfx), - .in_progress(enemy_is_drawing)); - - // collision detection logic - reg frame_collision; - always @(posedge clk2) - if (player_gfx && (enemy_gfx || track_gfx)) - frame_collision <= 1; - else if (vpos==0) - frame_collision <= 0; - - // track graphics - wire track_offside = (hpos[7:5]==0) || (hpos[7:5]==7); - wire track_shoulder = (hpos[7:3]==3) || (hpos[7:3]==28); - wire track_gfx = (vpos[5:1]!=ram[TRACKPOS_LO][5:1]) && track_offside; - - // RGB output - wire r = display_on && (player_gfx || enemy_gfx || track_shoulder); - wire g = display_on && (player_gfx || track_gfx); - wire b = display_on && (enemy_gfx || track_shoulder); - - assign out = (hsync||vsync) ? 0 : (1+g+(r|b)); - - //////////// CPU program code - - initial begin - $readmemh("racing.hex", rom); - end - -endmodule - diff --git a/fpga/examples/ram.v b/fpga/examples/ram.v deleted file mode 100644 index 182fca54..00000000 --- a/fpga/examples/ram.v +++ /dev/null @@ -1,80 +0,0 @@ - -`ifndef RAM_H -`define RAM_H - -/* -RAM_sync - Synchronous RAM module. -RAM_async - Asynchronous RAM module. -RAM_async_tristate - Async RAM module with bidirectional data bus. - -Module parameters: - -A - number of address bits (default = 10) -D - number of data bits (default = 8) -*/ - -module RAM_sync(clk, addr, din, dout, we); - - parameter A = 10; // # of address bits - parameter D = 8; // # of data bits - - input clk; // clock - input [A-1:0] addr; // address - input [D-1:0] din; // data input - output [D-1:0] dout; // data output - input we; // write enable - - reg [D-1:0] mem [0:(1<>1][15:8] : bitarray[addr>>1][7:0]; - - initial begin/*{w:16,h:16,bpw:16,count:5}*/ - bitarray['h00] = 16'b11110000000; - bitarray['h01] = 16'b11110000000; - bitarray['h02] = 16'b1100000000; - bitarray['h03] = 16'b1100000000; - bitarray['h04] = 16'b111101101111000; - bitarray['h05] = 16'b111101101111000; - bitarray['h06] = 16'b111111111111000; - bitarray['h07] = 16'b111111111111000; - bitarray['h08] = 16'b111111111111000; - bitarray['h09] = 16'b111111111111000; - bitarray['h0a] = 16'b111111111111000; - bitarray['h0b] = 16'b111100001111000; - bitarray['h0c] = 16'b111100001111000; - bitarray['h0d] = 16'b0; - bitarray['h0e] = 16'b0; - bitarray['h0f] = 16'b0; - - bitarray['h10] = 16'b111000000000; - bitarray['h11] = 16'b1111000000000; - bitarray['h12] = 16'b1111000000000; - bitarray['h13] = 16'b11000000000; - bitarray['h14] = 16'b11101110000; - bitarray['h15] = 16'b1101110000; - bitarray['h16] = 16'b111101111110000; - bitarray['h17] = 16'b111101111111000; - bitarray['h18] = 16'b111111111111000; - bitarray['h19] = 16'b11111111111000; - bitarray['h1a] = 16'b11111111111100; - bitarray['h1b] = 16'b11111111111100; - bitarray['h1c] = 16'b11111001111100; - bitarray['h1d] = 16'b1111001110000; - bitarray['h1e] = 16'b1111000000000; - bitarray['h1f] = 16'b1100000000000; - - bitarray['h20] = 16'b0; - bitarray['h21] = 16'b0; - bitarray['h22] = 16'b11000011000000; - bitarray['h23] = 16'b111000111100000; - bitarray['h24] = 16'b111101111110000; - bitarray['h25] = 16'b1110111111000; - bitarray['h26] = 16'b111111111100; - bitarray['h27] = 16'b11111111110; - bitarray['h28] = 16'b11011111111110; - bitarray['h29] = 16'b111111111111100; - bitarray['h2a] = 16'b111111111001000; - bitarray['h2b] = 16'b11111110000000; - bitarray['h2c] = 16'b1111100000000; - bitarray['h2d] = 16'b111110000000; - bitarray['h2e] = 16'b11110000000; - bitarray['h2f] = 16'b1100000000; - - bitarray['h30] = 16'b0; - bitarray['h31] = 16'b0; - bitarray['h32] = 16'b110000000; - bitarray['h33] = 16'b100001111000000; - bitarray['h34] = 16'b1110001111110000; - bitarray['h35] = 16'b1111010111111100; - bitarray['h36] = 16'b1111111111111111; - bitarray['h37] = 16'b1111111111111; - bitarray['h38] = 16'b11111111110; - bitarray['h39] = 16'b101111111110; - bitarray['h3a] = 16'b1111111101100; - bitarray['h3b] = 16'b11111111000000; - bitarray['h3c] = 16'b1111111100000; - bitarray['h3d] = 16'b11111110000; - bitarray['h3e] = 16'b111100000; - bitarray['h3f] = 16'b1100000; - - bitarray['h40] = 16'b0; - bitarray['h41] = 16'b0; - bitarray['h42] = 16'b0; - bitarray['h43] = 16'b111111111000; - bitarray['h44] = 16'b111111111000; - bitarray['h45] = 16'b111111111000; - bitarray['h46] = 16'b111111111000; - bitarray['h47] = 16'b1100001111100000; - bitarray['h48] = 16'b1111111111100000; - bitarray['h49] = 16'b1111111111100000; - bitarray['h4a] = 16'b1100001111100000; - bitarray['h4b] = 16'b111111111000; - bitarray['h4c] = 16'b111111111000; - bitarray['h4d] = 16'b111111111000; - bitarray['h4e] = 16'b111111111000; - bitarray['h4f] = 16'b0; - end -endmodule - -// 16x16 sprite renderer that supports rotation -module sprite_renderer2(clk, vstart, load, hstart, rom_addr, rom_bits, - hmirror, vmirror, - gfx, busy); - - input clk, vstart, load, hstart; - input hmirror, vmirror; - output [4:0] rom_addr; - input [7:0] rom_bits; - output gfx; - output busy; - - assign busy = state != WAIT_FOR_VSTART; - - reg [2:0] state; - reg [3:0] ycount; - reg [3:0] xcount; - - reg [15:0] outbits; - - localparam WAIT_FOR_VSTART = 0; - localparam WAIT_FOR_LOAD = 1; - localparam LOAD1_SETUP = 2; - localparam LOAD1_FETCH = 3; - localparam LOAD2_SETUP = 4; - localparam LOAD2_FETCH = 5; - localparam WAIT_FOR_HSTART = 6; - localparam DRAW = 7; - - always @(posedge clk) - begin - case (state) - WAIT_FOR_VSTART: begin - ycount <= 0; - // set a default value (blank) for pixel output - // note: multiple non-blocking assignments are vendor-specific - gfx <= 0; - if (vstart) state <= WAIT_FOR_LOAD; - end - WAIT_FOR_LOAD: begin - xcount <= 0; - gfx <= 0; - if (load) state <= LOAD1_SETUP; - end - LOAD1_SETUP: begin - rom_addr <= {vmirror?~ycount:ycount, 1'b0}; - state <= LOAD1_FETCH; - end - LOAD1_FETCH: begin - outbits[7:0] <= rom_bits; - state <= LOAD2_SETUP; - end - LOAD2_SETUP: begin - rom_addr <= {vmirror?~ycount:ycount, 1'b1}; - state <= LOAD2_FETCH; - end - LOAD2_FETCH: begin - outbits[15:8] <= rom_bits; - state <= WAIT_FOR_HSTART; - end - WAIT_FOR_HSTART: begin - if (hstart) state <= DRAW; - end - DRAW: begin - // mirror graphics left/right - gfx <= outbits[hmirror ? ~xcount[3:0] : xcount[3:0]]; - xcount <= xcount + 1; - if (xcount == 15) begin // pre-increment value - ycount <= ycount + 1; - if (ycount == 15) // pre-increment value - state <= WAIT_FOR_VSTART; // done drawing sprite - else - state <= WAIT_FOR_LOAD; // done drawing this scanline - end - end - endcase - end - -endmodule - -// converts 0..15 rotation value to bitmap index / mirror bits -module rotation_selector(rotation, bitmap_num, hmirror, vmirror); - - input [3:0] rotation; // angle (0..15) - output [2:0] bitmap_num; // bitmap index (0..4) - output hmirror, vmirror; // horiz & vert mirror bits - - always @(*) - case (rotation[3:2]) // 4 quadrants - 0: begin // 0..3 -> 0..3 - bitmap_num = {1'b0, rotation[1:0]}; - hmirror = 0; - vmirror = 0; - end - 1: begin // 4..7 -> 4..1 - bitmap_num = -rotation[2:0]; - hmirror = 0; - vmirror = 1; - end - 2: begin // 8-11 -> 0..3 - bitmap_num = {1'b0, rotation[1:0]}; - hmirror = 1; - vmirror = 1; - end - 3: begin // 12-15 -> 4..1 - bitmap_num = -rotation[2:0]; - hmirror = 1; - vmirror = 0; - end - endcase - -endmodule - -// tank controller module -- handles rendering and movement -module tank_controller(clk, reset, hpos, vpos, hsync, vsync, - sprite_addr, sprite_bits, gfx, - playfield, - switch_left, switch_right, switch_up); - - input clk; - input reset; - input hsync; - input vsync; - input [8:0] hpos; - input [8:0] vpos; - output [7:0] sprite_addr; - input [7:0] sprite_bits; - output gfx; - input playfield; - input switch_left, switch_right, switch_up; - - parameter initial_x = 128; - parameter initial_y = 120; - parameter initial_rot = 0; - - wire hmirror, vmirror; - wire busy; - wire collision_gfx = gfx && playfield; - - reg [11:0] player_x_fixed; - wire [7:0] player_x = player_x_fixed[11:4]; - wire [3:0] player_x_frac = player_x_fixed[3:0]; - - reg [11:0] player_y_fixed; - wire [7:0] player_y = player_y_fixed[11:4]; - wire [3:0] player_y_frac = player_y_fixed[3:0]; - - reg [3:0] player_rot; - reg [3:0] player_speed; - reg [3:0] frame = 0; - - wire vstart = {1'b0,player_y} == vpos; - wire hstart = {1'b0,player_x} == hpos; - - sprite_renderer2 renderer( - .clk(clk), - .vstart(vstart), - .load(hsync), - .hstart(hstart), - .hmirror(hmirror), - .vmirror(vmirror), - .rom_addr(sprite_addr[4:0]), - .rom_bits(sprite_bits), - .gfx(gfx), - .busy(busy)); - - rotation_selector rotsel( - .rotation(player_rot), - .bitmap_num(sprite_addr[7:5]), - .hmirror(hmirror), - .vmirror(vmirror)); - - always @(posedge vsync or posedge reset) - begin - if (reset) begin - player_rot <= initial_rot; - player_speed <= 0; - end else begin - frame <= frame + 1; // increment frame counter - if (frame[0]) begin // only update every other frame - if (switch_left) - player_rot <= player_rot - 1; // turn left - else if (switch_right) - player_rot <= player_rot + 1; // turn right - if (switch_up) begin - if (player_speed != 15) // max accel - player_speed <= player_speed + 1; - end else - player_speed <= 0; // stop - end - end - end - - // set if collision; cleared at vsync - reg collision_detected; - - always @(posedge clk) - if (vstart) - collision_detected <= 0; - else if (collision_gfx) - collision_detected <= 1; - - // sine lookup (4 bits input, 4 signed bits output) - function signed [3:0] sin_16x4; - input [3:0] in; // input angle 0..15 - integer y; - case (in[1:0]) // 4 values per quadrant - 0: y = 0; - 1: y = 3; - 2: y = 5; - 3: y = 6; - endcase - case (in[3:2]) // 4 quadrants - 0: sin_16x4 = 4'(y); - 1: sin_16x4 = 4'(7-y); - 2: sin_16x4 = 4'(-y); - 3: sin_16x4 = 4'(y-7); - endcase - endfunction - - always @(posedge hsync or posedge reset) - if (reset) begin - // set initial position - player_x_fixed <= initial_x << 4; - player_y_fixed <= initial_y << 4; - end else begin - // collision detected? move backwards - if (collision_detected && vpos[3:1] == 0) begin - if (vpos[0]) - player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot+8)); - else - player_y_fixed <= player_y_fixed - 12'(sin_16x4(player_rot+12)); - end else - // forward movement - if (vpos < 9'(player_speed)) begin - if (vpos[0]) - player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot)); - else - player_y_fixed <= player_y_fixed - 12'(sin_16x4(player_rot+4)); - end - end - -endmodule - diff --git a/fpga/examples/sprite_scanline_renderer.v b/fpga/examples/sprite_scanline_renderer.v deleted file mode 100644 index 039f70b0..00000000 --- a/fpga/examples/sprite_scanline_renderer.v +++ /dev/null @@ -1,183 +0,0 @@ - -`include "hvsync_generator.v" -`include "ram.v" - -/* -sprite_scanline_renderer - Module that renders multiple - sprites whose attributes are fetched from shared RAM, - and whose bitmaps are stored in ROM. Made to be paired - with the FEMTO-16 CPU. -*/ - -module example_bitmap_rom(addr, data); - - input [15:0] addr; - output [15:0] data; - - reg [15:0] bitarray[0:255]; - - assign data = bitarray[addr & 15]; - - initial begin/*{w:16,h:16,bpw:16,count:1}*/ - bitarray['h00] = 16'b11110000000; - bitarray['h01] = 16'b100001000000; - bitarray['h02] = 16'b1111111100000; - bitarray['h03] = 16'b1111111100000; - bitarray['h04] = 16'b11110000000; - bitarray['h05] = 16'b11111111110000; - bitarray['h06] = 16'b111100001111000; - bitarray['h07] = 16'b1111101101111100; - bitarray['h08] = 16'b1101100001101111; - bitarray['h09] = 16'b1101111111100110; - bitarray['h0a] = 16'b1001111111100000; - bitarray['h0b] = 16'b1111111100000; - bitarray['h0c] = 16'b1110011100000; - bitarray['h0d] = 16'b1100001100000; - bitarray['h0e] = 16'b1100001100000; - bitarray['h0f] = 16'b11100001110000; - end - -endmodule - -module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb, - ram_addr, ram_data, ram_busy, - rom_addr, rom_data); - - parameter NB = 5; // 2^NB == number of sprites - parameter MB = 3; // 2^MB == slots per scanline - - localparam N = 1<= 256 - if (reset || vpos[8]) begin - // load sprites from RAM on line 260 - // 8 cycles per sprite - // do first sprite twice b/c CPU might still be busy - if (vpos == 260 && hpos < N*2+8) begin - ram_busy <= 1; - case (hpos[0]) - 0: begin - ram_addr <= {load_index, 1'b0}; - // load X and Y position (2 cycles ago) - sprite_xpos[load_index] <= ram_data[7:0]; - sprite_ypos[load_index] <= ram_data[15:8]; - end - 1: begin - ram_addr <= {load_index, 1'b1}; - // load attribute (2 cycles ago) - sprite_attr[load_index] <= ram_data[7:0]; - end - endcase - end - end else if (hpos < N*2) begin - // setup vars for next phase - k <= 0; - romload <= 0; - // select the sprites that will appear in this scanline - case (hpos[0]) - // compute Y offset of sprite relative to scanline - 0: z <= 8'(vpos - sprite_ypos[i]); - 1: begin - // sprite is active if Y offset is 0..15 - if (z < 16) begin - line_xpos[j] <= sprite_xpos[i]; // save X pos - line_yofs[j] <= z; // save Y offset - line_attr[j] <= sprite_attr[i]; // save attr - line_active[j] <= 1; // mark sprite active - j <= j + 1; // inc counter - end - i <= i + 1; // inc main array counter - end - endcase - end else if (hpos < N*2+M*18) begin - // setup vars for next phase - j <= 0; - // if sprite shift register is empty, load new sprite - if (out_bitmap == 0) begin - case (romload) - 0: begin - // set ROM address and fetch bitmap - rom_addr <= {4'b0, line_attr[k][7:4], line_yofs[k]}; - end - 1: begin - // load scanline buffer offset to write - write_ofs <= {~vpos[0], line_xpos[k]}; - // fetch 0 if sprite is inactive - out_bitmap <= line_active[k] ? rom_data : 0; - // load attribute for sprite - out_attr <= line_attr[k]; - // disable sprite for next scanline - line_active[k] <= 0; - // go to next sprite in 2ndary buffer - k <= k + 1; - end - endcase - romload <= !romload; - end else begin - // write color to scanline buffer if low bit == 1 - if (out_bitmap[0]) - scanline[write_ofs] <= out_attr[3:0]; - // shift bits right - out_bitmap <= out_bitmap >> 1; - // increment to next scanline pixel - write_ofs <= write_ofs + 1; - end - end else begin - // clear counters - i <= 0; - end - - // read and clear buffer - rgb <= scanline[read_bufidx]; - scanline[read_bufidx] <= 0; - end - -endmodule - diff --git a/fpga/examples/spritetest.v b/fpga/examples/spritetest.v deleted file mode 100644 index 04d70592..00000000 --- a/fpga/examples/spritetest.v +++ /dev/null @@ -1,77 +0,0 @@ - -`include "hvsync_generator.v" -`include "sprite_bitmap.v" -`include "sprite_renderer.v" - -/* -A simple racing game with two sprites and a scrolling playfield. -This version does not use a CPU; all logic is straight Verilog. -*/ - -module racing_game_top(clk, reset, out); - - input clk, reset; - output [1:0] out; - - wire hsync, vsync; - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - // player car position (set at VSYNC) - reg [7:0] player_x; - reg [7:0] player_y; - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - // video sync generator - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - // select player or enemy access to ROM - wire player_load = (hpos >= 256); - // wire up car sprite ROM - wire [3:0] car_sprite_yofs; - wire [7:0] car_sprite_bits; - car_bitmap car( - .yofs(car_sprite_yofs), - .bits(car_sprite_bits)); - - // signals for player sprite generator - wire player_vstart = player_y == vpos; - wire player_hstart = player_x == hpos; - wire player_gfx; - wire player_is_drawing; - - // player sprite generator - sprite_renderer player_renderer( - .clk(clk2), - .reset(reset), - .vstart(player_vstart), - .load(player_load), - .hstart(player_hstart), - .rom_addr(car_sprite_yofs), - .rom_bits(car_sprite_bits), - .gfx(player_gfx), - .in_progress(player_is_drawing)); - - // runs once per frame - always @(posedge vsync) - begin - player_x <= player_x + 1; - player_y <= player_y + 1; - end - - assign out = (hsync||vsync) ? 0 : display_on ? (1+player_gfx+(player_vstart|player_hstart|player_is_drawing)) : 1; - -endmodule diff --git a/fpga/examples/starfield.v b/fpga/examples/starfield.v deleted file mode 100644 index b07b178d..00000000 --- a/fpga/examples/starfield.v +++ /dev/null @@ -1,47 +0,0 @@ - -`include "hvsync_generator.v" -`include "lfsr.v" - -/* -Scrolling starfield generator using a period (2^16-1) LFSR. -*/ - -module starfield_top(clk, reset, out); - - input clk, reset; - output [1:0] out; - wire hsync, vsync; - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - wire [15:0] lfsr; - - reg clk2; - always @(posedge clk) begin - clk2 <= !clk2; - end - - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk2), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - wire star_enable = !hpos[8] & !vpos[8]; - - // LFSR with period = 2^16-1 = 256*256-1 - LFSR #(16,16'b1000000001011,0) lfsr_gen( - .clk(clk2), - .reset(reset), - .enable(star_enable), - .lfsr(lfsr)); - - wire star_on = &lfsr[15:9]; - - assign out = (hsync||vsync) ? 0 : star_on ? (1+lfsr[1]+lfsr[2]) : 1; - -endmodule diff --git a/fpga/examples/test.vlog b/fpga/examples/test.vlog deleted file mode 100644 index ceaa5516..00000000 --- a/fpga/examples/test.vlog +++ /dev/null @@ -1,34 +0,0 @@ - -module test; - -reg clk; -reg reset; -reg hpaddle; -reg vpaddle; -wire out0; -wire out1; - -chip chip( - .io_7_0_0(clk), - .io_0_8_1(reset), - .io_13_4_0(hpaddle), - .io_13_3_1(vpaddle), - .io_13_6_0(out0), - .io_13_4_1(out1) -); - -always #2 clk = !clk; - -initial begin - $dumpfile("racing_game_cpu.vcd"); - $dumpvars(0,test); - - #1 clk = 0; - #5 reset = 1; - #10 reset = 0; - - #100000 $finish(); -end - -endmodule - diff --git a/fpga/examples/test_hvsync.v b/fpga/examples/test_hvsync.v deleted file mode 100644 index a3445ce8..00000000 --- a/fpga/examples/test_hvsync.v +++ /dev/null @@ -1,32 +0,0 @@ - -`include "hvsync_generator.v" - -/* -A simple test pattern using the hvsync_generator module. -*/ - -module test_hvsync_top(clk, reset, hsync, vsync, rgb); - - input clk, reset; - output hsync, vsync; - output [2:0] rgb; - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - hvsync_generator hvsync_gen( - .clk(clk), - .reset(0), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - wire r = display_on && (((hpos&7)==0) || ((vpos&7)==0)); - wire g = display_on && vpos[4]; - wire b = display_on && hpos[4]; - assign rgb = {b,g,r}; - -endmodule diff --git a/fpga/examples/tile_renderer.v b/fpga/examples/tile_renderer.v deleted file mode 100644 index 113fa151..00000000 --- a/fpga/examples/tile_renderer.v +++ /dev/null @@ -1,89 +0,0 @@ - -/* -Displays a 32x30 grid of 8x8 tiles, whose attributes are - fetched from RAM, and whose bitmap patterns are in ROM. -*/ - -module tile_renderer(clk, reset, hpos, vpos, - rgb, - ram_addr, ram_read, ram_busy, - rom_addr, rom_data); - - input clk, reset; - input [8:0] hpos; - input [8:0] vpos; - output [3:0] rgb; - - // start loading cells from RAM at this hpos value - // first column read will be ((HLOAD-2) % 32) - parameter HLOAD = 272; - - output reg [15:0] ram_addr; - input [15:0] ram_read; - output reg ram_busy; - - output [10:0] rom_addr; - input [7:0] rom_data; - - reg [7:0] page_base = 8'h7e; // page table base (8 bits) - reg [15:0] row_base; // row table base (16 bits) - reg [4:0] row; - //wire [4:0] row = vpos[7:3]; // 5-bit row, vpos / 8 - wire [4:0] col = hpos[7:3]; // 5-bit column, hpos / 8 - wire [2:0] yofs = vpos[2:0]; // scanline of cell (0-7) - wire [2:0] xofs = hpos[2:0]; // which pixel to draw (0-7) - - reg [15:0] cur_cell; - wire [7:0] cur_char = cur_cell[7:0]; - wire [7:0] cur_attr = cur_cell[15:8]; - - // tile ROM address - assign rom_addr = {cur_char, yofs}; - - reg [15:0] row_buffer[0:31]; - - // lookup char and attr - always @(posedge clk) begin - // reset row to 0 when last row displayed - if (vpos == 248) begin - row <= 0; - end - // time to read a row? - if (vpos[2:0] == 7) begin - // read row_base from page table (2 bytes) - case (hpos) - // assert busy 5 cycles before first RAM read - HLOAD-8: ram_busy <= 1; - // read page base for row - HLOAD-3: ram_addr <= {page_base, 3'b000, row}; - HLOAD-1: row_base <= ram_read; - // deassert BUSY and increment row counter - HLOAD+34: begin - ram_busy <= 0; - row <= row + 1; - end - endcase - // load row of tile data from RAM - // (last two twice) - if (hpos >= HLOAD && hpos < HLOAD+34) begin - ram_addr <= row_base + hpos[4:0]; - row_buffer[hpos[4:0] - 5'd2] <= ram_read; - end - end - // latch character data - if (hpos < 256) begin - case (hpos[2:0]) - 7: begin - cur_cell <= row_buffer[col+1]; - end - endcase - end else if (hpos == 308) begin - cur_cell <= row_buffer[0]; - end - end - - // extract bit from ROM output - assign rgb = rom_data[~xofs] ? cur_attr[3:0] : cur_attr[7:4]; - -endmodule - diff --git a/fpga/examples/tiletest.v b/fpga/examples/tiletest.v deleted file mode 100644 index ab9e2cc3..00000000 --- a/fpga/examples/tiletest.v +++ /dev/null @@ -1,68 +0,0 @@ - -`include "hvsync_generator.v" -`include "font_cp437_8x8.v" -`include "ram.v" -`include "tile_renderer.v" - -module test_tilerender_top(clk, reset, out); - - input clk, reset; - output [1:0] out; - wire hsync, vsync; - - wire display_on; - wire [8:0] hpos; - wire [8:0] vpos; - - reg [15:0] ram_addr; - wire [15:0] ram_read; - reg [15:0] ram_write = 0; - reg ram_writeenable = 0; - - wire [10:0] rom_addr; - wire [7:0] rom_data; - wire ram_busy; - - hvsync_generator #(256,60,40,25) hvsync_gen( - .clk(clk), - .reset(reset), - .hsync(hsync), - .vsync(vsync), - .display_on(display_on), - .hpos(hpos), - .vpos(vpos) - ); - - // RAM - RAM_sync #(10,16) ram( - .clk(clk), - .dout(ram_read), - .din(ram_write), - .addr(ram_addr), - .we(ram_writeenable) - ); - - wire [3:0] rgb_tile; - - tile_renderer tile_gen( - .clk(clk), - .reset(reset), - .hpos(hpos), - .vpos(vpos), - .ram_addr(ram_addr), - .ram_read(ram_read), - .ram_busy(ram_busy), - .rom_addr(rom_addr), - .rom_data(rom_data), - .rgb(rgb_tile) - ); - - assign out = (hsync||vsync) ? 0 : (1+rgb_tile[0]+rgb_tile[1]); - - // tile ROM - font_cp437_8x8 tile_rom( - .addr(rom_addr), - .data(rom_data) - ); - -endmodule diff --git a/presets/verilog/framebuffer.v b/presets/verilog/framebuffer.v index 5288de38..6651a2f6 100644 --- a/presets/verilog/framebuffer.v +++ b/presets/verilog/framebuffer.v @@ -1,19 +1,10 @@ - + `include "hvsync_generator.v" `include "cpu16.v" -// uncomment to see scope view -//`define DEBUG - module frame_buffer_top(clk, reset, hsync, vsync, hpaddle, vpaddle, - address_bus, to_cpu, from_cpu, write_enable -`ifdef DEBUG - , output [15:0] IP - , output carry - , output zero -`else - , rgb -`endif + address_bus, to_cpu, from_cpu, write_enable, + rgb ); input clk, reset; @@ -22,21 +13,12 @@ module frame_buffer_top(clk, reset, hsync, vsync, hpaddle, vpaddle, wire display_on; wire [8:0] hpos; wire [8:0] vpos; -`ifdef DEBUG - assign IP = cpu.regs[cpu.IP]; - assign carry = cpu.carry; - assign zero = cpu.zero; -`else output [3:0] rgb; -`endif - parameter IN_HPOS = 8'b01000000; - parameter IN_VPOS = 8'b01000001; - parameter IN_FLAGS = 8'b01000010; - - reg [15:0] ram[0:32767]; - reg [15:0] rom[0:1023]; + reg [15:0] ram[0:32767]; // RAM (32768 x 16 bits) + reg [15:0] rom[0:1023]; // ROM (1024 x 16 bits) + // 16-bit CPU output wire [15:0] address_bus; output reg [15:0] to_cpu; output wire [15:0] from_cpu; @@ -51,26 +33,20 @@ module frame_buffer_top(clk, reset, hsync, vsync, hpaddle, vpaddle, .data_out(from_cpu), .write(write_enable)); + // CPU -> RAM write bus (synchronous) always @(posedge clk) if (write_enable) begin ram[address_bus[14:0]] <= from_cpu; end + // RAM -> CPU read bus (asynchronous) always @(*) if (address_bus[15]) to_cpu = rom[address_bus[9:0]]; - else if (&address_bus[14:8]) begin - casez (address_bus[7:0]) - // special read registers - IN_HPOS: to_cpu = {8'b0, hpos[7:0]}; - IN_VPOS: to_cpu = {8'b0, vpos[7:0]}; - IN_FLAGS: to_cpu = {11'b0, - vsync, hsync, vpaddle, hpaddle, display_on}; - default: to_cpu = 0; - endcase - end else + else to_cpu = ram[address_bus[14:0]]; + // video sync generator hvsync_generator hvsync_gen( .clk(clk), .reset(0), @@ -81,38 +57,32 @@ module frame_buffer_top(clk, reset, hsync, vsync, hpaddle, vpaddle, .vpos(vpos) ); - // video DMA access - reg hold; + // CPU busy flags (not used here) + reg hold = 0; wire busy; - reg [15:0] vline[0:31]; // 32x16 bits = 256 4-color pixels - reg [4:0] vindex; // index into line array + + reg [12:0] vindex; // index into line array reg [15:0] vshift; // shift register with current word to output - reg [3:0] palette[0:3] = '{0,1,4,7}; // simple palette + reg [3:0] palette[0:3] = '{0,1,4,7}; // simple palette array always @(posedge clk) begin - // has CPU released the bus? - if (busy) begin - // write from main RAM -> scanline RAM - vline[vindex] <= ram[{2'b10,vpos[7:0],vindex}]; - // end of scanline read? - if (&vindex) - hold <= 0; // release CPU - vindex <= vindex + 1; // next address - end else if (hpos >= 256 && hpos < 256+4 && vpos < 240) begin - hold <= 1; // start DMA mode, hold CPU - end else if (!hpos[8] && vpos < 240) begin - // load next word from vline buffer + if (display_on) begin + // load next word from RAM every 8 pixels if (0 == hpos[2:0]) begin - vshift <= vline[vindex]; + vshift <= ram[{2'b10,vindex}]; vindex <= vindex + 1; end else - vshift <= vshift >> 2; + vshift <= vshift << 2; // shift next pixel in 16-bit word // decode scanline RAM to RGB output - rgb <= palette[vshift[1:0]]; - end else - rgb <= 0; + rgb <= palette[vshift[15:14]]; + end else begin + rgb <= 0; // set color to black + if (vsync) vindex <= 0; // reset vindex every frame + end; end + // test program + `ifdef EXT_INLINE_ASM initial begin rom = '{ @@ -121,26 +91,16 @@ module frame_buffer_top(clk, reset, hsync, vsync, hpaddle, vpaddle, .org 32768 .len 1024 -.define IN_HPOS $7f00 -.define IN_VPOS $7f01 -.define IN_FLAGS $7f02 - -.define F_DISPLAY 1 -.define F_HPADDLE 2 -.define F_VPADDLE 4 -.define F_HSYNC 8 -.define F_VSYNC 16 - Start: - mov ax,#0 - mov bx,ax + mov ax,cx ; ax = cx + mov bx,#0 ; bx = #0 Loop: - xor ax,[bx] - mov [bx],ax - inc bx - inc ax - bnz Loop - reset + mov [bx],ax ; ram[bx] = ax + inc ax ; ax = ax + 1 + inc bx ; bx = bx + 1 + bnz Loop ; loop until bx is 0 + inc cx + reset ; reset CPU __endasm }; end