I am currently programming a blackjack game in verilog with several modules including game logic and scoring. The goal of my project is to display onto a screen through VGA and a nexys3 FPGA board the blackjack game. Before I mess with setting up VGA, I need to make sure that my game logic is correctly working and setting the player hand and player score correctly. Unfortunately the player's hand is not being set correctly and is displaying X values where 1s should be. Below are all of my modules and code and at the bottom is the simulation I am running:
This is the main module that calls my other modules.
module blackJack(
input clk,
input btnhit, //deal card to player
input btnpass, //stay for player/pass to dealer
input btnreset, //reset game to 0 and redeal
output Hsync,
output Vsync,
output reg [2:0] vgaRed,
output reg [2:0] vgaGreen,
output reg [1:0] vgaBlue
);
wire [7:0] plscore;
wire [7:0] dlscore;
wire [7:0] plhand;
wire [7:0] dlhand;
wire [2:0] state;
wire [7:0] plcard;
wire [7:0] dlcard;
wire plbust;
wire dlbust;
wire plbj;
wire dlbj;
wire plhit;
wire dlhit;
wire plwin;
wire pllose;
reg vgaclk;
wire trigger;
clock vclk(
.clk(clk),
.vgaclk(vgaclk)
);
wire hit;
debouncer hitD(
.clk(clk),
.button_in(btnhit),
.button_out(hit)
);
wire pass;
debouncer passD(
.clk(clk),
.button_in(btnpass),
.button_out(pass)
);
wire reset;
debouncer resetD(
.clk(clk),
.button_in(btnreset),
.button_out(reset)
);
controller cntrl(
.clk(clk),
.trigger(trigger),
.state(state),
.curPlHand(plhand),
.curDlHand(dlhand),
.dlhit(dlhit),
.plhit(plhit),
.plwin(plwin),
.pllose(pllose),
.plscore(plscore),
.dlscore(dlscore)
);
randomGen gen(
.clk(clk),
.card1(plcard),
.card2(dlcard)
);
player pl(
.clk(clk),
.addCard(plhit),
.card(plcard),
.hand(plhand)
);
player dl(
.clk(clk),
.addCard(dlhit),
.card(dlcard),
.hand(dlhand)
);
checkBust chkpl(
.clk(clk),
.handTotal(plhand),
.bust(plbust),
.blackJack(plbj)
);
checkBust chkdl(
.clk(clk),
.handTotal(dlhand),
.bust(dlbust),
.blackJack(dlbj)
);
stateMonitor sm(
.clk(clk),
.reset(reset),
.hit(hit),
.pass(pass),
.plwin(plwin),
.pllose(pllose),
.state(state),
.trigger(trigger)
);
endmodule
Here are each individual module.
module clock(
input clk,
output vgaclk
);
reg vgaclk;
reg [31:0] out = 0;
always @ (posedge clk) begin
if (out >= 3) begin
out <= 0;
end
if (out == 3) begin
vgaclk <= 1;
end
else begin
vgaclk <= 0;
end
out <= out + 1;
end
endmodule
player module:
module player(
input clk,
input addCard,
input [7:0] card,
output [7:0] hand
);
reg [7:0] hand = 0;
always @(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
end
endmodule
statemonitor module:
module stateMonitor(
input clk,
input reset,
input hit,
input pass,
input plwin,
input pllose,
output [2:0] state,
output trigger
);
reg [2:0] currentState = 3'b000;
reg action = 1;
//modes
//000 = start of game. score = 0 and no hand dealt
//001 = player dealt first card
//010 = player dealt second card
//011 = dealer dealt first card - wait for player to hit or pass
//100 = player hits
//101 = player passes -> dealer hits
//110 = payer wins
//111 = player loses
always @ (posedge clk) begin
if (currentState == 3'b000 && action == 0) begin
currentState <= 3'b001;
action <= 1;
end
else if (currentState == 2'b001 && action == 0) begin
currentState <= 3'b010;
action <= 1;
end
else if (currentState == 3'b010 && action == 0) begin
currentState <= 3'b011;
action <= 1;
end
else if (currentState == 3'b011 && action == 0) begin
if (plwin == 1) begin
currentState <= 3'b110;
action <= 1;
end
else if (hit == 1) begin
currentState <= 3'b100;
action <= 1;
end
else if (pass == 1) begin
currentState <= 3'b101;
action <= 1;
end
else if (reset == 1) begin
currentState <= 3'b000;
action <= 1;
end
end
else if (currentState == 3'b100 && action == 0) begin
if (plwin == 1) begin
currentState <= 3'b110;
action <= 1;
end
else if (pllose == 1) begin
currentState <= 3'b111;
action <= 1;
end
else if (hit == 1) begin
currentState <= 3'b100;
action <= 1;
end
else if (pass == 1) begin
currentState <= 3'b101;
action <= 1;
end
else if (reset == 1) begin
currentState <= 3'b000;
action <= 1;
end
end
else if (currentState == 3'b101 && action == 0) begin
if (plwin == 1) begin
currentState <= 3'b110;
action <= 1;
end
else if (pllose == 1) begin
currentState <= 3'b111;
action <= 1;
end
else if (reset == 1) begin
currentState <= 3'b000;
action <= 1;
end
else
action <= 1;
end
else if (currentState == 3'b110 && action == 0) begin
if (hit == 1)
currentState <= 3'b000;
end
else if (currentState == 3'b111 && action == 0) begin
if (hit == 1)
currentState <= 3'b000;
end
else
action <= 0;
end
assign state = currentState;
assign trigger = action;
endmodule
controller module:
module controller(
input clk,
input trigger,
input reset,
input plbust,
input dlbust,
input plbj,
input [2:0] state,
output [7:0] curPlHand,
output [7:0] curDlHand,
output dlhit,
output plhit,
output plwin,
output pllose,
output [7:0] plscore,
output [7:0] dlscore
);
reg [7:0] curPlHand;
reg [7:0] curDlHand;
reg [7:0] plscore;
reg [7:0] dlscore;
//reg plbust;
//reg dlbust;
//reg plscore;
//reg dlscore;
reg plhit = 0;
reg dlhit = 0;
reg plwin = 0;
reg pllose = 0;
//modes
//000 = start of game. score = 0 and no hand dealt
//001 = player dealt first card
//010 = player dealt second card
//011 = dealer dealt first card - wait for player to hit or pass
//100 = player hits
//101 = player passes -> dealer hits
//110 = payer wins
//111 = player loses
always @(*) begin
if (plbust == 1)
pllose <= 1;
else if (plbj == 1)
plwin <= 1;
else if (dlbust == 1)
plwin <= 1;
end
always @(posedge clk) begin
plhit <= 0;
dlhit <= 0;
if (state == 3'b000 && trigger) begin
curPlHand <= 8'b00000000;
curDlHand <= 8'b00000000;
if (reset == 1) begin
plscore <= 8'b00000000;
dlscore <= 8'b00000000;
end
end
else if (state == 3'b001 && trigger) begin
plhit <= 1;
end
else if (state == 3'b010 && trigger) begin
plhit <= 1;
end
else if (state == 3'b011 && trigger) begin
if (plbj == 1)
plwin <= 1;
else
dlhit <= 1;
end
else if (state == 3'b100 && trigger) begin
if (plbust == 1)
pllose <= 1;
else if (plbj == 1)
plwin <= 1;
else
plhit <= 1;
end
else if (state == 3'b101 && trigger) begin
if (dlbust == 1)
plwin <= 1;
else if (plbust == 1)
pllose <= 1;
else if (plbj == 1)
plwin <= 1;
else
dlhit <= 1;
end
/*else if (state == 3'b110) begin
end
else if (state == 3'b111) begin
end
*/
end
endmodule
random card generator module:
module randomGen (
input clk,
output card1,
output card2
);
reg [7:0] card1;
reg [7:0] card2;
always @ (posedge clk) begin
card1 <= ({$random} % 51 >> 2) + 1;
card2 <= ({$random} % 51 >> 2) + 1;
end
endmodule
check for blackjack and bust module:
module checkBust (
input clk,
input handTotal,
output bust,
output blackJack
);
wire [7:0] handTotal;
reg blackJack;
reg bust;
always @(posedge clk) begin
if(handTotal == 8'd21) begin
bust <= 0;
blackJack <= 1;
end
else if(handTotal > 8'd21) begin
bust <= 1;
blackJack <= 0;
end
else begin
bust <= 0;
blackJack <= 0;
end
end
endmodule
debouncer for FPGA button presses:
module debouncer(
input clk,
input button_in,
output button_out
);
reg [1:0] button_buffer;
assign button_out = button_buffer[0];
always @(posedge clk or posedge button_in) begin
if (button_in)
button_buffer <= 2'b11;
else
button_buffer <= {1'b0, button_buffer[1]};
end
endmodule
Here is the testbench I am currently running:
module testBlackjack;
// Inputs
reg clk;
reg btnhit;
reg btnpass;
reg btnreset;
// Instantiate the Unit Under Test (UUT)
blackJack uut (
.clk(clk),
.btnhit(btnhit),
.btnpass(btnpass),
.btnreset(btnreset)
);
initial begin
// Initialize Inputs
clk = 0;
btnhit = 0;
btnpass = 0;
btnreset = 0;
// Wait 100 ns for global reset to finish
#1000;
$finish;
end
always #20 clk = ~clk;
endmodule
Here is a image of my simulation which is only testing the initial setup of the game by distributing 2 cards to the player and 1 card to the dealer:
As you can see from the simulation, the card 6 is being added to the players hand when plhit = 1 (this is addcard inside the player module). The correct value that should be displayed in plhand should be 00000110 but instead the 1's are X's.
The issue I am having is that when I am attempting to add a card to a player's total hand score (in 8 bits) the bits that should be a 1 are being set as X. I have tried restating plscore as a reg and tried multiple assigning operations however I have no luck. Any help would be greatly appreciated and if there is any information need I will be happy to respond quickly.
iverilog
(I don't have the Xilinx tools installed right now, unfortunately), it looks like you've not declaredcard1
andcard2
to be vectors in bothrandomGen
, and the same problem withhandTotal
incheckBust
. (In other words - in the module you sayreg [7:0] xyz
, but in the module declaration you skip the[7:0]
). – tonysdg