5. Phân tích khối TIME_COUNTERChọn giá trị:GREEN_TIME = 59. Đèn xanh sáng 60sYELLOW_TIME = 4. Thời gian đèn vàng sáng 5s.RED_TIME = 1 Thời gian đèn đỏ trên cả 2 đường cùng sáng là 2s.YELLOW_YELLOW_TIME = 17999. (5 giờ đồng hồ)LEFT_TIME = 24; thời gian rẽ trái là 25sSTART_YY_TIME = 68399; from 5h:00 to 24h:59DAY_TIME = 86399;Hình 5 Sơ đồ nguyên lý khối TIME_COUNTER Bộ đếm xung có output n+1 bit, cho phép người dùng điều chỉnh linh hoạt các giá trị RED_RED_TIME, GREEN_TIME, YELLOW_TIME, YELLOW_YELLOW_TIME và RED_LEFT_TIME tùy ý. Trong bài này có YELLOW_YELLOW_TIME = 200 nên chỉ cần sử dụng n=7 nhưng nhóm quyết định sử dụng n=14 là để phù hợp vợi với thực tế YELLOW_YELLOW_TIME = 18000s (từ 0 giờ đến 5 giờ sáng).Giả sử current_state = AGBR | ARBG, khi đó fsm_g=1, fsm_y=0, fsm_rr=0, fsm_l=0 và fsm_yy=0. Như vậy clk_countern:0 sẽ được đưa vào bộ so sánh với GREEN_TIME. Khi clk_countern:0 = 14’d29 thì g_end =0 =>> clr_counter = 0 =>> bộ đếm được tăng lên 1 đơn vị cho đến khi clk_countern:0 = 14’d29 thì đầu ra bộ so sánh bằng 1 =>> g_end = 1. Khi g_end = 1 sẽ làm cho clr_counter =1 =>> bộ đếm được thiết lập lại, nghĩa là clk_countern:0 =14’d0, đồng thời cũng tác động lên khối FSM chuyển sang next_state tương ứng.Với clk_counter_yy17:0 sẽ được đếm từ lúc có tín hiệu rst_n = 0 đến khi clk_counter_yy17:0=17’d1000 (với 1 ngày hoàn chỉnh nó sẽ đếm đến 17’d86400).
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ-VIỄN THÔNG
THIẾT KẾ VÀ TỔNG HỢP
IC SỐ
Đề tài: ĐIỀU KHIỂN ĐÈN GIAO THÔNG
Trang 2Mục lục
1 Đề tài 3
2 Sơ đồ tổng quát 4
3 Sơ đồ khối 5
3.1 TIME_COUNTER 6
3.2 FSM 6
4 Phân tích khối FSM 6
5 Phân tích khối TIME_COUNTER 7
6 Mã hóa trạng thái 9
7 Mô phỏng 10
8 Phụ luc (hình ảnh, bảng biểu và code) 11
Tài liệu tham khảo: Jr.Charles H.Roth - Digital Systems Design Usin
Trang 31 Đề tài
1.1 Giả sử STREET A có mức độ ưu tiên hơn STREET B, khi rst_n tích cực mức thấp thì đèn trên STREET A sẽ xanh trước
1.2 Mỗi đường sẽ có 4 tín hiệu điều khiển đèn tương ứng với 3 màu Red/Yellow/Green và Left (màu xanh) để rẽ trái viết tắt là R/Y/G/L
1.3 Đèn sẽ hoạt động bình thường chuyển trạng thái đỏ >> xanh >> vàng >> rẽ trái từ
5 giờ sáng đến hết 12 giờ đêm Sau 12 giờ đêm đến 5 giờ sáng đèn trên cả 2 đường màu vàng (nếu ko có tín hiệu rst_n/rst_nA/rst_nB)
1.4 Trạng thái khởi động là trạng thái đèn trên cả STREET A và STREET B đều đỏ (AR-BR1 hoặc AR-BR2)
1.5 Bảng chuyển trạng thái
Hình 1 Đèn giao thông tại 1 ngã tư
-STRE
ET
- B
STREET - B
G
Y
Y
R
R
Trang 4Street A Street B
Y
R
G
Y
R
R
Y
RL
R
R
R
R
Y
RL
Bảng 1 bảng chuyển trạng thái
2 Sơ đồ tổng quát
Hình 2 Sơ đồ tổng quát
Trong đó:
- clk là xung clock
- rst_n là tín hiệu dùng để khởi động bộ điều khiển đến trạng thái ban đầu Red-Red khi nó tích cực mức thấp, STREET A sẽ được ưu tiên đi trước rst_n được ưu tiên
so với rst_nA
- rst_nA là tín hiệu dùng để khởi động bộ điều khiển đến trạng thái ban đầu Red-Red khi nó tích cực mức thấp, STREET A sẽ được ưu tiên đi trước.rst_nA gần giống với rst_n và được ưu tiên so với rst_nB
- rst_nB là tín hiệu dùng để khởi động bộ điều khiển đến trạng thái ban đầu Red-Red khi nó tích cực mức thấp, STREET B sẽ được ưu tiên đi trước
Traffic_light_controller
street_a[3:0]
street_b[3:0]
clk rst_n rst_nA rst_nB
Trang 5- street_a[3:0] là tín hiệu điều khiển đèn trên đường STREET A Thứ tự bit từ 3 đến
0 tương ứng với trạng thái R/Y/G/L, tích cực mức 1
- street_b[3:0] tương tự street_a[3:0] trên đường STREET B
Bảng mã hóa giá trị ngõ ra tương ứng với các trạng thái đèn như sau:
Street A Street B Street_a[2:0] Street_b[20]
Bảng 2 Bảng giá trị ngõ ra bộ điều khiển tương ứng với trạng thái đèn
3 Sơ đồ khối
Hình 3 Sơ đồ khối của bộ điều khiển đèn giao thông
Time_counter
FSM Traffic_light
g_end rr_end
y_end yy_end
fsm_g fsm_y
fsm_rr fsm_yy
street_b[3:0]
street_a[3:0] clk
rst_n rst_nA rst_nB
l_end fsm_l
Trang 63.1 TIME_COUNTER : dùng để đếm xunh clock xác định thời gian duy trì trạng thái của đèn Đây là thời gian có thể cấu hình được trước khi biên dịch như yêu cầu đặt ra Năm tín hiệu g_end, rr_end, y_end, yy_end và l_end báo thời điểm kết thúc của trạng thái GREEN, RED_RED, YELLOW, YELLOW_YELLOW và RED_LEFT Năm tín hiệu fsm_g, fsm_rr, fsm_y , fsm_yy và fsm_l báo trạng thái GREEN, REG_RED, YELLOW, YELLOW_YELLOW và RED_LEFT để bộ đếm hoạt động theo giá trị cấu hình phù hợp
3.2 FSM : là máy trạng thái sẽ tạo ngõ ra street_a, street_b và fsm_g, fsm_rr, fsm_y, fsm_yy và fsm_l
4 Phân tích khối FSM
Hình 4 FSM điều khiển đèn giao thông
AR – BR2
AY-BR
AR – BR1
AG-BR
rst_n/ rst_nA
rr_end
g_end
g_end
AY - BY
rst_nB
rr_end
ARL-BR
AR-BRL
Trang 7Trong đó, ký hiệu A và B ứng với STREET A và STREET B G là GREEN, R là RED và Y là YELLOW Ví dụ, AG_BR nghĩa là trạng thái STREET A đang GREEN, STREET B đang RED
Sau khi reset thì cả hai đèn phải RED-RED nên ta có thể chọn trạng thái AR-BR1 hoặc AR-BR2 tùy vào yêu cầu ưu tiên
Việc tự động chuyển trạng thái chỉ xảy ra khi tín hiệu báo độ trễ tương ứng của trạng thái đó tích cực Ví dụ, khi đèn trên STREET A hoặc STREET B đang xanh thì g_end phải tích cực thì mới chuyển sang trạng thái tiếp theo
[3:0]
Street_b [3:0]
AY-BY 0100 0100 0 0 0 1 0
AR-BR1 1000 1000 0 0 1 0 0
AG-BR 0010 1000 1 0 0 0 0
AY-BR 0100 1000 0 1 0 0 0
ARL-BR 1001 1000 0 0 0 0 1
AR-BG 1000 0010 1 0 0 0 0
AR-BY 1000 0100 0 1 0 0 0
AR-BR2 1000 1000 0 0 1 0 0
Bảng 3 Bảng giá trị đầu ra của FSM
Chọn giá trị:
- GREEN_TIME = 59 Đèn xanh sáng 60s
- YELLOW_TIME = 4 Thời gian đèn vàng sáng 5s
- RED_TIME = 1 Thời gian đèn đỏ trên cả 2 đường cùng sáng là 2s
- YELLOW_YELLOW_TIME = 17999 (5 giờ đồng hồ)
- LEFT_TIME = 24; thời gian rẽ trái là 25s
Trang 8- DAY_TIME = 86399;
Hình 5 Sơ đồ nguyên lý khối TIME_COUNTER
Bộ đếm xung 1
GREEN_TIME
RED_RED_TIME
=?
?
=?
=?
?
=?
?
YELLOW_YELLOW_TIME
YELLOW_TIME clk
rst_n rst_nA rst_nB
0
+1
1
fsm_y
y_end fsm_g g_end
fsm_yy
yy_end
fsm_rr rr_end
clr_counter
clk_counter[14:0]
0
1
RED_LEFT_TIME
=?
?
fsm_l l_end
=?
?
=?
?
DAY_TIME
START_YY_TIME clk
rst_n
0
+1
1
pos_Y
clr_counter_yy
clk_counter_yy[17:0]
0
1
Hình 6 Bộ đếm xung 2
Trang 9
Bộ đếm xung có output n+1 bit, cho phép người dùng điều chỉnh linh hoạt các giá trị RED_RED_TIME, GREEN_TIME, YELLOW_TIME, YELLOW_YELLOW_TIME
và RED_LEFT_TIME tùy ý
Trong bài này có YELLOW_YELLOW_TIME = 200 nên chỉ cần sử dụng n=7 nhưng nhóm quyết định sử dụng n=14 là để phù hợp vợi với thực tế YELLOW_YELLOW_TIME = 18000s (từ 0 giờ đến 5 giờ sáng)
Giả sử current_state = AG-BR | AR-BG, khi đó fsm_g=1, fsm_y=0, fsm_rr=0,
fsm_l=0 và fsm_yy=0 Như vậy clk_counter[n:0] sẽ được đưa vào bộ so sánh với GREEN_TIME Khi clk_counter[n:0] != 14’d29 thì g_end =0 =>> clr_counter = 0
=>> bộ đếm được tăng lên 1 đơn vị cho đến khi clk_counter[n:0] = 14’d29 thì đầu ra
bộ so sánh bằng 1 =>> g_end = 1 Khi g_end = 1 sẽ làm cho clr_counter =1 =>> bộ đếm được thiết lập lại, nghĩa là clk_counter[n:0] =14’d0, đồng thời cũng tác động lên khối FSM chuyển sang next_state tương ứng
Với clk_counter_yy[17:0] sẽ được đếm từ lúc có tín hiệu rst_n = 0 đến khi clk_counter_yy[17:0]=17’d1000 (với 1 ngày hoàn chỉnh nó sẽ đếm đến 17’d86400)
6 Mã hóa trạng thái
AR-BR1 4’d2
ARL-BR 4’d5
AR-BR2 4’d8
AR-BRL 4’d9
Bảng 4 Mã hóa trạng thái
Trang 107 Mô phỏng
Hình 7 Thời điểm ban đầu có tín hiệu rst_n = 0
Hình 8 Thời điểm có pos_Y = 1
Trang 118 Phụ luc (hình ảnh, bảng biểu và code)
Bảng 1 bảng chuyển trạng thái 4
Bảng 2 Bảng giá trị ngõ ra bộ điều khiển tương ứng với trạng thái đèn 5
Bảng 3 Bảng giá trị đầu ra của FSM 7
Bảng 4 Mã hóa trạng thái 9
Hình 1 Đèn giao thông tại 1 ngã tư ( street B được rẽ trái ) 3
Hình 2 Sơ đồ tổng quát 4
Hình 3 Sơ đồ khối của bộ điều khiển đèn giao thông 5
Hình 4 FSM điều khiển đèn giao thông 6
Hình 5 Sơ đồ nguyên lý khối TIME_COUNTER 8
Hình 6 Bộ đếm xung 2 8
Hình 7 Thời điểm ban đầu có tín hiệu rst_n = 0 10
Hình 8 Thời điểm có pos_Y = 1 10
//CODE
/*FSM**************************/
module fsm (
// Outputs
street_a, street_b, fsm_g, fsm_y,
fsm_rr,fsm_yy, fsm_l,
// Inputs
clk,rst_n, rst_nA,rst_nB,pos_Y, g_end,
y_end, rr_end,yy_end,l_end
);
//
input clk;
input rst_n;
input rst_nA;
input rst_nB;
output pos_Y;
input g_end;
input y_end;
input rr_end;
input yy_end;
input l_end;
output reg [3:0] street_a;
output reg [3:0] street_b;
output wire fsm_g;
output wire fsm_y;
output wire fsm_rr;
output wire fsm_yy;
output wire fsm_l;
//
reg [3:0] current_state, next_state; //STATE code
localparam AY_BY = 4'd0;
localparam AR_BR1 = 4'd1;
localparam AG_BR = 4'd2;
localparam AY_BR = 4'd3;
localparam ARL_BR = 4'd4;
localparam AR_BG = 4'd5;
localparam AR_BY = 4'd6;
localparam AR_BR2 = 4'd7;
localparam AR_BRL = 4'd8;
//Next state logic always @ (*) begin case (current_state[3:0])
AY_BY: begin
if (yy_end) next_state[3:0] = AR_BR1;
else next_state[3:0] = current_state[3:0];
end
AR_BR1: begin
Trang 12if (rr_end) next_state[3:0] = AG_BR;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AG_BR: begin
if (g_end) next_state[3:0] = AY_BR;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AY_BR: begin
if (y_end) next_state[3:0] = ARL_BR;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
ARL_BR: begin
if (l_end) next_state[3:0] = AR_BG;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AR_BG: begin
if (g_end) next_state[3:0] = AR_BY;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AR_BY: begin
if (y_end) next_state[3:0] = AR_BRL;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AR_BRL: begin
if (l_end) next_state[3:0] = AG_BR;
else if (pos_Y) next_state[3:0] =
AY_BY;
else next_state[3:0] =
current_state[3:0];
end
AR_BR2: begin
if (rr_end) next_state[3:0] = AR_BG; else if (pos_Y) next_state[3:0] = AY_BY;
else next_state[3:0] = current_state[3:0];
end default: next_state[3:0] = current_state[3:0];
endcase end //STATE MEMORY always @ (posedge clk) begin
if (~rst_n|~rst_nA) current_state[3:0]
<= AR_BR1;
else if (~rst_nB) current_state[3:0] <= AR_BR2;
else current_state[3:0] <=
next_state[3:0];
end //Output logic always @ (*) begin case (current_state[3:0]) AY_BY: street_a[3:0] = 4'b0100; AG_BR: street_a[3:0] = 4'b0010; AY_BR: street_a[3:0] = 4'b0100; ARL_BR:street_a[3:0] = 4'b1001; default: street_a[3:0] = 4'b1000; endcase
end //
always @ (*) begin case (current_state[3:0]) AY_BY: street_b[3:0] = 4'b0100; AR_BG: street_b[3:0] = 4'b0010; AR_BY: street_b[3:0] = 4'b0100; AR_BRL:street_b[3:0] = 4'b1001; default: street_b[3:0] = 4'b1000; endcase
end assign fsm_g = (current_state[3:0] == AG_BR) | (current_state[3:0] ==
AR_BG);
assign fsm_y = (current_state[3:0] == AY_BR) | (current_state[3:0] == AR_BY);
Trang 13assign fsm_rr = (current_state[3:0] ==
AR_BR1)|(current_state[3:0] ==
AR_BR2);
assign fsm_yy = (current_state[3:0] ==
AY_BY);
assign fsm_l = (current_state[3:0] ==
ARL_BR)|(current_state[3:0] ==
AR_BRL);
endmodule
/*******************************/
/*TIME_COUNTER*****************/
module time_counter (
// Outputs
g_end, y_end, rr_end, yy_end,l_end,
// Inputs
clk,rst_n, rst_nA,rst_nB,pos_Y, fsm_g,
fsm_rr, fsm_y,fsm_yy,fsm_l
);
parameter RED_RED_TIME = 1;
parameter GREEN_TIME = 59;
parameter YELLOW_TIME = 4;
parameter LEFT_TIME = 24;
parameter START_YY_TIME = 68399;
parameter DAY_TIME = 86399;
parameter YELLOW_YELLOW_TIME =
17999;
parameter n=14;
parameter m=17;
//
input clk;
input rst_n;
input rst_nA;
input rst_nB;
output pos_Y;
input fsm_g;
input fsm_rr;
input fsm_yy;
input fsm_y;
input fsm_l;
output wire g_end;
output wire y_end;
output wire rr_end;
output wire yy_end;
output wire l_end;
//
reg [n:0] clk_counter;
wire clr_counter;
reg [m:0] clk_counter_yy;
wire clr_counter_yy;
//
always @ (posedge clk) begin
if (~rst_n|~rst_nA|~rst_nB|pos_Y) clk_counter[n:0] <=0;
else if (clr_counter) clk_counter[n:0]
<= 0;
else clk_counter[n:0] <=
clk_counter[n:0] + 1'b1;
end //
always @ (posedge clk) begin
if (~rst_n) clk_counter_yy[m:0] <=0; else if (clr_counter_yy)
clk_counter_yy[m:0] <= 0;
else clk_counter_yy[m:0] <=
clk_counter_yy[m:0] + 1'b1;
end //Compare the end time assign g_end = fsm_g &
(clk_counter[n:0] == GREEN_TIME); assign y_end = fsm_y &
(clk_counter[n:0] == YELLOW_TIME); assign rr_end = fsm_rr &
(clk_counter[n:0] == RED_RED_TIME); assign yy_end = fsm_yy &
(clk_counter[n:0] ==
YELLOW_YELLOW_TIME);
assign l_end = fsm_l & (clk_counter[n:0]
== LEFT_TIME);
assign pos_Y=(clk_counter_yy [m:0]
==START_YY_TIME);
//
assign clr_counter = g_end | y_end | rr_end|yy_end|l_end;
assign clr_counter_yy=(clk_counter_yy[m:0]
== DAY_TIME);
endmodule /*******************************/ /*CONTROLLER*******************/ module traffic_light_controller (
// Outputs street_b, street_a, // Inputs
rst_n,rst_nA,rst_nB , clk
Trang 14);
input clk;
input rst_n;
input rst_nA;
input rst_nB;
output [3:0]street_a;
output [3:0]street_b;
wire pos_Y;
wire fsm_l;
wire fsm_g;
wire fsm_rr;
wire fsm_y;
wire fsm_yy;
wire g_end;
wire rr_end;
wire y_end;
wire yy_end;
wire l_end;
time_counter cnt (
// Outputs l_end(l_end), g_end(g_end), y_end(y_end), rr_end(rr_end), yy_end(yy_end), // Inputs
clk(clk), rst_n(rst_n), rst_nA(rst_nA), rst_nB(rst_nB), pos_Y(pos_Y), fsm_g(fsm_g), fsm_rr(fsm_rr), fsm_y(fsm_y), fsm_yy(fsm_yy), fsm_l(fsm_l) );
fsm fsm (
// Outputs .street_a(street_a[3:0]), .street_b(street_b[3:0]), .fsm_l (fsm_l),
fsm_g (fsm_g),
fsm_y (fsm_y), .fsm_rr(fsm_rr), .fsm_yy(fsm_yy), // Inputs
clk(clk), .rst_n(rst_n), .rst_nA(rst_nA), .rst_nB(rst_nB), .pos_Y(pos_Y), .g_end(g_end), .y_end(y_end), .rr_end(rr_end), .yy_end(yy_end), .l_end(l_end) );
endmodule /*******************************/
/*TEST_BENCH*******************/
`timescale 1ns/1ns module tb_traffic_light;
reg clk;
reg rst_n;
reg rst_nA;
reg rst_nB;
wire [3:0]street_a;
wire [3:0]street_b;
traffic_light_controller DUT ( // Outputs
street_a(street_a[3:0]), .street_b(street_b[3:0]), // Inputs
.clk(clk), .rst_n(rst_n), .rst_nA(rst_nA), rst_nB(rst_nB) );
initial begin clk = 0;
forever #10 clk = !clk;
end initial begin rst_n = 0;rst_nA=1;rst_nB=1;
#20 rst_n = 1;
endmodule