Проект пешеходного светофора
Рассмотрим проект контроллера светофора для пешеходного перехода.
Имеем следующее оборудование:
светофор для автомобилей, три сигнала: красный, желтый, зеленый
светофор для пешеходов, два сигнала: красный, зеленый
кнопка переключения
генератор импульсов, задающий время
В обычном состоянии автомобильный светофор должен быть открыт (зеленый), а пешеходный - закрыт (красный). По нажатию кнопки светофоры должны переключиться, открыв пешеходный переход, затем вернуться в исходное состояние.
Для реального светофора время каждого состояния должно задаваться отдельно, но это оставим на потом.
Реализация на языке Verilog
Классическая реализация конечного автомата.
//
// Simple traffic light controller.
// Implemented using Verilog.
// There are two traffic lights: one for cars and another for pedestrians.
// Usually car light is green and pedestrian light is red.
// Pressing button requests opening the way for pedestrians.
//
module traffic_light (
input wire clock,
input wire button,
output wire car_red,
output wire car_yellow,
output wire car_green,
output wire ped_red,
output wire ped_green);
// Four states:
// 0) yellow for cars, red for pedestrians
// 1) red for cars, green for pedestrians
// 2) red+yellow for cars, red for pedestrians
// 3) green for cars, red for pedestrians
parameter [1:0] YELLOW = 0;
parameter [1:0] RED = 1;
parameter [1:0] RED_YELLOW = 2;
parameter [1:0] GREEN = 3;
reg [1:0] state, next_state;
// Pressing button forces state 0. Then states
// are changed every clock cycle 0->1->2->3.
// State 3 is kept until pressing req.
always @ (state or button)
begin
next_state = GREEN;
case (state)
YELLOW:
next_state = RED;
RED:
next_state = RED_YELLOW;
RED_YELLOW:
next_state = GREEN;
GREEN:
if (button == 1) begin
next_state = YELLOW;
end else begin
next_state = GREEN;
end
default:
next_state = GREEN;
endcase
end
always @ (posedge clock)
begin
state <= next_state;
case (next_state)
YELLOW: begin
car_red <= 0;
car_yellow <= 1;
car_green <= 0;
ped_red <= 1;
ped_green <= 0;
end
RED: begin
car_red <= 1;
car_yellow <= 0;
car_green <= 0;
ped_red <= 0;
ped_green <= 1;
end
RED_YELLOW: begin
car_red <= 1;
car_yellow <= 1;
car_green <= 0;
ped_red <= 1;
ped_green <= 0;
end
GREEN: begin
car_red <= 0;
car_yellow <= 0;
car_green <= 1;
ped_red <= 1;
ped_green <= 0;
end
endcase
end
endmodule
Реализация на языке Plog
Цикл с четырьмя состояниями. Код можно было бы еще упростить, убрав избыточные присваивания.
Оператор-метка «label» выполняет двойную функцию:
Операторы, находящиеся между двумя метками, выполняются одновременно и параллельно.
Данный код может быть транслирован в Verilog прозрачным образом.
//
// Simple traffic light controller.
// Implemented using Plog.
// There are two traffic lights: one for cars and another for pedestrians.
// Usually car light is green and pedestrian light is red.
// Pressing button requests opening the way for pedestrians.
//
traffic_light: module {
clock: input;
ped_req: input;
car_red: output;
car_yellow: output;
car_green: output;
ped_red: output;
ped_green: output;
};
synchronize posedge clock;
forever {
// Initial GREEN state
car_red := 0;
car_yellow := 0;
car_green := 1;
ped_red := 1;
ped_green := 0;
<<green>>
// Pressing button opens the way for pedestrians.
// States are changed every clock until back to GREEN.
if (button == 1) {
// Switch to YELLOW state
car_red := 0;
car_yellow := 1;
car_green := 0;
ped_red := 1;
ped_green := 0;
<<yellow>>
// On next tick switch to RED state
car_red := 1;
car_yellow := 0;
car_green := 0;
ped_red := 0;
ped_green := 1;
<<red>>
// On next tick switch to RED-YELLOW state
car_red := 1;
car_yellow := 1;
car_green := 0;
ped_red := 1;
ped_green := 0;
<<red_yellow>>
// On next tick switch to GREEN state
}
}