package TL9 (sysTL, TL) where -- Simple model of a traffic light -- Version 9: Use Bluespec layout rules to reduce lexical noise interface TL = ped_button_push :: Action set_car_state_N :: Bool -> Action set_car_state_S :: Bool -> Action set_car_state_E :: Bool -> Action set_car_state_W :: Bool -> Action lampRedNS :: Bool lampAmberNS :: Bool lampGreenNS :: Bool lampRedE :: Bool lampAmberE :: Bool lampGreenE :: Bool lampRedW :: Bool lampAmberW :: Bool lampGreenW :: Bool lampRedPed :: Bool lampAmberPed :: Bool lampGreenPed :: Bool data TLstates = AllRed | GreenNS | AmberNS | GreenE | AmberE | GreenW | AmberW | GreenPed | AmberPed deriving (Eq, Bits) type Time32 = UInt 5 sysTL :: Module TL sysTL = module state :: Reg TLstates state <- mkReg AllRed next_green :: Reg TLstates next_green <- mkReg GreenNS secs :: Reg Time32 secs <- mkReg 0 ped_button_pushed :: Reg Bool ped_button_pushed <- mkReg False car_present_NS :: Reg Bool car_present_NS <- mkReg True car_present_E :: Reg Bool car_present_E <- mkReg True car_present_W :: Reg Bool car_present_W <- mkReg True let allRedDelay :: Time32 allRedDelay = 2 amberDelay :: Time32 amberDelay = 4 ns_green_delay :: Time32 ns_green_delay = 20 ew_green_delay :: Time32 ew_green_delay = 10 pedGreenDelay :: Time32 pedGreenDelay = 10 pedAmberDelay :: Time32 pedAmberDelay = 6 next_state :: TLstates -> Action next_state ns = action { state := ns; secs := 0; } green_seq :: TLstates -> TLstates green_seq GreenNS = GreenE green_seq GreenE = GreenW green_seq GreenW = GreenNS car_present :: TLstates -> Bool car_present GreenNS = car_present_NS car_present GreenE = car_present_E car_present GreenW = car_present_W make_from_green_rule :: String -> TLstates -> Time32 -> Bool -> TLstates -> Rules make_from_green_rule rule_name green_state delay car_present ns = rules rule_name: when (state == green_state) && (((secs + 1) >= delay) || not car_present) ==> next_state (ns) make_from_amber_rule :: String -> TLstates -> TLstates -> Rules make_from_amber_rule rule_name amber_state ng = rules rule_name: when (state == amber_state) && ((secs + 1) >= amberDelay) ==> action { next_state (AllRed); next_green := ng; } interface ped_button_push = ped_button_pushed := True set_car_state_N b = car_present_NS := b set_car_state_S b = car_present_NS := b set_car_state_E b = car_present_E := b set_car_state_W b = car_present_W := b lampRedNS = not ((state == GreenNS) || (state == AmberNS)) lampAmberNS = state == AmberNS lampGreenNS = state == GreenNS lampRedE = not ((state == GreenE) || (state == AmberE)) lampAmberE = state == AmberE lampGreenE = state == GreenE lampRedW = not ((state == GreenW) || (state == AmberW)) lampAmberW = state == AmberW lampGreenW = state == GreenW lampRedPed = not ((state == GreenPed) || (state == AmberPed)) lampAmberPed = state == AmberPed lampGreenPed = state == GreenPed addRules $ rules "wait": when True ==> secs := secs + 1 +> ( rules "fromAllRed": when (state == AllRed) && ((secs + 1) >= allRedDelay) ==> if ped_button_pushed then action { ped_button_pushed := False; next_state (GreenPed); } else if car_present (next_green) then next_state (next_green) else if car_present (green_seq next_green) then next_state (green_seq next_green) else if car_present (green_seq (green_seq next_green)) then next_state (green_seq (green_seq next_green)) else next_state (AllRed) "fromGreenPed": when (state == GreenPed) && ((secs + 1) >= pedGreenDelay) ==> next_state (AmberPed) "fromAmberPed": when (state == AmberPed) && ((secs + 1) >= pedAmberDelay) ==> next_state (AllRed) <+> make_from_green_rule "fromGreenNS" GreenNS ns_green_delay car_present_NS AmberNS <+> make_from_amber_rule "fromAmberNS" AmberNS GreenE <+> make_from_green_rule "fromGreenE" GreenE ew_green_delay car_present_E AmberE <+> make_from_amber_rule "fromAmberE" AmberE GreenW <+> make_from_green_rule "fromGreenW" GreenW ew_green_delay car_present_W AmberW <+> make_from_amber_rule "fromAmberW" AmberW GreenNS )