mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-22 12:30:01 +00:00
more presets
This commit is contained in:
parent
122e462c9f
commit
11992645d6
@ -1,6 +1,7 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
module seven_segment_decoder(digit, segments);
|
module seven_segment_decoder(digit, segments);
|
||||||
|
|
||||||
input [3:0] digit;
|
input [3:0] digit;
|
||||||
output [6:0] segments;
|
output [6:0] segments;
|
||||||
|
|
||||||
@ -18,29 +19,41 @@ module seven_segment_decoder(digit, segments);
|
|||||||
9: segments = 7'b1111011;
|
9: segments = 7'b1111011;
|
||||||
default: segments = 7'b0000000;
|
default: segments = 7'b0000000;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module segments_to_bitmap(segments, line, bits);
|
module segments_to_bitmap(segments, line, bits);
|
||||||
|
|
||||||
input [6:0] segments;
|
input [6:0] segments;
|
||||||
input [2:0] line;
|
input [2:0] line;
|
||||||
output [4:0] bits;
|
output [4:0] bits;
|
||||||
|
|
||||||
always @(*)
|
always @(*)
|
||||||
case (line)
|
case (line)
|
||||||
0:bits = (segments[6]?5'b11111:0) ^ (segments[5]?5'b00001:0) ^ (segments[1]?5'b10000:0);
|
0:bits = (segments[6]?5'b11111:0)
|
||||||
1:bits = (segments[1]?5'b10000:0) ^ (segments[5]?5'b00001:0);
|
^ (segments[5]?5'b00001:0)
|
||||||
2:bits = (segments[0]?5'b11111:0) ^ (|segments[5:4]?5'b00001:0) ^ (|segments[2:1]?5'b10000:0);
|
^ (segments[1]?5'b10000:0);
|
||||||
3:bits = (segments[2]?5'b10000:0) ^ (segments[4]?5'b00001:0);
|
1:bits = (segments[1]?5'b10000:0)
|
||||||
4:bits = (segments[3]?5'b11111:0) ^ (segments[4]?5'b00001:0) ^ (segments[2]?5'b10000:0);
|
^ (segments[5]?5'b00001:0);
|
||||||
|
2:bits = (segments[0]?5'b11111:0)
|
||||||
|
^ (|segments[5:4]?5'b00001:0)
|
||||||
|
^ (|segments[2:1]?5'b10000:0);
|
||||||
|
3:bits = (segments[2]?5'b10000:0)
|
||||||
|
^ (segments[4]?5'b00001:0);
|
||||||
|
4:bits = (segments[3]?5'b11111:0)
|
||||||
|
^ (segments[4]?5'b00001:0)
|
||||||
|
^ (segments[2]?5'b10000:0);
|
||||||
default:bits = 0;
|
default:bits = 0;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module test_numbers_top(
|
module test_numbers_top(clk, reset, hsync, vsync, rgb);
|
||||||
input clk, reset,
|
|
||||||
output hsync, vsync,
|
input clk, reset;
|
||||||
output [2:0] rgb
|
output hsync, vsync;
|
||||||
);
|
output [2:0] rgb;
|
||||||
|
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
|
75
presets/verilog/ball_absolute.v
Normal file
75
presets/verilog/ball_absolute.v
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
module ball_paddle_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset;
|
||||||
|
output hsync, vsync;
|
||||||
|
output [2:0] rgb;
|
||||||
|
wire display_on;
|
||||||
|
wire [8:0] hpos;
|
||||||
|
wire [8:0] vpos;
|
||||||
|
|
||||||
|
reg [8:0] ball_hpos;
|
||||||
|
reg [8:0] ball_vpos;
|
||||||
|
|
||||||
|
reg [8:0] ball_horiz_initial = 128;
|
||||||
|
reg [8:0] ball_horiz_move = -2;
|
||||||
|
reg [8:0] ball_vert_initial = 128;
|
||||||
|
reg [8:0] ball_vert_move = 2;
|
||||||
|
|
||||||
|
localparam BALL_SIZE = 8;
|
||||||
|
|
||||||
|
hvsync_generator hvsync_gen(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.hsync(hsync),
|
||||||
|
.vsync(vsync),
|
||||||
|
.display_on(display_on),
|
||||||
|
.hpos(hpos),
|
||||||
|
.vpos(vpos)
|
||||||
|
);
|
||||||
|
|
||||||
|
// update horizontal timer
|
||||||
|
always @(posedge vsync or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset) begin
|
||||||
|
ball_hpos <= ball_horiz_initial;
|
||||||
|
ball_vpos <= ball_vert_initial;
|
||||||
|
end else begin
|
||||||
|
ball_hpos <= ball_hpos + ball_horiz_move;
|
||||||
|
ball_vpos <= ball_vpos + ball_vert_move;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// vertical bounce
|
||||||
|
always @(posedge ball_vert_collide)
|
||||||
|
begin
|
||||||
|
ball_vert_move <= -ball_vert_move;
|
||||||
|
end
|
||||||
|
|
||||||
|
// horizontal bounce
|
||||||
|
always @(posedge ball_horiz_collide)
|
||||||
|
begin
|
||||||
|
ball_horiz_move <= -ball_horiz_move;
|
||||||
|
end
|
||||||
|
|
||||||
|
wire [8:0] ball_hdiff = ball_hpos - hpos;
|
||||||
|
wire [8:0] ball_vdiff = ball_vpos - vpos;
|
||||||
|
|
||||||
|
wire ball_hgfx = ball_hdiff < BALL_SIZE;
|
||||||
|
wire ball_vgfx = ball_vdiff < BALL_SIZE;
|
||||||
|
wire ball_gfx = ball_hgfx && ball_vgfx;
|
||||||
|
|
||||||
|
// collide with vertical and horizontal boundaries
|
||||||
|
wire ball_vert_collide = ball_vgfx && (vpos==V_DISPLAY || vpos==0);
|
||||||
|
wire ball_horiz_collide = ball_hgfx && vpos==0 && (hpos==H_DISPLAY || hpos==0);
|
||||||
|
|
||||||
|
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
|
@ -1,37 +1,6 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
|
`include "scoreboard.v"
|
||||||
module player_stats(reset, score0, score1, lives, incscore, declives);
|
|
||||||
|
|
||||||
input reset;
|
|
||||||
output [3:0] score0;
|
|
||||||
output [3:0] score1;
|
|
||||||
input incscore;
|
|
||||||
output [3:0] lives;
|
|
||||||
input declives;
|
|
||||||
|
|
||||||
always @(posedge incscore or posedge reset)
|
|
||||||
begin
|
|
||||||
if (reset) begin
|
|
||||||
score0 <= 0;
|
|
||||||
score1 <= 0;
|
|
||||||
end else if (score0 == 9) begin
|
|
||||||
score0 <= 0;
|
|
||||||
score1 <= score1 + 1;
|
|
||||||
end else begin
|
|
||||||
score0 <= score0 + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge declives or posedge reset)
|
|
||||||
begin
|
|
||||||
if (reset)
|
|
||||||
lives <= 3;
|
|
||||||
else if (lives != 0)
|
|
||||||
lives <= lives - 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||||
|
|
||||||
@ -88,26 +57,12 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
|||||||
.score0(score0), .score1(score1), .incscore(incscore),
|
.score0(score0), .score1(score1), .incscore(incscore),
|
||||||
.lives(lives), .declives(declives));
|
.lives(lives), .declives(declives));
|
||||||
|
|
||||||
wire [3:0] score_digit;
|
wire score_gfx;
|
||||||
wire [4:0] score_bits;
|
|
||||||
|
|
||||||
always @(*)
|
scoreboard_generator score_gen(
|
||||||
begin
|
.score0(score0), .score1(score1), .lives(lives),
|
||||||
case (hpos[7:5])
|
.vpos(vpos), .hpos(hpos),
|
||||||
1: score_digit = score1;
|
.board_gfx(score_gfx));
|
||||||
2: score_digit = score0;
|
|
||||||
6: score_digit = lives;
|
|
||||||
default: score_digit = 15; // no digit
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
digits10_case numbers(
|
|
||||||
.digit(score_digit),
|
|
||||||
.yofs(vpos[4:2]),
|
|
||||||
.bits(score_bits)
|
|
||||||
);
|
|
||||||
|
|
||||||
wire score_gfx = display_on && score_bits[hpos[4:2] ^ 3'b111];
|
|
||||||
|
|
||||||
wire [5:0] hcell = hpos[8:3];
|
wire [5:0] hcell = hpos[8:3];
|
||||||
wire [5:0] vcell = vpos[8:3];
|
wire [5:0] vcell = vpos[8:3];
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
module clock_divider(
|
module clock_divider(
|
||||||
input clk,
|
input clk,
|
||||||
|
input reset,
|
||||||
output reg clk_div2,
|
output reg clk_div2,
|
||||||
output reg clk_div4,
|
output reg clk_div4,
|
||||||
output reg clk_div8,
|
output reg clk_div8,
|
||||||
@ -27,7 +28,10 @@ module clock_divider(
|
|||||||
|
|
||||||
// use bits of (4-bit) counter to divide clocks
|
// use bits of (4-bit) counter to divide clocks
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk or posedge reset)
|
||||||
|
if (reset)
|
||||||
|
counter <= 0;
|
||||||
|
else
|
||||||
counter <= counter + 1;
|
counter <= counter + 1;
|
||||||
|
|
||||||
assign cntr_div2 = counter[0];
|
assign cntr_div2 = counter[0];
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
|
|
||||||
`define OP_LOAD_A 4'h0
|
`define OP_LOAD_A 4'h0
|
||||||
`define OP_LOAD_B 4'h1
|
`define OP_LOAD_B 4'h1
|
||||||
`define OP_ADD 4'h2
|
`define OP_OR 4'h2
|
||||||
`define OP_SUB 4'h3
|
`define OP_AND 4'h3
|
||||||
`define OP_INC 4'h4
|
`define OP_XOR 4'h4
|
||||||
`define OP_DEC 4'h5
|
`define OP_INC 4'h5
|
||||||
`define OP_ASL 4'h6
|
`define OP_DEC 4'h6
|
||||||
`define OP_LSR 4'h7
|
`define OP_NOP 4'h7
|
||||||
`define OP_OR 4'h8
|
// operations that generate carry
|
||||||
`define OP_AND 4'h9
|
`define OP_ADD 4'h8
|
||||||
`define OP_XOR 4'ha
|
`define OP_SUB 4'h9
|
||||||
`define OP_NOP 4'hf
|
`define OP_ASL 4'ha
|
||||||
|
`define OP_LSR 4'hb
|
||||||
|
|
||||||
module ALU(
|
module ALU(
|
||||||
input [7:0] A,
|
input [7:0] A,
|
||||||
@ -42,12 +43,16 @@ endmodule
|
|||||||
`define DEST_IP 2'b10
|
`define DEST_IP 2'b10
|
||||||
`define DEST_NOP 2'b11
|
`define DEST_NOP 2'b11
|
||||||
`define I_COMPUTE(dest,op) { 2'b00, 2'(dest), 4'(op) }
|
`define I_COMPUTE(dest,op) { 2'b00, 2'(dest), 4'(op) }
|
||||||
`define I_LOAD_IMM_A { 2'b01, `DEST_A, `OP_LOAD_A }
|
`define I_COMPUTE_IMM(dest,op) { 2'b01, 2'(dest), 4'(op) }
|
||||||
`define I_LOAD_IMM_B { 2'b01, `DEST_B, `OP_LOAD_B }
|
`define I_COMPUTE_READB(dest,op) { 2'b11, 2'(dest), 4'(op) }
|
||||||
`define I_JUMP_IMM { 2'b01, `DEST_IP, `OP_NOP }
|
`define I_CONST_IMM_A { 2'b01, `DEST_A, `OP_LOAD_B }
|
||||||
`define I_STORE_B(op) { 4'b01100, 4'(op) }
|
`define I_CONST_IMM_B { 2'b01, `DEST_B, `OP_LOAD_B }
|
||||||
`define I_STORE_IMM(op) { 4'b01101, 4'(op) }
|
`define I_JUMP_IMM { 2'b01, `DEST_IP, `OP_LOAD_B }
|
||||||
`define I_RESET { 8'hff }
|
`define I_STORE_A_TO_B { 8'b10000000 }
|
||||||
|
`define I_CONST_SHORT_A(addr) { 4'b01010, 4'(addr) }
|
||||||
|
`define I_CONST_SHORT_B(addr) { 4'b01011, 4'(addr) }
|
||||||
|
`define I_BRANCH_IF_CARRY(carry) { 6'b100100, 1'(carry), 1'b1 }
|
||||||
|
`define I_RESET { 8'b10000001 }
|
||||||
|
|
||||||
module CPU(
|
module CPU(
|
||||||
input clk,
|
input clk,
|
||||||
@ -70,15 +75,15 @@ module CPU(
|
|||||||
reg [7:0] opcode;
|
reg [7:0] opcode;
|
||||||
wire [3:0] aluop = opcode[3:0];
|
wire [3:0] aluop = opcode[3:0];
|
||||||
wire [1:0] opdest = opcode[5:4];
|
wire [1:0] opdest = opcode[5:4];
|
||||||
|
wire memalu = opcode[6];
|
||||||
|
|
||||||
localparam S_RESET = 0;
|
localparam S_RESET = 0;
|
||||||
localparam S_SELECT = 1;
|
localparam S_SELECT = 1;
|
||||||
localparam S_DECODE = 2;
|
localparam S_DECODE = 2;
|
||||||
localparam S_LOAD_ADDR = 3;
|
localparam S_COMPUTE = 3;
|
||||||
localparam S_STORE_ADDR = 4;
|
localparam S_READ_IP = 4;
|
||||||
localparam S_COMPUTE = 5;
|
|
||||||
|
|
||||||
ALU alu(.A(A), .B(B), .Y(Y), .aluop(aluop));
|
ALU alu(.A(A), .B(memalu?data_in:B), .Y(Y), .aluop(aluop));
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@ -111,23 +116,42 @@ module CPU(
|
|||||||
8'b01??????: begin
|
8'b01??????: begin
|
||||||
address <= IP;
|
address <= IP;
|
||||||
IP <= IP + 1;
|
IP <= IP + 1;
|
||||||
state <= S_LOAD_ADDR;
|
state <= S_COMPUTE;
|
||||||
end
|
end
|
||||||
// read[B] -> dest, ALU A + B -> dest
|
// ALU A + [B] -> dest
|
||||||
8'b10??????: begin
|
8'b11??????: begin
|
||||||
address <= B;
|
address <= B;
|
||||||
state <= S_LOAD_ADDR;
|
state <= S_COMPUTE;
|
||||||
end
|
end
|
||||||
// ALU A + B -> write [B] -> dest
|
// A -> write [B]
|
||||||
8'b1100????: begin
|
8'b10000000: begin
|
||||||
address <= B;
|
address <= B;
|
||||||
state <= S_STORE_ADDR;
|
data_out <= A;
|
||||||
|
write <= 1;
|
||||||
|
state <= S_SELECT;
|
||||||
end
|
end
|
||||||
// ALU A + B -> write [immediate] -> dest
|
// conditional branch
|
||||||
8'b1101????: begin
|
8'b1001????: begin
|
||||||
|
if (
|
||||||
|
(data_in[0] && (data_in[1] == carry)) ||
|
||||||
|
(data_in[2] && (data_in[3] == zero)))
|
||||||
|
begin
|
||||||
address <= IP;
|
address <= IP;
|
||||||
IP <= IP + 1;
|
state <= S_READ_IP;
|
||||||
state <= S_STORE_ADDR;
|
end else begin
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
IP <= IP + 1; // skip immediate
|
||||||
|
end
|
||||||
|
// aluop -> A
|
||||||
|
8'b1010????: begin
|
||||||
|
A <= {4'b0, data_in[3:0]};
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
// aluop -> B
|
||||||
|
8'b1011????: begin
|
||||||
|
B <= {4'b0, data_in[3:0]};
|
||||||
|
state <= S_SELECT;
|
||||||
end
|
end
|
||||||
// fall-through RESET
|
// fall-through RESET
|
||||||
default: begin
|
default: begin
|
||||||
@ -135,37 +159,25 @@ module CPU(
|
|||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
// state 3: load address
|
// state 3: compute ALU op and flags
|
||||||
S_LOAD_ADDR: begin
|
|
||||||
case (opdest)
|
|
||||||
`DEST_A: A <= data_in;
|
|
||||||
`DEST_B: B <= data_in;
|
|
||||||
`DEST_IP: IP <= data_in;
|
|
||||||
// use ALU-op for conditional branch
|
|
||||||
`DEST_NOP: if (
|
|
||||||
(aluop[0] && (aluop[1] ^ carry)) ||
|
|
||||||
(aluop[2] && (aluop[3] ^ zero)))
|
|
||||||
IP <= data_in;
|
|
||||||
endcase
|
|
||||||
// short-circuit ALU for branches
|
|
||||||
state <= opdest[1] ? S_SELECT : S_COMPUTE;
|
|
||||||
end
|
|
||||||
// state 4: store address
|
|
||||||
S_STORE_ADDR: begin
|
|
||||||
data_out <= Y[7:0];
|
|
||||||
write <= 1;
|
|
||||||
state <= S_SELECT;
|
|
||||||
end
|
|
||||||
// state 5: compute ALU op and flags
|
|
||||||
S_COMPUTE: begin
|
S_COMPUTE: begin
|
||||||
|
// transfer ALU output to destination
|
||||||
case (opdest)
|
case (opdest)
|
||||||
`DEST_A: A <= Y[7:0];
|
`DEST_A: A <= Y[7:0];
|
||||||
`DEST_B: B <= Y[7:0];
|
`DEST_B: B <= Y[7:0];
|
||||||
`DEST_IP: IP <= Y[7:0];
|
`DEST_IP: IP <= Y[7:0];
|
||||||
`DEST_NOP: ;
|
`DEST_NOP: ;
|
||||||
endcase
|
endcase
|
||||||
carry <= Y[8];
|
// set carry for certain operations (code >= 8)
|
||||||
|
if (aluop[3]) carry <= Y[8];
|
||||||
|
// set zero flag
|
||||||
zero <= ~|Y;
|
zero <= ~|Y;
|
||||||
|
// 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;
|
state <= S_SELECT;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
@ -209,13 +221,17 @@ module test_CPU_top(
|
|||||||
to_cpu = rom[address_bus[6:0]];
|
to_cpu = rom[address_bus[6:0]];
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// address 0x80
|
// ROM starts at address 0x80
|
||||||
rom['h00] = `I_LOAD_IMM_A;
|
rom['h00] = `I_CONST_IMM_A;
|
||||||
rom['h01] = 42;
|
rom['h01] = 1;
|
||||||
rom['h02] = `I_COMPUTE(`DEST_A, `OP_ASL);
|
rom['h02] = `I_CONST_SHORT_B(0);
|
||||||
rom['h03] = `I_COMPUTE(`DEST_B, `OP_INC);
|
rom['h03] = `I_COMPUTE(`DEST_A, `OP_ADD);
|
||||||
rom['h04] = `I_STORE_B(`OP_LOAD_B);
|
rom['h04] = `I_COMPUTE(`DEST_B, `OP_ADD);
|
||||||
rom['h05] = `I_RESET;
|
rom['h05] = `I_STORE_A_TO_B;
|
||||||
|
//rom['h06] = `I_JUMP_IMM;
|
||||||
|
rom['h06] = `I_BRANCH_IF_CARRY(0);
|
||||||
|
rom['h07] = 3 + 'h80; // correct for ROM offset
|
||||||
|
rom['h08] = `I_RESET;
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
`ifndef DIGITS10_H
|
||||||
|
`define DIGITS10_H
|
||||||
|
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
module digits10_case(
|
module digits10_case(digit, yofs, bits);
|
||||||
input [3:0] digit,
|
|
||||||
input [2:0] yofs,
|
input [3:0] digit;
|
||||||
output [4:0] bits
|
input [2:0] yofs;
|
||||||
);
|
output [4:0] bits;
|
||||||
|
|
||||||
wire [6:0] caseexpr = {digit,yofs};
|
wire [6:0] caseexpr = {digit,yofs};
|
||||||
always @(*)
|
always @(*)
|
||||||
case (caseexpr)/*{w:5,h:5,count:10}*/
|
case (caseexpr)/*{w:5,h:5,count:10}*/
|
||||||
@ -72,11 +76,12 @@ module digits10_case(
|
|||||||
endcase
|
endcase
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module digits10_array(
|
module digits10_array(digit, yofs, bits);
|
||||||
input [3:0] digit,
|
|
||||||
input [2:0] yofs,
|
input [3:0] digit;
|
||||||
output [4:0] bits
|
input [2:0] yofs;
|
||||||
);
|
output [4:0] bits;
|
||||||
|
|
||||||
reg [4:0] bitarray[16][5];
|
reg [4:0] bitarray[16][5];
|
||||||
|
|
||||||
assign bits = bitarray[digit][yofs];
|
assign bits = bitarray[digit][yofs];
|
||||||
@ -142,17 +147,19 @@ module digits10_array(
|
|||||||
bitarray[9][3] = 5'b00001;
|
bitarray[9][3] = 5'b00001;
|
||||||
bitarray[9][4] = 5'b11111;
|
bitarray[9][4] = 5'b11111;
|
||||||
|
|
||||||
|
// clear unused array entries
|
||||||
for (int i = 10; i <= 15; i++)
|
for (int i = 10; i <= 15; i++)
|
||||||
for (int j = 0; j <= 4; j++)
|
for (int j = 0; j <= 4; j++)
|
||||||
bitarray[i][j] = 0;
|
bitarray[i][j] = 0;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module test_numbers_top(
|
module test_numbers_top(clk, reset, hsync, vsync, rgb);
|
||||||
input clk, reset,
|
|
||||||
output hsync, vsync,
|
input clk, reset;
|
||||||
output [2:0] rgb
|
output hsync, vsync;
|
||||||
);
|
output [2:0] rgb;
|
||||||
|
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
@ -167,8 +174,9 @@ module test_numbers_top(
|
|||||||
.vpos(vpos)
|
.vpos(vpos)
|
||||||
);
|
);
|
||||||
|
|
||||||
wire [3:0] digit = hpos[6:3];
|
wire [3:0] digit = hpos[7:4];
|
||||||
wire [2:0] yofs = vpos[2:0];
|
wire [2:0] xofs = hpos[3:1];
|
||||||
|
wire [2:0] yofs = vpos[3:1];
|
||||||
wire [4:0] bits;
|
wire [4:0] bits;
|
||||||
|
|
||||||
digits10_array numbers(
|
digits10_array numbers(
|
||||||
@ -178,8 +186,10 @@ module test_numbers_top(
|
|||||||
);
|
);
|
||||||
|
|
||||||
wire r = display_on && 0;
|
wire r = display_on && 0;
|
||||||
wire g = display_on && bits[hpos[2:0] ^ 3'b111];
|
wire g = display_on && bits[xofs ^ 3'b111];
|
||||||
wire b = display_on && 0;
|
wire b = display_on && 0;
|
||||||
assign rgb = {b,g,r};
|
assign rgb = {b,g,r};
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
`define HVSYNC_GENERATOR_H
|
`define HVSYNC_GENERATOR_H
|
||||||
|
|
||||||
// constant declarations for TV-simulator sync parameters
|
// constant declarations for TV-simulator sync parameters
|
||||||
|
// horizontal
|
||||||
localparam H_DISPLAY = 256; // horizontal display width
|
localparam H_DISPLAY = 256; // horizontal display width
|
||||||
localparam H_BACK = 23; // horizontal left border (back porch)
|
localparam H_BACK = 23; // horizontal left border (back porch)
|
||||||
localparam H_FRONT = 7; // horizontal right border (front porch)
|
localparam H_FRONT = 7; // horizontal right border (front porch)
|
||||||
@ -9,7 +10,7 @@ localparam H_SYNC = 23; // horizontal sync width
|
|||||||
localparam H_SYNC_START = H_DISPLAY + H_FRONT;
|
localparam H_SYNC_START = H_DISPLAY + H_FRONT;
|
||||||
localparam H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1;
|
localparam H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1;
|
||||||
localparam H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1;
|
localparam H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1;
|
||||||
|
// vertical
|
||||||
localparam V_DISPLAY = 240; // vertical display height
|
localparam V_DISPLAY = 240; // vertical display height
|
||||||
localparam V_TOP = 5; // vertical top border
|
localparam V_TOP = 5; // vertical top border
|
||||||
localparam V_BOTTOM = 14; // vertical bottom border
|
localparam V_BOTTOM = 14; // vertical bottom border
|
||||||
@ -18,14 +19,14 @@ localparam V_SYNC_START = V_DISPLAY + V_BOTTOM;
|
|||||||
localparam V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1;
|
localparam V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1;
|
||||||
localparam V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1;
|
localparam V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1;
|
||||||
|
|
||||||
module hvsync_generator(
|
module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||||
input clk,
|
|
||||||
input reset,
|
input clk;
|
||||||
output hsync, vsync,
|
input reset;
|
||||||
output display_on,
|
output hsync, vsync;
|
||||||
output [8:0] hpos,
|
output display_on;
|
||||||
output [8:0] vpos
|
output [8:0] hpos;
|
||||||
);
|
output [8:0] vpos;
|
||||||
|
|
||||||
wire hmaxxed = (hpos == H_MAX) || reset;
|
wire hmaxxed = (hpos == H_MAX) || reset;
|
||||||
wire vmaxxed = (vpos == V_MAX) || reset;
|
wire vmaxxed = (vpos == V_MAX) || reset;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
`include "digits10.v"
|
`include "digits10.v"
|
||||||
|
|
||||||
module RAM_1KB(clk, addr, din, dout, we);
|
module RAM_1KB(clk, addr, din, dout, we);
|
||||||
|
|
||||||
input clk; // clock
|
input clk; // clock
|
||||||
input [9:0] addr; // 10-bit address
|
input [9:0] addr; // 10-bit address
|
||||||
input [7:0] din; // 8-bit data input
|
input [7:0] din; // 8-bit data input
|
||||||
@ -15,13 +16,15 @@ module RAM_1KB(clk, addr, din, dout, we);
|
|||||||
mem[addr] <= din; // write memory from din
|
mem[addr] <= din; // write memory from din
|
||||||
dout <= mem[addr]; // read memory to dout
|
dout <= mem[addr]; // read memory to dout
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module test_framebuf_top(
|
module test_framebuf_top(clk, reset, hsync, vsync, rgb);
|
||||||
input clk, reset,
|
|
||||||
output hsync, vsync,
|
input clk, reset;
|
||||||
output [2:0] rgb
|
output hsync, vsync;
|
||||||
);
|
output [2:0] rgb;
|
||||||
|
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
|
103
presets/verilog/scoreboard.v
Normal file
103
presets/verilog/scoreboard.v
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
`include "hvsync_generator.v"
|
||||||
|
`include "digits10.v"
|
||||||
|
|
||||||
|
module player_stats(reset, score0, score1, lives, incscore, declives);
|
||||||
|
|
||||||
|
input reset;
|
||||||
|
output [3:0] score0;
|
||||||
|
output [3:0] score1;
|
||||||
|
input incscore;
|
||||||
|
output [3:0] lives;
|
||||||
|
input declives;
|
||||||
|
|
||||||
|
always @(posedge incscore or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset) begin
|
||||||
|
score0 <= 0;
|
||||||
|
score1 <= 0;
|
||||||
|
end else if (score0 == 9) begin
|
||||||
|
score0 <= 0;
|
||||||
|
score1 <= score1 + 1;
|
||||||
|
end else begin
|
||||||
|
score0 <= score0 + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge declives or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset)
|
||||||
|
lives <= 3;
|
||||||
|
else if (lives != 0)
|
||||||
|
lives <= lives - 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module scoreboard_generator(score0, score1, lives, vpos, hpos, board_gfx);
|
||||||
|
|
||||||
|
input [3:0] score0;
|
||||||
|
input [3:0] score1;
|
||||||
|
input [3:0] lives;
|
||||||
|
input [8:0] vpos;
|
||||||
|
input [8:0] hpos;
|
||||||
|
output board_gfx;
|
||||||
|
|
||||||
|
wire [3:0] score_digit;
|
||||||
|
wire [4:0] score_bits;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
case (hpos[7:5])
|
||||||
|
1: score_digit = score1;
|
||||||
|
2: score_digit = score0;
|
||||||
|
6: score_digit = lives;
|
||||||
|
default: score_digit = 15; // no digit
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
digits10_array digits(
|
||||||
|
.digit(score_digit),
|
||||||
|
.yofs(vpos[4:2]),
|
||||||
|
.bits(score_bits)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign board_gfx = score_bits[hpos[4:2] ^ 3'b111];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module 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;
|
||||||
|
|
||||||
|
wire board_gfx;
|
||||||
|
|
||||||
|
hvsync_generator hvsync_gen(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.hsync(hsync),
|
||||||
|
.vsync(vsync),
|
||||||
|
.display_on(display_on),
|
||||||
|
.hpos(hpos),
|
||||||
|
.vpos(vpos)
|
||||||
|
);
|
||||||
|
|
||||||
|
scoreboard_generator scoreboard_gen(
|
||||||
|
.score0(0),
|
||||||
|
.score1(1),
|
||||||
|
.lives(3),
|
||||||
|
.vpos(vpos),
|
||||||
|
.hpos(hpos),
|
||||||
|
.board_gfx(board_gfx)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire r = display_on && board_gfx;
|
||||||
|
wire g = display_on && board_gfx;
|
||||||
|
wire b = display_on && board_gfx;
|
||||||
|
assign rgb = {b,g,r};
|
||||||
|
|
||||||
|
endmodule
|
@ -1,9 +1,10 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
module car_bitmap(
|
module car_bitmap(yofs, bits);
|
||||||
input [3:0] yofs,
|
|
||||||
output [7:0] bits
|
input [3:0] yofs;
|
||||||
);
|
output [7:0] bits;
|
||||||
|
|
||||||
reg [7:0] bitarray[16];
|
reg [7:0] bitarray[16];
|
||||||
assign bits = bitarray[yofs];
|
assign bits = bitarray[yofs];
|
||||||
initial begin/*{w:8,h:16}*/
|
initial begin/*{w:8,h:16}*/
|
||||||
@ -24,6 +25,7 @@ module car_bitmap(
|
|||||||
bitarray[14] = 8'b11001100;
|
bitarray[14] = 8'b11001100;
|
||||||
bitarray[15] = 8'b1100;
|
bitarray[15] = 8'b1100;
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module sprite_bitmap_top(clk, reset, hsync, vsync, rgb);
|
module sprite_bitmap_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
@ -10,90 +10,90 @@ module tank_bitmap(addr, bits);
|
|||||||
assign bits = (addr[0]) ? bitarray[addr>>1][15:8] : bitarray[addr>>1][7:0];
|
assign bits = (addr[0]) ? bitarray[addr>>1][15:8] : bitarray[addr>>1][7:0];
|
||||||
|
|
||||||
initial begin/*{w:16,h:16,bpw:16,count:5}*/
|
initial begin/*{w:16,h:16,bpw:16,count:5}*/
|
||||||
bitarray[0'h00] = 16'b11110000000;
|
bitarray[8'h00] = 16'b11110000000;
|
||||||
bitarray[0'h01] = 16'b11110000000;
|
bitarray[8'h01] = 16'b11110000000;
|
||||||
bitarray[0'h02] = 16'b1100000000;
|
bitarray[8'h02] = 16'b1100000000;
|
||||||
bitarray[0'h03] = 16'b1100000000;
|
bitarray[8'h03] = 16'b1100000000;
|
||||||
bitarray[0'h04] = 16'b111101101111000;
|
bitarray[8'h04] = 16'b111101101111000;
|
||||||
bitarray[0'h05] = 16'b111101101111000;
|
bitarray[8'h05] = 16'b111101101111000;
|
||||||
bitarray[0'h06] = 16'b111111111111000;
|
bitarray[8'h06] = 16'b111111111111000;
|
||||||
bitarray[0'h07] = 16'b111111111111000;
|
bitarray[8'h07] = 16'b111111111111000;
|
||||||
bitarray[0'h08] = 16'b111111111111000;
|
bitarray[8'h08] = 16'b111111111111000;
|
||||||
bitarray[0'h09] = 16'b111111111111000;
|
bitarray[8'h09] = 16'b111111111111000;
|
||||||
bitarray[0'h0a] = 16'b111111111111000;
|
bitarray[8'h0a] = 16'b111111111111000;
|
||||||
bitarray[0'h0b] = 16'b111100001111000;
|
bitarray[8'h0b] = 16'b111100001111000;
|
||||||
bitarray[0'h0c] = 16'b111100001111000;
|
bitarray[8'h0c] = 16'b111100001111000;
|
||||||
bitarray[0'h0d] = 16'b0;
|
bitarray[8'h0d] = 16'b0;
|
||||||
bitarray[0'h0e] = 16'b0;
|
bitarray[8'h0e] = 16'b0;
|
||||||
bitarray[0'h0f] = 16'b0;
|
bitarray[8'h0f] = 16'b0;
|
||||||
|
|
||||||
bitarray[0'h10] = 16'b111000000000;
|
bitarray[8'h10] = 16'b111000000000;
|
||||||
bitarray[0'h11] = 16'b1111000000000;
|
bitarray[8'h11] = 16'b1111000000000;
|
||||||
bitarray[0'h12] = 16'b1111000000000;
|
bitarray[8'h12] = 16'b1111000000000;
|
||||||
bitarray[0'h13] = 16'b11000000000;
|
bitarray[8'h13] = 16'b11000000000;
|
||||||
bitarray[0'h14] = 16'b11101110000;
|
bitarray[8'h14] = 16'b11101110000;
|
||||||
bitarray[0'h15] = 16'b1101110000;
|
bitarray[8'h15] = 16'b1101110000;
|
||||||
bitarray[0'h16] = 16'b111101111110000;
|
bitarray[8'h16] = 16'b111101111110000;
|
||||||
bitarray[0'h17] = 16'b111101111111000;
|
bitarray[8'h17] = 16'b111101111111000;
|
||||||
bitarray[0'h18] = 16'b111111111111000;
|
bitarray[8'h18] = 16'b111111111111000;
|
||||||
bitarray[0'h19] = 16'b11111111111000;
|
bitarray[8'h19] = 16'b11111111111000;
|
||||||
bitarray[0'h1a] = 16'b11111111111100;
|
bitarray[8'h1a] = 16'b11111111111100;
|
||||||
bitarray[0'h1b] = 16'b11111111111100;
|
bitarray[8'h1b] = 16'b11111111111100;
|
||||||
bitarray[0'h1c] = 16'b11111001111100;
|
bitarray[8'h1c] = 16'b11111001111100;
|
||||||
bitarray[0'h1d] = 16'b1111001110000;
|
bitarray[8'h1d] = 16'b1111001110000;
|
||||||
bitarray[0'h1e] = 16'b1111000000000;
|
bitarray[8'h1e] = 16'b1111000000000;
|
||||||
bitarray[0'h1f] = 16'b1100000000000;
|
bitarray[8'h1f] = 16'b1100000000000;
|
||||||
|
|
||||||
bitarray[0'h20] = 16'b0;
|
bitarray[8'h20] = 16'b0;
|
||||||
bitarray[0'h21] = 16'b0;
|
bitarray[8'h21] = 16'b0;
|
||||||
bitarray[0'h22] = 16'b11000011000000;
|
bitarray[8'h22] = 16'b11000011000000;
|
||||||
bitarray[0'h23] = 16'b111000111100000;
|
bitarray[8'h23] = 16'b111000111100000;
|
||||||
bitarray[0'h24] = 16'b111101111110000;
|
bitarray[8'h24] = 16'b111101111110000;
|
||||||
bitarray[0'h25] = 16'b1110111111000;
|
bitarray[8'h25] = 16'b1110111111000;
|
||||||
bitarray[0'h26] = 16'b111111111100;
|
bitarray[8'h26] = 16'b111111111100;
|
||||||
bitarray[0'h27] = 16'b11111111110;
|
bitarray[8'h27] = 16'b11111111110;
|
||||||
bitarray[0'h28] = 16'b11011111111110;
|
bitarray[8'h28] = 16'b11011111111110;
|
||||||
bitarray[0'h29] = 16'b111111111111100;
|
bitarray[8'h29] = 16'b111111111111100;
|
||||||
bitarray[0'h2a] = 16'b111111111001000;
|
bitarray[8'h2a] = 16'b111111111001000;
|
||||||
bitarray[0'h2b] = 16'b11111110000000;
|
bitarray[8'h2b] = 16'b11111110000000;
|
||||||
bitarray[0'h2c] = 16'b1111100000000;
|
bitarray[8'h2c] = 16'b1111100000000;
|
||||||
bitarray[0'h2d] = 16'b111110000000;
|
bitarray[8'h2d] = 16'b111110000000;
|
||||||
bitarray[0'h2e] = 16'b11110000000;
|
bitarray[8'h2e] = 16'b11110000000;
|
||||||
bitarray[0'h2f] = 16'b1100000000;
|
bitarray[8'h2f] = 16'b1100000000;
|
||||||
|
|
||||||
bitarray[0'h30] = 16'b0;
|
bitarray[8'h30] = 16'b0;
|
||||||
bitarray[0'h31] = 16'b0;
|
bitarray[8'h31] = 16'b0;
|
||||||
bitarray[0'h32] = 16'b110000000;
|
bitarray[8'h32] = 16'b110000000;
|
||||||
bitarray[0'h33] = 16'b100001111000000;
|
bitarray[8'h33] = 16'b100001111000000;
|
||||||
bitarray[0'h34] = 16'b1110001111110000;
|
bitarray[8'h34] = 16'b1110001111110000;
|
||||||
bitarray[0'h35] = 16'b1111010111111100;
|
bitarray[8'h35] = 16'b1111010111111100;
|
||||||
bitarray[0'h36] = 16'b1111111111111111;
|
bitarray[8'h36] = 16'b1111111111111111;
|
||||||
bitarray[0'h37] = 16'b1111111111111;
|
bitarray[8'h37] = 16'b1111111111111;
|
||||||
bitarray[0'h38] = 16'b11111111110;
|
bitarray[8'h38] = 16'b11111111110;
|
||||||
bitarray[0'h39] = 16'b101111111110;
|
bitarray[8'h39] = 16'b101111111110;
|
||||||
bitarray[0'h3a] = 16'b1111111101100;
|
bitarray[8'h3a] = 16'b1111111101100;
|
||||||
bitarray[0'h3b] = 16'b11111111000000;
|
bitarray[8'h3b] = 16'b11111111000000;
|
||||||
bitarray[0'h3c] = 16'b1111111100000;
|
bitarray[8'h3c] = 16'b1111111100000;
|
||||||
bitarray[0'h3d] = 16'b11111110000;
|
bitarray[8'h3d] = 16'b11111110000;
|
||||||
bitarray[0'h3e] = 16'b111100000;
|
bitarray[8'h3e] = 16'b111100000;
|
||||||
bitarray[0'h3f] = 16'b1100000;
|
bitarray[8'h3f] = 16'b1100000;
|
||||||
|
|
||||||
bitarray[0'h40] = 16'b0;
|
bitarray[8'h40] = 16'b0;
|
||||||
bitarray[0'h41] = 16'b0;
|
bitarray[8'h41] = 16'b0;
|
||||||
bitarray[0'h42] = 16'b0;
|
bitarray[8'h42] = 16'b0;
|
||||||
bitarray[0'h43] = 16'b111111111000;
|
bitarray[8'h43] = 16'b111111111000;
|
||||||
bitarray[0'h44] = 16'b111111111000;
|
bitarray[8'h44] = 16'b111111111000;
|
||||||
bitarray[0'h45] = 16'b111111111000;
|
bitarray[8'h45] = 16'b111111111000;
|
||||||
bitarray[0'h46] = 16'b111111111000;
|
bitarray[8'h46] = 16'b111111111000;
|
||||||
bitarray[0'h47] = 16'b1100001111100000;
|
bitarray[8'h47] = 16'b1100001111100000;
|
||||||
bitarray[0'h48] = 16'b1111111111100000;
|
bitarray[8'h48] = 16'b1111111111100000;
|
||||||
bitarray[0'h49] = 16'b1111111111100000;
|
bitarray[8'h49] = 16'b1111111111100000;
|
||||||
bitarray[0'h4a] = 16'b1100001111100000;
|
bitarray[8'h4a] = 16'b1100001111100000;
|
||||||
bitarray[0'h4b] = 16'b111111111000;
|
bitarray[8'h4b] = 16'b111111111000;
|
||||||
bitarray[0'h4c] = 16'b111111111000;
|
bitarray[8'h4c] = 16'b111111111000;
|
||||||
bitarray[0'h4d] = 16'b111111111000;
|
bitarray[8'h4d] = 16'b111111111000;
|
||||||
bitarray[0'h4e] = 16'b111111111000;
|
bitarray[8'h4e] = 16'b111111111000;
|
||||||
bitarray[0'h4f] = 16'b0;
|
bitarray[8'h4f] = 16'b0;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
@ -224,6 +224,7 @@ endfunction
|
|||||||
|
|
||||||
module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
||||||
sprite_addr, sprite_bits, gfx,
|
sprite_addr, sprite_bits, gfx,
|
||||||
|
playfield,
|
||||||
switch_left, switch_right, switch_up);
|
switch_left, switch_right, switch_up);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
@ -235,10 +236,16 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
|||||||
output [7:0] sprite_addr;
|
output [7:0] sprite_addr;
|
||||||
input [7:0] sprite_bits;
|
input [7:0] sprite_bits;
|
||||||
output gfx;
|
output gfx;
|
||||||
|
input playfield;
|
||||||
input switch_left, switch_right, switch_up;
|
input switch_left, switch_right, switch_up;
|
||||||
|
|
||||||
|
parameter initial_x = 128;
|
||||||
|
parameter initial_y = 120;
|
||||||
|
parameter initial_rot = 0;
|
||||||
|
|
||||||
wire hmirror, vmirror;
|
wire hmirror, vmirror;
|
||||||
wire busy;
|
wire busy;
|
||||||
|
wire collision_gfx = gfx && playfield;
|
||||||
|
|
||||||
reg [11:0] player_x_fixed;
|
reg [11:0] player_x_fixed;
|
||||||
wire [7:0] player_x = player_x_fixed[11:4];
|
wire [7:0] player_x = player_x_fixed[11:4];
|
||||||
@ -249,7 +256,7 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
|||||||
wire [3:0] player_y_frac = player_y_fixed[3:0];
|
wire [3:0] player_y_frac = player_y_fixed[3:0];
|
||||||
|
|
||||||
reg [3:0] player_rot;
|
reg [3:0] player_rot;
|
||||||
reg [3:0] player_speed = 0;
|
reg [3:0] player_speed;
|
||||||
reg [3:0] frame = 0;
|
reg [3:0] frame = 0;
|
||||||
|
|
||||||
wire vstart = {1'b0,player_y} == vpos;
|
wire vstart = {1'b0,player_y} == vpos;
|
||||||
@ -274,8 +281,10 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
|||||||
.vmirror(vmirror));
|
.vmirror(vmirror));
|
||||||
|
|
||||||
always @(posedge vsync or posedge reset)
|
always @(posedge vsync or posedge reset)
|
||||||
|
begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
player_rot <= 0;
|
player_rot <= initial_rot;
|
||||||
|
player_speed <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
frame <= frame + 1;
|
frame <= frame + 1;
|
||||||
// rotation
|
// rotation
|
||||||
@ -291,13 +300,24 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
|||||||
player_speed <= 0;
|
player_speed <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg collision_detected;
|
||||||
|
always @(posedge collision_gfx or posedge vsync or posedge reset)
|
||||||
|
collision_detected <= collision_gfx;
|
||||||
|
|
||||||
always @(posedge hsync or posedge reset)
|
always @(posedge hsync or posedge reset)
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
player_x_fixed <= 128<<4;
|
player_x_fixed <= initial_x << 4;
|
||||||
player_y_fixed <= 120<<4;
|
player_y_fixed <= initial_y << 4;
|
||||||
end else begin
|
end else begin
|
||||||
// movement
|
// movement
|
||||||
|
if (collision_detected && vpos[1]) 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
|
||||||
if (vpos < 9'(player_speed)) begin
|
if (vpos < 9'(player_speed)) begin
|
||||||
if (vpos[0])
|
if (vpos[0])
|
||||||
player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot));
|
player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot));
|
||||||
@ -310,7 +330,7 @@ endmodule
|
|||||||
|
|
||||||
//TODO: debouncing
|
//TODO: debouncing
|
||||||
|
|
||||||
module test_top(clk, reset, hsync, vsync, rgb, switches_p1);
|
module control_test_top(clk, reset, hsync, vsync, rgb, switches_p1);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
input reset;
|
input reset;
|
||||||
@ -353,17 +373,18 @@ module test_top(clk, reset, hsync, vsync, rgb, switches_p1);
|
|||||||
.sprite_addr(tank_sprite_addr),
|
.sprite_addr(tank_sprite_addr),
|
||||||
.sprite_bits(tank_sprite_bits),
|
.sprite_bits(tank_sprite_bits),
|
||||||
.gfx(tank1_gfx),
|
.gfx(tank1_gfx),
|
||||||
|
.playfield(playfield_gfx),
|
||||||
.switch_left(switches_p1[0]),
|
.switch_left(switches_p1[0]),
|
||||||
.switch_right(switches_p1[1]),
|
.switch_right(switches_p1[1]),
|
||||||
.switch_up(switches_p1[2])
|
.switch_up(switches_p1[2])
|
||||||
);
|
);
|
||||||
|
|
||||||
wire tank1_gfx;
|
wire tank1_gfx;
|
||||||
wire unused;
|
wire playfield_gfx = hpos[5] && vpos[5];
|
||||||
|
|
||||||
wire r = display_on && tank1_gfx;
|
wire r = display_on && tank1_gfx;
|
||||||
wire g = display_on && tank1_gfx;
|
wire g = display_on && tank1_gfx;
|
||||||
wire b = display_on && tank1_gfx;
|
wire b = display_on && (tank1_gfx || playfield_gfx);
|
||||||
assign rgb = {b,g,r};
|
assign rgb = {b,g,r};
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
`include "sprite_rotation.v"
|
||||||
|
|
||||||
module minefield(hpos, vpos, mine_gfx);
|
module minefield(hpos, vpos, mine_gfx);
|
||||||
|
|
||||||
@ -72,43 +73,47 @@ module playfield(hpos, vpos, playfield_gfx);
|
|||||||
maze[2] = 32'b10000000000100000000001000000001;
|
maze[2] = 32'b10000000000100000000001000000001;
|
||||||
maze[3] = 32'b10000000000100000000000000000001;
|
maze[3] = 32'b10000000000100000000000000000001;
|
||||||
maze[4] = 32'b10011110000000000000000000000001;
|
maze[4] = 32'b10011110000000000000000000000001;
|
||||||
maze[5] = 32'b10000000000000000000000011111001;
|
maze[5] = 32'b10000000000000000000000000000001;
|
||||||
maze[6] = 32'b10000000001000000000000000100001;
|
maze[6] = 32'b10000000001000000000000011110001;
|
||||||
maze[7] = 32'b11100010000000000000000000100001;
|
maze[7] = 32'b11100010000000000000000000100001;
|
||||||
maze[8] = 32'b10000010000000000000000000000001;
|
maze[8] = 32'b10000010000000000000000000100001;
|
||||||
maze[9] = 32'b10000011100000000000000000000001;
|
maze[9] = 32'b10000011100000000000000000000001;
|
||||||
maze[10] = 32'b10000000000000000000000000000001;
|
maze[10] = 32'b10000000000000000000000000000001;
|
||||||
maze[11] = 32'b10000000000000000000000000000001;
|
maze[11] = 32'b10000000000000000000000000000001;
|
||||||
maze[12] = 32'b11111000001000000000000000000001;
|
maze[12] = 32'b11111000001000000000000000000001;
|
||||||
maze[13] = 32'b10001000001000000000000111100001;
|
maze[13] = 32'b10001000001000000000000111100001;
|
||||||
maze[14] = 32'b10001110001000000000000000000001;
|
maze[14] = 32'b10001000001000000000000000000001;
|
||||||
maze[15] = 32'b10000000001000000000000000000001;
|
maze[15] = 32'b10000000001000000000000000000001;
|
||||||
maze[16] = 32'b10000000001000000000000000000001;
|
maze[16] = 32'b10000000001000000000000000000001;
|
||||||
maze[17] = 32'b10001111000000000000000000000001;
|
maze[17] = 32'b10000000000000000000000000000001;
|
||||||
maze[18] = 32'b10000000000000000000000100011001;
|
maze[18] = 32'b10000010000000000000000100011001;
|
||||||
maze[19] = 32'b10000000000000000000000100010001;
|
maze[19] = 32'b10001110000000000000000100010001;
|
||||||
maze[20] = 32'b10000001001000000000000100010001;
|
maze[20] = 32'b10000000001000000000000100010001;
|
||||||
maze[21] = 32'b10000001001110000000000100000001;
|
maze[21] = 32'b10000000001110000000000100000001;
|
||||||
maze[22] = 32'b10000001000000000010001100000001;
|
maze[22] = 32'b10000000000000000010001100000001;
|
||||||
maze[23] = 32'b10001000000000000000000000000001;
|
maze[23] = 32'b10000000000000000000000000000001;
|
||||||
maze[24] = 32'b10001000000111100000000000010001;
|
maze[24] = 32'b10000010000111100000000000010001;
|
||||||
maze[25] = 32'b10001000000000100000000000010001;
|
maze[25] = 32'b10000010000000100000000000010001;
|
||||||
maze[26] = 32'b10001000000000000010000000010001;
|
maze[26] = 32'b10000010000000000010000000010001;
|
||||||
maze[27] = 32'b11111111111111111111111111111111;
|
maze[27] = 32'b11111111111111111111111111111111;
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module mine_test_top(clk, hsync, vsync, rgb);
|
module mine_test_top(clk, reset, hsync, vsync, rgb, switches_p1, switches_p2);
|
||||||
|
|
||||||
input clk;
|
input clk, reset;
|
||||||
|
input [7:0] switches_p1;
|
||||||
|
input [7:0] switches_p2;
|
||||||
output hsync, vsync;
|
output hsync, vsync;
|
||||||
output [2:0] rgb;
|
output [2:0] rgb;
|
||||||
|
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
wire mine_gfx;
|
wire mine_gfx;
|
||||||
wire playfield_gfx;
|
wire playfield_gfx;
|
||||||
|
wire tank1_gfx, tank2_gfx;
|
||||||
|
|
||||||
hvsync_generator hvsync_gen(
|
hvsync_generator hvsync_gen(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
@ -132,9 +137,54 @@ module mine_test_top(clk, hsync, vsync, rgb);
|
|||||||
.playfield_gfx(playfield_gfx)
|
.playfield_gfx(playfield_gfx)
|
||||||
);
|
);
|
||||||
|
|
||||||
wire r = display_on && mine_gfx;
|
// multiplex player 1 and 2 load times during hsync
|
||||||
wire g = display_on && playfield_gfx;
|
wire p2sel = hpos[3];
|
||||||
wire b = display_on && 0;
|
// sprite ROM inputs for each player
|
||||||
|
wire [7:0] tank1_sprite_addr;
|
||||||
|
wire [7:0] tank2_sprite_addr;
|
||||||
|
// multiplex sprite ROM output
|
||||||
|
wire [7:0] tank_sprite_bits;
|
||||||
|
|
||||||
|
// bitmap ROM is shared between tank 1 and 2
|
||||||
|
tank_bitmap tank_bmp(
|
||||||
|
.addr(p2sel ? tank2_sprite_addr : tank1_sprite_addr),
|
||||||
|
.bits(tank_sprite_bits));
|
||||||
|
|
||||||
|
tank_controller #(16,36,4) tank1(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.hpos(hpos),
|
||||||
|
.vpos(vpos),
|
||||||
|
.hsync(hsync && !p2sel),
|
||||||
|
.vsync(vsync),
|
||||||
|
.sprite_addr(tank1_sprite_addr),
|
||||||
|
.sprite_bits(tank_sprite_bits),
|
||||||
|
.gfx(tank1_gfx),
|
||||||
|
.playfield(playfield_gfx),
|
||||||
|
.switch_left(switches_p1[0]),
|
||||||
|
.switch_right(switches_p1[1]),
|
||||||
|
.switch_up(switches_p1[2])
|
||||||
|
);
|
||||||
|
|
||||||
|
tank_controller #(220,190,12) tank2(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.hpos(hpos),
|
||||||
|
.vpos(vpos),
|
||||||
|
.hsync(hsync && p2sel),
|
||||||
|
.vsync(vsync),
|
||||||
|
.sprite_addr(tank2_sprite_addr),
|
||||||
|
.sprite_bits(tank_sprite_bits),
|
||||||
|
.gfx(tank2_gfx),
|
||||||
|
.playfield(playfield_gfx),
|
||||||
|
.switch_left(switches_p2[0]),
|
||||||
|
.switch_right(switches_p2[1]),
|
||||||
|
.switch_up(switches_p2[2])
|
||||||
|
);
|
||||||
|
|
||||||
|
wire r = display_on && (mine_gfx || tank2_gfx);
|
||||||
|
wire g = display_on && tank1_gfx;
|
||||||
|
wire b = display_on && (playfield_gfx || tank2_gfx);
|
||||||
assign rgb = {b,g,r};
|
assign rgb = {b,g,r};
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
module test_hvsync_top(
|
module test_hvsync_top(clk, reset, hsync, vsync, rgb);
|
||||||
input clk,
|
|
||||||
output hsync,
|
|
||||||
output vsync,
|
|
||||||
output [2:0] rgb
|
|
||||||
);
|
|
||||||
|
|
||||||
|
input clk, reset;
|
||||||
|
output hsync, vsync;
|
||||||
|
output [2:0] rgb;
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
|
@ -7,13 +7,14 @@ var VERILOG_PRESETS = [
|
|||||||
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
|
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
|
||||||
{id:'digits10.v', name:'Bitmapped Digits'},
|
{id:'digits10.v', name:'Bitmapped Digits'},
|
||||||
{id:'7segment.v', name:'7-Segment Decoder'},
|
{id:'7segment.v', name:'7-Segment Decoder'},
|
||||||
|
{id:'scoreboard.v', name:'Scoreboard'},
|
||||||
{id:'ball_slip_counter.v', name:'Ball Motion (slipping counter)'},
|
{id:'ball_slip_counter.v', name:'Ball Motion (slipping counter)'},
|
||||||
{id:'ball_paddle.v', name:'Brick Smash Game'},
|
{id:'ball_paddle.v', name:'Brick Smash Game'},
|
||||||
|
{id:'ram1.v', name:'RAM Text Display'},
|
||||||
{id:'sprite_bitmap.v', name:'Sprite Bitmaps'},
|
{id:'sprite_bitmap.v', name:'Sprite Bitmaps'},
|
||||||
{id:'sprite_renderer.v', name:'Sprite Rendering'},
|
{id:'sprite_renderer.v', name:'Sprite Rendering'},
|
||||||
{id:'sprite_multiple.v', name:'Multiple Sprites'},
|
{id:'sprite_multiple.v', name:'Multiple Sprites'},
|
||||||
{id:'sprite_rotation.v', name:'Sprite Rotation'},
|
{id:'sprite_rotation.v', name:'Sprite Rotation'},
|
||||||
{id:'ram1.v', name:'RAM Text Display'},
|
|
||||||
{id:'tank.v', name:'Tank Game'},
|
{id:'tank.v', name:'Tank Game'},
|
||||||
{id:'cpu8.v', name:'Simple 8-Bit CPU'},
|
{id:'cpu8.v', name:'Simple 8-Bit CPU'},
|
||||||
];
|
];
|
||||||
|
@ -1047,10 +1047,11 @@ function writeDependencies(depends, FS, errors) {
|
|||||||
if (depends) {
|
if (depends) {
|
||||||
for (var i=0; i<depends.length; i++) {
|
for (var i=0; i<depends.length; i++) {
|
||||||
var d = depends[i];
|
var d = depends[i];
|
||||||
if (d.text)
|
if (d.text) {
|
||||||
FS.writeFile(d.filename, d.text, {encoding:'utf8'});
|
FS.writeFile(d.filename, d.text, {encoding:'utf8'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileVerilator(code, platform, options) {
|
function compileVerilator(code, platform, options) {
|
||||||
|
Loading…
Reference in New Issue
Block a user