From b2beb2670c9d2f029ddbe828494683d846b43852 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 21 Feb 2018 13:32:11 -0600 Subject: [PATCH] more Verilog code; inline asm for depends; fixed tank --- presets/verilog/7segment.v | 12 + presets/verilog/cpu16.v | 42 ++-- presets/verilog/cpu8.v | 42 ++-- presets/verilog/femto8.json | 29 +++ presets/verilog/framebuffer.v | 2 - .../{sprite_multiple.v => racing_game.v} | 0 presets/verilog/ram1.v | 64 +++--- presets/verilog/sharedbuffer.v | 175 +++++++++++++++ presets/verilog/sound_generator.v | 104 +++++++++ presets/verilog/sprite_rotation.v | 8 +- presets/verilog/sprite_scanline_renderer.v | 206 ++++++++++++++++++ presets/verilog/tank.v | 5 +- src/emu.js | 7 +- src/platform/verilog.js | 40 +++- src/worker/assembler.js | 19 +- src/worker/workermain.js | 41 ++-- 16 files changed, 697 insertions(+), 99 deletions(-) create mode 100644 presets/verilog/femto8.json rename presets/verilog/{sprite_multiple.v => racing_game.v} (100%) create mode 100644 presets/verilog/sharedbuffer.v create mode 100644 presets/verilog/sound_generator.v create mode 100644 presets/verilog/sprite_scanline_renderer.v diff --git a/presets/verilog/7segment.v b/presets/verilog/7segment.v index ce841ae0..9bed775a 100644 --- a/presets/verilog/7segment.v +++ b/presets/verilog/7segment.v @@ -1,5 +1,17 @@ `include "hvsync_generator.v" +/* +Segment bit indices: + + 6666 + 1 5 + 1 5 + 0000 + 2 4 + 2 4 + 3333 +*/ + module seven_segment_decoder(digit, segments); input [3:0] digit; diff --git a/presets/verilog/cpu16.v b/presets/verilog/cpu16.v index 98591897..be0846e3 100644 --- a/presets/verilog/cpu16.v +++ b/presets/verilog/cpu16.v @@ -1,6 +1,7 @@ `ifndef CPU16_H `define CPU16_H +// include ALU module `include "cpu8.v" /* @@ -17,34 +18,35 @@ 11+++aaa ######## immediate binary operation */ -module CPU16(clk, reset, halt, busy, +module CPU16(clk, reset, hold, busy, address, data_in, data_out, write); input clk; input reset; - input halt; + input hold; output busy; output [15:0] address; input [15:0] data_in; output [15:0] data_out; output write; - reg [15:0] regs[0:7]; - reg [2:0] state; + reg [15:0] regs[0:7]; // 8 16-bit registers + reg [2:0] state; // CPU state - reg carry; - reg zero; - reg neg; - wire [2:0] flags = { neg, zero, carry }; + reg carry; // carry flag + reg zero; // zero flag + reg neg; // negative flag - reg [15:0] opcode; - wire [16:0] Y; - reg [3:0] aluop; - wire [2:0] rdest = opcode[10:8]; - wire [2:0] rsrc = opcode[2:0]; - wire Bconst = opcode[15]; // TODO - wire Bload = opcode[11]; // TODO + wire [16:0] Y; // ALU 16-bit + carry output + reg [3:0] aluop; // ALU operation + + reg [15:0] opcode; // used to decode ALU inputs + wire [2:0] rdest = opcode[10:8]; // ALU A input reg. + wire [2:0] rsrc = opcode[2:0]; // ALU B input reg. + wire Bconst = opcode[15]; // ALU B = 8-bit constant + wire Bload = opcode[11]; // ALU B = data bus + // CPU states localparam S_RESET = 0; localparam S_SELECT = 1; localparam S_DECODE = 2; @@ -77,7 +79,7 @@ module CPU16(clk, reset, halt, busy, // state 1: select opcode address S_SELECT: begin write <= 0; - if (halt) begin + if (hold) begin busy <= 1; state <= S_SELECT; end else begin @@ -89,7 +91,6 @@ module CPU16(clk, reset, halt, busy, end // state 2: read/decode opcode S_DECODE: begin - opcode <= data_in; // (only use opcode next cycle) casez (data_in) // 00000aaa0++++bbb operation A+B->A 16'b00000???0???????: begin @@ -180,6 +181,7 @@ module CPU16(clk, reset, halt, busy, state <= S_RESET; // reset end endcase + opcode <= data_in; // (only use opcode next cycle) end // state 3: compute ALU op and flags S_COMPUTE: begin @@ -198,6 +200,8 @@ module CPU16(clk, reset, halt, busy, endmodule +`ifdef TOPMOD__test_CPU16_top + module test_CPU16_top( input clk, input reset, @@ -221,7 +225,7 @@ module test_CPU16_top( CPU16 cpu( .clk(clk), .reset(reset), - .halt(0), + .hold(0), .busy(busy), .address(address_bus), .data_in(to_cpu), @@ -271,3 +275,5 @@ Loop: endmodule `endif + +`endif diff --git a/presets/verilog/cpu8.v b/presets/verilog/cpu8.v index 8dce2b86..d8409fa5 100644 --- a/presets/verilog/cpu8.v +++ b/presets/verilog/cpu8.v @@ -233,6 +233,8 @@ module CPU(clk, reset, address, data_in, data_out, write); endmodule +`ifdef TOPMOD__test_CPU_top + module test_CPU_top( input clk, input reset, @@ -275,29 +277,31 @@ module test_CPU_top( to_cpu = rom[address_bus[6:0]]; initial begin +`ifdef EXT_INLINE_ASM + // example code: Fibonacci sequence rom = '{ - `I_CLEAR_CARRY, - `I_ZERO_A, - `I_CONST_IMM_B, - 1, - `I_COMPUTE(`DEST_A, `OP_ADC), // addr 4 - `I_SWAP_AB, - `I_BRANCH_IF_CARRY(1'b0), - 4 + 'h80, // correct for ROM offset - `I_STORE_A(4'd0), - `I_RESET, - // leftover elements - 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,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,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 + __asm + +.arch femto8 +.org 128 +.len 128 + +Start: + zero A ; A <= 0 + ldb #1 ; B <= 1 +Loop: + add A,B ; A <= A + B + swapab ; swap A,B + bcc Loop ; repeat until carry set + reset ; end of loop; reset CPU + + __endasm }; +`endif end endmodule `endif + +`endif diff --git a/presets/verilog/femto8.json b/presets/verilog/femto8.json new file mode 100644 index 00000000..ce6eb4c5 --- /dev/null +++ b/presets/verilog/femto8.json @@ -0,0 +1,29 @@ +{ + "name":"femto8", + "vars":{ + "reg":{"bits":2, "toks":["a", "b", "ip", "none"]}, + "unop":{"bits":3, "toks":["zero","loada","inc","dec","asl","lsr","rol","ror"]}, + "binop":{"bits":3, "toks":["or","and","xor","mov","add","sub","adc","sbb"]}, + "const4":{"bits":4}, + "imm8":{"bits":8} + }, + "rules":[ + {"fmt":"~binop ~reg,b", "bits":["00",1,"1",0]}, + {"fmt":"~binop ~reg,#~imm8", "bits":["01",1,"1",0,2]}, + {"fmt":"~binop ~reg,[b]", "bits":["11",1,"1",0]}, + {"fmt":"~unop ~reg", "bits":["00",1,"0",0]}, + {"fmt":"mov ~reg,[b]", "bits":["11",0,"1011"]}, + {"fmt":"zero ~reg", "bits":["00",0,"1011"]}, + {"fmt":"lda #~imm8", "bits":["01","00","1011",0]}, + {"fmt":"ldb #~imm8", "bits":["01","01","1011",0]}, + {"fmt":"jmp ~imm8", "bits":["01","10","1011",0]}, + {"fmt":"sta ~const4", "bits":["1001",0]}, + {"fmt":"bcc ~imm8", "bits":["1010","0001",0]}, + {"fmt":"bcs ~imm8", "bits":["1010","0011",0]}, + {"fmt":"bz ~imm8", "bits":["1010","1100",0]}, + {"fmt":"bnz ~imm8", "bits":["1010","0100",0]}, + {"fmt":"clc", "bits":["10001000"]}, + {"fmt":"swapab", "bits":["10000001"]}, + {"fmt":"reset", "bits":["10001111"]} + ] +} diff --git a/presets/verilog/framebuffer.v b/presets/verilog/framebuffer.v index 69552adb..31d97527 100644 --- a/presets/verilog/framebuffer.v +++ b/presets/verilog/framebuffer.v @@ -1,8 +1,6 @@ -`undef EXT_INLINE_ASM `include "hvsync_generator.v" `include "cpu8.v" `include "cpu16.v" -`define EXT_INLINE_ASM // uncomment to see scope view //`define DEBUG diff --git a/presets/verilog/sprite_multiple.v b/presets/verilog/racing_game.v similarity index 100% rename from presets/verilog/sprite_multiple.v rename to presets/verilog/racing_game.v diff --git a/presets/verilog/ram1.v b/presets/verilog/ram1.v index 02e80d94..e727e775 100644 --- a/presets/verilog/ram1.v +++ b/presets/verilog/ram1.v @@ -1,15 +1,18 @@ `include "hvsync_generator.v" `include "digits10.v" -module RAM_1KB(clk, addr, din, dout, we); +module RAM(clk, addr, din, dout, we); + + parameter A = 10; // # of address bits + parameter D = 8; // # of data bits input clk; // clock - input [9:0] addr; // 10-bit address - input [7:0] din; // 8-bit data input - output [7:0] dout; // 8-bit data output + input [A-1:0] addr; // 10-bit address + input [D-1:0] din; // 8-bit data input + output [D-1:0] dout; // 8-bit data output input we; // write enable - reg [7:0] mem [0:1023]; // 1024x8 bit memory + reg [D-1:0] mem [0:(1< 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]) begin + // load next word from vline buffer + if (!&hpos[2:0]) begin + vshift <= vline[vindex]; + vindex <= vindex + 1; + end else + vshift <= {2'b0, vshift[15:2]}; + // decode scanline RAM to RGB output + rgb <= vshift[3:0]; + end else + rgb <= 0; + end + + /* + reg [14:0] vpu_read; + reg [15:0] vpu_buffer; + reg [3:0] rgb; + + always @(posedge clk) begin + if (!hpos[8] && !vpos[8]) begin + if (hpos[1:0] == 0) begin + vpu_buffer <= ram[vpu_read]; + vpu_read <= vpu_read + 1; + end + //rgb <= ram[{vpos[6:0],hpos[7:0]}][3:0]; + case (hpos[1:0]) + 0: rgb <= vpu_buffer[3:0]; + 1: rgb <= vpu_buffer[7:4]; + 2: rgb <= vpu_buffer[11:8]; + 3: rgb <= vpu_buffer[15:12]; + endcase + end else begin + rgb <= 0; + if (vpos[8]) + vpu_read <= 0; + end + end + */ + +`ifdef EXT_INLINE_ASM + initial begin + rom = '{ + __asm +.arch femto16 +.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 +Loop: + mov [bx],ax + inc bx + inc ax + bnz Loop + reset + __endasm + }; + end +`endif + +endmodule diff --git a/presets/verilog/sound_generator.v b/presets/verilog/sound_generator.v new file mode 100644 index 00000000..11213fad --- /dev/null +++ b/presets/verilog/sound_generator.v @@ -0,0 +1,104 @@ +`include "hvsync_generator.v" +`include "lfsr.v" + +module sound_generator(clk, reset, spkr, + lfo_freq,noise_freq, vco_freq, + vco_select, noise_select, lfo_shift, mixer); + + input clk, reset; + output reg spkr = 0; // module output + + input [9:0] lfo_freq; // LFO frequency (10 bits) + input [11:0] noise_freq; // noise frequency (12 bits) + input [11:0] vco_freq; // VCO frequency (12 bits) + input vco_select; // 1 = LFO modulates VCO + input noise_select; // 1 = LFO modulates Noise + input [2:0] lfo_shift; // LFO modulation depth + input [2:0] mixer; // mix enable {LFO, Noise, VCO} + + reg [3:0] div16; // divide-by-16 counter + reg [17:0] lfo_count; // LFO counter (18 bits) + reg lfo_state; // LFO output + reg [12:0] noise_count; // Noise counter (13 bits) + reg noise_state; // Noise output + reg [12:0] vco_count; // VCO counter (12 bits) + reg vco_state; // VCO output + + reg [15:0] lfsr; // LFSR output + + LFSR #(16,16'b1000000001011,0) lfsr_gen( + .clk(clk), + .reset(reset), + .enable(div16 == 0 && noise_count == 0), + .lfsr(lfsr) + ); + + // create triangle waveform from LFO + wire [11:0] lfo_triangle = lfo_count[17] ? ~lfo_count[17:6] : lfo_count[17:6]; + wire [11:0] vco_delta = lfo_triangle >> lfo_shift; + + always @(posedge clk) begin + // divide clock by 64 + div16 <= div16 + 1; + if (div16 == 0) begin + // VCO oscillator + if (reset || vco_count == 0) begin + vco_state <= ~vco_state; + if (vco_select) + vco_count <= vco_freq + vco_delta; + else + vco_count <= vco_freq + 0; + end else + vco_count <= vco_count - 1; + // LFO oscillator + if (reset || lfo_count == 0) begin + lfo_state <= ~lfo_state; + lfo_count <= {lfo_freq, 8'b0}; + end else + lfo_count <= lfo_count - 1; + // Noise oscillator + if (reset || noise_count == 0) begin + if (lfsr[0]) + noise_state <= ~noise_state; + if (noise_select) + noise_count <= noise_freq + vco_delta; + else + noise_count <= noise_freq + 0; + end else + noise_count <= noise_count - 1; + // Mixer + spkr <= (lfo_state | ~mixer[2]) + & (noise_state | ~mixer[1]) + & (vco_state | ~mixer[0]); + end + end + +endmodule + +module test_snchip_top(clk, reset, hsync, vsync, rgb, spkr); + + input clk, reset; + output hsync; + output vsync; + output spkr; + output [2:0] rgb; + + // don't output a valid sync signal + assign hsync = 0; + assign vsync = 0; + assign rgb = {spkr,1'b0,1'b0}; + + sound_generator sndgen( + .clk(clk), + .reset(reset), + .spkr(spkr), + .lfo_freq(1000), + .noise_freq(90), + .vco_freq(250), + .vco_select(1), + .noise_select(1), + .lfo_shift(1), + .mixer(3) + ); + +endmodule diff --git a/presets/verilog/sprite_rotation.v b/presets/verilog/sprite_rotation.v index 2c96a730..e841f5cc 100644 --- a/presets/verilog/sprite_rotation.v +++ b/presets/verilog/sprite_rotation.v @@ -295,10 +295,10 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync, reg collision_detected; always @(posedge clk) - if (collision_gfx) - collision_detected <= collision_gfx; - else if (vsync) + if (vstart) collision_detected <= 0; + else if (collision_gfx) + collision_detected <= 1; // sine lookup (4 bits input, 4 signed bits output) @@ -325,7 +325,7 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync, player_y_fixed <= initial_y << 4; end else begin // movement - if (collision_detected && vpos[1]) begin + if (collision_detected && vpos[3:1] == 0) begin if (vpos[0]) player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot+8)); else diff --git a/presets/verilog/sprite_scanline_renderer.v b/presets/verilog/sprite_scanline_renderer.v new file mode 100644 index 00000000..76f89c9e --- /dev/null +++ b/presets/verilog/sprite_scanline_renderer.v @@ -0,0 +1,206 @@ +`include "hvsync_generator.v" + +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[8'h00] = 16'b11110000000; + bitarray[8'h01] = 16'b100001000000; + bitarray[8'h02] = 16'b1111111100000; + bitarray[8'h03] = 16'b1111111100000; + bitarray[8'h04] = 16'b11110000000; + bitarray[8'h05] = 16'b11111111110000; + bitarray[8'h06] = 16'b111100001111000; + bitarray[8'h07] = 16'b1111101101111100; + bitarray[8'h08] = 16'b1101100001101111; + bitarray[8'h09] = 16'b1101111111100110; + bitarray[8'h0a] = 16'b1001111111100000; + bitarray[8'h0b] = 16'b1111111100000; + bitarray[8'h0c] = 16'b1110011100000; + bitarray[8'h0d] = 16'b1100001100000; + bitarray[8'h0e] = 16'b1100001100000; + bitarray[8'h0f] = 16'b11100001110000; + end + +endmodule + +module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb, + rom_addr, rom_data); + + parameter NB = 5; + parameter MB = 2; + + localparam N = 1<= 256 + if (reset || vpos[8]) begin + // initialize counters, even though it works w/o it + i <= 0; + j <= 0; + k <= 0; + // wiggle sprites randomly once per frame + if (vpos == 256 && hpos < N) begin + sprite_xpos[move_index] <= sprite_xpos[move_index] + 8'(($random&3)-1); + sprite_ypos[move_index] <= sprite_ypos[move_index] + 8'(($random&3)-1); + end + end else + if (hpos < N*2) begin + // 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]); + // sprite is active if Y offset is 0..15 + 1: begin + if (z < 16) begin + line_yofs[j] <= z; // save Y offset + sprite_to_line[j] <= i; // save main array index + 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*4) begin + // copy sprites from main array to local array + case (hpos[1:0]) + 0: i <= sprite_to_line[j]; + // transfer sprite X pos to line array + 1: line_xpos[j] <= sprite_xpos[i]; + // transfer sprite attribte to line array + 2: line_attr[j] <= sprite_attr[i]; + // increment 2nd array counter + 3: j <= j + 1; + endcase + end else if (hpos < N*2+M*4+M*32) begin + i <= 0; + j <= 0; + if (hpos[4:0] < 16) begin + // render sprites into write buffer + case (hpos[4:0]) + // load scanline buffer offset to write + 0: write_ofs <= {~vpos[0], line_xpos[k]}; + // set ROM address and fetch bitmap + 1: rom_addr <= {4'b0, line_attr[k][7:4], line_yofs[k]}; + // fetch 0 if sprite is inactive + 2: out_bitmap <= line_active[k] ? rom_data : 0; + // load attribute for sprite + 3: out_attr <= line_attr[k]; + // disable sprite for next scanline + 6: line_active[k] <= 0; + // go to next sprite in 2ndary buffer + 7: k <= k + 1; + endcase + 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 + + // read and clear buffer + rgb <= scanline[read_bufidx]; + scanline[read_bufidx] <= 0; + end + + initial + begin + sprite_xpos[0] = 0; + sprite_ypos[0] = 0; + sprite_attr[0] = 1; + end + +endmodule + +module test_scanline_render_top(clk, reset, hsync, vsync, rgb); + + input clk, reset; + output hsync, vsync; + output [3: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 [15:0] rom_addr; + wire [15:0] rom_data; + + example_bitmap_rom bitmap_rom( + .addr(rom_addr), + .data(rom_data) + ); + + sprite_scanline_renderer ssr( + .clk(clk), + .reset(reset), + .hpos(hpos), + .vpos(vpos), + .rgb(rgb), + .rom_addr(rom_addr), + .rom_data(rom_data) + ); + +endmodule diff --git a/presets/verilog/tank.v b/presets/verilog/tank.v index c01e06b6..1fbcb905 100644 --- a/presets/verilog/tank.v +++ b/presets/verilog/tank.v @@ -1,4 +1,5 @@ `include "hvsync_generator.v" +`include "digits10.v" `include "sprite_rotation.v" module minefield(hpos, vpos, mine_gfx); @@ -100,7 +101,7 @@ module playfield(hpos, vpos, playfield_gfx); endmodule -module mine_test_top(clk, reset, hsync, vsync, rgb, switches_p1, switches_p2); +module tank_game_top(clk, reset, hsync, vsync, rgb, switches_p1, switches_p2); input clk, reset; input [7:0] switches_p1; @@ -114,7 +115,7 @@ module mine_test_top(clk, reset, hsync, vsync, rgb, switches_p1, switches_p2); wire mine_gfx; wire playfield_gfx; wire tank1_gfx, tank2_gfx; - + hvsync_generator hvsync_gen( .clk(clk), .reset(0), diff --git a/src/emu.js b/src/emu.js index 6a5cdf0b..e2c906ce 100644 --- a/src/emu.js +++ b/src/emu.js @@ -228,7 +228,12 @@ var AnimationTimer = function(frequencyHz, callback) { } if (!useReqAnimFrame || ts - lastts > intervalMsec/2) { if (running) { - callback(); + try { + callback(); + } catch (e) { + running = false; + throw e; + } } if (ts - lastts < intervalMsec*30) { lastts += intervalMsec; diff --git a/src/platform/verilog.js b/src/platform/verilog.js index b0ef0af2..292a359f 100644 --- a/src/platform/verilog.js +++ b/src/platform/verilog.js @@ -4,23 +4,24 @@ var VERILOG_PRESETS = [ {id:'clock_divider.v', name:'Clock Divider'}, {id:'hvsync_generator.v', name:'Video Sync Generator'}, {id:'test_hvsync.v', name:'Test Pattern'}, - {id:'digits10.v', name:'Bitmapped Digits'}, {id:'7segment.v', name:'7-Segment Decoder'}, + {id:'digits10.v', name:'Bitmapped Digits'}, {id:'scoreboard.v', name:'Scoreboard'}, {id:'ball_slip_counter.v', name:'Ball Motion (slipping counter)'}, {id:'ball_paddle.v', name:'Brick Smash Game'}, {id:'ram1.v', name:'RAM Text Display'}, {id:'sprite_bitmap.v', name:'Sprite Bitmaps'}, {id:'sprite_renderer.v', name:'Sprite Rendering'}, - {id:'sprite_multiple.v', name:'Multiple Sprites'}, {id:'sprite_rotation.v', name:'Sprite Rotation'}, {id:'tank.v', name:'Tank Game'}, - {id:'cpu8.v', name:'Simple 8-Bit CPU'}, - {id:'racing_game_cpu.v', name:'Racing Game With CPU'}, - {id:'music.v', name:'3-Voice Music'}, + {id:'sound_generator.v', name:'Sound Generator'}, {id:'lfsr.v', name:'Linear Feedback Shift Register'}, {id:'starfield.v', name:'Scrolling Starfield'}, + {id:'racing_game.v', name:'Racing Game'}, + {id:'cpu8.v', name:'Simple 8-Bit CPU'}, + {id:'racing_game_cpu.v', name:'Racing Game with CPU'}, {id:'framebuffer.v', name:'Frame Buffer'}, + {id:'sprite_scanline_renderer.v', name:'Sprite Scanline Renderer'}, ]; var VERILOG_KEYCODE_MAP = makeKeycodeMap([ @@ -80,6 +81,9 @@ var vl_stopped = false; var VL_MODDIV_III = this.VL_MODDIV_III = function(lbits,lhs,rhs) { return (((rhs)==0)?0:(lhs)%(rhs)); } + var VL_MODDIVS_III = this.VL_MODDIVS_III = function(lbits,lhs,rhs) { + return (((rhs)==0)?0:(lhs)%(rhs)); } + var VL_REDXOR_32 = this.VL_REDXOR_32 = function(r) { r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); return r; @@ -98,6 +102,8 @@ var vl_stopped = false; var VL_RAND_RESET_I = this.VL_RAND_RESET_I = function(bits) { return 0 | Math.floor(Math.random() * (1< paddle_x ? 1 : 0; gen.vpaddle = y > paddle_y ? 1 : 0; @@ -283,15 +298,16 @@ var VerilogPlatform = function(mainElement, options) { if (trace) { inspect_data[i] = inspect_obj[inspect_sym]; } - idata[i++] = RGBLOOKUP[gen.rgb & 7]; + idata[i++] = RGBLOOKUP[gen.rgb & 15]; } var z=0; while (!gen.hsync && z++