This is a module for a 8 bit shift register using two 4 bit shift registers. 4 bit register modules works fine. (Just testing this for right shift for the moment)
module shift_reg_8 (Out,In,shift_left,shift_right,s0,s1,enable,clock);
output [7:0] Out;
wire [3:0]Least_Out,Most_Out;
input [7:0] In;
wire [3:0]Least_In,Most_In;
reg temp;
initial
temp = In[4];
assign {Most_In,Least_In} = In;
input shift_left,shift_right,enable,s0,s1,clock;
shift_reg least_sig_reg(Least_Out,Least_In,shift_left,shift_right,s0,s1,enable,clock);
shift_reg most_sig_reg(Most_Out,Most_In,shift_left,shift_right,s0,s1,enable,clock);
assign Out = {Most_Out,Least_Out};
assign Out[3] = temp;
endmodule
Here's the test bench.
module stimulus;
reg [7:0]INPUT;
reg ENABLE,CLOCK,S0,S1,SL,SR;
wire [7:0] OUTPUT;
shift_reg_8 my8shiftreg(OUTPUT,INPUT,SL,SR,S0,S1,ENABLE,CLOCK); // SL = Shift_Left, SR = Shift_Right, SO,S1 = Controls
initial
begin
CLOCK = 1'b0;
INPUT = 8'b01101110; ENABLE = 1;S0 = 0;S1 = 1;SL = 0;SR = 1;
#14 $display("Test 1 (Right Shift): INPUT = %b, S1 = %b, S0 = %b, SR = %b, OUTPUT = %b\n",INPUT,S1,S0,SR,OUTPUT);
end
always
#5 CLOCK = ~CLOCK;
initial
#100 $stop;
endmodule
This gives an output like this when simulated.
Test 1 (Right Shift): INPUT = 01101110, S1 = 1, S0 = 0, SR = 1, OUTPUT = 1011x111
what might be the problem?
Here's the shift_reg code...
module shift_reg(Out,In,shift_left,shift_right,s0,s1,enable,clock);
output [3:0] Out;
input [3:0] In;
input shift_left,shift_right,enable,s0,s1,clock;
reg [3:0] out_reg;
always #(posedge clock & enable)
begin
if ((s0 == 1'b0) && (s1 == 1'b0)) // Holding
begin
end
else if ((s0 == 1'b1) && (s1 == 1'b0)) // Left Shift
begin
out_reg[0] <= shift_left;
out_reg[1] <= In[0];
out_reg[2] <= In[1];
out_reg[3] <= In[2];
end
else if ((s0 == 1'b0) && (s1 == 1'b1)) // Right Shift
begin
out_reg[0] <= In[1];
out_reg[1] <= In[2];
out_reg[2] <= In[3];
out_reg[3] <= shift_right;
end
else if ((s0 == 1'b1) && (s1 == 1'b1)) // Loading
begin
out_reg <= In;
end
end
assign Out = out_reg;
endmodule
You are assigning out[3] twice.
assign Out = {Most_Out,Least_Out}; // Assigns all 8 bits
assign Out[3] = temp; // Assigns bit 3 again.
The multiple drivers is causing an unknown state.
Related
I am having some issues when attempting to run a simulation. It seems there is an issue with my instances of my first 2 modules inside of my 3rd module. The code is compiling okay, but I am running into trouble when I try to run a simulation.
I am not really sure if the problem is in my code or my test bench.
module fulladder
(
input [15:0] x,
input [15:0] y,
output [15:0] O
);
assign O = y + x;
endmodule
module shifter
(
input [15:0] in,
input [2:0] N,
output [15:0] O
);
reg [7:0] out_reg;
assign O = out_reg;
always #(N or in) begin
case (N)
7 : out_reg <= { in[7:0],7'b0};
6 : out_reg <= { in[7:0],6'b0};
5 : out_reg <= { in[7:0],5'b0};
4 : out_reg <= { in[7:0],4'b0};
3 : out_reg <= { in[7:0],3'b0};
2 : out_reg <= { in[7:0],2'b0};
1 : out_reg <= { in[7:0],1'b0};
0 : out_reg <= in[7:0];
endcase
end
endmodule
module my_multiplier(Rst, Ld, clk, A, B, O);
input clk;
input [7:0]A, B;
input Rst, Ld;
output [15:0] O;
reg Done;
reg [15:0] Otemp;
reg [15:0] O;
reg [7:0] Atemp;
reg [1:0] state;
reg [1:0] C;
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
always #(posedge clk or posedge Rst)
begin
case(state)
S0: begin
Done <= 0;
if (Ld == 1)
begin
C <= 0;
Atemp <= A;
state <= S1;
end
else
state <= S0;
end
S1: if (B[C] == 1)
begin
shifter ( A, C, Atemp);
O <= Otemp;
C <= C + 1;
state <= S2;
end
else
begin
Atemp <= 0;
O <= Otemp;
C <= C + 1;
state <= S2;
end
S2: begin
O <= Otemp;
if (C == 3)
state <= S3;
else
state <= S2;
end
S3: begin
Done <= 1;
state <= S0;
end
default
state <= S0;
endcase
fulladder (Atemp, O, Otemp);
end
endmodule
module my_multiplier_tb;
reg clk_tb;
reg [7:0]A_tb, B_tb;
reg Rst_tb, Ld_tb;
wire [15:0] O_tb;
my_multiplier dut( Rst_tb, Ld_tb, clk_tb, A_tb, B_tb, O_tb );
always #5 clk_tb = ~clk_tb;
initial begin
A_tb = 8'd8;
B_tb = 8'd7;
#15 Ld_tb = 1; // set Load to begin multiplication
#10 Ld_tb = 0; // wait 1 clock cycle
#300
$monitor($time, "\t A=%d,\t B=%d,\t O=%d", A_tb, B_tb, O_tb);
$finish;
end
endmodule
The problem is in the my_multiplier module where you have multiple syntax errors. If you sign up for a free account on edaplayground and post your code there, you may see more helpful compile errors there.
You must not place a module instance inside an always block. These 2 lines must be moved outside the always:
fulladder (Atemp, O, Otemp);
shifter ( A, C, Atemp);
Once you do that, you need to add instance names, like i0 and i1 below:
fulladder i0 (Atemp, O, Otemp);
shifter i1 ( A, C, Atemp);
While I was trying to run the simulation in vivado, I got:
ERROR: Iteration limit 10000 is reached. Possible zero delay
oscillation detected where simulation time can not advance. Please
check your source code. Note that the iteration limit can be changed
using switch -maxdeltaid. Time: 10 ns Iteration: 10000
I don't have any initial statement in my module being tested.
Could anybody point out where the problem could be?
`timescale 1ns / 1ps
module mulp(
input clk,
input rst,
input start,
input [4:0] mplier, // -13
input [4:0] mplcant, // -9
output reg done,
output [9:0] product
);
parameter N = 6;
parameter Idle = 2'b00;
parameter Load = 2'b01;
parameter Oper = 2'b10;
parameter Finish = 2'b11;
reg done_r;
reg [N-1:0] A, A_r, B, B_r;
reg [1:0] state, state_r;
reg [2:0] count, count_r;
wire [N-2:0] C, C_comp;
reg [N-2:0] C_r;
assign C = mplcant; assign C_comp = {~C + 1};
assign product = {A_r[N-2:0], B_r[N-2:0]};
always #(posedge clk) begin
if (rst) begin
state_r <= Idle;
count_r <= 0;
done_r <= 0;
A_r <= 0;
B_r <= 0;
end else begin
state_r <= state;
count_r <= count;
done_r <= done;
A_r <= A;
B_r <= B;
end // if
end // always
always #(*) begin
state = state_r;
count = count_r - 1; // count: 6
done = done_r;
A = A_r;
B = B_r;
case (state)
Idle: begin
if (start) begin
state <= Load;
end // if
end
Load: begin
A = 0; B = {mplier, 1'b0}; count = N; // start at 6
state = Oper;
end
Oper: begin
if (count == 0)
state = Finish;
else begin
case (B[1:0])
2'b01: begin
// add C to A
A = A_r + {C[N-2], C[N-2:0]};
// shift A and B
A = {A_r[N-1], A_r[N-1:1]};
B = {A_r[0], B_r[N-1:1]};
end
2'b10: begin
A = A_r + {C_comp[N-2], C_comp[N-2:0]};
A = {A_r[N-1], A[N-1:1]};
B = {A_r[0], B_r[N-1:1]};
end
(2'b00 | 2'b11): begin
A = {A_r[N-1], A[N-1:1]};
B = {A_r[0], B_r[N-1:1]};
end
default: begin
state = Idle; done = 1'bx; // error
end
endcase
end // else
end // Oper
Finish: begin
done = 1;
state = Idle;
end // Finish
default: begin
done = 1'bx;
state = Idle;
end
endcase
end // always
endmodule
You have a combinational loop. You are sampling and driving the state signal in the combinational always block. Typically, you sample the registered state variable (state_r in your code) in an FSM. Change:
case (state)
to:
case (state_r)
Unrelated, but you should use all blocking assignments in the combo block (not a mixture). Change:
state <= Load;
to:
state = Load;
module DSD_Project(flag0, flag1, hit0, hit1,room_counter,someone_inRoom,someone_Spying,hit0_LED, hit1_LED,echo0_LED, echo1_LED, anti_theft_output,reset_Antitheft_output,echo0, echo1, CLOCK_50,anti_theft, reset_Antitheft);
output reg hit0_LED = 1'b0;
output reg hit1_LED = 1'b0;
output reg echo0_LED = 1'b0;
output reg echo1_LED = 1'b0;
output reg flag0 = 1'b0;
output reg flag1 = 1'b0;
output reg hit0 = 1'b0;
output reg hit1 = 1'b0;
output reg room_counter = 1'b0;
output reg someone_inRoom = 1'b0;
output reg someone_Spying = 1'b0;
output reg anti_theft_output = 1'b0;
output reg reset_Antitheft_output = 1'b0;
input echo0; // input_signal from the sensor 1
input echo1;// input_signal from the sensor 2
input CLOCK_50;
input anti_theft ; //= 1'b0; // switch button
input reset_Antitheft; // = 1'b0; // push button
sensor s1(hit0, echo0) ; // , CLOCK_50);
sensor s2(hit1, echo1) ; // , CLOCK_50);
always#(posedge CLOCK_50)
begin
hit0_LED <= hit0;
hit1_LED <= hit1;
echo0_LED <= echo0;
echo1_LED <= echo1;
end
//anti_theft: seting and reseting the output
//always#(anti_theft) //or reset_Antitheft)
//begin
//anti_theft_output <= anti_theft ;
//reset_Antitheft_output <= reset_Antitheft ;
//end
always#(posedge hit0 or posedge hit1)
begin
if (hit0 == 1 && hit1== 0)
begin
flag0<= 1;
//flag1<= 0;
if(flag1==0)
begin
hit0=0;
room_counter <= room_counter +1 ;
someone_inRoom <=1 ;
if(anti_theft == 1)
someone_Spying <= 1;
end
else
flag1<=0;
end
else
begin
if ((hit0 == 0) && (hit1 == 1))
begin
//flag0<=0;
flag1<=1;
if(flag0 == 0)
begin
hit1=0;
room_counter <= room_counter -1 ;
if(room_counter==0)
begin
someone_inRoom <=0 ;
end
end
else
flag0<=0;
end
end
end
always#(reset_Antitheft)
begin
if( (anti_theft==1) && (someone_Spying == 1) )
begin
anti_theft_output <= 0 ;
someone_Spying <= 0 ;
end
end
endmodule
module sensor(hit, input_signal); //, CLOCK_50);
input input_signal;
output reg hit = 1'b0;
//reg [25:0] clock_counter;
always#(input_signal) // posedge CLOCK_50 ||
begin
//if (clock_counter == 8_000_000)
begin
if (input_signal==1)
begin
hit <= 1;
end
else
begin
hit <= 0;
end
end
//else
// clock_counter <= clock_counter+1;
end
endmodule
ScreenShoot
As you would know, the problem is with the following lines:
sensor s1(hit0, echo0) ; // , CLOCK_50);
sensor s2(hit1, echo1) ; // , CLOCK_50);
In sensor, the first port, hit is a output. However, you're attempting to connect it to a reg, as you specified in the lines above:
output reg hit0 = 1'b0;
output reg hit1 = 1'b0;
You should use these signals as wires, not regs.
I make a design for an adder but the result is wrong.
module FMUL(CLK, St, F1, E1, F2, E2, F, V, done);
input CLK;
input St;
input [3:0] F1;
input [3:0] E1;
input [3:0] F2;
input [3:0] E2;
output[6:0] F;
output V;
output done;
reg[6:0] F;
reg done;
reg V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
initial
begin
State = 0;
PS1 = 0;
NS1 = 0;
Nextstate=0;
end
always #(PS1 or St or Mdone or X or A or B)
begin : main_control
Load = 1'b0;
Adx = 1'b0;
NS1 = 0;
SM8 = 1'b0;
RSF = 1'b0;
LSF = 1'b0;
V = 1'b0;
F = 7'b0000000;
done = 1'b0;
case (PS1)
0 :
begin
F = 7'b0000000;
done = 1'b0;
V = 1'b0;
if(St == 1'b1)
begin
Load = 1'b1;
NS1 = 1;
end
end
1 :
begin
Adx = 1'b1;
NS1 = 2;
end
2 :
begin
if(Mdone == 1'b1)
begin
if(A==0)
begin
SM8 = 1'b1;
end
else if(A == 4 & B == 0)
begin
RSF = 1'b1;
end
else if (A[2] == A[1])
begin
LSF = 1'b1;
end
NS1 = 3;
end
else
begin
NS1 = 2;
end
end
3 : begin
if(X[4] != X[3])
begin
V = 1'b1;
end
else
begin
V = 1'b0;
end
done = 1'b1;
F = {A[2:0],B};
if(St==1'b0)
begin
NS1 = 0;
end
end
endcase
end
always #(State or Adx or B)
begin : mul2c
AdSh = 1'b0;
Sh = 1'b0;
Cm = 1'b0;
Mdone = 1'b0;
Nextstate = 0;
case(State)
0 :
begin
if(Adx==1'b1)
begin
if((B[0]) == 1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 1;
end
end
1,2 :
begin
if((B[0])==1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = State + 1;
end
3:
begin
if((B[0])==1'b1)
begin
Cm = 1'b1;
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 4;
end
4:
begin
Mdone = 1'b1;
Nextstate = 0;
end
endcase
end
wire [3:0] addout;
assign addout = (Cm == 1'b0)? (A+C) : (A-C);
always #(posedge CLK)
begin : update
PS1 <= NS1;
State <= Nextstate;
if(Load == 1'b1)
begin
X <= {E1[3], E1};
Y <= {E2[3], E2};
A <= 4'b0000;
B <= F1;
C <= F2;
end
if(Adx == 1'b1)
begin
X <= X+Y;
end
if(SM8 == 1'b1)
begin
X <= 5'b11000;
end
if(RSF == 1'b1)
begin
A <= {1'b0, A[3:1]};
B <= {A[0], B[3:1]};
X <= X+1;
end
if(LSF == 1'b1)
begin
A <= {A[2:0], B[3]};
B <= {B[2:0], 1'b0};
X <= X+31;
end
if(AdSh == 1'b1)
begin
A <= {(C[3]^Cm), addout[3:1]};
B <= {addout[0], B[3:1]};
end
if(Sh == 1'b1)
begin
A <= {A[3], A[3:1]};
B <= {A[0], B[3:1]};
end
end
endmodule
test bench.
module tb_FMUL();
wire[6:0] F;
wire done;
wire V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
reg CLK;
reg St;
reg [3:0] F1;
reg [3:0] E1;
reg [3:0] F2;
reg [3:0] E2;
FMUL u0(CLK, St, F1, E1, F2, E2, F, V, done);
always
begin
#10 CLK <= ~CLK;
end
initial
begin
#100 F1 = 2.125;
E1 = 5; F2 = 5.1; E2 = 1; St=0;
#100 F1 = 1.125;
E1 = 5; F2 = 2.1; E2 = 2; St=0;
#100 F1 = 5.125;
E1 = 5; F2 = 3.1; E2 = 3; St=0;
end
endmodule
The simulation results waveform.
enter image description here
I refer to the book.There is no code test bench.
So I made. But did't operate.
also CLK not is not changed.
please review the testbench code.
You have (at least) two problems:
Your clock needs to be initialised (eg to 1'b0):
initial CLK = 1'b0;
The initial value of any wire or reg in Verilog is 1'bx; ~1'bx is 1'bx; so CLK remains at 1'bx.
Your simulation doesn't stop. I added a call to $finish in the main initial block.
https://www.edaplayground.com/x/r4U
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.
A couple if issue:
Fist off the header. You are mixing ANSI and non-ANSI header styles. This is illegal syntax. Some simulator/synthesizer is allowing it, but it is bad practice. I've already answered header related question in more depth here "object <name> is not declared in verlog" and "Issue with parameters in Modelsim" so I'll just summarize; follow ANSI or non-ANSI, don't blend header styles in the same module. You may use different header styles with different modules, but it is recommended to be consistent. I prefer ANSI style.
For example:
module clock(
input clk,
output vgaclk
);
reg vgaclk; // <-- this is mixing styles
...
module checkBust (
input clk,
input handTotal,
output bust,
output blackJack
);
wire [7:0] handTotal; // <-- these are mixing styles too
reg blackJack;
reg bust;
...
should be:
module clock(
input clk, reset,
output reg vgaclk
);
...
module checkBust (
input clk,
input [7:0] handTotal,
output reg bust,
output reg blackJack
);
...
Some signals (for example vgaclk) are not initialized. You could initialize them inline or an initial block, however it is recommended to reset them in an always block. This way you can restore the initial values without powering down the design. FPGAs have limited number of asynchronous reset flops, so use synchronous reset only. ASIC prefer using asynchronous reset flops to initialize all values and use synchronous reset for dynamic resets. Example:
always #(posedge clk) begin
if (reset) begin
hand <= 8'h0;
end
if (addCard == 1) begin
hand <= hand + card;
end
end
plhand and dlhand are begin driven by controller by player. Based on the code, it should only be assigned within player. controller should send a reset signal to player to set the value back to 0.
The last issue I can quickly spot is that following code is infers level-sensitive latches and assigned in two separate always blocks. Latches are not necessarily bad, but they have a higher change of glitching and should only be used when specifically requited. The fact the variables are assigned in two different always blocks will be a synthesis error. I believe you can safely delete the latching code.
always #(*) begin
if (plbust == 1)
pllose <= 1;
else if (plbj == 1)
plwin <= 1;
else if (dlbust == 1)
plwin <= 1;
end
You have to remember that signals in verilog represent physical circuitry. We refer to something that sets a value to a wire signal as a driver. Signals aren't allowed to have multiple drivers, as this can cause shorts (one driver want to put Vdd on a wire, while another connects it to ground).
In your case, both the controller and the player specify that they output to plhand, which makes both of them drivers. So when player want to write a 1 to a bit of plhand, the controller is still writing a 0, which causes a conflict. You should've gotten an error or warning that a signal had multiple drivers, which would let you know that you were getting this behavior.
In short, you can pass a wire between as many modules as you want, but only one of those modules can output to it. So, consider changing curPlHand from an output to an input.
NOTE: This is not the problem. See other answers/comments for more information.
In the player module, you don't set hand properly for all conditions. Specifically:
always #(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
end
needs to handle addCard != 1. So try:
always #(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
else
hand <= hand;
end