verilog why doesn't it make proper result in register file? - verilog

i'm making 8x32b register file below is my verilog code
module register_file(clk, reset, dstW, valW, write, srcA, srcB, valA, valB );
input clk;
input reset;
input[2:0] dstW;
input[31:0] valW;
input write;
input[2:0] srcA;
input[2:0] srcB;
output[31:0] valA;
output[31:0] valB;
reg[31:0] r0eax, r1ecx, r2edx, r3ebx, r4esi, r5edi, r6esp, r7edi;
wire[31:0] reg_input_0, reg_input_1, reg_input_2, reg_input3, reg_input4,
reg_input5, reg_input6, reg_input7;
wire[7:0] decoder_out, select;
assign valA =
(srcA == 3'b000) ? r0eax:
(srcA == 3'b001) ? r1ecx:
(srcA == 3'b010) ? r2edx:
(srcA == 3'b011) ? r3ebx:
(srcA == 3'b100) ? r4esi:
(srcA == 3'b101) ? r5edi:
(srcA == 3'b110) ? r6esp:
(srcA == 3'b111) ? r7edi: 32'bx;
assign valB =
(srcB == 3'b000) ? r0eax:
(srcB == 3'b001) ? r1ecx:
(srcB == 3'b010) ? r2edx:
(srcB == 3'b011) ? r3ebx:
(srcB == 3'b100) ? r4esi:
(srcB == 3'b101) ? r5edi:
(srcB == 3'b110) ? r6esp:
(srcB == 3'b111) ? r7edi: 32'bx;
assign decoder_out[0] = (dstW == 3'b000)? 1'b1 : 1'b0;
assign decoder_out[1] = (dstW == 3'b001)? 1'b1 : 1'b0;
assign decoder_out[2] = (dstW == 3'b010)? 1'b1 : 1'b0;
assign decoder_out[3] = (dstW == 3'b011)? 1'b1 : 1'b0;
assign decoder_out[4] = (dstW == 3'b100)? 1'b1 : 1'b0;
assign decoder_out[5] = (dstW == 3'b101)? 1'b1 : 1'b0;
assign decoder_out[6] = (dstW == 3'b110)? 1'b1 : 1'b0;
assign decoder_out[7] = (dstW == 3'b111)? 1'b1 : 1'b0;
and(select[0], write, decoder_out[0]);
and(select[1], write, decoder_out[1]);
and(select[2], write, decoder_out[2]);
and(select[3], write, decoder_out[3]);
and(select[4], write, decoder_out[4]);
and(select[5], write, decoder_out[5]);
and(select[6], write, decoder_out[6]);
and(select[7], write, decoder_out[7]);
assign reg_input_0 = select[0] ? valW : r0eax;
assign reg_input_1 = select[1] ? valW : r1ecx;
assign reg_input_2 = select[2] ? valW : r2edx;
assign reg_input_3 = select[3] ? valW : r3ebx;
assign reg_input_4 = select[4] ? valW : r4esi;
assign reg_input_5 = select[5] ? valW : r5edi;
assign reg_input_6 = select[6] ? valW : r6esp;
assign reg_input_7 = select[7] ? valW : r7edi;
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r0eax <= 32'b0;
r1ecx <= 32'b0;
r2edx <= 32'b0;
r3ebx <= 32'b0;
r4esi <= 32'b0;
r5edi <= 32'b0;
r6esp <= 32'b0;
r7edi <= 32'b0;
end
else begin
r0eax <= reg_input_0;
r1ecx <= reg_input_1;
r2edx <= reg_input_2;
r3ebx <= reg_input_3;
r4esi <= reg_input_4;
r5edi <= reg_input_5;
r6esp <= reg_input_6;
r7edi <= reg_input_7;
end
end
endmodule
and testbench is as follows
module tttt;
// Inputs
reg clk;
reg reset;
reg [2:0] dstW;
reg [31:0] valW;
reg write;
reg [2:0] srcA;
reg [2:0] srcB;
// Outputs
wire [31:0] valA;
wire [31:0] valB;
integer i;
// Instantiate the Unit Under Test (UUT)
register_file uut (
.clk(clk),
.reset(reset),
.dstW(dstW),
.valW(valW),
.write(write),
.srcA(srcA),
.srcB(srcB),
.valA(valA),
.valB(valB)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 1;
dstW = 0;
valW = 0;
write = 0;
srcA = 0;
srcB = 0;
i =0;
#10
reset = 0;
#10
reset = 1;
// Wait 100 ns for global reset to finish
#100;
clk=1;
valW = 100;
write = 1;
for(i=0; i<8; i = i+1) begin
clk =0;
#10;
dstW = i;
clk = 1;
#10;
clk =0;
#10;
valW = valW + 10;
clk =1;
#10;
end
#100;
write =0;
for(i=0; i<8; i=i+1 ) begin
clk = 0;
#10;
srcA = i;
srcB = i;
#10;
clk=1;
#10;
end
clk =0;
#10;
clk = 1;
// Add stimulus here
end
endmodule
and result
it just results 0 value after third i value.
i checked using red rectangular. could you give me a advice ? thanks in advance

When you synthetize your design, these warnings show up:
WARNING:Xst:1780 - Signal <reg_input7> is never used or assigned. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:1780 - Signal <reg_input6> is never used or assigned. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:1780 - Signal <reg_input5> is never used or assigned. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:1780 - Signal <reg_input4> is never used or assigned. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:1780 - Signal <reg_input3> is never used or assigned. This unconnected signal will be trimmed during the optimization process.
If the synthetizer detects that those signals are not being used, it discards them. Note that these signals affect the selection of registers 3 to 7, and because of that, you cannot see the loaded value when you read them.
But... your code assigns and use these signals, doesn't it?
assign reg_input_0 = select[0] ? valW : r0eax;
assign reg_input_1 = select[1] ? valW : r1ecx;
assign reg_input_2 = select[2] ? valW : r2edx;
assign reg_input_3 = select[3] ? valW : r3ebx;
assign reg_input_4 = select[4] ? valW : r4esi;
assign reg_input_5 = select[5] ? valW : r5edi;
assign reg_input_6 = select[6] ? valW : r6esp;
assign reg_input_7 = select[7] ? valW : r7edi;
What makes reg_input_0,1 and 2 different from reg_input_3,4,5,6 and 7 ? This:
wire[31:0] reg_input_0, reg_input_1, reg_input_2, reg_input3, reg_input4,
reg_input5, reg_input6, reg_input7;
Look: reg_input_0, reg_input_1 and reg_input_2. Then, reg_input3 (where's the underscore??)
As reg_input_3 to reg_input_7 are not defined, they default to a 1-bit signal, instead of 32 bits. When you use the multiplexer, at reg_input_3 for instance, to define its value...
assign reg_input_3 = select[3] ? valW : r3ebx;
You are actually synthetizing this:
assign reg_input_3 = select[3] ? valW[0] : r3ebx[0];
And in your clocked always, the actual register assignment is not as this:
r3ebx <= reg_input_3;
But as this:
r3ebx[0] <= reg_input_3;
This description of yours causes feedback from the register output through the input via the mentioned multiplexor. While this is ok when the there's a clock triggered register, if the synthetizer doesn't detect it, you will end up generating a lot of unnecesary multiplexers. Look at this generated schematic from the results of the synthesis process (synthetizer is XST)
The eight squares at the right are your eight registers. At the left, there are a massive amount of multiplexers. I cannot show you all of them, because the generated schematic it's too large for screen capture.
I suggest not to use an explicit loopback path with the multiplexor to decide when to write a new value to the register. Instead of that, modify your synchronous always to load a new value into the register only if that register is selected for writting:
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r0eax <= 32'b0;
r1ecx <= 32'b0;
r2edx <= 32'b0;
r3ebx <= 32'b0;
r4esi <= 32'b0;
r5edi <= 32'b0;
r6esp <= 32'b0;
r7edi <= 32'b0;
end
else begin
if (select[0])
r0eax <= valW;
if (select[1])
r1ecx <= valW;
if (select[2])
r2edx <= valW;
if (select[3])
r3ebx <= valW;
if (select[4])
r4esi <= valW;
if (select[5])
r5edi <= valW;
if (select[6])
r6esp <= valW;
if (select[7])
r7edi <= valW;
end
end
This description allows the synthetizer to infer a register with CLK and CE inputs: the register will accept a new value from its D input if CE is enabled. If not, the value doesn't change. Your description makes the register to change its value on every clock cycle, whether is needed or not.
Now the circuit inferred is as this (it actually fits on screen!):
With this proposed solution, the first block, where the different reg_input_X signals are assigned, can be eliminated.
Tested using ISIM with ISE Webpack 12.4 and works :)

Related

Verilog If statement -Appears to be triggering before Condition

Why does r_D <= 8'h40 execute before w_Rx_DV == 1'b1 according to below code and waveform? R_D should not be assigned any value until w_Rx_DV goes high.
Thank you for any comments
Joe
module main(
input i_Clock,
input i_Rx_Serial,
output o_PWM
);
reg r_Load ;
reg [7:0] r_D =0;
wire w_Rx_DV;
wire [7:0] w_RX_Byte;
reg [7:0] r_RX_Byte;
PWM PWM(
.i_Clock(i_Clock),
.i_Load(r_Load),
.i_D (r_D),
.o_PWM(o_PWM)
);
rx rx(
.i_Clock (i_Clock),
.i_Rx_Serial (i_Rx_Serial),
.o_Rx_DV (w_Rx_DV),
.o_Rx_Byte (w_RX_Byte)
);
always # (posedge i_Clock)
begin
r_Load <= 0;
if(w_Rx_DV == 1'b1) ;
begin
r_RX_Byte <= w_RX_Byte;
if(r_RX_Byte ==8'h0)
begin
r_D <= 0;
r_Load <= 1;
end
if(r_RX_Byte == 8'h3F)
begin
r_D <= 8'h40;
r_Load <= 1;
end
else
begin
r_Load <= 0;
end
end
end
endmodule
waveform
Why does r_D <= 8'h40 execute before w_Rx_DV == 1'b1
Because you have a semicolon after the if here:
if(w_Rx_DV == 1'b1) ;
// ^ End of if statement.

inout verilog protocol I2C

I'm creating the I2C protocol in verilog to read data from a sensor (BMP180), AS you know, the sensor sends me a bit of ack recognition. How do I use the inout i2c_sda port to send and how do I receive.
As delivery and receipt i2c_sda the same line, if my variable is declared of type inout.
module stepPrueba(
input wire clk1,
input wire reset,
input wire start,
inout i2c_sda,
inout i2c_scl,
output wire ready,
output reg led1,
output reg led2
);
reg i2c_scl_out;
assign i2c_scl1= (i2c_scl_out == 1'b0) ? 1'b0 : 1'bz;
wire i2c_scl_in = i2c_scl;
assign i2c_scl = (i2c_scl_enable == 0) ? i2c_scl1 : clk1;
reg clk;
assign clk1 = (clk == 1)? 1'bz:1'b0;
reg i2c_sda_out;
assign i2c_sda = (i2c_sda_out == 1'b0) ? 1'b0 : 1'bz;
wire i2c_sda_in = i2c_sda ;
reg [6:0] addr;
reg [7:0] data;
reg enable; //(read=1, write=0)
reg datas;
reg enable2; //(read=1, write = 0)
reg [7:0] state;
reg [7:0] count;
reg i2c_scl_enable = 0;
reg [6:0] saved_addr;
reg [7:0] saved_data;
//goal es escribir al dispositivo direccion 0X55, 0Xaa
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_ADDR =2;
localparam STATE_RW = 3;
localparam STATE_WACK = 4;
localparam STATE_DATA = 5;
localparam STATE_WACK2 = 6;
localparam STATE_STOP = 7;
always#(posedge clk)
begin
//enable2 <= 0; //i2c_scl==zetas & c_lectura=z;
if(reset == 1)
begin
i2c_scl_out<=1;
i2c_scl_enable <= 0;
end
else
begin
if((state == STATE_IDLE) || (state == STATE_START) )
begin
//i2c_scl_enable <= 0; //dats == 1 --> ztas == z
i2c_scl_out<=1;
i2c_scl_enable <= 0;
end
else
begin
i2c_scl_enable <= 1; // dats==clk;
clk<=clk1;
end
end
end
always#(posedge clk)
begin
if(reset == 1)
begin
led1 <=0;
led2 <=0;
state <=0;
i2c_sda_out <= 1;// i2c_sda ==z;
addr <= 7'b1110111; // direccion del sensor
count <= 8'd0;
data <= 8'b11110100; //direccion interna PRESION
end
else //reset ==0
begin
case (state)
STATE_IDLE:
begin //idle
//datas <= 1; //zetas==z
i2c_scl_out<=1;
i2c_scl_enable <= 0;
i2c_sda_out <= 1;
if(start)
begin
state <= STATE_START;
saved_addr <= addr;
saved_data <= data;
// reg i2c_scl_out;
// assign i2c_scl1= (i2c_scl_out == 1'b0) ? 1'b0 : 1'bz;
// wire i2c_scl_in = i2c_scl;
// assign i2c_scl = (i2c_scl_enable == 0) ? i2c_scl1 : ~clk;
end
else
begin
state <= STATE_IDLE;
end
end
STATE_START:
begin // start
//enable <= 0; // lectura==z; --> i2c_sda==zetas
i2c_sda_out <= 0;
//datas <= 0; // zetas==0
state<= STATE_ADDR;
count <= 6;
end
STATE_ADDR:
begin //msb addres bit
//enable <= 0; // lectura==z; --> i2c_sda==zetas
i2c_sda_out <= saved_addr[count]; // datas ==0 --> zetas==0 || datas==1 --> zetas==z
if (count == 0)
begin
state <= STATE_RW;
end
else
begin
count <= count - 1;
end
end
STATE_RW:
begin
//enable <= 0; //enable==0 --> i2c_sda==zetas
i2c_sda_out <= 0;//datas <= 0;
state <= STATE_WACK;
end
STATE_WACK:
begin
//enable <= 1; //enable==1 lee i2c_sda==z & lectura==i2c_sda
//enable <= 0;
//if(APA)
if(i2c_sda_in==1)
begin
state <= STATE_IDLE;
end
else
begin
state <= STATE_DATA;
led1 <= 1;
end
count <= 7;
end
STATE_DATA:
begin
//enable <= 0;
i2c_sda_out <= saved_data[count];
if(count ==0)
begin
state <= STATE_WACK2;
end
else
begin
count <= count - 1;
end
end
STATE_WACK2:
begin
//enable <= 1;
if(i2c_sda_in ==1)
begin
state <= STATE_IDLE;
end
else
begin
state <= STATE_STOP;
led2 <= 1;
end
end
STATE_STOP:
begin
//enable <= 0;
i2c_sda_out <= 0;
state <= STATE_IDLE;
end
endcase
end
end
endmodule
If you have a module pin defined as
inout wire pin
then you can access it like so
wire pin_input = pin;
assign pin = pin_oe ? pin_output : 1'bz;
this should infer a tristate buffer.
However, I would be careful when doing this, as if you infer a tristate buffer too early, it can limit what you can do with the module. For example, it would be possible to connect multiple internal I2C components together, such as allowing multiple masters inside the FPGA access to the same pins. However, tristate signals cannot be routed inside the FPGA, so if you implement the tristate inside the I2C master module, this becomes impossible. Instead, what you might consider is implementing each pin as three module pins: input, output, and output enable/tristate. This allows multiple modules to be connected with an emulated tristate bus, and allows them to share one set of tristate buffers to the actual I/O pin on the chip.
For a good example of how this works, see the comments in https://github.com/alexforencich/verilog-i2c/blob/master/rtl/i2c_master.v .

Verilog wires being set to X instead 1

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

XXX on output ports

I have written an asynchronous fifo buffer but when I run it I get XXX on output ports. I referred to concerned questions on SO which said asserting reset signals should make it work but despite of doing it I am still facing the same issue.
Any help will be appreciated.
Thanks
module fifo
#(parameter width =8,
addr_width = 4,
depth = (1 << addr_width)
)
( // Read port
output [width - 1:0] dout,
output reg empty_out,
input wire rd_en,
input wire rclk,
//write port
input wire [width-1:0] din,
output reg full,
input wire wr_en,
input wire wclk,
input wire rst
);
(* ram_style = "bram" *)
reg [width-1:0] memory_s[depth-1:0];
reg [31:0] push_ptr;
reg [31:0] pop_ptr;
assign dout = memory_s[pop_ptr]; // assign cannot assign values to registers
always #(posedge wclk)
begin
if (rst == 1)
push_ptr <= 0;
else if(wr_en == 1)
begin
memory_s\[push_ptr\] <= din;
//$display("w: %d", push_ptr);
if (push_ptr == (depth -1))
push_ptr <= 0;
else
push_ptr <= push_ptr + 1;
end
end
always # (posedge rclk)
if (rst == 1)
pop_ptr <= 0;
else if (rd_en ==1)
begin
//dout <= memory_s\[pop_ptr\];
//$display("r: %d", pop_ptr);
if (pop_ptr == depth-1)
pop_ptr <=0;
else
pop_ptr <= pop_ptr+1;
end
reg full_s;
reg overflow;
always #*
begin
if (rst == 1)
full_s <= 0;
else if (push_ptr <= pop_ptr)
if (push_ptr + 1 == pop_ptr)
begin
full_s <= 1;
$display("push,pop,full: %d %d %d", push_ptr,pop_ptr,full_s);
end
else
full_s <=0;
else
if(push_ptr + 1 == pop_ptr + depth)
begin
full_s <= 1;
$display("push,pop,full: %d %d %d", push_ptr,pop_ptr,full_s);
end
else
full_s <= 0;
end
endmodule]
Here is a waveform:
(external link)
Added Testbench
module fifoTb;
// Inputs
reg rd_en;
reg rclk;
reg [7:0] din;
reg wr_en;
reg wclk;
reg rst;
// Outputs
wire[7:0] dout;
wire empty_out;
wire full;
// Instantiate the Unit Under Test (UUT)
fifo uut (
.dout(dout),
.empty_out(empty_out),
.rd_en(rd_en),
.rclk(rclk),
.din(din),
.full(full),
.wr_en(wr_en),
.wclk(wclk),
.rst(rst)
);
initial begin
// Initialize Inputs
rd_en = 0;
rclk = 0;
wr_en = 0;
wclk = 0;
rst = 1;
din = 8'h0;
// Wait 100 ns for global reset to finish
#100;
rst = 0;
wr_en = 1;
din = 8'h1;
#101 din = 8'h2;
rd_en = 1;
// Add stimulus here
end
always begin #10 wclk = ~wclk; end
always begin #10 rclk = ~rclk; end
endmodule
I would suggest adding additional logic on your output dout signal
to avoid having 'bxxx values because memory_s has an initial value
of 'bxxx:
assign dout = (rd_en) ? memory_s[pop_ptr] : 0;
Additional tips in creating your testbench:
First, it is very important to try to understand how your
device works.
Upon reading your RTL code, I concluded that your fifo works in the
following manner:
Write operation
always #(posedge wclk)
begin
if (rst == 1)
push_ptr <= 0;
else if(wr_en == 1)
begin
memory_s[push_ptr] <= din;
if (push_ptr == (depth -1))
push_ptr <= 0;
else
push_ptr <= push_ptr + 1;
end
end
When wr_en is high, two operations are performed.
The value from din will be written on memory_s pointed by
push_ptr at the next positive edge of wclk.
If push_ptr is equal with (depth -1), 0 will be written to
the register push_ptr else register push_ptr is incremented by 1
instead.
Write operation will not be performed when wr_en is low.
Read operation
assign dout = memory_s[pop_ptr];
always # (posedge rclk)
if (rst == 1)
pop_ptr <= 0;
else if (rd_en ==1)
begin
if (pop_ptr == depth-1)
pop_ptr <=0;
else
pop_ptr <= pop_ptr+1;
end
When rd_en is high, increment the register pop_ptr by 1 if
pop_ptr is not equal to depth-1 else write it with 0 instead.
dout will all the time hold the value of memory_s pointed by the register
pop_ptr.
Creating tasks for every operation that you are going to perform
is usually convenient.
wr_en = 1;
din = 8'h1;
#101 din = 8'h2;
rd_en = 1;
I created write and read tasks for you as an example and you might want
to substitute your code above.
task write(input [7:0] pdin);
$display("[ testbench ] writing data: %0x", pdin);
din <= pdin;
wr_en <= 1;
#(posedge wclk);
din <= 0;
wr_en <= 0;
endtask
task read(output [7:0] prdata);
rd_en <= 1;
#(posedge rclk);
prdata = dout;
rd_en <= 0;
$display("[ testbench ] reading data: %0x", prdata);
endtask
Here is how to use the tasks:
write(8'hAA);
read(read_data);
write(8'hCC);
read(read_data);
write(8'hBC);
read(read_data);
In writing a combinational circuit, it is not recommended to add
a reset logic on to it.
always #*
begin
if (rst == 1)
full_s <= 0; . . .
Also, most of the EDA tool vendors recommend to use blocking (=) assignment
in writing a combinational circuit and non-blocking assignment (<=) in a
sequential circuit.
End you're simulation when you're done by calling $finish.
initial begin
#1000; $finish;
end

verilog to FSM convert

I have a program written in Verilog and I want to convert it into a FSM automatically. Is this possible (just to visualize it)?
Here is the code :
module pci(reset,clk,frame,irdy,trdy,devsel,idsel,ad,cbe,par,stop,inta,led_out);
input reset;
input clk;
input frame;
input irdy;
output trdy;
output devsel;
input idsel;
inout [31:0] ad;
input [3:0] cbe;
inout par;
output stop;
output inta;
output [3:0] led_out;
parameter DEVICE_ID = 16'h9500;
parameter VENDOR_ID = 16'h106d; // Sequent!
parameter DEVICE_CLASS = 24'hFF0000; // Misc
parameter DEVICE_REV = 8'h01;
parameter SUBSYSTEM_ID = 16'h0001; // Card identifier
parameter SUBSYSTEM_VENDOR_ID = 16'hBEBE; // Card identifier
parameter DEVSEL_TIMING = 2'b00; // Fast!
reg [2:0] state;
reg [31:0] data;
reg [1:0] enable;
parameter EN_NONE = 0;
parameter EN_RD = 1;
parameter EN_WR = 2;
parameter EN_TR = 3;
reg memen; // respond to baseaddr?
reg [7:0] baseaddr;
reg [5:0] address;
parameter ST_IDLE = 3'b000;
parameter ST_BUSY = 3'b010;
parameter ST_MEMREAD = 3'b100;
parameter ST_MEMWRITE = 3'b101;
parameter ST_CFGREAD = 3'b110;
parameter ST_CFGWRITE = 3'b111;
parameter MEMREAD = 4'b0110;
parameter MEMWRITE = 4'b0111;
parameter CFGREAD = 4'b1010;
parameter CFGWRITE = 4'b1011;
`define LED
`ifdef LED
reg [3:0] led;
`endif
`undef STATE_DEBUG_LED
`ifdef STATE_DEBUG_LED
assign led_out = ~state;
`else
`ifdef LED
assign led_out = ~led; // board is wired for active low LEDs
`endif
`endif
assign ad = (enable == EN_RD) ? data : 32'bZ;
assign trdy = (enable == EN_NONE) ? 'bZ : (enable == EN_TR ? 1 : 0);
assign par = (enable == EN_RD) ? 0 : 'bZ;
reg devsel;
assign stop = 1'bZ;
assign inta = 1'bZ;
wire cfg_hit = ((cbe == CFGREAD || cbe == CFGWRITE) && idsel && ad[1:0] == 2'b00);
wire addr_hit = ((cbe == MEMREAD || cbe == MEMWRITE) && memen && ad[31:12] == {12'b0, baseaddr});
wire hit = cfg_hit | addr_hit;
always #(posedge clk)
begin
if (~reset) begin
state <= ST_IDLE;
enable <= EN_NONE;
baseaddr <= 0;
devsel <= 'bZ;
memen <= 0;
`ifdef LED
led <= 0;
`endif
end
else begin
case (state)
ST_IDLE: begin
enable <= EN_NONE;
devsel <= 'bZ;
if (~frame) begin
address <= ad[7:2];
if (hit) begin
state <= {1'b1, cbe[3], cbe[0]};
devsel <= 0;
// pipeline the write enable
if (cbe[0])
enable <= EN_WR;
end
else begin
state <= ST_BUSY;
enable <= EN_NONE;
end
end
end
ST_BUSY: begin
devsel <= 'bZ;
enable <= EN_NONE;
if (frame)
state <= ST_IDLE;
end
ST_CFGREAD: begin
enable <= EN_RD;
if (~irdy || trdy) begin
case (address)
0: data <= { DEVICE_ID, VENDOR_ID };
1: data <= { 5'b0, DEVSEL_TIMING, 9'b0, 14'b0, memen, 1'b0};
2: data <= { DEVICE_CLASS, DEVICE_REV };
4: data <= { 12'b0, baseaddr, 8'b0, 4'b0010 }; // baseaddr + request mem < 1Mbyte
11: data <= {SUBSYSTEM_ID, SUBSYSTEM_VENDOR_ID };
16: data <= { 24'b0, baseaddr };
default: data <= 'h00000000;
endcase
address <= address + 1;
end
if (frame && ~irdy && ~trdy) begin
devsel <= 1;
state <= ST_IDLE;
enable <= EN_TR;
end
end
ST_CFGWRITE: begin
enable <= EN_WR;
if (~irdy) begin
case (address)
4: baseaddr <= ad[19:12]; // XXX examine cbe
1: memen <= ad[1];
default: ;
endcase
address <= address + 1;
if (frame) begin
devsel <= 1;
state <= ST_IDLE;
enable <= EN_TR;
end
end
end
ST_MEMREAD: begin
enable <= EN_RD;
if (~irdy || trdy) begin
case (address)
`ifdef LED
0: data <= { 28'b0, led };
`endif
default: data <= 'h00000000;
endcase
address <= address + 1;
end
if (frame && ~irdy && ~trdy) begin
devsel <= 1;
state <= ST_IDLE;
enable <= EN_TR;
end
end
ST_MEMWRITE: begin
enable <= EN_WR;
if (~irdy) begin
case (address)
`ifdef LED
0: led <= ad[3:0];
`endif
default: ;
endcase
address <= address + 1;
if (frame) begin
devsel <= 1;
state <= ST_IDLE;
enable <= EN_TR;
end
end
end
endcase
end
end
endmodule
If there is no automatic way, could you explain a way of doing this?
Here is an FSM made with hand but can't test so ...
Does it seem ok?
It is sometimes easier to write the code and have the documentation generated from that. Sometimes you inherit legacy code without documentation, in these situations especially if new to a language tools to help visualise what is happening can be quite useful.
With cadence tools you can run your code with 'code coverage' then imc can load the coverage data and run FSM Analysis.
I have included a simple FSM below and show the generated state diagram.
module simple_fsm();
//Inputs to FSM
logic clk;
logic rst_n;
logic [1:0] state ;
logic [1:0] nextstate;
logic turn_on ;
logic turn_off ;
localparam S_OFF = 2'b00;
localparam S_GO_ON = 2'b01;
localparam S_ON = 2'b10;
localparam S_GO_OFF = 2'b11;
// State FlipFlop
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
state <= 2'b0;
end
else begin
state <= nextstate;
end
end
//Nextstate Logic
always #* begin
case (state)
2'd0 : if (turn_on) begin
nextstate = S_GO_ON;
end
2'd1 : nextstate = S_ON;
2'd2 : if (turn_off) begin
nextstate = S_GO_OFF ;
end
2'd3 : nextstate = S_OFF;
endcase
end
//TB clk
initial begin
#1ns;
clk = 0;
forever begin
#20ns;
clk = ~clk;
end
end
//The Test
initial begin
rst_n = 1'b0;
turn_on = 1'b0;
turn_off = 1'b0;
#(posedge clk);
#(posedge clk);
rst_n = 1'b1 ;
#(posedge clk);
turn_on = 1'b1;
#(posedge clk);
turn_on = 1'b0;
#(posedge clk);
#(posedge clk);
#100ms;
$finish();
end
endmodule
Execute with :
$ irun simple_fsm.sv -coverage all -covdut simple_fsm
$ imc &
Load cov_work (folder created by above simulation) in imc, select simple_fsm and choose FSM Analysis.
imc also helps to visualise your test coverage as well. Arcs and states that have not been hit are shown in red.
We have seen that there are some tools which can visualise the FSM, another part of the question is; is the syntax of the purposed FSM suitable for these tools.
#vermaete has reported that Modelsim SE can not see the FSM. From imc I get :
Which does not seem to cover the complexity of the code, and is shown as only having 2 reachable states, IDLE and BUSY. I would recommend if OP is going down the route of using tools to visualise, adopt a simpler (syntax) FSM structure so that the tools can parse it better.
The better and expensive simulators can detect FSM's in the code and make a visualization of it. E.g. the Modelsim SE version. These can be nice to understand code and check the coveage.
But making you're own drawing of a 6-state FSM is not that hard.
The way to check if it's OK is to write a simulation and check that the behaviour is what you want. There is no point getting a bubble diagram out and seeing if it matches your hand-drawn one, as you have no way of knowing if your hand-drawn diagram is correct...
case(segmentRead)
//-------------------
SEGMENT0: begin
READ_Ready_EEPROM <= 1'b0;
READ_RDSR_Enable <= 1'b0;
Read_Enable <= 1'b0;
READ_RDSR_DATA_REG <= 8'b0;
// READ_DATA_REG <= 8'b0;
end
//-------------------
SEGMENT2: begin
READ_RDSR_Enable <= 1'b1;
READ_RDSR_DATA_REG <= 8'b0;
end
// //-------------------
SEGMENT3: begin
READ_RDSR_Enable <= 1'b0;
READ_RDSR_DATA_REG <= RDSR_Data;
end
//-------------------
SEGMENT4: begin
Read_Enable <= 1'b1;
end
//-------------------
SEGMENT5: begin
Read_Enable <= 1'b0;
READ_DATA_REG <= Read_Data;
end
//-------------------
SEGMENT6: begin
READ_Ready_EEPROM <= 1'b1;
end
//-------------------
endcase

Resources