Реализация на языке Plog
Ниже приведена “примерная” реализация светофора на языке Plog. Спецификация языка еще не готова, пока только образец кода.
Все операторы, в отличие от традиционного программирования, выполняются параллельно. Для разделения на такты служат метки синхронизации (сокращенно “синхроны”) вида «имя». Каждый синхрон превращается в одно состояние конечного автомата. Поскольку все синхроны присутствуют в тексте программы явным образом, количество тактов выполнения легко посчитать.
Еще один необычный оператор - “start (rst, clk) {…}”. Операторы, находящиеся внутри, выполняются независимо (параллельно) и постоянно (как бы в бесконечном цикле). Первый параметр задаёт сигнал сброса. При его установке система переходит в начальное состояние. Второй параметр определяет сигнал синхронизации. Синхроны срабатывают по переднему фронту этого сигнала.
После компиляции должен получиться код на Верилоге примерно следующего вида: tlight-v.
type Wire: Bit; type Unsigned8: Bit [8]; module traffic_light_controller ( input rst: Wire, // Сброс в исходное состояние input clk: Wire, // Синхросигнал, 10 импульсов в секунду input button: Wire, // Кнопка запроса на переход output red: Wire, // Красный output yellow: Wire, // Желтый output green: Wire, // Зелёный output stop: Wire, // "Стойте" output walk: Wire, // "Идите" ) { // Исходное состояние: красный, "стойте". red := 1; yellow := 0; green := 0; stop := 1; walk := 0; // Запомненный запрос на переход button_request: Bit := 0; // Отсюда начинается выполнение при сбросе. // Операторы в блоке start выполняются параллельно. start (rst, clk) { // В стартовом блоке все операторы выполняются параллельно. traffic_light (); // Если нажата кнопка, запоминаем запрос. if (button) button_request := 1; } // // Работа светофора, бесконечный цикл. // procedure traffic_light () { // Задержим исходное состояние на одну секунду. /*1*/ delay (10); forever { // Жёлтый+красный для автомобилей, // “стойте” для пешеходов. Длится одну секунду. yellow := 1; stop := 1; walk := 0; /*2*/ delay (10); // Зеленый для автомобилей, “стойте” для пешеходов. // Обычное состояние при отсутствии пешеходов. red := 0; yellow := 0; green := 1; /*3*/ delay (250); // Ждём нажатия кнопки пешеходом. // Перед циклом требуется синхрон. <<wait_request>> while (! button_request) { // Пустой цикл. } button_request := 0; // Мигает зеленый для автомобилей, // горит “стойте” для пешеходов. // Включается через некоторое время (не более // 25 секунд) после нажатия кнопки запроса. // Длится три секунды. /*4*/ green := 0; delay (5); /*5*/ green := 1; delay (5); /*6*/ green := 0; delay (5); /*7*/ green := 1; delay (5); /*8*/ green := 0; delay (5); /*9*/ green := 1; delay (5); // Жёлтый для автомобилей, “стойте” для пешеходов. // Длится три секунды. yellow := 1; green := 0; /*10*/ delay (30); // Красный для автомобилей, “идите” для пешеходов. // Длится десять секунд. red := 1; yellow := 0; stop := 0; walk := 1; /*11*/ delay (100); // Красный для автомобилей, мигает “идите” // для пешеходов. Длится три секунды. /*12*/ walk := 0; delay (5); /*13*/ walk := 1; delay (5); /*14*/ walk := 0; delay (5); /*15*/ walk := 1; delay (5); /*16*/ walk := 0; delay (5); /*17*/ walk := 1; delay (5); } } // // Ожидание N тактов синхросигнала. // procedure delay (n: Unsigned8) { // Перед циклом требуется синхрон. <<delay>> while (n > 0) { n := n - 1; } } }