mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-26 22:29:56 +00:00
work on simple CPU, paddle game, `include local files too, scope scrolling, hvsync reset
This commit is contained in:
parent
80588fcb31
commit
d732f320b0
@ -74,6 +74,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
@ -125,10 +126,11 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
reg main_gfx;
|
||||
reg brick_present;
|
||||
reg [6:0] brick_index;
|
||||
wire brick_gfx = lr_border || (brick_present && vpos[2:0] != 0 && hpos[3:1] != 4);
|
||||
|
||||
wire visible_clk = clk & display_on;
|
||||
|
||||
// compute main_gfx and locate bricks
|
||||
// scan bricks: compute brick_index and brick_present flag
|
||||
always @(posedge visible_clk)
|
||||
// see if we are scanning brick area
|
||||
if (vpos[8:6] == 1 && !lr_border)
|
||||
@ -137,29 +139,17 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
if (hpos[3:0] == 8) begin
|
||||
// compute brick index
|
||||
brick_index <= {vpos[5:3], hpos[7:4]};
|
||||
main_gfx <= 0; // 2 pixel horiz spacing between bricks
|
||||
//main_gfx <= 0; // 2 pixel horiz spacing between bricks
|
||||
end
|
||||
// every 17th pixel
|
||||
else if (hpos[3:0] == 9) begin
|
||||
// load brick bit from array
|
||||
brick_present <= brick_array[brick_index];
|
||||
end else begin
|
||||
main_gfx <= brick_present && vpos[2:0] != 0; // 1 pixel vert. spacing
|
||||
//main_gfx <= brick_present && vpos[2:0] != 0; // 1 pixel vert. spacing
|
||||
end
|
||||
end else begin
|
||||
brick_present <= 0;
|
||||
case (vpos[8:3])
|
||||
0: main_gfx <= score_gfx; // scoreboard
|
||||
1: main_gfx <= score_gfx;
|
||||
2: main_gfx <= score_gfx;
|
||||
3: main_gfx <= 0;
|
||||
4: main_gfx <= 1; // top border
|
||||
//14: main_gfx <= hpos[4];
|
||||
//21: main_gfx <= hpos[5];
|
||||
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
|
||||
|
||||
// only works when paddle at bottom of screen!
|
||||
@ -171,15 +161,16 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
wire ball_pixel_collide = main_gfx & ball_gfx;
|
||||
|
||||
/* verilator lint_off MULTIDRIVEN */
|
||||
reg [4:0] ball_collide_bits = 0;
|
||||
reg ball_collide_paddle = 0;
|
||||
reg [3:0] ball_collide_bits = 0;
|
||||
/* verilator lint_on MULTIDRIVEN */
|
||||
|
||||
// compute ball collisions with paddle and playfield
|
||||
always @(posedge visible_clk)
|
||||
if (ball_pixel_collide) begin
|
||||
if (paddle_gfx) begin
|
||||
// did we collide w/ paddle?
|
||||
ball_collide_bits[4] <= 1; // bit 4 == paddle collide
|
||||
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;
|
||||
@ -188,7 +179,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
if (ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[3] <= 1;
|
||||
end
|
||||
|
||||
// compute ball collisions with brick
|
||||
// compute ball collisions with brick and increment score
|
||||
always @(posedge visible_clk)
|
||||
if (ball_pixel_collide && brick_present) begin
|
||||
brick_array[brick_index] <= 0;
|
||||
@ -199,18 +190,18 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
|
||||
wire signed [8:0] ball_paddle_dx = ball_x - paddle_pos + 8;
|
||||
|
||||
// compute ball new position and velocity
|
||||
// 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_bits[4]) begin
|
||||
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 < 16) ? BALL_DIR_LEFT : BALL_DIR_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
|
||||
@ -238,8 +229,10 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
endcase
|
||||
end
|
||||
ball_collide_bits <= 0; // clear all collide bits for frame
|
||||
ball_collide_paddle <= 0;
|
||||
end
|
||||
|
||||
// ball motion: update ball position
|
||||
always @(negedge vsync or posedge reset)
|
||||
begin
|
||||
if (reset) begin
|
||||
@ -254,6 +247,29 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
end
|
||||
end
|
||||
|
||||
// compute main_gfx
|
||||
always @(*)
|
||||
begin
|
||||
case (vpos[8:3])
|
||||
0: main_gfx = score_gfx; // scoreboard
|
||||
1: main_gfx = score_gfx;
|
||||
2: main_gfx = score_gfx;
|
||||
3: main_gfx = 0;
|
||||
4: main_gfx = 1; // top border
|
||||
8: main_gfx = brick_gfx; // 1st brick row
|
||||
9: main_gfx = brick_gfx; // ...
|
||||
10: main_gfx = brick_gfx;
|
||||
11: main_gfx = brick_gfx;
|
||||
12: main_gfx = brick_gfx;
|
||||
13: main_gfx = brick_gfx;
|
||||
14: main_gfx = brick_gfx;
|
||||
15: main_gfx = brick_gfx; // 8th brick row
|
||||
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
|
||||
|
||||
wire grid_gfx = (((hpos&7)==0) || ((vpos&7)==0));
|
||||
|
||||
wire r = display_on && (ball_gfx | paddle_gfx);
|
||||
|
@ -10,14 +10,17 @@ module ball_paddle_top(clk, reset, hsync, vsync, rgb);
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
|
||||
reg [7:0] ball_htimer;
|
||||
reg [7:0] ball_vtimer;
|
||||
reg [8:0] ball_htimer;
|
||||
reg [8:0] ball_vtimer;
|
||||
|
||||
reg [3:0] ball_horiz_vel;
|
||||
reg [3:0] ball_vert_vel;
|
||||
reg [8:0] ball_horiz_stop = 209;
|
||||
reg [8:0] ball_horiz_move = -2;
|
||||
reg [8:0] ball_vert_stop = 251;
|
||||
reg [8:0] ball_vert_move = 2;
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
@ -25,29 +28,56 @@ module ball_paddle_top(clk, reset, hsync, vsync, rgb);
|
||||
.vpos(vpos)
|
||||
);
|
||||
|
||||
always @(posedge clk)
|
||||
// update horizontal timer
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (hpos == 0 && vpos == 0)
|
||||
ball_htimer <= ball_htimer + 8'(ball_horiz_vel) - 4;
|
||||
else if (display_on)
|
||||
if (reset)
|
||||
ball_htimer <= ball_horiz_stop - 128;
|
||||
else if (ball_htimer == 0) begin
|
||||
if (ball_vtimer == 0)
|
||||
ball_htimer <= ball_horiz_stop + ball_horiz_move;
|
||||
else
|
||||
ball_htimer <= ball_horiz_stop;
|
||||
end else
|
||||
ball_htimer <= ball_htimer + 1;
|
||||
end;
|
||||
|
||||
always @(posedge hsync)
|
||||
// update vertical timer
|
||||
always @(posedge hsync or posedge reset)
|
||||
begin
|
||||
if (vpos > 9'(ball_vert_vel))
|
||||
if (reset)
|
||||
ball_vtimer <= ball_vert_stop - 128;
|
||||
else if (ball_vtimer == 0)
|
||||
ball_vtimer <= ball_vert_stop + ball_vert_move;
|
||||
else
|
||||
ball_vtimer <= ball_vtimer + 1;
|
||||
end;
|
||||
|
||||
wire ball_hgfx = ball_htimer < 8;
|
||||
wire ball_vgfx = ball_vtimer < 8;
|
||||
wire ball_gfx = ball_hgfx & ball_vgfx;
|
||||
// vertical bounce
|
||||
always @(posedge ball_vert_collide)
|
||||
begin
|
||||
ball_vert_move <= -ball_vert_move;
|
||||
end;
|
||||
|
||||
wire grid_gfx = (((hpos&7)==0) || ((vpos&7)==0));
|
||||
// horizontal bounce
|
||||
always @(posedge ball_horiz_collide)
|
||||
begin
|
||||
ball_horiz_move <= -ball_horiz_move;
|
||||
end;
|
||||
|
||||
wire r = display_on && (grid_gfx | ball_gfx);
|
||||
wire g = display_on && ball_gfx;
|
||||
wire b = display_on && ball_gfx;
|
||||
wire ball_hgfx = ball_htimer >= 508;
|
||||
wire ball_vgfx = ball_vtimer >= 508;
|
||||
wire ball_gfx = ball_hgfx && ball_vgfx;
|
||||
|
||||
// collide with vertical and horizontal boundaries
|
||||
wire ball_vert_collide = ball_vgfx && vpos >= 240;
|
||||
wire ball_horiz_collide = ball_hgfx && hpos >= 256 && vpos == 255;
|
||||
|
||||
wire grid_gfx = (((hpos&7)==0) && ((vpos&7)==0));
|
||||
|
||||
wire r = display_on && (ball_hgfx | ball_gfx);
|
||||
wire g = display_on && (grid_gfx | ball_gfx);
|
||||
wire b = display_on && (ball_vgfx | ball_gfx);
|
||||
assign rgb = {b,g,r};
|
||||
|
||||
endmodule
|
||||
|
@ -157,6 +157,7 @@ module test_numbers_top(clk, hsync, vsync, rgb);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
|
@ -2,15 +2,16 @@
|
||||
`define HVSYNC_GENERATOR_H
|
||||
|
||||
module hvsync_generator(
|
||||
clk, hsync, vsync, display_on, hpos, vpos);
|
||||
clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||
|
||||
input clk;
|
||||
output hsync, vsync;
|
||||
input reset;
|
||||
output reg hsync, vsync;
|
||||
output reg display_on;
|
||||
output reg [8:0] hpos;
|
||||
output reg [8:0] vpos;
|
||||
|
||||
// constant declarations for VGA sync parameters
|
||||
// constant declarations for TV-simulator sync parameters
|
||||
localparam H_DISPLAY = 256; // horizontal display area
|
||||
localparam H_L_BORDER = 16; // horizontal left border
|
||||
localparam H_R_BORDER = 16; // horizontal right border
|
||||
@ -27,15 +28,17 @@ module hvsync_generator(
|
||||
localparam START_V_RETRACE = V_DISPLAY + V_B_BORDER;
|
||||
localparam END_V_RETRACE = V_DISPLAY + V_B_BORDER + V_RETRACE - 1;
|
||||
|
||||
wire hmaxxed = (hpos==H_MAX);
|
||||
wire vmaxxed = (vpos==V_MAX);
|
||||
wire hmaxxed = (hpos == H_MAX) || reset;
|
||||
wire vmaxxed = (vpos == V_MAX) || reset;
|
||||
|
||||
// increment horizontal position counter
|
||||
always @(posedge clk)
|
||||
if(hmaxxed)
|
||||
hpos <= 0;
|
||||
else
|
||||
hpos <= hpos + 1;
|
||||
|
||||
// increment vertical position counter
|
||||
always @(posedge clk)
|
||||
if(hmaxxed)
|
||||
if (!vmaxxed)
|
||||
@ -43,14 +46,11 @@ module hvsync_generator(
|
||||
else
|
||||
vpos <= 0;
|
||||
|
||||
// compute hsync + vsync + display_on signals
|
||||
always @(posedge clk)
|
||||
begin
|
||||
hsync <= (hpos>=START_H_RETRACE && hpos<=END_H_RETRACE);
|
||||
vsync <= (vpos==START_V_RETRACE);
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
display_on <= (hpos<H_DISPLAY) && (vpos<V_DISPLAY);
|
||||
end
|
||||
|
||||
|
@ -1,196 +0,0 @@
|
||||
|
||||
`define OP_LOAD_A 4'h0
|
||||
`define OP_LOAD_B 4'h1
|
||||
`define OP_ADD 4'h2
|
||||
`define OP_SUB 4'h3
|
||||
`define OP_INC 4'h4
|
||||
`define OP_DEC 4'h5
|
||||
`define OP_ASL 4'h6
|
||||
`define OP_LSR 4'h7
|
||||
`define OP_OR 4'h8
|
||||
`define OP_AND 4'h9
|
||||
`define OP_XOR 4'ha
|
||||
|
||||
module ALU(A, B, Y, aluop);
|
||||
|
||||
input [7:0] A;
|
||||
input [7:0] B;
|
||||
output [8:0] Y;
|
||||
input [3:0] aluop;
|
||||
|
||||
always @(*)
|
||||
case (aluop)
|
||||
`OP_LOAD_A: Y = {1'b0, A};
|
||||
`OP_LOAD_B: Y = {1'b0, B};
|
||||
`OP_ADD: Y = A + B;
|
||||
`OP_SUB: Y = A - B;
|
||||
`OP_INC: Y = A + 1;
|
||||
`OP_DEC: Y = A - 1;
|
||||
`OP_ASL: Y = {A[7], A + A};
|
||||
`OP_LSR: Y = {A[0], A >> 1};
|
||||
`OP_OR: Y = {1'b0, A | B};
|
||||
`OP_AND: Y = {1'b0, A & B};
|
||||
`OP_XOR: Y = {1'b0, A ^ B};
|
||||
default: Y = 9'bx;
|
||||
endcase
|
||||
|
||||
endmodule
|
||||
|
||||
`define REG_A 1'b0
|
||||
`define REG_B 1'b1
|
||||
`define I_CONST(r,x) { 2'b00, r, x }
|
||||
`define I_LOAD_ADDR(r,addr) { 3'b010, r, addr }
|
||||
`define I_STORE_ADDR(r,addr) { 3'b011, r, addr }
|
||||
`define I_COMPUTE(r,op) { 3'b100, r, op }
|
||||
`define I_RESET 8'hff
|
||||
|
||||
module CPU(clk, reset, address, data_in, data_out, write);
|
||||
|
||||
input clk, reset;
|
||||
output [7:0] address;
|
||||
input [7:0] data_in;
|
||||
output [7:0] data_out;
|
||||
output write;
|
||||
|
||||
reg [7:0] ip;
|
||||
reg [7:0] opcode;
|
||||
reg [3:0] aluop;
|
||||
reg [7:0] A, B;
|
||||
reg [8:0] Y;
|
||||
reg [1:0] state;
|
||||
reg [2:0] action;
|
||||
|
||||
reg carry;
|
||||
reg zero;
|
||||
|
||||
localparam NOOP = 0;
|
||||
localparam MAKE_CONST = 1;
|
||||
localparam LOAD_ADDR = 2;
|
||||
localparam STORE_ADDR = 3;
|
||||
localparam COMPUTE = 4;
|
||||
|
||||
wire load_const = opcode[3:1] == 3'b111;
|
||||
|
||||
ALU alu(.A(A), .B(B), .Y(Y), .aluop(aluop));
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset) begin
|
||||
state <= 0;
|
||||
write <= 0;
|
||||
end else begin
|
||||
case (state)
|
||||
// state 0: reset
|
||||
0: begin
|
||||
ip <= 8'h80;
|
||||
write <= 0;
|
||||
state <= 1;
|
||||
end
|
||||
// state 1: select opcode address
|
||||
1: begin
|
||||
address <= ip;
|
||||
ip <= ip + 1;
|
||||
write <= 0;
|
||||
state <= 2;
|
||||
end
|
||||
// state 2: read/decode opcode
|
||||
2: begin
|
||||
casez (data_in)
|
||||
8'b00??????: begin
|
||||
action <= MAKE_CONST;
|
||||
if (data_in[5])
|
||||
B <= {3'b0, data_in[4:0]};
|
||||
else
|
||||
A <= {3'b0, data_in[4:0]};
|
||||
state <= 1;
|
||||
end
|
||||
8'b010?????: begin
|
||||
action <= LOAD_ADDR;
|
||||
address <= {4'b0, data_in[3:0]};
|
||||
state <= 3;
|
||||
end
|
||||
8'b011?????: begin
|
||||
action <= STORE_ADDR;
|
||||
address <= {4'b0, data_in[3:0]};
|
||||
state <= 3;
|
||||
end
|
||||
8'b100?????: begin
|
||||
action <= COMPUTE;
|
||||
aluop <= data_in[3:0];
|
||||
state <= 3;
|
||||
end
|
||||
default: begin
|
||||
action <= NOOP;
|
||||
state <= 0; // reset
|
||||
end
|
||||
endcase
|
||||
opcode <= data_in;
|
||||
end
|
||||
// state 3: perform action
|
||||
3: begin
|
||||
if (action == LOAD_ADDR) begin
|
||||
if (opcode[4])
|
||||
B <= data_in;
|
||||
else
|
||||
A <= data_in;
|
||||
end else if (action == STORE_ADDR) begin
|
||||
if (opcode[4])
|
||||
data_out <= B;
|
||||
else
|
||||
data_out <= A;
|
||||
write <= 1;
|
||||
end else if (action == COMPUTE) begin
|
||||
if (opcode[4])
|
||||
B <= Y[7:0];
|
||||
else
|
||||
A <= Y[7:0];
|
||||
carry <= Y[8];
|
||||
zero <= ~|Y;
|
||||
end
|
||||
state <= 1; // repeat loop at state 1
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test_CPU_top(clk, reset, address_bus, to_cpu, from_cpu, write_enable);
|
||||
|
||||
input clk, reset;
|
||||
output [7:0] address_bus;
|
||||
output reg [7:0] to_cpu;
|
||||
output [7:0] from_cpu;
|
||||
output write_enable;
|
||||
|
||||
reg [7:0] ram[128];
|
||||
reg [7:0] rom[128];
|
||||
|
||||
CPU cpu(.clk(clk),
|
||||
.reset(reset),
|
||||
.address(address_bus),
|
||||
.data_in(to_cpu),
|
||||
.data_out(from_cpu),
|
||||
.write(write_enable));
|
||||
|
||||
// does not work as (posedge clk)
|
||||
always @(*)
|
||||
if (write_enable)
|
||||
ram[address_bus[6:0]] = from_cpu;
|
||||
else if (address_bus[7] == 0)
|
||||
to_cpu = ram[address_bus[6:0]];
|
||||
else
|
||||
to_cpu = rom[address_bus[6:0]];
|
||||
|
||||
initial begin
|
||||
// address 0x80
|
||||
rom['h00] = `I_CONST(`REG_A, 5'h1f);
|
||||
rom['h01] = `I_COMPUTE(`REG_A, `OP_ASL);
|
||||
rom['h02] = `I_COMPUTE(`REG_A, `OP_ASL);
|
||||
rom['h03] = `I_COMPUTE(`REG_A, `OP_ASL);
|
||||
rom['h04] = `I_COMPUTE(`REG_A, `OP_ASL);
|
||||
rom['h05] = `I_COMPUTE(`REG_B, `OP_LOAD_A);
|
||||
rom['h06] = `I_STORE_ADDR(`REG_B, 4'd1);
|
||||
rom['h07] = `I_LOAD_ADDR(`REG_B, 4'd1);
|
||||
rom['h08] = `I_RESET;
|
||||
end
|
||||
|
||||
endmodule
|
@ -29,7 +29,7 @@ module car_bitmap(yofs, bits);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module test_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
module sprite_bitmap_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
|
||||
input clk;
|
||||
input hpaddle, vpaddle;
|
||||
@ -49,6 +49,7 @@ module test_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
|
@ -24,6 +24,7 @@ module sprite_multiple_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
|
@ -102,6 +102,7 @@ module test_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
|
@ -11,6 +11,7 @@ module test_hvsync_top(clk, hsync, vsync, rgb);
|
||||
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
.display_on(display_on),
|
||||
|
@ -11,6 +11,7 @@ var VERILOG_PRESETS = [
|
||||
{id:'sprite_bitmap.v', name:'Sprite Bitmaps'},
|
||||
{id:'sprite_renderer.v', name:'Sprite Rendering'},
|
||||
{id:'sprite_multiple.v', name:'Multiple Sprites'},
|
||||
{id:'cpu8.v', name:'Simple 8-Bit CPU'},
|
||||
];
|
||||
|
||||
var VERILOG_KEYCODE_MAP = makeKeycodeMap([
|
||||
@ -170,7 +171,8 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
var switches = [0];
|
||||
var inspect_obj, inspect_sym;
|
||||
var inspect_data = new Uint32Array(videoWidth * videoHeight);
|
||||
var scope_time_x = 0;
|
||||
var scope_time_x = 0; // scope cursor
|
||||
var scope_x_offset = 0;
|
||||
var scope_y_offset = 0;
|
||||
var scope_max_y = 0;
|
||||
|
||||
@ -289,7 +291,8 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
var COLOR_BORDER = 0xff662222;
|
||||
var COLOR_TRANS_SIGNAL = 0xff226622;
|
||||
var COLOR_BLIP_SIGNAL = 0xff226622;
|
||||
var j = 0;
|
||||
var jstart = scope_x_offset * arr.length;
|
||||
var j = jstart;
|
||||
for (var x=0; x<videoWidth; x++) {
|
||||
var yb = 8;
|
||||
var y1 = scope_y_offset;
|
||||
@ -315,7 +318,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
y1 += ys+yb;
|
||||
}
|
||||
}
|
||||
scope_max_y = y1;
|
||||
scope_max_y = y1 - scope_y_offset;
|
||||
video.updateFrame();
|
||||
// draw labels
|
||||
var ctx = video.getContext();
|
||||
@ -327,12 +330,27 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
ctx.textAlign = 'left';
|
||||
ctx.fillText(name, 1, yposlist[i]);
|
||||
if (scope_time_x > 0) {
|
||||
ctx.fillRect(scope_time_x, 0, 1, 4000);
|
||||
ctx.textAlign = 'right';
|
||||
var value = arr.length * scope_time_x + i;
|
||||
var value = arr.length * scope_time_x + i + jstart;
|
||||
ctx.fillText(""+trace_buffer[value], videoWidth-1, yposlist[i]);
|
||||
}
|
||||
}
|
||||
// draw scope line & label
|
||||
if (scope_time_x > 0) {
|
||||
ctx.fillStyle = "cyan";
|
||||
ctx.fillText(""+(scope_time_x+scope_x_offset),
|
||||
(scope_time_x>10)?(scope_time_x-2):(scope_time_x+20), videoHeight-2);
|
||||
ctx.fillRect(scope_time_x, 0, 1, 4000);
|
||||
}
|
||||
// scroll left/right
|
||||
if (scope_time_x >= videoWidth && scope_x_offset < (trace_buffer.length / arr.length) - videoWidth) {
|
||||
scope_x_offset += 1 + (scope_time_x - videoWidth);
|
||||
dirty = true;
|
||||
}
|
||||
else if (scope_time_x < 0 && scope_x_offset > 0) {
|
||||
scope_x_offset = Math.max(0, scope_x_offset + scope_time_x);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
function clamp(minv,maxv,v) {
|
||||
@ -352,7 +370,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
var new_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 20);
|
||||
var new_y = Math.floor(e.offsetY * video.canvas.height / $(video.canvas).height() - 20);
|
||||
if (mouse_pressed) {
|
||||
scope_y_offset = clamp(-scope_max_y, 0, scope_y_offset + new_y - paddle_y);
|
||||
scope_y_offset = clamp(Math.min(0,-scope_max_y+videoHeight), 0, scope_y_offset + new_y - paddle_y);
|
||||
scope_time_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 16);
|
||||
dirty = true;
|
||||
}
|
||||
@ -432,7 +450,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
}
|
||||
this.reset = function() {
|
||||
gen.__reset();
|
||||
trace_index = 0;
|
||||
trace_index = scope_x_offset = 0;
|
||||
trace_buffer.fill(0);
|
||||
dirty = true;
|
||||
}
|
||||
@ -462,6 +480,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
} else {
|
||||
inspect_obj = inspect_sym = null;
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// DEBUGGING
|
||||
|
@ -419,12 +419,12 @@ function updateSelector() {
|
||||
function loadFileDependencies(text) {
|
||||
var arr = [];
|
||||
if (platform_id == 'verilog') {
|
||||
var re = /`include\s+"(.+)"/g;
|
||||
var re = /`include\s+"(.+?)"/g;
|
||||
var m;
|
||||
while (m = re.exec(text)) {
|
||||
arr.push({
|
||||
filename:m[1],
|
||||
text:store.loadFile(m[1]) // TODO: if missing?
|
||||
text:store.loadFile(m[1]) || store.loadFile('local/'+m[1]) // TODO??
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -836,7 +836,7 @@ function toggleDisassembly() {
|
||||
}
|
||||
|
||||
function resetAndDebug() {
|
||||
if (platform.setupDebug) {
|
||||
if (platform.setupDebug && platform.readAddress) { // TODO??
|
||||
clearBreakpoint();
|
||||
_resume();
|
||||
platform.reset();
|
||||
|
@ -1087,7 +1087,7 @@ function compileVerilator(code, platform, options) {
|
||||
function compileYosys(code, platform, options) {
|
||||
loadNative("yosys");
|
||||
var errors = [];
|
||||
var match_fn = makeErrorMatcher(errors, /ERROR: (.+?) in line (.+?[.]v):(\d+) (.+)/i, 3, 4);
|
||||
var match_fn = makeErrorMatcher(errors, /ERROR: (.+?) in line (.+?[.]v):(\d+)[: ]+(.+)/i, 3, 4);
|
||||
starttime();
|
||||
var yosys_mod = yosys({
|
||||
wasmBinary:wasmBlob['yosys'],
|
||||
@ -1101,7 +1101,13 @@ function compileYosys(code, platform, options) {
|
||||
FS.writeFile(topmod+".v", code);
|
||||
writeDependencies(options.dependencies, FS, errors);
|
||||
starttime();
|
||||
try {
|
||||
yosys_mod.callMain(["-q", "-o", topmod+".json", "-S", topmod+".v"]);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
endtime("compile");
|
||||
return {errors:errors};
|
||||
}
|
||||
endtime("compile");
|
||||
if (errors.length) return {errors:errors};
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user