mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-14 00:29:35 +00:00
work on cpu, sprite
This commit is contained in:
parent
f0f6783f6b
commit
122e462c9f
|
@ -10,6 +10,7 @@
|
||||||
`define OP_OR 4'h8
|
`define OP_OR 4'h8
|
||||||
`define OP_AND 4'h9
|
`define OP_AND 4'h9
|
||||||
`define OP_XOR 4'ha
|
`define OP_XOR 4'ha
|
||||||
|
`define OP_NOP 4'hf
|
||||||
|
|
||||||
module ALU(
|
module ALU(
|
||||||
input [7:0] A,
|
input [7:0] A,
|
||||||
|
@ -26,7 +27,7 @@ module ALU(
|
||||||
`OP_SUB: Y = A - B;
|
`OP_SUB: Y = A - B;
|
||||||
`OP_INC: Y = A + 1;
|
`OP_INC: Y = A + 1;
|
||||||
`OP_DEC: Y = A - 1;
|
`OP_DEC: Y = A - 1;
|
||||||
`OP_ASL: Y = {A[7], A + A};
|
`OP_ASL: Y = A + A;
|
||||||
`OP_LSR: Y = {A[0], A >> 1};
|
`OP_LSR: Y = {A[0], A >> 1};
|
||||||
`OP_OR: Y = {1'b0, A | B};
|
`OP_OR: Y = {1'b0, A | B};
|
||||||
`OP_AND: Y = {1'b0, A & B};
|
`OP_AND: Y = {1'b0, A & B};
|
||||||
|
@ -36,13 +37,17 @@ module ALU(
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
`define REG_A 1'b0
|
`define DEST_A 2'b00
|
||||||
`define REG_B 1'b1
|
`define DEST_B 2'b01
|
||||||
`define I_CONST(r,x) { 2'b00, r, x }
|
`define DEST_IP 2'b10
|
||||||
`define I_LOAD_ADDR(r,addr) { 3'b010, r, addr }
|
`define DEST_NOP 2'b11
|
||||||
`define I_STORE_ADDR(r,addr) { 3'b011, r, addr }
|
`define I_COMPUTE(dest,op) { 2'b00, 2'(dest), 4'(op) }
|
||||||
`define I_COMPUTE(r,op) { 3'b100, r, op }
|
`define I_LOAD_IMM_A { 2'b01, `DEST_A, `OP_LOAD_A }
|
||||||
`define I_RESET 8'hff
|
`define I_LOAD_IMM_B { 2'b01, `DEST_B, `OP_LOAD_B }
|
||||||
|
`define I_JUMP_IMM { 2'b01, `DEST_IP, `OP_NOP }
|
||||||
|
`define I_STORE_B(op) { 4'b01100, 4'(op) }
|
||||||
|
`define I_STORE_IMM(op) { 4'b01101, 4'(op) }
|
||||||
|
`define I_RESET { 8'hff }
|
||||||
|
|
||||||
module CPU(
|
module CPU(
|
||||||
input clk,
|
input clk,
|
||||||
|
@ -53,9 +58,7 @@ module CPU(
|
||||||
output write
|
output write
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [7:0] ip;
|
reg [7:0] IP;
|
||||||
reg [7:0] opcode;
|
|
||||||
reg [3:0] aluop;
|
|
||||||
reg [7:0] A, B;
|
reg [7:0] A, B;
|
||||||
reg [8:0] Y;
|
reg [8:0] Y;
|
||||||
reg [2:0] state;
|
reg [2:0] state;
|
||||||
|
@ -63,7 +66,11 @@ module CPU(
|
||||||
reg carry;
|
reg carry;
|
||||||
reg zero;
|
reg zero;
|
||||||
wire [1:0] flags = { zero, carry };
|
wire [1:0] flags = { zero, carry };
|
||||||
|
|
||||||
|
reg [7:0] opcode;
|
||||||
|
wire [3:0] aluop = opcode[3:0];
|
||||||
|
wire [1:0] opdest = opcode[5:4];
|
||||||
|
|
||||||
localparam S_RESET = 0;
|
localparam S_RESET = 0;
|
||||||
localparam S_SELECT = 1;
|
localparam S_SELECT = 1;
|
||||||
localparam S_DECODE = 2;
|
localparam S_DECODE = 2;
|
||||||
|
@ -71,8 +78,6 @@ module CPU(
|
||||||
localparam S_STORE_ADDR = 4;
|
localparam S_STORE_ADDR = 4;
|
||||||
localparam S_COMPUTE = 5;
|
localparam S_COMPUTE = 5;
|
||||||
|
|
||||||
wire load_const = opcode[3:1] == 3'b111;
|
|
||||||
|
|
||||||
ALU alu(.A(A), .B(B), .Y(Y), .aluop(aluop));
|
ALU alu(.A(A), .B(B), .Y(Y), .aluop(aluop));
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
|
@ -83,68 +88,82 @@ module CPU(
|
||||||
case (state)
|
case (state)
|
||||||
// state 0: reset
|
// state 0: reset
|
||||||
S_RESET: begin
|
S_RESET: begin
|
||||||
ip <= 8'h80;
|
IP <= 8'h80;
|
||||||
write <= 0;
|
write <= 0;
|
||||||
state <= S_SELECT;
|
state <= S_SELECT;
|
||||||
end
|
end
|
||||||
// state 1: select opcode address
|
// state 1: select opcode address
|
||||||
S_SELECT: begin
|
S_SELECT: begin
|
||||||
address <= ip;
|
address <= IP;
|
||||||
ip <= ip + 1;
|
IP <= IP + 1;
|
||||||
write <= 0;
|
write <= 0;
|
||||||
state <= S_DECODE;
|
state <= S_DECODE;
|
||||||
end
|
end
|
||||||
// state 2: read/decode opcode
|
// state 2: read/decode opcode
|
||||||
S_DECODE: begin
|
S_DECODE: begin
|
||||||
|
opcode <= data_in;
|
||||||
casez (data_in)
|
casez (data_in)
|
||||||
|
// ALU A + B -> dest
|
||||||
8'b00??????: begin
|
8'b00??????: begin
|
||||||
if (data_in[5])
|
|
||||||
B <= {3'b0, data_in[4:0]};
|
|
||||||
else
|
|
||||||
A <= {3'b0, data_in[4:0]};
|
|
||||||
state <= S_SELECT;
|
|
||||||
end
|
|
||||||
8'b010?????: begin
|
|
||||||
address <= {4'b0, data_in[3:0]};
|
|
||||||
state <= S_LOAD_ADDR;
|
|
||||||
end
|
|
||||||
8'b011?????: begin
|
|
||||||
address <= {4'b0, data_in[3:0]};
|
|
||||||
state <= S_STORE_ADDR;
|
|
||||||
end
|
|
||||||
8'b100?????: begin
|
|
||||||
aluop <= data_in[3:0];
|
|
||||||
state <= S_COMPUTE;
|
state <= S_COMPUTE;
|
||||||
end
|
end
|
||||||
|
// ALU A + immediate -> dest
|
||||||
|
8'b01??????: begin
|
||||||
|
address <= IP;
|
||||||
|
IP <= IP + 1;
|
||||||
|
state <= S_LOAD_ADDR;
|
||||||
|
end
|
||||||
|
// read[B] -> dest, ALU A + B -> dest
|
||||||
|
8'b10??????: begin
|
||||||
|
address <= B;
|
||||||
|
state <= S_LOAD_ADDR;
|
||||||
|
end
|
||||||
|
// ALU A + B -> write [B] -> dest
|
||||||
|
8'b1100????: begin
|
||||||
|
address <= B;
|
||||||
|
state <= S_STORE_ADDR;
|
||||||
|
end
|
||||||
|
// ALU A + B -> write [immediate] -> dest
|
||||||
|
8'b1101????: begin
|
||||||
|
address <= IP;
|
||||||
|
IP <= IP + 1;
|
||||||
|
state <= S_STORE_ADDR;
|
||||||
|
end
|
||||||
|
// fall-through RESET
|
||||||
default: begin
|
default: begin
|
||||||
state <= S_RESET; // reset
|
state <= S_RESET; // reset
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
opcode <= data_in;
|
|
||||||
end
|
end
|
||||||
// state 3: load address
|
// state 3: load address
|
||||||
S_LOAD_ADDR: begin
|
S_LOAD_ADDR: begin
|
||||||
if (opcode[4])
|
case (opdest)
|
||||||
B <= data_in;
|
`DEST_A: A <= data_in;
|
||||||
else
|
`DEST_B: B <= data_in;
|
||||||
A <= data_in;
|
`DEST_IP: IP <= data_in;
|
||||||
state <= S_SELECT;
|
// 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
|
end
|
||||||
// state 4: store address
|
// state 4: store address
|
||||||
S_STORE_ADDR: begin
|
S_STORE_ADDR: begin
|
||||||
if (opcode[4])
|
data_out <= Y[7:0];
|
||||||
data_out <= B;
|
|
||||||
else
|
|
||||||
data_out <= A;
|
|
||||||
write <= 1;
|
write <= 1;
|
||||||
state <= S_SELECT;
|
state <= S_SELECT;
|
||||||
end
|
end
|
||||||
// state 5: compute ALU op and flags
|
// state 5: compute ALU op and flags
|
||||||
S_COMPUTE: begin
|
S_COMPUTE: begin
|
||||||
if (opcode[4])
|
case (opdest)
|
||||||
B <= Y[7:0];
|
`DEST_A: A <= Y[7:0];
|
||||||
else
|
`DEST_B: B <= Y[7:0];
|
||||||
A <= Y[7:0];
|
`DEST_IP: IP <= Y[7:0];
|
||||||
|
`DEST_NOP: ;
|
||||||
|
endcase
|
||||||
carry <= Y[8];
|
carry <= Y[8];
|
||||||
zero <= ~|Y;
|
zero <= ~|Y;
|
||||||
state <= S_SELECT;
|
state <= S_SELECT;
|
||||||
|
@ -160,12 +179,19 @@ module test_CPU_top(
|
||||||
output [7:0] address_bus,
|
output [7:0] address_bus,
|
||||||
output reg [7:0] to_cpu,
|
output reg [7:0] to_cpu,
|
||||||
output [7:0] from_cpu,
|
output [7:0] from_cpu,
|
||||||
output write_enable
|
output write_enable,
|
||||||
|
output [7:0] IP,
|
||||||
|
output [7:0] A,
|
||||||
|
output [7:0] B
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [7:0] ram[127:0];
|
reg [7:0] ram[127:0];
|
||||||
reg [7:0] rom[127:0];
|
reg [7:0] rom[127:0];
|
||||||
|
|
||||||
|
assign IP = cpu.IP;
|
||||||
|
assign A = cpu.A;
|
||||||
|
assign B = cpu.B;
|
||||||
|
|
||||||
CPU cpu(.clk(clk),
|
CPU cpu(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.address(address_bus),
|
.address(address_bus),
|
||||||
|
@ -184,15 +210,12 @@ module test_CPU_top(
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// address 0x80
|
// address 0x80
|
||||||
rom['h00] = `I_CONST(`REG_A, 5'h1f);
|
rom['h00] = `I_LOAD_IMM_A;
|
||||||
rom['h01] = `I_COMPUTE(`REG_A, `OP_ASL);
|
rom['h01] = 42;
|
||||||
rom['h02] = `I_COMPUTE(`REG_A, `OP_ASL);
|
rom['h02] = `I_COMPUTE(`DEST_A, `OP_ASL);
|
||||||
rom['h03] = `I_COMPUTE(`REG_A, `OP_ASL);
|
rom['h03] = `I_COMPUTE(`DEST_B, `OP_INC);
|
||||||
rom['h04] = `I_COMPUTE(`REG_A, `OP_ASL);
|
rom['h04] = `I_STORE_B(`OP_LOAD_B);
|
||||||
rom['h05] = `I_COMPUTE(`REG_B, `OP_LOAD_A);
|
rom['h05] = `I_RESET;
|
||||||
rom['h06] = `I_STORE_ADDR(`REG_B, 4'd1);
|
|
||||||
rom['h07] = `I_LOAD_ADDR(`REG_B, 4'd1);
|
|
||||||
rom['h08] = `I_RESET;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
203
presets/verilog/simplecpu.v
Normal file
203
presets/verilog/simplecpu.v
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
|
||||||
|
`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(
|
||||||
|
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(
|
||||||
|
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] opcode;
|
||||||
|
reg [3:0] aluop;
|
||||||
|
reg [7:0] A, B;
|
||||||
|
reg [8:0] Y;
|
||||||
|
reg [2:0] state;
|
||||||
|
|
||||||
|
reg carry;
|
||||||
|
reg zero;
|
||||||
|
wire [1:0] flags = { zero, carry };
|
||||||
|
|
||||||
|
localparam S_RESET = 0;
|
||||||
|
localparam S_SELECT = 1;
|
||||||
|
localparam S_DECODE = 2;
|
||||||
|
localparam S_LOAD_ADDR = 3;
|
||||||
|
localparam S_STORE_ADDR = 4;
|
||||||
|
localparam S_COMPUTE = 5;
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
casez (data_in)
|
||||||
|
8'b00??????: begin // load constant
|
||||||
|
if (data_in[5])
|
||||||
|
B <= {3'b0, data_in[4:0]};
|
||||||
|
else
|
||||||
|
A <= {3'b0, data_in[4:0]};
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
8'b010?????: begin // read memory
|
||||||
|
address <= {4'b0, data_in[3:0]};
|
||||||
|
state <= S_LOAD_ADDR;
|
||||||
|
end
|
||||||
|
8'b011?????: begin // write memory
|
||||||
|
address <= {4'b0, data_in[3:0]};
|
||||||
|
state <= S_STORE_ADDR;
|
||||||
|
end
|
||||||
|
8'b100?????: begin // compute w/ ALU
|
||||||
|
aluop <= data_in[3:0];
|
||||||
|
state <= S_COMPUTE;
|
||||||
|
end
|
||||||
|
8'b101000??: begin // branch if flag set/clear
|
||||||
|
if ((data_in[0] ? carry : zero) ^ data_in[1])
|
||||||
|
ip <= A;
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
state <= S_RESET; // reset
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
opcode <= data_in;
|
||||||
|
end
|
||||||
|
// state 3: load address
|
||||||
|
S_LOAD_ADDR: begin
|
||||||
|
if (opcode[4])
|
||||||
|
B <= data_in;
|
||||||
|
else
|
||||||
|
A <= data_in;
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
// state 4: store address
|
||||||
|
S_STORE_ADDR: begin
|
||||||
|
if (opcode[4])
|
||||||
|
data_out <= B;
|
||||||
|
else
|
||||||
|
data_out <= A;
|
||||||
|
write <= 1;
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
// state 5: compute ALU op and flags
|
||||||
|
S_COMPUTE: begin
|
||||||
|
if (opcode[4])
|
||||||
|
B <= Y[7:0];
|
||||||
|
else
|
||||||
|
A <= Y[7:0];
|
||||||
|
carry <= Y[8];
|
||||||
|
zero <= ~|Y;
|
||||||
|
state <= S_SELECT;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module test_CPU_top(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
output [7:0] address_bus,
|
||||||
|
output reg [7:0] to_cpu,
|
||||||
|
output [7:0] from_cpu,
|
||||||
|
output write_enable
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [7:0] ram[127:0];
|
||||||
|
reg [7:0] rom[127:0];
|
||||||
|
|
||||||
|
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
|
|
@ -1,8 +1,8 @@
|
||||||
`include "hvsync_generator.v"
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
module top(clk, hsync, vsync, rgb);
|
module top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
input clk;
|
input clk, reset;
|
||||||
output hsync, vsync;
|
output hsync, vsync;
|
||||||
output [2:0] rgb;
|
output [2:0] rgb;
|
||||||
wire display_on;
|
wire display_on;
|
||||||
|
@ -11,6 +11,7 @@ module top(clk, hsync, vsync, rgb);
|
||||||
|
|
||||||
hvsync_generator hvsync_gen(
|
hvsync_generator hvsync_gen(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
.hsync(hsync),
|
.hsync(hsync),
|
||||||
.vsync(vsync),
|
.vsync(vsync),
|
||||||
.display_on(display_on),
|
.display_on(display_on),
|
||||||
|
|
|
@ -175,7 +175,7 @@ module sprite_renderer(clk, vstart, load, hstart, rom_addr, rom_bits,
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module rotation_selector(rotation, bitmap_num, hmirror, vmirror);
|
module rotation_selector(rotation, bitmap_num, hmirror, vmirror);
|
||||||
input [4:0] rotation;
|
input [3:0] rotation;
|
||||||
output [2:0] bitmap_num;
|
output [2:0] bitmap_num;
|
||||||
output hmirror, vmirror;
|
output hmirror, vmirror;
|
||||||
|
|
||||||
|
@ -205,8 +205,26 @@ module rotation_selector(rotation, bitmap_num, hmirror, vmirror);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
function signed [7:0] sin_16x4;
|
||||||
|
input [3:0] in;
|
||||||
|
integer y;
|
||||||
|
case (in[1:0])
|
||||||
|
0: y = 0;
|
||||||
|
1: y = 3;
|
||||||
|
2: y = 5;
|
||||||
|
3: y = 6;
|
||||||
|
endcase
|
||||||
|
case (in[3:2])
|
||||||
|
0: sin_16x4 = 8'(y);
|
||||||
|
1: sin_16x4 = 8'(7-y);
|
||||||
|
2: sin_16x4 = 8'(-y);
|
||||||
|
3: sin_16x4 = 8'(y-7);
|
||||||
|
endcase
|
||||||
|
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,
|
||||||
|
switch_left, switch_right, switch_up);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
input reset;
|
input reset;
|
||||||
|
@ -216,14 +234,23 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
||||||
input [8:0] vpos;
|
input [8:0] vpos;
|
||||||
output [7:0] sprite_addr;
|
output [7:0] sprite_addr;
|
||||||
input [7:0] sprite_bits;
|
input [7:0] sprite_bits;
|
||||||
reg hmirror;
|
|
||||||
reg vmirror;
|
|
||||||
output gfx;
|
output gfx;
|
||||||
|
input switch_left, switch_right, switch_up;
|
||||||
|
|
||||||
|
wire hmirror, vmirror;
|
||||||
wire busy;
|
wire busy;
|
||||||
|
|
||||||
reg [7:0] player_x = 64;
|
reg [11:0] player_x_fixed;
|
||||||
reg [7:0] player_y = 64;
|
wire [7:0] player_x = player_x_fixed[11:4];
|
||||||
reg [4:0] player_rot = 0;
|
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 = 0;
|
||||||
|
reg [3:0] frame = 0;
|
||||||
|
|
||||||
wire vstart = {1'b0,player_y} == vpos;
|
wire vstart = {1'b0,player_y} == vpos;
|
||||||
wire hstart = {1'b0,player_x} == hpos;
|
wire hstart = {1'b0,player_x} == hpos;
|
||||||
|
@ -245,19 +272,53 @@ module tank_controller(clk, reset, hpos, vpos, hsync, vsync,
|
||||||
.bitmap_num(sprite_addr[7:5]),
|
.bitmap_num(sprite_addr[7:5]),
|
||||||
.hmirror(hmirror),
|
.hmirror(hmirror),
|
||||||
.vmirror(vmirror));
|
.vmirror(vmirror));
|
||||||
|
|
||||||
|
always @(posedge vsync or posedge reset)
|
||||||
|
if (reset) begin
|
||||||
|
player_rot <= 0;
|
||||||
|
end else begin
|
||||||
|
frame <= frame + 1;
|
||||||
|
// rotation
|
||||||
|
if (frame[0]) begin
|
||||||
|
if (switch_left)
|
||||||
|
player_rot <= player_rot - 1;
|
||||||
|
else if (switch_right)
|
||||||
|
player_rot <= player_rot + 1;
|
||||||
|
if (switch_up) begin
|
||||||
|
if (player_speed != 15)
|
||||||
|
player_speed <= player_speed + 1;
|
||||||
|
end else
|
||||||
|
player_speed <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge vsync)
|
always @(posedge hsync or posedge reset)
|
||||||
player_rot <= player_rot + 1;
|
if (reset) begin
|
||||||
|
player_x_fixed <= 128<<4;
|
||||||
|
player_y_fixed <= 120<<4;
|
||||||
|
end else begin
|
||||||
|
// 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
|
endmodule
|
||||||
|
|
||||||
module test_top(clk, reset, hsync, vsync, rgb);
|
//TODO: debouncing
|
||||||
|
|
||||||
|
module test_top(clk, reset, hsync, vsync, rgb, switches_p1);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
input reset;
|
input reset;
|
||||||
output hsync;
|
output hsync;
|
||||||
output vsync;
|
output vsync;
|
||||||
output [2:0] rgb;
|
output [2:0] rgb;
|
||||||
|
input [7:0] switches_p1;
|
||||||
|
|
||||||
wire display_on;
|
wire display_on;
|
||||||
wire [8:0] hpos;
|
wire [8:0] hpos;
|
||||||
wire [8:0] vpos;
|
wire [8:0] vpos;
|
||||||
|
@ -291,7 +352,10 @@ module test_top(clk, reset, hsync, vsync, rgb);
|
||||||
.vsync(vsync),
|
.vsync(vsync),
|
||||||
.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),
|
||||||
|
.switch_left(switches_p1[0]),
|
||||||
|
.switch_right(switches_p1[1]),
|
||||||
|
.switch_up(switches_p1[2])
|
||||||
);
|
);
|
||||||
|
|
||||||
wire tank1_gfx;
|
wire tank1_gfx;
|
||||||
|
|
|
@ -253,6 +253,9 @@ var VerilogPlatform = function(mainElement, options) {
|
||||||
debugCond = self.getDebugCallback();
|
debugCond = self.getDebugCallback();
|
||||||
var i=4; // TODO, start @ 0?
|
var i=4; // TODO, start @ 0?
|
||||||
var trace=inspect_obj && inspect_sym;
|
var trace=inspect_obj && inspect_sym;
|
||||||
|
gen.switches_p1 = switches[0];
|
||||||
|
gen.switches_p2 = switches[1];
|
||||||
|
gen.switches_gen = switches[2];
|
||||||
for (var y=0; y<videoHeight; y++) {
|
for (var y=0; y<videoHeight; y++) {
|
||||||
gen.hpaddle = y > paddle_x ? 1 : 0;
|
gen.hpaddle = y > paddle_x ? 1 : 0;
|
||||||
gen.vpaddle = y > paddle_y ? 1 : 0;
|
gen.vpaddle = y > paddle_y ? 1 : 0;
|
||||||
|
|
|
@ -4,10 +4,11 @@ import math
|
||||||
#n = 8
|
#n = 8
|
||||||
#m = 127
|
#m = 127
|
||||||
|
|
||||||
n = 64
|
n = 32
|
||||||
m = 127
|
m = 127
|
||||||
|
|
||||||
n=32
|
n = 4
|
||||||
|
m = 7
|
||||||
|
|
||||||
for i in range(0,n*4):
|
for i in range(0,n*4):
|
||||||
print '%d,' % int(round(math.sin(i*math.pi/2/n)*m)),
|
print '%d,' % int(round(math.sin(i*math.pi/2/n)*m)),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user