first commit

This commit is contained in:
2025-04-06 00:11:28 -04:00
commit 6206025f5a
16 changed files with 930 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
`include "constants.sv"
module baseball_controlpath (
input logic got_strike,
input logic got_ball,
input logic got_foul,
input logic got_hit,
input logic got_out,
input logic strikeout,
input logic walk,
input logic three_outs,
input logic game_ended,
input logic [1:0] strike_count,
input logic team_active,
output logic [1:0] strike_mut_sel,
output logic [1:0] ball_mut_sel,
output logic [1:0] out_mut_sel,
output logic inning_mut_sel,
output logic team_toggle
);
always_comb begin
strike_mut_sel = `STRIKE_NOCHANGE;
ball_mut_sel = `BALL_NOCHANGE;
out_mut_sel = `OUT_NOCHANGE;
inning_mut_sel = `INNING_NOCHANGE;
team_toggle = 1'b0;
if(!game_ended) begin
if(strikeout) begin
strike_mut_sel = `STRIKE_ZERO;
ball_mut_sel = `BALL_ZERO;
out_mut_sel = `OUT_PLUSONE;
end
if(walk) begin
strike_mut_sel = `STRIKE_ZERO;
ball_mut_sel = `BALL_ZERO;
end
if(three_outs) begin
strike_mut_sel = `STRIKE_ZERO;
ball_mut_sel = `BALL_ZERO;
out_mut_sel = `OUT_ZERO;
team_toggle = 1'b1;
if(team_active)
inning_mut_sel = `INNING_PLUSONE;
end
if(got_strike)
strike_mut_sel = `STRIKE_PLUSONE;
if(got_ball)
ball_mut_sel = `BALL_PLUSONE;
if(got_foul && strike_count < 2)
strike_mut_sel = `STRIKE_PLUSONE;
if(got_hit) begin
strike_mut_sel = `STRIKE_ZERO;
ball_mut_sel = `BALL_ZERO;
end
if(got_out) begin
strike_mut_sel = `STRIKE_ZERO;
ball_mut_sel = `BALL_ZERO;
out_mut_sel = `OUT_PLUSONE;
end
end
end
endmodule

115
rtl/baseball_datapath.sv Normal file
View File

@@ -0,0 +1,115 @@
module baseball_datapath (
input logic clock,
input logic reset,
input logic [1:0] strike_mut_sel,
input logic [1:0] ball_mut_sel,
input logic [1:0] out_mut_sel,
input logic inning_mut_sel,
input logic team_toggle,
output logic strikeout,
output logic walk,
output logic three_outs,
output logic game_ended,
output logic [1:0] strike_count,
output logic [2:0] ball_count,
output logic [1:0] out_count,
output logic [3:0] inning_count,
output logic team_active
);
logic [1:0] strike_next;
logic [2:0] ball_next;
logic [1:0] out_next;
logic [3:0] inning_next;
logic team_next;
assign strikeout = (strike_count >= 3);
assign walk = (ball_count >= 4);
assign three_outs = (out_count >= 3);
assign game_ended = (inning_count >= 10);
multiplexer4 #(.WIDTH(2)) strike_mut (
.sel(strike_mut_sel),
.in0(strike_count),
.in1('b0),
.in2(strike_count + 1),
.in3('bx),
.out(strike_next)
);
multiplexer4 #(.WIDTH(3)) ball_mut (
.sel(ball_mut_sel),
.in0(ball_count),
.in1('b0),
.in2(ball_count + 1),
.in3('bx),
.out(ball_next)
);
multiplexer4 #(.WIDTH(2)) out_mut (
.sel(out_mut_sel),
.in0(out_count),
.in1('b0),
.in2(out_count + 1),
.in3('bx),
.out(out_next)
);
multiplexer2 #(.WIDTH(4)) inning_mut (
.sel(inning_mut_sel),
.in0(inning_count),
.in1(inning_count + 1),
.out(inning_next)
);
multiplexer2 #(.WIDTH(1)) team_mut (
.sel(team_toggle),
.in0(team_active),
.in1(~team_active),
.out(team_next)
);
register #(.WIDTH(2)) strike_register (
.clock(clock),
.reset(reset),
.write_en('1),
.next(strike_next),
.value(strike_count)
);
register #(.WIDTH(3)) ball_register (
.clock(clock),
.reset(reset),
.write_en('1),
.next(ball_next),
.value(ball_count)
);
register #(.WIDTH(2)) out_register (
.clock(clock),
.reset(reset),
.write_en('1),
.next(out_next),
.value(out_count)
);
register #(.WIDTH(4), .RESET(1)) inning_register (
.clock(clock),
.reset(reset),
.write_en('1),
.next(inning_next),
.value(inning_count)
);
register #(.WIDTH(1)) team_register (
.clock(clock),
.reset(reset),
.write_en('1),
.next(team_next),
.value(team_active)
);
endmodule

View File

@@ -0,0 +1,65 @@
module baseball_scoreboard (
input logic clock,
input logic reset,
input logic got_strike,
input logic got_ball,
input logic got_foul,
input logic got_hit,
input logic got_out,
output logic [1:0] strike_count,
output logic [2:0] ball_count,
output logic [1:0] out_count,
output logic [3:0] inning_count,
output logic team_active
);
logic [1:0] strike_mut_sel;
logic [1:0] ball_mut_sel;
logic [1:0] out_mut_sel;
logic inning_mut_sel;
logic team_toggle;
logic strikeout;
logic walk;
logic three_outs;
logic game_ended;
baseball_controlpath ctlpath (
.got_strike(got_strike),
.got_ball(got_ball),
.got_foul(got_foul),
.got_hit(got_hit),
.got_out(got_out),
.strikeout(strikeout),
.walk(walk),
.three_outs(three_outs),
.game_ended(game_ended),
.strike_count(strike_count),
.team_active(team_active),
.strike_mut_sel(strike_mut_sel),
.ball_mut_sel(ball_mut_sel),
.out_mut_sel(out_mut_sel),
.inning_mut_sel(inning_mut_sel),
.team_toggle(team_toggle)
);
baseball_datapath datapath (
.clock(clock),
.reset(reset),
.strike_mut_sel(strike_mut_sel),
.ball_mut_sel(ball_mut_sel),
.out_mut_sel(out_mut_sel),
.inning_mut_sel(inning_mut_sel),
.team_toggle(team_toggle),
.strikeout(strikeout),
.walk(walk),
.three_outs(three_outs),
.game_ended(game_ended),
.strike_count(strike_count),
.ball_count(ball_count),
.out_count(out_count),
.inning_count(inning_count),
.team_active(team_active)
);
endmodule

92
rtl/basys3_toplevel.sv Normal file
View File

@@ -0,0 +1,92 @@
module basys3_toplevel (
input logic clk,
input logic btnC,
input logic btnU,
input logic btnL,
input logic btnR,
input logic btnD,
input logic [15:0] sw,
output logic [15:0] led
);
logic clock;
logic reset;
assign clock = clk;
assign reset = sw[0];
logic got_strike;
logic got_ball;
logic got_foul;
logic got_hit;
logic got_out;
logic [1:0] strike_count;
logic [2:0] ball_count;
logic [1:0] out_count;
logic [3:0] inning_count;
logic team_active;
assign led[15:12] = inning_count;
assign led[11] = 'b0;
assign led[10] = team_active;
assign led[9] = 'b0;
assign led[8] = (strike_count > 0);
assign led[7] = (strike_count > 1);
assign led[6] = 'b0;
assign led[5] = (ball_count > 0);
assign led[4] = (ball_count > 1);
assign led[3] = (ball_count > 2);
assign led[2] = 'b0;
assign led[1] = (out_count > 0);
assign led[0] = (out_count > 1);
button_trigger btnC_trigger (
.clock(clock),
.reset(reset),
.raw_button(btnC),
.trigger_signal(got_out)
);
button_trigger btnU_trigger (
.clock(clock),
.reset(reset),
.raw_button(btnU),
.trigger_signal(got_hit)
);
button_trigger btnL_trigger (
.clock(clock),
.reset(reset),
.raw_button(btnL),
.trigger_signal(got_strike)
);
button_trigger btnR_trigger (
.clock(clock),
.reset(reset),
.raw_button(btnR),
.trigger_signal(got_ball)
);
button_trigger btnD_trigger (
.clock(clock),
.reset(reset),
.raw_button(btnD),
.trigger_signal(got_foul)
);
baseball_scoreboard baseball(
.clock(clock),
.reset(reset),
.got_strike(got_strike),
.got_ball(got_ball),
.got_foul(got_foul),
.got_hit(got_hit),
.got_out(got_out),
.strike_count(strike_count),
.ball_count(ball_count),
.out_count(out_count),
.inning_count(inning_count),
.team_active(team_active)
);
endmodule

49
rtl/button_trigger.sv Normal file
View File

@@ -0,0 +1,49 @@
module button_trigger # (
parameter CLOCK_FREQUENCY = 100_000_000,
parameter DEBOUNCE_MILLIS = 40
) (
input logic clock,
input logic reset,
input logic raw_button,
output logic trigger_signal
);
localparam DEBOUNCE_COUNTER_MAX = (CLOCK_FREQUENCY / 1000) * DEBOUNCE_MILLIS;
logic [$clog2(DEBOUNCE_COUNTER_MAX)-1:0] counter;
enum logic [1:0] { ST_IDLE, ST_FILTER, ST_RELEASE } state;
always_ff @(posedge clock, posedge reset) begin
if(reset) begin
state <= ST_IDLE;
counter <= 'bx;
trigger_signal <= '0;
end else case(state)
ST_IDLE: begin
if(raw_button) begin
counter <= DEBOUNCE_COUNTER_MAX;
state <= ST_FILTER;
end
end
ST_FILTER: begin
if(!raw_button)
state <= ST_IDLE;
else if(counter > 0)
counter <= counter - 1;
else begin
trigger_signal <= '1;
state <= ST_RELEASE;
end
end
ST_RELEASE: begin
trigger_signal <= '0;
if(!raw_button)
state <= ST_IDLE;
end
default: state <= ST_IDLE;
endcase
end
endmodule

19
rtl/common/multiplexer.sv Normal file
View File

@@ -0,0 +1,19 @@
module multiplexer #(
parameter WIDTH = 32,
parameter CHANNELS = 2
) (
input logic [$clog2(CHANNELS)-1:0] sel,
input logic [(CHANNELS*WIDTH)-1:0] in_bus,
output logic [WIDTH-1:0] out
);
genvar ig;
logic [WIDTH-1:0] in_array [CHANNELS];
assign out = in_array[sel];
for(ig = 0; ig < CHANNELS; ig = ig + 1) begin
assign in_array[(CHANNELS - 1) - ig] = in_bus[ig * WIDTH +: WIDTH];
end
endmodule

View File

@@ -0,0 +1,16 @@
module multiplexer2 #(
parameter WIDTH = 32
) (
input logic sel,
input logic [WIDTH-1:0] in0,
input logic [WIDTH-1:0] in1,
output logic [WIDTH-1:0] out
);
multiplexer #(.WIDTH(WIDTH), .CHANNELS(2)) multiplexer_inst (
.sel(sel),
.in_bus({in0, in1}),
.out(out)
);
endmodule

View File

@@ -0,0 +1,18 @@
module multiplexer4 #(
parameter WIDTH = 32
) (
input logic [1:0] sel,
input logic [WIDTH-1:0] in0,
input logic [WIDTH-1:0] in1,
input logic [WIDTH-1:0] in2,
input logic [WIDTH-1:0] in3,
output logic [WIDTH-1:0] out
);
multiplexer #(.WIDTH(WIDTH), .CHANNELS(4)) multiplexer_inst (
.sel(sel),
.in_bus({in0, in1, in2, in3}),
.out(out)
);
endmodule

18
rtl/common/register.sv Normal file
View File

@@ -0,0 +1,18 @@
module register #(
parameter WIDTH = 32,
parameter RESET = 0
) (
input logic clock,
input logic reset,
input logic write_en,
input logic [WIDTH-1:0] next,
output logic [WIDTH-1:0] value
);
always_ff @(posedge clock, posedge reset)
if(reset)
value <= RESET;
else if(write_en)
value <= next;
endmodule

21
rtl/constants.sv Normal file
View File

@@ -0,0 +1,21 @@
`define EVENT_NONE 3'h0
`define EVENT_STRIKE 3'h1
`define EVENT_BALL 3'h2
`define EVENT_FOUL 3'h3
`define EVENT_HIT 3'h4
`define EVENT_OUT 3'h5
`define STRIKE_NOCHANGE 2'b00
`define STRIKE_ZERO 2'b01
`define STRIKE_PLUSONE 2'b10
`define BALL_NOCHANGE 2'b00
`define BALL_ZERO 2'b01
`define BALL_PLUSONE 2'b10
`define OUT_NOCHANGE 2'b00
`define OUT_ZERO 2'b01
`define OUT_PLUSONE 2'b10
`define INNING_NOCHANGE 1'b0
`define INNING_PLUSONE 1'b1