Monday 6 January 2020

digital logic - Design simulates perfectly but won't work on FPGA


First, thanks for the help yesterday. This time I will document my code correctly.


So, we were tasked with creating a parking meter that would take 4 inputs, one adding 50 seconds, one adding 150 seconds, one adding 250 seconds, and one adding 500 seconds. When there are over 10 seconds remaining, a green led should flash with a period of 2 seconds. When there are less than 10 seconds a red led should flash with period 2 seconds, and when there are no seconds left a red led should flash with period 1 second. Every clock cycle with no input is supposed to subtract one from the meter.



We were tasked with using a debouncer as well a single pulse state machine for the inputs, and a 7 segment display for the outputs. So, I used a state machine for my addition and led flashing, then sent the counter to a binarytoBCD converter and then that one to a BCD to 7 segment display. I'm wondering if I messed up the clock and somehow the simulation ignores my errors, somehow making the FPGA unable to correcly use my code?


without further ado, here are my code snippets:


Top Module


module parkingmeter(clk,rst,b0,b1,b2,b3,out0,out1,out2,out3,GRNLED,REDLED);
input b0,b1,b2,b3,clk,rst;
output [6:0] out0,out1,out2,out3;
output GRNLED,REDLED;
wire outt0,outt1,outt2,outt3;
wire [15:0] counter;
wire [3:0] bcd0,bcd1,bcd2,bcd3;

wire clkout;
clockdivider onesec(clk,clkout);
add_sub yep(b0,clkout,rst,outt0);
add_sub yesh(b1,clkout,rst,outt1);
add_sub yeah(b2,clkout,rst,outt2);
add_sub ok(b3,clk,rst,outt3);
controlparker Second(outt0,outt1,outt2,outt3,clkout,rst,counter,REDLED,GRNLED);
EC Third(counter,bcd0,bcd1,bcd2,bcd3,out0,out1,out2,out3);
endmodule


my debounce module


module cleandebounce(clk,rst,I0,out);
input clk,rst,I0;
output out;
reg f0,f1;
always @ (posedge clk, posedge rst) begin
if (rst==1) begin
f0 <= I0;
f1 <= f0;
end else begin

f0 <= 0;
f1 <= 0;
end
end
assign out = f1;
endmodule

My single pulse state machine


module add_sub(in,clk,rst,out);
input in,clk,rst;

output reg out = 1'b0;
reg state = 1'b0;
wire outt;
cleandebounce one(clk,rst,in,outt);
always @ (posedge clk,posedge rst) begin
case(state)
1'b0: begin
if (rst==1) begin
out <= 0;
if (outt == 1) begin

out <= 1'b1;
state <= 1'b1;
end else state <= 1'b0;
end else begin
out <= 1'b0;
state <= 1'b0;
end
end
1'b1: begin
out <= 1'b0;

if (outt == 1) begin
out <= 1'b0;
state <= 1'b1;
end else state <= 1'b0;
end
endcase
end
endmodule

And my module for adding the inputs as well as flashing on and off leds



module controlparker(B0,B1,B2,B3,clk,rst,counter,REDLED,GRNLED);
input B0,B1,B2,B3,clk,rst;
output reg [15:0] counter = 16'b0000000000000000;
reg state = 1'b0;
reg [2:0] area = 3'b000;
output reg REDLED = 0;
output reg GRNLED = 0;
always @ (posedge clk, posedge rst) begin
case(state)
0: begin

if (rst==1) begin
if (counter > 0)
counter <= counter - 1;
if (counter > 9999)begin
counter <= 9999;
end
state <= 1;
end else begin
counter <= 0;
state <= 0;

end
end
1: begin
if (B0 == 1) begin
counter <= counter + 16'b00000000000110010;
state <= 0;
end else if (B1 == 1) begin
counter <= counter + 16'b00000000010010110;
state <= 0;
end else if (B2 == 1) begin

counter <= counter + 16'b00000000011111010;
state <= 0;
end else if (B3 == 1) begin
counter <= counter + 16'b00000000111110010;
state <= 0;
end else state <= 0;
end
endcase
end
always @ (posedge clk, posedge rst) begin

case(area)
3'b000: begin
if (rst==1)begin
if (counter >= 10)begin
GRNLED <= 1;
REDLED <= 0;
area <= 3'b001;
end
else if (counter < 10 && counter > 0) begin
REDLED <= 1;

GRNLED <= 0;
area <= 3'b010;
end
else REDLED <= ~REDLED;
end
else begin
REDLED <= 0;
GRNLED <= 0;
end
end

3'b001: begin
GRNLED <= 0;
area <= 3'b000;
end
3'b010: begin
REDLED <= 0;
area <= 3'b000;
end
endcase
end

endmodule

My module converting BinarytoBCD as well as the 7 segment display output:


module EC(in,bcd0,bcd1,bcd2,bcd3,out0,out1,out2,out3);
input [15:0] in;
output reg [3:0] bcd0 = 4'b0000;
output reg [3:0] bcd1 = 4'b0000;
output reg [3:0] bcd2 = 4'b0000;
output reg [3:0] bcd3 = 4'b0000;
output reg [6:0] out0 = 7'b0000000;

output reg [6:0] out1 = 7'b0000000;
output reg [6:0] out2 = 7'b0000000;
output reg [6:0] out3 = 7'b0000000;
reg [15:0] temp;
integer i;
always @ (in) begin
bcd0 = 4'b0000;
bcd1 = 4'b0000;
bcd2 = 4'b0000;
bcd3 = 4'b0000;

temp = in;
for(i=15; i>=0; i=i-1) begin
if (bcd3 >= 4'b0101)
bcd3 = bcd3 + 4'b0011;
if (bcd2 >= 4'b0101)
bcd2 = bcd2 + 4'b0011;
if (bcd1 >= 4'b0101)
bcd1 = bcd1 + 4'b0011;
if (bcd0 >= 4'b0101)
bcd0 = bcd0 + 4'b0011;

bcd3 = bcd3 << 1;
bcd3[0] = bcd2[3];
bcd2 = bcd2 << 1;
bcd2[0] = bcd1[3];
bcd1 = bcd1 << 1;
bcd1[0] = bcd0[3];
bcd0 = bcd0 << 1;
bcd0[0] = temp[i];
end
end

always @ (bcd0) begin
if (bcd0==4'b0000) out0 = 7'b0000001;
else if (bcd0==4'b0001) out0 = 7'b1001111;
else if (bcd0==4'b0010) out0 = 7'b0010010;
else if (bcd0==4'b0011) out0 = 7'b0000110;
else if (bcd0==4'b0100) out0 = 7'b1001100;
else if (bcd0==4'b0101) out0 = 7'b0100100;
else if (bcd0==4'b0110) out0 = 7'b0100000;
else if (bcd0==4'b0111) out0 = 7'b0001111;
else if (bcd0==4'b1000) out0 = 7'b0000000;

else if (bcd0==4'b1001) out0 = 7'b0000100;
else out0=7'b0000001;
end
always @ (bcd1) begin
if (bcd1==4'b0000) out1 = 7'b0000001;
else if (bcd1==4'b0001) out1 = 7'b1001111;
else if (bcd1==4'b0010) out1 = 7'b0010010;
else if (bcd1==4'b0011) out1 = 7'b0000110;
else if (bcd1==4'b0100) out1 = 7'b1001100;
else if (bcd1==4'b0101) out1 = 7'b0100100;

else if (bcd1==4'b0110) out1 = 7'b0100000;
else if (bcd1==4'b0111) out1 = 7'b0001111;
else if (bcd1==4'b1000) out1 = 7'b0000000;
else if (bcd1==4'b1001) out1 = 7'b0000100;
else out1=7'b0000001;
end
always @ (bcd2) begin
if (bcd2==4'b0000) out2 = 7'b0000001;
else if (bcd2==4'b0001) out2 = 7'b1001111;
else if (bcd2==4'b0010) out2 = 7'b0010010;

else if (bcd2==4'b0011) out2 = 7'b0000110;
else if (bcd2==4'b0100) out2 = 7'b1001100;
else if (bcd2==4'b0101) out2 = 7'b0100100;
else if (bcd2==4'b0110) out2 = 7'b0100000;
else if (bcd2==4'b0111) out2 = 7'b0001111;
else if (bcd2==4'b1000) out2 = 7'b0000000;
else if (bcd2==4'b1001) out2 = 7'b0000100;
else out2=7'b0000001;
end
always @ (bcd3) begin

if (bcd3==4'b0000) out3 = 7'b0000001;
else if (bcd3==4'b0001) out3 = 7'b1001111;
else if (bcd3==4'b0010) out3 = 7'b0010010;
else if (bcd3==4'b0011) out3 = 7'b0000110;
else if (bcd3==4'b0100) out3 = 7'b1001100;
else if (bcd3==4'b0101) out3 = 7'b0100100;
else if (bcd3==4'b0110) out3 = 7'b0100000;
else if (bcd3==4'b0111) out3 = 7'b0001111;
else if (bcd3==4'b1000) out3 = 7'b0000000;
else if (bcd3==4'b1001) out3 = 7'b0000100;

else out3=7'b0000001;
end
endmodule

And finally, my clock divider I feed to every module requiring a clock to run correctly on FPGA:


module clockdivider(clk,clkout);
input clk;
output clkout;
reg [24:0] q = 0;
always @ (posedge clk) begin

q <= q + 1;
end
assign clkout = q[0];
endmodule

So there it all is. When I enable my FPGA to it displays random numbers even though I haven't pushed any buttons. How is this possible? I'm relatively new to verilog so if theres any way I can simplify my code it would be greatly appreciated. Again, everything simulates perfectly. Thanks all




No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...