`timescale 1ns/1ps
module lcd_control (
input clk,
input reset,
input prod1,
input prod2,
input prod3,
input prod4,
input disp_up,
input disp_down,
input confirm,
input cancel,
output lcd_e,
output reg lcd_rs,
output reg lcd_rw,
output reg [7:0] lcd_data
);
reg [3:0] state;
reg [3:0] n_state;
parameter delay = 4'b0000;
parameter funtion_set = 4'b0001;
parameter entry_mode = 4'b0010;
parameter disp_onoff = 4'b0011;
parameter line1_list = 4'b0100;
parameter line2_list = 4'b0101;
parameter delay_t = 4'b0110;
parameter select = 4'b0111;
parameter up_disp = 4'b1000;
parameter down_disp = 4'b1001;
parameter cola = 4'b1010;
parameter water = 4'b1011;
parameter coffee = 4'b1100;
parameter tea = 4'b1101;
parameter clear_disp = 4'b1110;
integer cnt;
integer cnt_100hz;
reg clk_100hz;
wire disp_down_100, disp_up_100, prod1_100, prod2_100, prod3_100, prod4_100, confirm_100, cancel_100;
always @(posedge clk or posedge reset) begin
if(reset) begin
cnt_100hz <= 0;
clk_100hz <= 0;
end
else if(cnt_100hz >= 4) begin
cnt_100hz <= 0;
clk_100hz <= ~clk_100hz;
end
else
cnt_100hz <= cnt_100hz + 1;
end
always @(posedge clk_100hz or posedge reset) begin //state control
if(reset)
state <= delay;
else begin
case (state)
delay: if(cnt == 70) state <= funtion_set;
funtion_set: if(cnt == 30) state <= disp_onoff;
disp_onoff: if(cnt == 30) state <= entry_mode;
entry_mode: if(cnt == 30) state <= line1_list;
line1_list: if(cnt == 40) state <= line2_list;
line2_list: if(cnt == 40) state <= delay_t;
delay_t: if(cnt == 10) state <= select;
select: case ({disp_up_100, disp_down_100, prod1_100, prod2_100, prod3_100, prod4_100})
6'b100000: state <= up_disp;
6'b010000: state <= down_disp;
6'b001000: begin n_state <= cola; state <= clear_disp; end
6'b000100: begin n_state <= water; state <= clear_disp; end
6'b000010: begin n_state <= tea; state <= clear_disp; end
6'b000001: begin n_state <= coffee; state <= clear_disp; end
default: state <= select;
endcase
up_disp: if(cnt == 39) state <= select;
down_disp: if(cnt == 39) state <= select;
clear_disp: if(cnt == 40) state <= n_state;
cola: if(confirm_100 | cancel_100) state <= delay_t;
water: if(confirm_100 | cancel_100) state <= delay_t;
tea: if(confirm_100 | cancel_100) state <= delay_t;
coffee: if(confirm_100 | cancel_100) state <= delay_t;
delay_t: if(cnt == 10) state <= line1_list;
default: state = delay;
endcase
end
end
always @(posedge clk_100hz or posedge reset) begin //cnt control
if(reset)
cnt <= 0;
else begin
case (state)
delay: begin if(cnt == 70) cnt<=0; else cnt<=cnt+1; end
funtion_set: begin if(cnt == 30) cnt<=0; else cnt<=cnt+1; end
disp_onoff: begin if(cnt == 30) cnt<=0; else cnt<=cnt+1; end
entry_mode: begin if(cnt == 30) cnt<=0; else cnt<=cnt+1; end
line1_list: begin if(cnt == 40) cnt<=0; else cnt<=cnt+1; end
line2_list: begin if(cnt == 40) cnt<=0; else cnt<=cnt+1; end
delay_t: begin if(cnt == 10) cnt<=0; else cnt<=cnt+1; end
up_disp: begin if(cnt == 39) cnt<=0; else cnt<=cnt+1; end
down_disp: begin if(cnt == 39) cnt<=0; else cnt<=cnt+1; end
cola: begin if(cnt == 40) begin
if(confirm_100 | cancel_100) cnt<=0;
else cnt<=cnt; end
else cnt<=cnt+1; end
water: begin if(cnt == 40) begin
if(confirm_100 | cancel_100) cnt<=0;
else cnt<=cnt; end
else cnt<=cnt+1; end
tea: begin if(cnt == 40) begin
if(confirm_100 | cancel_100) cnt<=0;
else cnt<=cnt; end
else cnt<=cnt+1; end
coffee: begin if(cnt == 40) begin
if(confirm_100 | cancel_100) cnt<=0;
else cnt<=cnt; end
else cnt<=cnt+1; end
clear_disp: begin if(cnt == 40) cnt <=0; else cnt<=cnt+1; end
delay_t: begin if(cnt == 10) cnt <=0; else cnt<=cnt+1; end
default: cnt<=0;
endcase
end
end
always @(posedge clk_100hz or posedge reset) begin
if(reset) begin
lcd_rs<=1;
lcd_rw<=1;
lcd_data<=8'b00000000;
end
else begin
case (state)
funtion_set: begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00111000;
end
disp_onoff: begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00001100;
end
entry_mode: begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00000110;
end
line1_list: begin //line1 control
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b10000000; end
1: begin lcd_rs<=1; lcd_data<=8'h31; end
2: begin lcd_rs<=1; lcd_data<=8'h2E; end
3: begin lcd_rs<=1; lcd_data<=8'h43; end
4: begin lcd_rs<=1; lcd_data<=8'h4F; end
5: begin lcd_rs<=1; lcd_data<=8'h4C; end
6: begin lcd_rs<=1; lcd_data<=8'h41; end
7: begin lcd_rs<=1; lcd_data<=8'h20; end
8: begin lcd_rs<=1; lcd_data<=8'h20; end
9: begin lcd_rs<=1; lcd_data<=8'h20; end
10: begin lcd_rs<=1; lcd_data<=8'h20; end
11: begin lcd_rs<=1; lcd_data<=8'h31; end
12: begin lcd_rs<=1; lcd_data<=8'h36; end
13: begin lcd_rs<=1; lcd_data<=8'h30; end
14: begin lcd_rs<=1; lcd_data<=8'h30; end
15: begin lcd_rs<=1; lcd_data<=8'h57; end
16: begin lcd_rs<=1; lcd_data<=8'h1E; end
17: begin lcd_rs<=1; lcd_data<=8'h33; end
18: begin lcd_rs<=1; lcd_data<=8'h2E; end
19: begin lcd_rs<=1; lcd_data<=8'h43; end
20: begin lcd_rs<=1; lcd_data<=8'h4F; end
21: begin lcd_rs<=1; lcd_data<=8'h46; end
22: begin lcd_rs<=1; lcd_data<=8'h46; end
23: begin lcd_rs<=1; lcd_data<=8'h45; end
24: begin lcd_rs<=1; lcd_data<=8'h45; end
25: begin lcd_rs<=1; lcd_data<=8'h20; end
26: begin lcd_rs<=1; lcd_data<=8'h20; end
27: begin lcd_rs<=1; lcd_data<=8'h31; end
28: begin lcd_rs<=1; lcd_data<=8'h30; end
29: begin lcd_rs<=1; lcd_data<=8'h30; end
30: begin lcd_rs<=1; lcd_data<=8'h30; end
31: begin lcd_rs<=1; lcd_data<=8'h57; end
32: begin lcd_rs<=1; lcd_data<=8'h1E; end
default: begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
line2_list:begin //line2 control
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b11000000; end
1: begin lcd_rs<=1; lcd_data<=8'h32; end
2: begin lcd_rs<=1; lcd_data<=8'h2E; end
3: begin lcd_rs<=1; lcd_data<=8'h57; end
4: begin lcd_rs<=1; lcd_data<=8'h41; end
5: begin lcd_rs<=1; lcd_data<=8'h54; end
6: begin lcd_rs<=1; lcd_data<=8'h45; end
7: begin lcd_rs<=1; lcd_data<=8'h52; end
8: begin lcd_rs<=1; lcd_data<=8'h20; end
9: begin lcd_rs<=1; lcd_data<=8'h20; end
10: begin lcd_rs<=1; lcd_data<=8'h20; end
11: begin lcd_rs<=1; lcd_data<=8'h20; end
12: begin lcd_rs<=1; lcd_data<=8'h37; end
13: begin lcd_rs<=1; lcd_data<=8'h30; end
14: begin lcd_rs<=1; lcd_data<=8'h30; end
15: begin lcd_rs<=1; lcd_data<=8'h57; end
16: begin lcd_rs<=1; lcd_data<=8'h1F; end
17: begin lcd_rs<=1; lcd_data<=8'h34; end
18: begin lcd_rs<=1; lcd_data<=8'h2E; end
19: begin lcd_rs<=1; lcd_data<=8'h54; end
20: begin lcd_rs<=1; lcd_data<=8'h45; end
21: begin lcd_rs<=1; lcd_data<=8'h41; end
22: begin lcd_rs<=1; lcd_data<=8'h20; end
23: begin lcd_rs<=1; lcd_data<=8'h20; end
24: begin lcd_rs<=1; lcd_data<=8'h20; end
25: begin lcd_rs<=1; lcd_data<=8'h20; end
26: begin lcd_rs<=1; lcd_data<=8'h20; end
27: begin lcd_rs<=1; lcd_data<=8'h20; end
28: begin lcd_rs<=1; lcd_data<=8'h39; end
29: begin lcd_rs<=1; lcd_data<=8'h30; end
30: begin lcd_rs<=1; lcd_data<=8'h30; end
31: begin lcd_rs<=1; lcd_data<=8'h57; end
32: begin lcd_rs<=1; lcd_data<=8'h1F; end
default:begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
delay_t:begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00000010;
end
select: begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00001100;
end
up_disp: begin
lcd_rs<=1;
lcd_rw<=1;
lcd_data<=8'b00011000;
end
down_disp: begin
lcd_rs<=1;
lcd_rw<=1;
lcd_data<=8'b00011100;
end
clear_disp: begin
lcd_rs<=1;
lcd_rw<=1;
lcd_data<=8'b00000001;
end
cola: begin
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b10000000; end
1: begin lcd_rs<=1; lcd_data<=8'h53; end
2: begin lcd_rs<=1; lcd_data<=8'h54; end
3: begin lcd_rs<=1; lcd_data<=8'h4F; end
4: begin lcd_rs<=1; lcd_data<=8'h43; end
5: begin lcd_rs<=1; lcd_data<=8'h4B; end
6: begin lcd_rs<=1; lcd_data<=8'h3A; end
7: begin lcd_rs<=1; lcd_data<=8'h30; end
8: begin lcd_rs<=1; lcd_data<=8'h30; end
13: begin lcd_rs<=1; lcd_data<=8'h59; end
14: begin lcd_rs<=1; lcd_data<=8'h2F; end
15: begin lcd_rs<=1; lcd_data<=8'h4E; end
default:begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
water: begin
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b10000000; end
1: begin lcd_rs<=1; lcd_data<=8'h53; end
2: begin lcd_rs<=1; lcd_data<=8'h54; end
3: begin lcd_rs<=1; lcd_data<=8'h4F; end
4: begin lcd_rs<=1; lcd_data<=8'h43; end
5: begin lcd_rs<=1; lcd_data<=8'h4B; end
6: begin lcd_rs<=1; lcd_data<=8'h3A; end
7: begin lcd_rs<=1; lcd_data<=8'h30; end
8: begin lcd_rs<=1; lcd_data<=8'h30; end
13: begin lcd_rs<=1; lcd_data<=8'h59; end
14: begin lcd_rs<=1; lcd_data<=8'h2F; end
15: begin lcd_rs<=1; lcd_data<=8'h4E; end
default:begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
tea: begin
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b10000000; end
1: begin lcd_rs<=1; lcd_data<=8'h53; end
2: begin lcd_rs<=1; lcd_data<=8'h54; end
3: begin lcd_rs<=1; lcd_data<=8'h4F; end
4: begin lcd_rs<=1; lcd_data<=8'h43; end
5: begin lcd_rs<=1; lcd_data<=8'h4B; end
6: begin lcd_rs<=1; lcd_data<=8'h3A; end
7: begin lcd_rs<=1; lcd_data<=8'h30; end
8: begin lcd_rs<=1; lcd_data<=8'h30; end
13: begin lcd_rs<=1; lcd_data<=8'h59; end
14: begin lcd_rs<=1; lcd_data<=8'h2F; end
15: begin lcd_rs<=1; lcd_data<=8'h4E; end
default:begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
coffee: begin
lcd_rw<=0;
case (cnt)
0: begin lcd_rs<=0; lcd_data<=8'b10000000; end
1: begin lcd_rs<=1; lcd_data<=8'h53; end
2: begin lcd_rs<=1; lcd_data<=8'h54; end
3: begin lcd_rs<=1; lcd_data<=8'h4F; end
4: begin lcd_rs<=1; lcd_data<=8'h43; end
5: begin lcd_rs<=1; lcd_data<=8'h4B; end
6: begin lcd_rs<=1; lcd_data<=8'h3A; end
7: begin lcd_rs<=1; lcd_data<=8'h30; end
8: begin lcd_rs<=1; lcd_data<=8'h30; end
13: begin lcd_rs<=1; lcd_data<=8'h59; end
14: begin lcd_rs<=1; lcd_data<=8'h2F; end
15: begin lcd_rs<=1; lcd_data<=8'h4E; end
default:begin lcd_rs<=1; lcd_data<=8'h20; end
endcase
end
delay_t: begin
lcd_rs<=0;
lcd_rw<=0;
lcd_data<=8'b00000010;
end
default:begin
lcd_rs<=1;
lcd_rw<=1;
lcd_data<=8'b00000000;
end
endcase
end
end
assign lcd_e = clk_100hz;
oneshot lcd1(
.clk(clk_100hz),
.btn(disp_up),
.oneshot(disp_up_100)
);
oneshot lcd2(
.clk(clk_100hz),
.btn(disp_down),
.oneshot(disp_down_100)
);
oneshot lcd3(
.clk(clk_100hz),
.btn(prod1),
.oneshot(prod1_100)
);
oneshot lcd4(
.clk(clk_100hz),
.btn(prod2),
.oneshot(prod2_100)
);
oneshot lcd5(
.clk(clk_100hz),
.btn(prod3),
.oneshot(prod3_100)
);
oneshot lcd6(
.clk(clk_100hz),
.btn(prod4),
.oneshot(prod4_100)
);
oneshot lcd7(
.clk(clk_100hz),
.btn(confirm),
.oneshot(confirm_100)
);
oneshot lcd8(
.clk(clk_100hz),
.btn(cancel),
.oneshot(cancel_100)
);
endmodule
This module is a sub-module of the vending machine module, responsible for controlling the LCD. I think I write all pass to each cases, but after synthesis, I got this error message:
[Synth 8-151] case item 4'b0110 is unreachable
I don't know why this message appeared.
I've checked and written all the paths leading to the delay_t
state with the 4'b0110 condition, but the error message persists.
You have duplicate case items in the case
statement with delay_t
:
case (state)
...
delay_t: if(cnt == 10) state <= select;
...
delay_t: if(cnt == 10) state <= line1_list;
The first is reachable; the second is not. Once state
matches the first delay_t
line, the case
statement exits; it no longer looks at other case items. Refer to IEEE Std 1800-2017, section 12.5 Case statement
Since the second case item is not used, you should either delete it or re-design your logic.