Рассмотрим проект контроллера светофора для пешеходного перехода.
Имеем следующее оборудование:
В обычном состоянии автомобильный светофор должен быть открыт (зеленый), а пешеходный - закрыт (красный). По нажатию кнопки светофоры должны переключиться, открыв пешеходный переход, затем вернуться в исходное состояние.
Для реального светофора время каждого состояния должно задаваться отдельно, но это оставим на потом.
Классическая реализация конечного автомата.
// // 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
Цикл с четырьмя состояниями. Код можно было бы еще упростить, убрав избыточные присваивания.
Оператор-метка «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 } }